mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-04 12:53:19 +00:00
* chore: added sql formatter for json * chore: updated json extract columns * chore: added apend ident * chore: resolved pr comments * chore: resolved pr comments * chore: resolved pr comments * chore: resolved pr comments * chore: minor changes * chore: minor changes * chore: minor changes * chore: minor changes * chore: resolve comments * chore: added append value * chore: added append value * chore: added append value * chore: added append value * chore: added append value * chore: added append value * chore: added append value * chore: added append value --------- Co-authored-by: Vikrant Gupta <vikrant@signoz.io>
423 lines
8.9 KiB
Go
423 lines
8.9 KiB
Go
package sqlitesqlstore
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
|
)
|
|
|
|
func TestJSONExtractString(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple path",
|
|
column: "data",
|
|
path: "$.field",
|
|
expected: `json_extract("data", '$.field')`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.user.name",
|
|
expected: `json_extract("metadata", '$.user.name')`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "$",
|
|
expected: `json_extract("json_col", '$')`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "",
|
|
expected: `json_extract("json_col", '')`,
|
|
},
|
|
{
|
|
name: "array index path",
|
|
column: "items",
|
|
path: "$.list[0]",
|
|
expected: `json_extract("items", '$.list[0]')`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.JSONExtractString(tt.column, tt.path))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple path",
|
|
column: "data",
|
|
path: "$.field",
|
|
expected: `json_type("data", '$.field')`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.user.age",
|
|
expected: `json_type("metadata", '$.user.age')`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "$",
|
|
expected: `json_type("json_col", '$')`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "",
|
|
expected: `json_type("json_col", '')`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.JSONType(tt.column, tt.path))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONIsArray(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple path",
|
|
column: "data",
|
|
path: "$.items",
|
|
expected: `json_type("data", '$.items') = 'array'`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.user.tags",
|
|
expected: `json_type("metadata", '$.user.tags') = 'array'`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "$",
|
|
expected: `json_type("json_col", '$') = 'array'`,
|
|
},
|
|
{
|
|
name: "root path",
|
|
column: "json_col",
|
|
path: "",
|
|
expected: `json_type("json_col", '') = 'array'`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.JSONIsArray(tt.column, tt.path))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONArrayElements(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
alias string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "root path with dollar sign",
|
|
column: "data",
|
|
path: "$",
|
|
alias: "elem",
|
|
expected: `json_each("data") AS "elem"`,
|
|
},
|
|
{
|
|
name: "root path empty",
|
|
column: "data",
|
|
path: "",
|
|
alias: "elem",
|
|
expected: `json_each("data") AS "elem"`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.items",
|
|
alias: "item",
|
|
expected: `json_each("metadata", '$.items') AS "item"`,
|
|
},
|
|
{
|
|
name: "deeply nested path",
|
|
column: "json_col",
|
|
path: "$.user.tags",
|
|
alias: "tag",
|
|
expected: `json_each("json_col", '$.user.tags') AS "tag"`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "",
|
|
alias: "item",
|
|
expected: `json_each("metadata") AS "item"`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got, _ := f.JSONArrayElements(tt.column, tt.path, tt.alias)
|
|
assert.Equal(t, tt.expected, string(got))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONArrayOfStrings(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
alias string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "root path with dollar sign",
|
|
column: "data",
|
|
path: "$",
|
|
alias: "str",
|
|
expected: `json_each("data") AS "str"`,
|
|
},
|
|
{
|
|
name: "root path empty",
|
|
column: "data",
|
|
path: "",
|
|
alias: "str",
|
|
expected: `json_each("data") AS "str"`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.strings",
|
|
alias: "s",
|
|
expected: `json_each("metadata", '$.strings') AS "s"`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got, _ := f.JSONArrayOfStrings(tt.column, tt.path, tt.alias)
|
|
assert.Equal(t, tt.expected, string(got))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONKeys(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
path string
|
|
alias string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "root path with dollar sign",
|
|
column: "data",
|
|
path: "$",
|
|
alias: "k",
|
|
expected: `json_each("data") AS "k"`,
|
|
},
|
|
{
|
|
name: "root path empty",
|
|
column: "data",
|
|
path: "",
|
|
alias: "k",
|
|
expected: `json_each("data") AS "k"`,
|
|
},
|
|
{
|
|
name: "nested path",
|
|
column: "metadata",
|
|
path: "$.object",
|
|
alias: "key",
|
|
expected: `json_each("metadata", '$.object') AS "key"`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got, _ := f.JSONKeys(tt.column, tt.path, tt.alias)
|
|
assert.Equal(t, tt.expected, string(got))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONArrayAgg(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
expression string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple column",
|
|
expression: "id",
|
|
expected: "json_group_array(id)",
|
|
},
|
|
{
|
|
name: "expression with function",
|
|
expression: "DISTINCT name",
|
|
expected: "json_group_array(DISTINCT name)",
|
|
},
|
|
{
|
|
name: "complex expression",
|
|
expression: "json_extract(data, '$.field')",
|
|
expected: "json_group_array(json_extract(data, '$.field'))",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.JSONArrayAgg(tt.expression))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONArrayLiteral(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
values []string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "empty array",
|
|
values: []string{},
|
|
expected: "json_array()",
|
|
},
|
|
{
|
|
name: "single value",
|
|
values: []string{"value1"},
|
|
expected: "json_array('value1')",
|
|
},
|
|
{
|
|
name: "multiple values",
|
|
values: []string{"value1", "value2", "value3"},
|
|
expected: "json_array('value1', 'value2', 'value3')",
|
|
},
|
|
{
|
|
name: "values with special characters",
|
|
values: []string{"test", "with space", "with-dash"},
|
|
expected: "json_array('test', 'with space', 'with-dash')",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.JSONArrayLiteral(tt.values...))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTextToJsonColumn(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
column string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple column name",
|
|
column: "data",
|
|
expected: `"data"`,
|
|
},
|
|
{
|
|
name: "column with underscore",
|
|
column: "user_data",
|
|
expected: `"user_data"`,
|
|
},
|
|
{
|
|
name: "column with special characters",
|
|
column: "json-col",
|
|
expected: `"json-col"`,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.TextToJsonColumn(tt.column))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLowerExpression(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
expr string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "json_extract expression",
|
|
expr: "json_extract(data, '$.field')",
|
|
expected: "lower(json_extract(data, '$.field'))",
|
|
},
|
|
{
|
|
name: "nested json_extract",
|
|
expr: "json_extract(metadata, '$.user.name')",
|
|
expected: "lower(json_extract(metadata, '$.user.name'))",
|
|
},
|
|
{
|
|
name: "json_type expression",
|
|
expr: "json_type(data, '$.field')",
|
|
expected: "lower(json_type(data, '$.field'))",
|
|
},
|
|
{
|
|
name: "string concatenation",
|
|
expr: "first_name || ' ' || last_name",
|
|
expected: "lower(first_name || ' ' || last_name)",
|
|
},
|
|
{
|
|
name: "CAST expression",
|
|
expr: "CAST(value AS TEXT)",
|
|
expected: "lower(CAST(value AS TEXT))",
|
|
},
|
|
{
|
|
name: "COALESCE expression",
|
|
expr: "COALESCE(name, 'default')",
|
|
expected: "lower(COALESCE(name, 'default'))",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
f := newFormatter(sqlitedialect.New())
|
|
got := string(f.LowerExpression(tt.expr))
|
|
assert.Equal(t, tt.expected, got)
|
|
})
|
|
}
|
|
}
|