Skip to content

Commit 02deabf

Browse files
authored
Support for UDT (hierarchyid, geometry and geography) (#216)
* Accept hierarchyid as a valid type * error * derp * geography and geometry * Return value * Tests * Typo * Upper * hasSize
1 parent 9b84d9b commit 02deabf

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

queries_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func TestSelect(t *testing.T) {
135135
{"cast(cast('abc' as varchar(3)) as sql_variant)", "abc"},
136136
{"cast(cast('abc' as char(3)) as sql_variant)", "abc"},
137137
{"cast(N'abc' as sql_variant)", "abc"},
138+
{"cast('/' as hierarchyid)", []byte{}},
138139
}
139140

140141
for _, test := range values {
@@ -1682,6 +1683,9 @@ func TestColumnTypeIntrospection(t *testing.T) {
16821683
{"cast('abc' as char(3))", "CHAR", reflect.TypeOf(""), true, 3, false, 0, 0},
16831684
{"cast(N'abc' as nchar(3))", "NCHAR", reflect.TypeOf(""), true, 3, false, 0, 0},
16841685
{"cast(1 as sql_variant)", "SQL_VARIANT", reflect.TypeOf(nil), false, 0, false, 0, 0},
1686+
{"geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0)", "GEOMETRY", reflect.TypeOf([]byte{}), true, 2147483647, false, 0, 0},
1687+
{"geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326)", "GEOGRAPHY", reflect.TypeOf([]byte{}), false, 2147483647, false, 0, 0},
1688+
{"cast('/1/2/3/' as hierarchyid)", "HIERARCHYID", reflect.TypeOf([]byte{}), true, 892, false, 0, 0},
16851689
}
16861690
conn, logger := open(t)
16871691
defer conn.Close()

types.go

+20
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"math"
99
"reflect"
1010
"strconv"
11+
"strings"
1112
"time"
1213

1314
"github.com/microsoft/go-mssqldb/internal/cp"
@@ -1137,6 +1138,8 @@ func makeGoLangScanType(ti typeInfo) reflect.Type {
11371138
return reflect.TypeOf([]byte{})
11381139
case typeVariant:
11391140
return reflect.TypeOf(nil)
1141+
case typeUdt:
1142+
return reflect.TypeOf([]byte{})
11401143
default:
11411144
panic(fmt.Sprintf("not implemented makeGoLangScanType for type %d", ti.TypeId))
11421145
}
@@ -1366,6 +1369,8 @@ func makeGoLangTypeName(ti typeInfo) string {
13661369
return "SQL_VARIANT"
13671370
case typeBigBinary:
13681371
return "BINARY"
1372+
case typeUdt:
1373+
return strings.ToUpper(ti.UdtInfo.TypeName)
13691374
default:
13701375
panic(fmt.Sprintf("not implemented makeGoLangTypeName for type %d", ti.TypeId))
13711376
}
@@ -1490,9 +1495,22 @@ func makeGoLangTypeLength(ti typeInfo) (int64, bool) {
14901495
return 0, false
14911496
case typeBigBinary:
14921497
return int64(ti.Size), true
1498+
case typeUdt:
1499+
switch ti.UdtInfo.TypeName {
1500+
case "hierarchyid":
1501+
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/hierarchyid-data-type-method-reference?view=sql-server-ver16
1502+
return 892, true
1503+
case "geography":
1504+
case "geometry":
1505+
return 2147483647, true
1506+
default:
1507+
panic(fmt.Sprintf("not implemented makeGoLangTypeLength for user defined type %s", ti.UdtInfo.TypeName))
1508+
}
14931509
default:
14941510
panic(fmt.Sprintf("not implemented makeGoLangTypeLength for type %d", ti.TypeId))
14951511
}
1512+
1513+
return 0, false
14961514
}
14971515

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

0 commit comments

Comments
 (0)