[#7538] set OnlyInt:true when a view column expression is loosely known to return int-only values
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
## v0.36.6 (WIP)
|
||||
|
||||
- Set `NumberField.OnlyInt:true` for the generated View collection schema fields when a view column expression is known to return int-only values ([#7538](https://github.com/pocketbase/pocketbase/issues/7538)).
|
||||
|
||||
|
||||
## v0.36.5
|
||||
|
||||
- Disabled collection and fields name normalization while in IME mode ([#7532](https://github.com/pocketbase/pocketbase/pull/7532); thanks @miaopan607).
|
||||
|
||||
23
core/view.go
23
core/view.go
@@ -257,7 +257,16 @@ func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, er
|
||||
}
|
||||
|
||||
// numeric aggregations
|
||||
if strings.HasPrefix(colLower, "count(") || strings.HasPrefix(colLower, "total(") {
|
||||
if strings.HasPrefix(colLower, "count(") {
|
||||
result[col.alias] = &queryField{
|
||||
field: &NumberField{
|
||||
Name: col.alias,
|
||||
OnlyInt: true,
|
||||
},
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(colLower, "total(") {
|
||||
result[col.alias] = &queryField{
|
||||
field: &NumberField{
|
||||
Name: col.alias,
|
||||
@@ -268,16 +277,24 @@ func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, er
|
||||
|
||||
castMatch := castRegex.FindStringSubmatch(colLower)
|
||||
|
||||
// numeric casts
|
||||
// casts
|
||||
if len(castMatch) == 2 {
|
||||
switch castMatch[1] {
|
||||
case "real", "integer", "int", "decimal", "numeric":
|
||||
case "real", "decimal", "numeric":
|
||||
result[col.alias] = &queryField{
|
||||
field: &NumberField{
|
||||
Name: col.alias,
|
||||
},
|
||||
}
|
||||
continue
|
||||
case "int", "integer":
|
||||
result[col.alias] = &queryField{
|
||||
field: &NumberField{
|
||||
Name: col.alias,
|
||||
OnlyInt: true,
|
||||
},
|
||||
}
|
||||
continue
|
||||
case "text":
|
||||
result[col.alias] = &queryField{
|
||||
field: &TextField{
|
||||
|
||||
@@ -545,6 +545,61 @@ func TestCreateViewFields(t *testing.T) {
|
||||
ensureNoTempViews(app, t)
|
||||
}
|
||||
|
||||
func TestCreateViewFieldsWithNumberOnlyInt(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app, _ := tests.NewTestApp()
|
||||
defer app.Cleanup()
|
||||
|
||||
sql := `select
|
||||
a.id,
|
||||
count(a.id) count,
|
||||
total(a.id) total,
|
||||
cast(a.id as int) cast_int,
|
||||
cast(a.id as integer) cast_integer,
|
||||
cast(a.id as real) cast_real,
|
||||
cast(a.id as decimal) cast_decimal,
|
||||
cast(a.id as numeric) cast_numeric
|
||||
from demo1 a`
|
||||
|
||||
result, err := app.CreateViewFields(sql)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
onlyInts := map[string]bool{
|
||||
"count": true,
|
||||
"total": false,
|
||||
"cast_int": true,
|
||||
"cast_integer": true,
|
||||
"cast_real": false,
|
||||
"cast_decimal": false,
|
||||
"cast_numeric": false,
|
||||
}
|
||||
|
||||
totalExpected := len(onlyInts) + 1
|
||||
if total := len(result); total != totalExpected {
|
||||
t.Fatalf("Expected %d, got %d", totalExpected, total)
|
||||
}
|
||||
|
||||
for _, f := range result {
|
||||
if f.GetName() == "id" {
|
||||
continue
|
||||
}
|
||||
|
||||
t.Run(f.GetName(), func(t *testing.T) {
|
||||
nf, ok := f.(*core.NumberField)
|
||||
if !ok {
|
||||
t.Fatalf("Expected *core.NumberField, got %v", f)
|
||||
}
|
||||
|
||||
if nf.OnlyInt != onlyInts[nf.Name] {
|
||||
t.Fatalf("Expected OnlyInt %v, got %v", onlyInts[nf.Name], nf.OnlyInt)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindRecordByViewFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user