Skip to content

Commit

Permalink
Support for UDT (hierarchyid, geometry and geography) (#216)
Browse files Browse the repository at this point in the history
* Accept hierarchyid as a valid type

* error

* derp

* geography and geometry

* Return value

* Tests

* Typo

* Upper

* hasSize
  • Loading branch information
tentone authored Aug 22, 2024
1 parent 9b84d9b commit 02deabf
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
4 changes: 4 additions & 0 deletions queries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func TestSelect(t *testing.T) {
{"cast(cast('abc' as varchar(3)) as sql_variant)", "abc"},
{"cast(cast('abc' as char(3)) as sql_variant)", "abc"},
{"cast(N'abc' as sql_variant)", "abc"},
{"cast('/' as hierarchyid)", []byte{}},
}

for _, test := range values {
Expand Down Expand Up @@ -1682,6 +1683,9 @@ func TestColumnTypeIntrospection(t *testing.T) {
{"cast('abc' as char(3))", "CHAR", reflect.TypeOf(""), true, 3, false, 0, 0},
{"cast(N'abc' as nchar(3))", "NCHAR", reflect.TypeOf(""), true, 3, false, 0, 0},
{"cast(1 as sql_variant)", "SQL_VARIANT", reflect.TypeOf(nil), false, 0, false, 0, 0},
{"geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0)", "GEOMETRY", reflect.TypeOf([]byte{}), true, 2147483647, false, 0, 0},
{"geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326)", "GEOGRAPHY", reflect.TypeOf([]byte{}), false, 2147483647, false, 0, 0},
{"cast('/1/2/3/' as hierarchyid)", "HIERARCHYID", reflect.TypeOf([]byte{}), true, 892, false, 0, 0},
}
conn, logger := open(t)
defer conn.Close()
Expand Down
20 changes: 20 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"math"
"reflect"
"strconv"
"strings"
"time"

"github.com/microsoft/go-mssqldb/internal/cp"
Expand Down Expand Up @@ -1137,6 +1138,8 @@ func makeGoLangScanType(ti typeInfo) reflect.Type {
return reflect.TypeOf([]byte{})
case typeVariant:
return reflect.TypeOf(nil)
case typeUdt:
return reflect.TypeOf([]byte{})
default:
panic(fmt.Sprintf("not implemented makeGoLangScanType for type %d", ti.TypeId))
}
Expand Down Expand Up @@ -1366,6 +1369,8 @@ func makeGoLangTypeName(ti typeInfo) string {
return "SQL_VARIANT"
case typeBigBinary:
return "BINARY"
case typeUdt:
return strings.ToUpper(ti.UdtInfo.TypeName)
default:
panic(fmt.Sprintf("not implemented makeGoLangTypeName for type %d", ti.TypeId))
}
Expand Down Expand Up @@ -1490,9 +1495,22 @@ func makeGoLangTypeLength(ti typeInfo) (int64, bool) {
return 0, false
case typeBigBinary:
return int64(ti.Size), true
case typeUdt:
switch ti.UdtInfo.TypeName {
case "hierarchyid":
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/hierarchyid-data-type-method-reference?view=sql-server-ver16
return 892, true
case "geography":
case "geometry":
return 2147483647, true
default:
panic(fmt.Sprintf("not implemented makeGoLangTypeLength for user defined type %s", ti.UdtInfo.TypeName))
}
default:
panic(fmt.Sprintf("not implemented makeGoLangTypeLength for type %d", ti.TypeId))
}

return 0, false
}

// makes go/sql type precision and scale as described below
Expand Down Expand Up @@ -1602,6 +1620,8 @@ func makeGoLangTypePrecisionScale(ti typeInfo) (int64, int64, bool) {
return 0, 0, false
case typeBigBinary:
return 0, 0, false
case typeUdt:
return 0, 0, false
default:
panic(fmt.Sprintf("not implemented makeGoLangTypePrecisionScale for type %d", ti.TypeId))
}
Expand Down

0 comments on commit 02deabf

Please sign in to comment.