3
0

Add tests & tweaks for RDBMS dialect column fit checks

This commit is contained in:
Tomaž Jerman
2023-06-25 16:06:47 +02:00
parent caabf6647e
commit 1e10db1e95
5 changed files with 309 additions and 8 deletions

View File

@@ -273,27 +273,34 @@ func (mssqlDialect) ColumnFits(target, assert *ddl.Column) bool {
// Special cases
switch {
case assertName == "varchar" && targetName == "varchar":
// @note mssql represents max as -1 so we're just going with this
if assertMeta[0] == "max" {
assertMeta[0] = "-1"
}
if targetMeta[0] == "max" {
targetMeta[0] = "-1"
}
// Check varchar size
for i := len(assertMeta); i < 1; i++ {
assertMeta = append(assertMeta, "0")
}
if assertMeta[0] == "max" {
assertMeta[0] = "-1"
}
assertA := cast.ToInt(assertMeta[0])
for i := len(targetMeta); i < 1; i++ {
targetMeta = append(targetMeta, "0")
}
if targetMeta[0] == "max" {
targetMeta[0] = "-1"
}
targetA := cast.ToInt(targetMeta[0])
// -1 means no limit so it can fit any length
// - if target is max, any varchar fits
if targetA == -1 {
return baseMatch
}
// - if assert is max, only max fits
if assertA == -1 {
return baseMatch && targetA == -1
}
return baseMatch && assertA <= targetA

View File

@@ -0,0 +1,136 @@
package mssql
import (
"testing"
"github.com/cortezaproject/corteza/server/store/adapters/rdbms/ddl"
"github.com/stretchr/testify/assert"
)
func TestColumnFits(t *testing.T) {
tcc := []struct {
name string
target *ddl.Column
assert *ddl.Column
expected bool
}{
{
name: "exact match (varchar)",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "varchar",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "varchar",
},
},
expected: true,
},
{
name: "fits somewhere",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "varchar(max)",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "decimal(1,2)",
},
},
expected: true,
},
{
name: "doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "decimal(1,2)",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "varchar(max)",
},
},
expected: false,
},
{
name: "decimal fits",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "decimal(1,2)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "decimal(1,2)"},
},
expected: true,
},
{
name: "decimal doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "decimal(1,2)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "decimal(2,3)"},
},
expected: false,
},
{
name: "varchar fits",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
expected: true,
},
{
name: "varchar doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(84)"},
},
expected: false,
},
{
name: "varchar(max) fits",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(max)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
expected: true,
},
{
name: "varchar(max) doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(max)"},
},
expected: false,
},
}
d := mssqlDialect{}
for _, c := range tcc {
t.Run(c.name, func(t *testing.T) {
out := d.ColumnFits(c.target, c.assert)
assert.Equal(t, c.expected, out)
})
}
}

View File

@@ -310,7 +310,7 @@ func (mysqlDialect) ColumnFits(target, assert *ddl.Column) bool {
switch {
case assertName == "varchar" && targetName == "varchar":
// Check varchar size
return baseMatch && assertMeta[0] <= targetMeta[0]
return baseMatch && cast.ToInt(assertMeta[0]) <= cast.ToInt(targetMeta[0])
case assertName == "decimal" && targetName == "decimal":
// Check numeric size and precision

View File

@@ -282,6 +282,8 @@ func (postgresDialect) ColumnFits(target, assert *ddl.Column) bool {
targetMeta = append(targetMeta, "0")
}
return baseMatch && cast.ToInt(assertMeta[0]) <= cast.ToInt(targetMeta[0])
case assertName == "numeric" && targetName == "numeric":
// Check numeric size and precision
for i := len(assertMeta); i < 2; i++ {
@@ -291,7 +293,7 @@ func (postgresDialect) ColumnFits(target, assert *ddl.Column) bool {
targetMeta = append(targetMeta, "0")
}
return baseMatch && assertMeta[0] <= targetMeta[0] && assertMeta[1] <= targetMeta[1]
return baseMatch && cast.ToInt(assertMeta[0]) <= cast.ToInt(targetMeta[0]) && cast.ToInt(assertMeta[1]) <= cast.ToInt(targetMeta[1])
}
return baseMatch

View File

@@ -0,0 +1,156 @@
package postgres
import (
"testing"
"github.com/cortezaproject/corteza/server/store/adapters/rdbms/ddl"
"github.com/stretchr/testify/assert"
)
func TestColumnFits(t *testing.T) {
tcc := []struct {
name string
target *ddl.Column
assert *ddl.Column
expected bool
}{
{
name: "exact match (text)",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "text",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "text",
},
},
expected: true,
},
{
name: "fits somewhere",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "text",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "numeric(1,2)",
},
},
expected: true,
},
{
name: "doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{
Name: "numeric(1,2)",
},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{
Name: "text",
},
},
expected: false,
},
{
name: "numeric fits",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "numeric(1,2)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "numeric(1,2)"},
},
expected: true,
},
{
name: "numeric doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "numeric(1,2)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "numeric(2,3)"},
},
expected: false,
},
{
name: "varchar fits",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
expected: true,
},
{
name: "varchar doesn't fit",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(42)"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "varchar(84)"},
},
expected: false,
},
{
name: "timestamp fits into timestamptz",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "timestamptz"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "timestamp"},
},
expected: true,
},
{
name: "timestamptz doesn't fit into timestamp",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "timestamp"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "timestamptz"},
},
expected: false,
},
{
name: "time fits into timetz",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "timetz"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "time"},
},
expected: true,
},
{
name: "timetz doesn't fit into time",
target: &ddl.Column{
Type: &ddl.ColumnType{Name: "time"},
},
assert: &ddl.Column{
Type: &ddl.ColumnType{Name: "timetz"},
},
expected: false,
},
}
d := postgresDialect{}
for _, c := range tcc {
t.Run(c.name, func(t *testing.T) {
out := d.ColumnFits(c.target, c.assert)
assert.Equal(t, c.expected, out)
})
}
}