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
|
package engine
import (
"fmt"
"strconv"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb/schema_pb"
)
// Helper function to convert schema_pb.Value to float64
func (e *SQLEngine) valueToFloat64(value *schema_pb.Value) (float64, error) {
switch v := value.Kind.(type) {
case *schema_pb.Value_Int32Value:
return float64(v.Int32Value), nil
case *schema_pb.Value_Int64Value:
return float64(v.Int64Value), nil
case *schema_pb.Value_FloatValue:
return float64(v.FloatValue), nil
case *schema_pb.Value_DoubleValue:
return v.DoubleValue, nil
case *schema_pb.Value_StringValue:
// Try to parse string as number
if f, err := strconv.ParseFloat(v.StringValue, 64); err == nil {
return f, nil
}
return 0, fmt.Errorf("cannot convert string '%s' to number", v.StringValue)
case *schema_pb.Value_BoolValue:
if v.BoolValue {
return 1, nil
}
return 0, nil
default:
return 0, fmt.Errorf("cannot convert value type to number")
}
}
// Helper function to check if a value is an integer type
func (e *SQLEngine) isIntegerValue(value *schema_pb.Value) bool {
switch value.Kind.(type) {
case *schema_pb.Value_Int32Value, *schema_pb.Value_Int64Value:
return true
default:
return false
}
}
// Helper function to convert schema_pb.Value to string
func (e *SQLEngine) valueToString(value *schema_pb.Value) (string, error) {
switch v := value.Kind.(type) {
case *schema_pb.Value_StringValue:
return v.StringValue, nil
case *schema_pb.Value_Int32Value:
return strconv.FormatInt(int64(v.Int32Value), 10), nil
case *schema_pb.Value_Int64Value:
return strconv.FormatInt(v.Int64Value, 10), nil
case *schema_pb.Value_FloatValue:
return strconv.FormatFloat(float64(v.FloatValue), 'g', -1, 32), nil
case *schema_pb.Value_DoubleValue:
return strconv.FormatFloat(v.DoubleValue, 'g', -1, 64), nil
case *schema_pb.Value_BoolValue:
if v.BoolValue {
return "true", nil
}
return "false", nil
case *schema_pb.Value_BytesValue:
return string(v.BytesValue), nil
default:
return "", fmt.Errorf("cannot convert value type to string")
}
}
// Helper function to convert schema_pb.Value to int64
func (e *SQLEngine) valueToInt64(value *schema_pb.Value) (int64, error) {
switch v := value.Kind.(type) {
case *schema_pb.Value_Int32Value:
return int64(v.Int32Value), nil
case *schema_pb.Value_Int64Value:
return v.Int64Value, nil
case *schema_pb.Value_FloatValue:
return int64(v.FloatValue), nil
case *schema_pb.Value_DoubleValue:
return int64(v.DoubleValue), nil
case *schema_pb.Value_StringValue:
if i, err := strconv.ParseInt(v.StringValue, 10, 64); err == nil {
return i, nil
}
return 0, fmt.Errorf("cannot convert string '%s' to integer", v.StringValue)
default:
return 0, fmt.Errorf("cannot convert value type to integer")
}
}
// Helper function to convert schema_pb.Value to time.Time
func (e *SQLEngine) valueToTime(value *schema_pb.Value) (time.Time, error) {
switch v := value.Kind.(type) {
case *schema_pb.Value_TimestampValue:
if v.TimestampValue == nil {
return time.Time{}, fmt.Errorf("null timestamp value")
}
return time.UnixMicro(v.TimestampValue.TimestampMicros), nil
case *schema_pb.Value_StringValue:
// Try to parse various date/time string formats
dateFormats := []struct {
format string
useLocal bool
}{
{"2006-01-02 15:04:05", true}, // Local time assumed for non-timezone formats
{"2006-01-02T15:04:05Z", false}, // UTC format
{"2006-01-02T15:04:05", true}, // Local time assumed
{"2006-01-02", true}, // Local time assumed for date only
{"15:04:05", true}, // Local time assumed for time only
}
for _, formatSpec := range dateFormats {
if t, err := time.Parse(formatSpec.format, v.StringValue); err == nil {
if formatSpec.useLocal {
// Convert to UTC for consistency if no timezone was specified
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC), nil
}
return t, nil
}
}
return time.Time{}, fmt.Errorf("unable to parse date/time string: %s", v.StringValue)
case *schema_pb.Value_Int64Value:
// Assume Unix timestamp (seconds)
return time.Unix(v.Int64Value, 0), nil
default:
return time.Time{}, fmt.Errorf("cannot convert value type to date/time")
}
}
|