Skip to content

Commit

Permalink
Merge pull request #97 from shiv3/master
Browse files Browse the repository at this point in the history
Support GENERATE_ARRAY
  • Loading branch information
sinmetal authored May 16, 2024
2 parents a33cef5 + b996b14 commit 5f7a593
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
35 changes: 35 additions & 0 deletions server/database_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,41 @@ var customFunctions map[string]CustomFunction = map[string]CustomFunction{
return ValueType{Code: TCInt64}
},
},
"GENERATE_ARRAY": {
Func: sqlite3FnGenerateArray,
NArgs: -2,
ArgTypes: func(vts []ValueType) bool {
if len(vts) < 2 || len(vts) > 3 {
return false
}
if vts[0].Code == TCInt64 && vts[1].Code == TCInt64 {
if len(vts) == 3 {
return vts[2].Code == TCInt64
}
return true
}
return false
},
ReturnType: func(vts []ValueType) ValueType {
return ValueType{
Code: TCArray,
ArrayType: &ValueType{Code: TCInt64},
}
},
},
}

func sqlite3FnGenerateArray(xs ...int64) []byte {
step := int64(1)
if len(xs) == 3 {
step = xs[2]
}
a, b := xs[0], xs[1]
res := make([]byte, 0, b-a)
for i := a; i <= b; i += step {
res = append(res, byte(i))
}
return res
}

func sqlite3FnMod(a, b int64) int64 {
Expand Down
14 changes: 14 additions & 0 deletions server/database_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3427,6 +3427,20 @@ func TestQuery(t *testing.T) {
[]interface{}{int64(1)},
},
},
{
name: "Function_GENERATE_ARRAY",
sql: `SELECT GENERATE_ARRAY(1, 3)`,
expected: [][]interface{}{
{[]int64{1, 2, 3}},
},
},
{
name: "Function_GENERATE_ARRAY2",
sql: `SELECT GENERATE_ARRAY(1, 10, 2)`,
expected: [][]interface{}{
{[]int64{1, 3, 5, 7, 9}},
},
},
},
}

Expand Down
15 changes: 11 additions & 4 deletions server/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,19 @@ func (a *ArrayValueDecoder) Scan(src interface{}) error {
return nil
}

v, ok := src.(string)
if !ok {
switch v := src.(type) {
case string:
return a.UnmarshalJSON([]byte(v))
case []uint8:
res := make([]int64, len(v))
for i, _ := range v {
res[i] = int64(v[i])
}
a.Values = res
default:
return fmt.Errorf("unexpected type %T for %T", src, a)
}

return a.UnmarshalJSON([]byte(v))
return nil
}

func (a *ArrayValueDecoder) UnmarshalJSON(b []byte) error {
Expand Down

0 comments on commit 5f7a593

Please sign in to comment.