Skip to content

Commit

Permalink
Support for decimal -> numeric
Browse files Browse the repository at this point in the history
  • Loading branch information
marccampbell committed May 16, 2019
1 parent 664e968 commit 46a48fb
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 51 deletions.
50 changes: 35 additions & 15 deletions pkg/database/postgres/column.go
Expand Up @@ -12,8 +12,7 @@ import (
schemasv1alpha1 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha1"
)

// simpleColumnTypes are unparameterized, easy-to-parse types
var simpleColumnTypes = []string{
var unparameterizedColumnTypes = []string{
"bigint",
"bigserial",
"boolean",
Expand Down Expand Up @@ -59,7 +58,7 @@ type Column struct {
Constraints *ColumnConstraints
}

func maybeParseComplexColumnType(requestedType string) (string, int64, error) {
func maybeParseParameterizedColumnType(requestedType string) (string, int64, error) {
columnType := ""
maxLength := int64(0)

Expand Down Expand Up @@ -88,17 +87,17 @@ func maybeParseComplexColumnType(requestedType string) (string, int64, error) {
return columnType, maxLength, nil
}

func isSimpleColumnType(requestedType string) bool {
for _, simpleColumnType := range simpleColumnTypes {
if simpleColumnType == requestedType {
return true
func isParameterizedColumnType(requestedType string) bool {
for _, unparameterizedColumnType := range unparameterizedColumnTypes {
if unparameterizedColumnType == requestedType {
return false
}
}

return false
return true
}

func unaliasSimpleColumnType(requestedType string) string {
func unaliasUnparameterizedColumnType(requestedType string) string {
switch requestedType {
case "int8":
return "bigint"
Expand All @@ -122,9 +121,8 @@ func unaliasSimpleColumnType(requestedType string) string {
return "serial"
}

// Simple types just pass through
for _, simpleColumnType := range simpleColumnTypes {
if simpleColumnType == requestedType {
for _, unparameterizedColumnType := range unparameterizedColumnTypes {
if unparameterizedColumnType == requestedType {
return requestedType
}
}
Expand Down Expand Up @@ -163,7 +161,29 @@ func unaliasParameterizedColumnType(requestedType string) string {

return fmt.Sprintf("character varying (%s)", matchGroups[1])
}
if strings.HasPrefix(requestedType, "decimal") {
precisionAndScale := regexp.MustCompile(`decimal\s*\((?P<precision>\d*),\s*(?P<scale>[0-9.]\s*)\)`)
precisionOnly := regexp.MustCompile(`decimal\s*\((?P<precision>\d*)\)`)

precisionAndScaleMatchGroups := precisionAndScale.FindStringSubmatch(requestedType)
precisionOnlyMatchGroups := precisionOnly.FindStringSubmatch(requestedType)

if len(precisionAndScaleMatchGroups) == 0 && len(precisionOnlyMatchGroups) == 0 {
return "numeric"
}

if len(precisionAndScaleMatchGroups) > 0 {
return fmt.Sprintf("numeric (%s, %s)", precisionAndScaleMatchGroups[1], precisionAndScaleMatchGroups[2])
}

return fmt.Sprintf("numeric (%s)", precisionOnlyMatchGroups[1])
}
if strings.HasPrefix(requestedType, "timetz") {

}
if strings.HasPrefix(requestedType, "timestamptz") {

}
return ""
}

Expand All @@ -177,7 +197,7 @@ func schemaColumnToPostgresColumn(schemaColumn *schemasv1alpha1.PostgresTableCol
}

requestedType := schemaColumn.Type
unaliasedColumnType := unaliasSimpleColumnType(requestedType)
unaliasedColumnType := unaliasUnparameterizedColumnType(requestedType)
if unaliasedColumnType != "" {
requestedType = unaliasedColumnType
}
Expand All @@ -187,12 +207,12 @@ func schemaColumnToPostgresColumn(schemaColumn *schemasv1alpha1.PostgresTableCol
requestedType = unaliasedColumnType
}

if isSimpleColumnType(requestedType) {
if !isParameterizedColumnType(requestedType) {
column.DataType = requestedType
return column, nil
}

columnType, maxLength, err := maybeParseComplexColumnType(requestedType)
columnType, maxLength, err := maybeParseParameterizedColumnType(requestedType)
if err != nil {
return nil, err
}
Expand Down
54 changes: 18 additions & 36 deletions pkg/database/postgres/column_test.go
Expand Up @@ -10,47 +10,29 @@ import (
)

func Test_unaliasParameterizedColumnType(t *testing.T) {
tests := []struct {
name string
requestedType string
expectedUnaliasedType string
}{
{
name: "varchar(255)",
requestedType: "varchar(255)",
expectedUnaliasedType: "character varying (255)",
}, {
name: "varchar",
requestedType: "varchar",
expectedUnaliasedType: "character varying",
}, {
name: "varchar (100)",
requestedType: "varchar (100)",
expectedUnaliasedType: "character varying (100)",
}, {
name: "varbit (50)",
requestedType: "varbit (50)",
expectedUnaliasedType: "bit varying (50)",
}, {
name: "char",
requestedType: "char",
expectedUnaliasedType: "character",
}, {
name: "char(36)",
requestedType: "char(36)",
expectedUnaliasedType: "character (36)",
},
aliasedParmeterizedTests := map[string]string{
"varchar(255)": "character varying (255)",
"varchar": "character varying",
"varchar (100)": "character varying (100)",
"varbit (50)": "bit varying (50)",
"char": "character",
"char(36)": "character (36)",
"decimal": "numeric",
"decimal (10)": "numeric (10)",
// "timetz": "time with time zone",
// "timestamptz": "timestamp with time zone",

}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
unaliasedType := unaliasParameterizedColumnType(test.requestedType)
assert.Equal(t, test.expectedUnaliasedType, unaliasedType)
for aliased, expectedUnaliased := range aliasedParmeterizedTests {
t.Run(aliased, func(t *testing.T) {
unaliasedType := unaliasParameterizedColumnType(aliased)
assert.Equal(t, expectedUnaliased, unaliasedType)
})
}
}

func Test_unaliasSimpleColumnType(t *testing.T) {
func Test_unaliasUnparameterizedColumnType(t *testing.T) {
tests := []struct {
name string
requestedType string
Expand Down Expand Up @@ -105,7 +87,7 @@ func Test_unaliasSimpleColumnType(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
unaliasedType := unaliasSimpleColumnType(test.requestedType)
unaliasedType := unaliasUnparameterizedColumnType(test.requestedType)
assert.Equal(t, test.expectedUnaliasedType, unaliasedType)
})
}
Expand Down

0 comments on commit 46a48fb

Please sign in to comment.