You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580
  1. package mssql
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. "math"
  8. "reflect"
  9. "strconv"
  10. "time"
  11. "github.com/denisenkom/go-mssqldb/internal/cp"
  12. )
  13. // fixed-length data types
  14. // http://msdn.microsoft.com/en-us/library/dd341171.aspx
  15. const (
  16. typeNull = 0x1f
  17. typeInt1 = 0x30
  18. typeBit = 0x32
  19. typeInt2 = 0x34
  20. typeInt4 = 0x38
  21. typeDateTim4 = 0x3a
  22. typeFlt4 = 0x3b
  23. typeMoney = 0x3c
  24. typeDateTime = 0x3d
  25. typeFlt8 = 0x3e
  26. typeMoney4 = 0x7a
  27. typeInt8 = 0x7f
  28. )
  29. // variable-length data types
  30. // http://msdn.microsoft.com/en-us/library/dd358341.aspx
  31. const (
  32. // byte len types
  33. typeGuid = 0x24
  34. typeIntN = 0x26
  35. typeDecimal = 0x37 // legacy
  36. typeNumeric = 0x3f // legacy
  37. typeBitN = 0x68
  38. typeDecimalN = 0x6a
  39. typeNumericN = 0x6c
  40. typeFltN = 0x6d
  41. typeMoneyN = 0x6e
  42. typeDateTimeN = 0x6f
  43. typeDateN = 0x28
  44. typeTimeN = 0x29
  45. typeDateTime2N = 0x2a
  46. typeDateTimeOffsetN = 0x2b
  47. typeChar = 0x2f // legacy
  48. typeVarChar = 0x27 // legacy
  49. typeBinary = 0x2d // legacy
  50. typeVarBinary = 0x25 // legacy
  51. // short length types
  52. typeBigVarBin = 0xa5
  53. typeBigVarChar = 0xa7
  54. typeBigBinary = 0xad
  55. typeBigChar = 0xaf
  56. typeNVarChar = 0xe7
  57. typeNChar = 0xef
  58. typeXml = 0xf1
  59. typeUdt = 0xf0
  60. typeTvp = 0xf3
  61. // long length types
  62. typeText = 0x23
  63. typeImage = 0x22
  64. typeNText = 0x63
  65. typeVariant = 0x62
  66. )
  67. const _PLP_NULL = 0xFFFFFFFFFFFFFFFF
  68. const _UNKNOWN_PLP_LEN = 0xFFFFFFFFFFFFFFFE
  69. const _PLP_TERMINATOR = 0x00000000
  70. // TVP COLUMN FLAGS
  71. const _TVP_END_TOKEN = 0x00
  72. const _TVP_ROW_TOKEN = 0x01
  73. // TYPE_INFO rule
  74. // http://msdn.microsoft.com/en-us/library/dd358284.aspx
  75. type typeInfo struct {
  76. TypeId uint8
  77. Size int
  78. Scale uint8
  79. Prec uint8
  80. Buffer []byte
  81. Collation cp.Collation
  82. UdtInfo udtInfo
  83. XmlInfo xmlInfo
  84. Reader func(ti *typeInfo, r *tdsBuffer) (res interface{})
  85. Writer func(w io.Writer, ti typeInfo, buf []byte) (err error)
  86. }
  87. // Common Language Runtime (CLR) Instances
  88. // http://msdn.microsoft.com/en-us/library/dd357962.aspx
  89. type udtInfo struct {
  90. //MaxByteSize uint32
  91. DBName string
  92. SchemaName string
  93. TypeName string
  94. AssemblyQualifiedName string
  95. }
  96. // XML Values
  97. // http://msdn.microsoft.com/en-us/library/dd304764.aspx
  98. type xmlInfo struct {
  99. SchemaPresent uint8
  100. DBName string
  101. OwningSchema string
  102. XmlSchemaCollection string
  103. }
  104. func readTypeInfo(r *tdsBuffer) (res typeInfo) {
  105. res.TypeId = r.byte()
  106. switch res.TypeId {
  107. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  108. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  109. // those are fixed length types
  110. switch res.TypeId {
  111. case typeNull:
  112. res.Size = 0
  113. case typeInt1, typeBit:
  114. res.Size = 1
  115. case typeInt2:
  116. res.Size = 2
  117. case typeInt4, typeDateTim4, typeFlt4, typeMoney4:
  118. res.Size = 4
  119. case typeMoney, typeDateTime, typeFlt8, typeInt8:
  120. res.Size = 8
  121. }
  122. res.Reader = readFixedType
  123. res.Buffer = make([]byte, res.Size)
  124. default: // all others are VARLENTYPE
  125. readVarLen(&res, r)
  126. }
  127. return
  128. }
  129. // https://msdn.microsoft.com/en-us/library/dd358284.aspx
  130. func writeTypeInfo(w io.Writer, ti *typeInfo) (err error) {
  131. err = binary.Write(w, binary.LittleEndian, ti.TypeId)
  132. if err != nil {
  133. return
  134. }
  135. switch ti.TypeId {
  136. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  137. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  138. // those are fixed length
  139. // https://msdn.microsoft.com/en-us/library/dd341171.aspx
  140. ti.Writer = writeFixedType
  141. case typeTvp:
  142. ti.Writer = writeFixedType
  143. default: // all others are VARLENTYPE
  144. err = writeVarLen(w, ti)
  145. if err != nil {
  146. return
  147. }
  148. }
  149. return
  150. }
  151. func writeFixedType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  152. _, err = w.Write(buf)
  153. return
  154. }
  155. // https://msdn.microsoft.com/en-us/library/dd358341.aspx
  156. func writeVarLen(w io.Writer, ti *typeInfo) (err error) {
  157. switch ti.TypeId {
  158. case typeDateN:
  159. ti.Writer = writeByteLenType
  160. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  161. if err = binary.Write(w, binary.LittleEndian, ti.Scale); err != nil {
  162. return
  163. }
  164. ti.Writer = writeByteLenType
  165. case typeIntN, typeDecimal, typeNumeric,
  166. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  167. typeMoneyN, typeDateTimeN, typeChar,
  168. typeVarChar, typeBinary, typeVarBinary:
  169. // byle len types
  170. if ti.Size > 0xff {
  171. panic("Invalid size for BYLELEN_TYPE")
  172. }
  173. if err = binary.Write(w, binary.LittleEndian, uint8(ti.Size)); err != nil {
  174. return
  175. }
  176. switch ti.TypeId {
  177. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  178. err = binary.Write(w, binary.LittleEndian, ti.Prec)
  179. if err != nil {
  180. return
  181. }
  182. err = binary.Write(w, binary.LittleEndian, ti.Scale)
  183. if err != nil {
  184. return
  185. }
  186. }
  187. ti.Writer = writeByteLenType
  188. case typeGuid:
  189. if !(ti.Size == 0x10 || ti.Size == 0x00) {
  190. panic("Invalid size for BYLELEN_TYPE")
  191. }
  192. if err = binary.Write(w, binary.LittleEndian, uint8(ti.Size)); err != nil {
  193. return
  194. }
  195. ti.Writer = writeByteLenType
  196. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  197. typeNVarChar, typeNChar, typeXml, typeUdt:
  198. // short len types
  199. if ti.Size > 8000 || ti.Size == 0 {
  200. if err = binary.Write(w, binary.LittleEndian, uint16(0xffff)); err != nil {
  201. return
  202. }
  203. ti.Writer = writePLPType
  204. } else {
  205. if err = binary.Write(w, binary.LittleEndian, uint16(ti.Size)); err != nil {
  206. return
  207. }
  208. ti.Writer = writeShortLenType
  209. }
  210. switch ti.TypeId {
  211. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  212. if err = writeCollation(w, ti.Collation); err != nil {
  213. return
  214. }
  215. case typeXml:
  216. if err = binary.Write(w, binary.LittleEndian, ti.XmlInfo.SchemaPresent); err != nil {
  217. return
  218. }
  219. }
  220. case typeText, typeImage, typeNText, typeVariant:
  221. // LONGLEN_TYPE
  222. if err = binary.Write(w, binary.LittleEndian, uint32(ti.Size)); err != nil {
  223. return
  224. }
  225. if err = writeCollation(w, ti.Collation); err != nil {
  226. return
  227. }
  228. ti.Writer = writeLongLenType
  229. default:
  230. panic("Invalid type")
  231. }
  232. return
  233. }
  234. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  235. func decodeDateTim4(buf []byte) time.Time {
  236. days := binary.LittleEndian.Uint16(buf)
  237. mins := binary.LittleEndian.Uint16(buf[2:])
  238. return time.Date(1900, 1, 1+int(days),
  239. 0, int(mins), 0, 0, time.UTC)
  240. }
  241. func encodeDateTim4(val time.Time) (buf []byte) {
  242. buf = make([]byte, 4)
  243. ref := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC)
  244. dur := val.Sub(ref)
  245. days := dur / (24 * time.Hour)
  246. mins := val.Hour()*60 + val.Minute()
  247. if days < 0 {
  248. days = 0
  249. mins = 0
  250. }
  251. binary.LittleEndian.PutUint16(buf[:2], uint16(days))
  252. binary.LittleEndian.PutUint16(buf[2:], uint16(mins))
  253. return
  254. }
  255. // encodes datetime value
  256. // type identifier is typeDateTimeN
  257. func encodeDateTime(t time.Time) (res []byte) {
  258. // base date in days since Jan 1st 1900
  259. basedays := gregorianDays(1900, 1)
  260. // days since Jan 1st 1900 (same TZ as t)
  261. days := gregorianDays(t.Year(), t.YearDay()) - basedays
  262. tm := 300*(t.Second()+t.Minute()*60+t.Hour()*60*60) + t.Nanosecond()*300/1e9
  263. // minimum and maximum possible
  264. mindays := gregorianDays(1753, 1) - basedays
  265. maxdays := gregorianDays(9999, 365) - basedays
  266. if days < mindays {
  267. days = mindays
  268. tm = 0
  269. }
  270. if days > maxdays {
  271. days = maxdays
  272. tm = (23*60*60+59*60+59)*300 + 299
  273. }
  274. res = make([]byte, 8)
  275. binary.LittleEndian.PutUint32(res[0:4], uint32(days))
  276. binary.LittleEndian.PutUint32(res[4:8], uint32(tm))
  277. return
  278. }
  279. func decodeDateTime(buf []byte) time.Time {
  280. days := int32(binary.LittleEndian.Uint32(buf))
  281. tm := binary.LittleEndian.Uint32(buf[4:])
  282. ns := int(math.Trunc(float64(tm%300)/0.3+0.5)) * 1000000
  283. secs := int(tm / 300)
  284. return time.Date(1900, 1, 1+int(days),
  285. 0, 0, secs, ns, time.UTC)
  286. }
  287. func readFixedType(ti *typeInfo, r *tdsBuffer) interface{} {
  288. r.ReadFull(ti.Buffer)
  289. buf := ti.Buffer
  290. switch ti.TypeId {
  291. case typeNull:
  292. return nil
  293. case typeInt1:
  294. return int64(buf[0])
  295. case typeBit:
  296. return buf[0] != 0
  297. case typeInt2:
  298. return int64(int16(binary.LittleEndian.Uint16(buf)))
  299. case typeInt4:
  300. return int64(int32(binary.LittleEndian.Uint32(buf)))
  301. case typeDateTim4:
  302. return decodeDateTim4(buf)
  303. case typeFlt4:
  304. return math.Float32frombits(binary.LittleEndian.Uint32(buf))
  305. case typeMoney4:
  306. return decodeMoney4(buf)
  307. case typeMoney:
  308. return decodeMoney(buf)
  309. case typeDateTime:
  310. return decodeDateTime(buf)
  311. case typeFlt8:
  312. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  313. case typeInt8:
  314. return int64(binary.LittleEndian.Uint64(buf))
  315. default:
  316. badStreamPanicf("Invalid typeid")
  317. }
  318. panic("shoulnd't get here")
  319. }
  320. func readByteLenType(ti *typeInfo, r *tdsBuffer) interface{} {
  321. size := r.byte()
  322. if size == 0 {
  323. return nil
  324. }
  325. r.ReadFull(ti.Buffer[:size])
  326. buf := ti.Buffer[:size]
  327. switch ti.TypeId {
  328. case typeDateN:
  329. if len(buf) != 3 {
  330. badStreamPanicf("Invalid size for DATENTYPE")
  331. }
  332. return decodeDate(buf)
  333. case typeTimeN:
  334. return decodeTime(ti.Scale, buf)
  335. case typeDateTime2N:
  336. return decodeDateTime2(ti.Scale, buf)
  337. case typeDateTimeOffsetN:
  338. return decodeDateTimeOffset(ti.Scale, buf)
  339. case typeGuid:
  340. return decodeGuid(buf)
  341. case typeIntN:
  342. switch len(buf) {
  343. case 1:
  344. return int64(buf[0])
  345. case 2:
  346. return int64(int16((binary.LittleEndian.Uint16(buf))))
  347. case 4:
  348. return int64(int32(binary.LittleEndian.Uint32(buf)))
  349. case 8:
  350. return int64(binary.LittleEndian.Uint64(buf))
  351. default:
  352. badStreamPanicf("Invalid size for INTNTYPE: %d", len(buf))
  353. }
  354. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  355. return decodeDecimal(ti.Prec, ti.Scale, buf)
  356. case typeBitN:
  357. if len(buf) != 1 {
  358. badStreamPanicf("Invalid size for BITNTYPE")
  359. }
  360. return buf[0] != 0
  361. case typeFltN:
  362. switch len(buf) {
  363. case 4:
  364. return float64(math.Float32frombits(binary.LittleEndian.Uint32(buf)))
  365. case 8:
  366. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  367. default:
  368. badStreamPanicf("Invalid size for FLTNTYPE")
  369. }
  370. case typeMoneyN:
  371. switch len(buf) {
  372. case 4:
  373. return decodeMoney4(buf)
  374. case 8:
  375. return decodeMoney(buf)
  376. default:
  377. badStreamPanicf("Invalid size for MONEYNTYPE")
  378. }
  379. case typeDateTim4:
  380. return decodeDateTim4(buf)
  381. case typeDateTime:
  382. return decodeDateTime(buf)
  383. case typeDateTimeN:
  384. switch len(buf) {
  385. case 4:
  386. return decodeDateTim4(buf)
  387. case 8:
  388. return decodeDateTime(buf)
  389. default:
  390. badStreamPanicf("Invalid size for DATETIMENTYPE")
  391. }
  392. case typeChar, typeVarChar:
  393. return decodeChar(ti.Collation, buf)
  394. case typeBinary, typeVarBinary:
  395. // a copy, because the backing array for ti.Buffer is reused
  396. // and can be overwritten by the next row while this row waits
  397. // in a buffered chan
  398. cpy := make([]byte, len(buf))
  399. copy(cpy, buf)
  400. return cpy
  401. default:
  402. badStreamPanicf("Invalid typeid")
  403. }
  404. panic("shoulnd't get here")
  405. }
  406. func writeByteLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  407. if ti.Size > 0xff {
  408. panic("Invalid size for BYTELEN_TYPE")
  409. }
  410. err = binary.Write(w, binary.LittleEndian, uint8(len(buf)))
  411. if err != nil {
  412. return
  413. }
  414. _, err = w.Write(buf)
  415. return
  416. }
  417. func readShortLenType(ti *typeInfo, r *tdsBuffer) interface{} {
  418. size := r.uint16()
  419. if size == 0xffff {
  420. return nil
  421. }
  422. r.ReadFull(ti.Buffer[:size])
  423. buf := ti.Buffer[:size]
  424. switch ti.TypeId {
  425. case typeBigVarChar, typeBigChar:
  426. return decodeChar(ti.Collation, buf)
  427. case typeBigVarBin, typeBigBinary:
  428. // a copy, because the backing array for ti.Buffer is reused
  429. // and can be overwritten by the next row while this row waits
  430. // in a buffered chan
  431. cpy := make([]byte, len(buf))
  432. copy(cpy, buf)
  433. return cpy
  434. case typeNVarChar, typeNChar:
  435. return decodeNChar(buf)
  436. case typeUdt:
  437. return decodeUdt(*ti, buf)
  438. default:
  439. badStreamPanicf("Invalid typeid")
  440. }
  441. panic("shoulnd't get here")
  442. }
  443. func writeShortLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  444. if buf == nil {
  445. err = binary.Write(w, binary.LittleEndian, uint16(0xffff))
  446. return
  447. }
  448. if ti.Size > 0xfffe {
  449. panic("Invalid size for USHORTLEN_TYPE")
  450. }
  451. err = binary.Write(w, binary.LittleEndian, uint16(ti.Size))
  452. if err != nil {
  453. return
  454. }
  455. _, err = w.Write(buf)
  456. return
  457. }
  458. func readLongLenType(ti *typeInfo, r *tdsBuffer) interface{} {
  459. // information about this format can be found here:
  460. // http://msdn.microsoft.com/en-us/library/dd304783.aspx
  461. // and here:
  462. // http://msdn.microsoft.com/en-us/library/dd357254.aspx
  463. textptrsize := int(r.byte())
  464. if textptrsize == 0 {
  465. return nil
  466. }
  467. textptr := make([]byte, textptrsize)
  468. r.ReadFull(textptr)
  469. timestamp := r.uint64()
  470. _ = timestamp // ignore timestamp
  471. size := r.int32()
  472. if size == -1 {
  473. return nil
  474. }
  475. buf := make([]byte, size)
  476. r.ReadFull(buf)
  477. switch ti.TypeId {
  478. case typeText:
  479. return decodeChar(ti.Collation, buf)
  480. case typeImage:
  481. return buf
  482. case typeNText:
  483. return decodeNChar(buf)
  484. default:
  485. badStreamPanicf("Invalid typeid")
  486. }
  487. panic("shoulnd't get here")
  488. }
  489. func writeLongLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  490. //textptr
  491. err = binary.Write(w, binary.LittleEndian, byte(0x10))
  492. if err != nil {
  493. return
  494. }
  495. err = binary.Write(w, binary.LittleEndian, uint64(0xFFFFFFFFFFFFFFFF))
  496. if err != nil {
  497. return
  498. }
  499. err = binary.Write(w, binary.LittleEndian, uint64(0xFFFFFFFFFFFFFFFF))
  500. if err != nil {
  501. return
  502. }
  503. //timestamp?
  504. err = binary.Write(w, binary.LittleEndian, uint64(0xFFFFFFFFFFFFFFFF))
  505. if err != nil {
  506. return
  507. }
  508. err = binary.Write(w, binary.LittleEndian, uint32(ti.Size))
  509. if err != nil {
  510. return
  511. }
  512. _, err = w.Write(buf)
  513. return
  514. }
  515. func readCollation(r *tdsBuffer) (res cp.Collation) {
  516. res.LcidAndFlags = r.uint32()
  517. res.SortId = r.byte()
  518. return
  519. }
  520. func writeCollation(w io.Writer, col cp.Collation) (err error) {
  521. if err = binary.Write(w, binary.LittleEndian, col.LcidAndFlags); err != nil {
  522. return
  523. }
  524. err = binary.Write(w, binary.LittleEndian, col.SortId)
  525. return
  526. }
  527. // reads variant value
  528. // http://msdn.microsoft.com/en-us/library/dd303302.aspx
  529. func readVariantType(ti *typeInfo, r *tdsBuffer) interface{} {
  530. size := r.int32()
  531. if size == 0 {
  532. return nil
  533. }
  534. vartype := r.byte()
  535. propbytes := int32(r.byte())
  536. switch vartype {
  537. case typeGuid:
  538. buf := make([]byte, size-2-propbytes)
  539. r.ReadFull(buf)
  540. return buf
  541. case typeBit:
  542. return r.byte() != 0
  543. case typeInt1:
  544. return int64(r.byte())
  545. case typeInt2:
  546. return int64(int16(r.uint16()))
  547. case typeInt4:
  548. return int64(r.int32())
  549. case typeInt8:
  550. return int64(r.uint64())
  551. case typeDateTime:
  552. buf := make([]byte, size-2-propbytes)
  553. r.ReadFull(buf)
  554. return decodeDateTime(buf)
  555. case typeDateTim4:
  556. buf := make([]byte, size-2-propbytes)
  557. r.ReadFull(buf)
  558. return decodeDateTim4(buf)
  559. case typeFlt4:
  560. return float64(math.Float32frombits(r.uint32()))
  561. case typeFlt8:
  562. return math.Float64frombits(r.uint64())
  563. case typeMoney4:
  564. buf := make([]byte, size-2-propbytes)
  565. r.ReadFull(buf)
  566. return decodeMoney4(buf)
  567. case typeMoney:
  568. buf := make([]byte, size-2-propbytes)
  569. r.ReadFull(buf)
  570. return decodeMoney(buf)
  571. case typeDateN:
  572. buf := make([]byte, size-2-propbytes)
  573. r.ReadFull(buf)
  574. return decodeDate(buf)
  575. case typeTimeN:
  576. scale := r.byte()
  577. buf := make([]byte, size-2-propbytes)
  578. r.ReadFull(buf)
  579. return decodeTime(scale, buf)
  580. case typeDateTime2N:
  581. scale := r.byte()
  582. buf := make([]byte, size-2-propbytes)
  583. r.ReadFull(buf)
  584. return decodeDateTime2(scale, buf)
  585. case typeDateTimeOffsetN:
  586. scale := r.byte()
  587. buf := make([]byte, size-2-propbytes)
  588. r.ReadFull(buf)
  589. return decodeDateTimeOffset(scale, buf)
  590. case typeBigVarBin, typeBigBinary:
  591. r.uint16() // max length, ignoring
  592. buf := make([]byte, size-2-propbytes)
  593. r.ReadFull(buf)
  594. return buf
  595. case typeDecimalN, typeNumericN:
  596. prec := r.byte()
  597. scale := r.byte()
  598. buf := make([]byte, size-2-propbytes)
  599. r.ReadFull(buf)
  600. return decodeDecimal(prec, scale, buf)
  601. case typeBigVarChar, typeBigChar:
  602. col := readCollation(r)
  603. r.uint16() // max length, ignoring
  604. buf := make([]byte, size-2-propbytes)
  605. r.ReadFull(buf)
  606. return decodeChar(col, buf)
  607. case typeNVarChar, typeNChar:
  608. _ = readCollation(r)
  609. r.uint16() // max length, ignoring
  610. buf := make([]byte, size-2-propbytes)
  611. r.ReadFull(buf)
  612. return decodeNChar(buf)
  613. default:
  614. badStreamPanicf("Invalid variant typeid")
  615. }
  616. panic("shoulnd't get here")
  617. }
  618. // partially length prefixed stream
  619. // http://msdn.microsoft.com/en-us/library/dd340469.aspx
  620. func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
  621. size := r.uint64()
  622. var buf *bytes.Buffer
  623. switch size {
  624. case _PLP_NULL:
  625. // null
  626. return nil
  627. case _UNKNOWN_PLP_LEN:
  628. // size unknown
  629. buf = bytes.NewBuffer(make([]byte, 0, 1000))
  630. default:
  631. buf = bytes.NewBuffer(make([]byte, 0, size))
  632. }
  633. for true {
  634. chunksize := r.uint32()
  635. if chunksize == 0 {
  636. break
  637. }
  638. if _, err := io.CopyN(buf, r, int64(chunksize)); err != nil {
  639. badStreamPanicf("Reading PLP type failed: %s", err.Error())
  640. }
  641. }
  642. switch ti.TypeId {
  643. case typeXml:
  644. return decodeXml(*ti, buf.Bytes())
  645. case typeBigVarChar, typeBigChar, typeText:
  646. return decodeChar(ti.Collation, buf.Bytes())
  647. case typeBigVarBin, typeBigBinary, typeImage:
  648. return buf.Bytes()
  649. case typeNVarChar, typeNChar, typeNText:
  650. return decodeNChar(buf.Bytes())
  651. case typeUdt:
  652. return decodeUdt(*ti, buf.Bytes())
  653. }
  654. panic("shoulnd't get here")
  655. }
  656. func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  657. if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
  658. return
  659. }
  660. for {
  661. chunksize := uint32(len(buf))
  662. if chunksize == 0 {
  663. err = binary.Write(w, binary.LittleEndian, uint32(_PLP_TERMINATOR))
  664. return
  665. }
  666. if err = binary.Write(w, binary.LittleEndian, chunksize); err != nil {
  667. return
  668. }
  669. if _, err = w.Write(buf[:chunksize]); err != nil {
  670. return
  671. }
  672. buf = buf[chunksize:]
  673. }
  674. }
  675. func readVarLen(ti *typeInfo, r *tdsBuffer) {
  676. switch ti.TypeId {
  677. case typeDateN:
  678. ti.Size = 3
  679. ti.Reader = readByteLenType
  680. ti.Buffer = make([]byte, ti.Size)
  681. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  682. ti.Scale = r.byte()
  683. switch ti.Scale {
  684. case 0, 1, 2:
  685. ti.Size = 3
  686. case 3, 4:
  687. ti.Size = 4
  688. case 5, 6, 7:
  689. ti.Size = 5
  690. default:
  691. badStreamPanicf("Invalid scale for TIME/DATETIME2/DATETIMEOFFSET type")
  692. }
  693. switch ti.TypeId {
  694. case typeDateTime2N:
  695. ti.Size += 3
  696. case typeDateTimeOffsetN:
  697. ti.Size += 5
  698. }
  699. ti.Reader = readByteLenType
  700. ti.Buffer = make([]byte, ti.Size)
  701. case typeGuid, typeIntN, typeDecimal, typeNumeric,
  702. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  703. typeMoneyN, typeDateTimeN, typeChar,
  704. typeVarChar, typeBinary, typeVarBinary:
  705. // byle len types
  706. ti.Size = int(r.byte())
  707. ti.Buffer = make([]byte, ti.Size)
  708. switch ti.TypeId {
  709. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  710. ti.Prec = r.byte()
  711. ti.Scale = r.byte()
  712. }
  713. ti.Reader = readByteLenType
  714. case typeXml:
  715. ti.XmlInfo.SchemaPresent = r.byte()
  716. if ti.XmlInfo.SchemaPresent != 0 {
  717. // dbname
  718. ti.XmlInfo.DBName = r.BVarChar()
  719. // owning schema
  720. ti.XmlInfo.OwningSchema = r.BVarChar()
  721. // xml schema collection
  722. ti.XmlInfo.XmlSchemaCollection = r.UsVarChar()
  723. }
  724. ti.Reader = readPLPType
  725. case typeUdt:
  726. ti.Size = int(r.uint16())
  727. ti.UdtInfo.DBName = r.BVarChar()
  728. ti.UdtInfo.SchemaName = r.BVarChar()
  729. ti.UdtInfo.TypeName = r.BVarChar()
  730. ti.UdtInfo.AssemblyQualifiedName = r.UsVarChar()
  731. ti.Buffer = make([]byte, ti.Size)
  732. ti.Reader = readPLPType
  733. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  734. typeNVarChar, typeNChar:
  735. // short len types
  736. ti.Size = int(r.uint16())
  737. switch ti.TypeId {
  738. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  739. ti.Collation = readCollation(r)
  740. }
  741. if ti.Size == 0xffff {
  742. ti.Reader = readPLPType
  743. } else {
  744. ti.Buffer = make([]byte, ti.Size)
  745. ti.Reader = readShortLenType
  746. }
  747. case typeText, typeImage, typeNText, typeVariant:
  748. // LONGLEN_TYPE
  749. ti.Size = int(r.int32())
  750. switch ti.TypeId {
  751. case typeText, typeNText:
  752. ti.Collation = readCollation(r)
  753. // ignore tablenames
  754. numparts := int(r.byte())
  755. for i := 0; i < numparts; i++ {
  756. r.UsVarChar()
  757. }
  758. ti.Reader = readLongLenType
  759. case typeImage:
  760. // ignore tablenames
  761. numparts := int(r.byte())
  762. for i := 0; i < numparts; i++ {
  763. r.UsVarChar()
  764. }
  765. ti.Reader = readLongLenType
  766. case typeVariant:
  767. ti.Reader = readVariantType
  768. }
  769. default:
  770. badStreamPanicf("Invalid type %d", ti.TypeId)
  771. }
  772. return
  773. }
  774. func decodeMoney(buf []byte) []byte {
  775. money := int64(uint64(buf[4]) |
  776. uint64(buf[5])<<8 |
  777. uint64(buf[6])<<16 |
  778. uint64(buf[7])<<24 |
  779. uint64(buf[0])<<32 |
  780. uint64(buf[1])<<40 |
  781. uint64(buf[2])<<48 |
  782. uint64(buf[3])<<56)
  783. return scaleBytes(strconv.FormatInt(money, 10), 4)
  784. }
  785. func decodeMoney4(buf []byte) []byte {
  786. money := int32(binary.LittleEndian.Uint32(buf[0:4]))
  787. return scaleBytes(strconv.FormatInt(int64(money), 10), 4)
  788. }
  789. func decodeGuid(buf []byte) []byte {
  790. res := make([]byte, 16)
  791. copy(res, buf)
  792. return res
  793. }
  794. func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
  795. var sign uint8
  796. sign = buf[0]
  797. dec := Decimal{
  798. positive: sign != 0,
  799. prec: prec,
  800. scale: scale,
  801. }
  802. buf = buf[1:]
  803. l := len(buf) / 4
  804. for i := 0; i < l; i++ {
  805. dec.integer[i] = binary.LittleEndian.Uint32(buf[0:4])
  806. buf = buf[4:]
  807. }
  808. return dec.Bytes()
  809. }
  810. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  811. func decodeDateInt(buf []byte) (days int) {
  812. days = int(buf[0]) + int(buf[1])*256 + int(buf[2])*256*256
  813. return
  814. }
  815. func decodeDate(buf []byte) time.Time {
  816. return time.Date(1, 1, 1+decodeDateInt(buf), 0, 0, 0, 0, time.UTC)
  817. }
  818. func encodeDate(val time.Time) (buf []byte) {
  819. days, _, _ := dateTime2(val)
  820. buf = make([]byte, 3)
  821. buf[0] = byte(days)
  822. buf[1] = byte(days >> 8)
  823. buf[2] = byte(days >> 16)
  824. return
  825. }
  826. func decodeTimeInt(scale uint8, buf []byte) (sec int, ns int) {
  827. var acc uint64 = 0
  828. for i := len(buf) - 1; i >= 0; i-- {
  829. acc <<= 8
  830. acc |= uint64(buf[i])
  831. }
  832. for i := 0; i < 7-int(scale); i++ {
  833. acc *= 10
  834. }
  835. nsbig := acc * 100
  836. sec = int(nsbig / 1000000000)
  837. ns = int(nsbig % 1000000000)
  838. return
  839. }
  840. // calculate size of time field in bytes
  841. func calcTimeSize(scale int) int {
  842. if scale <= 2 {
  843. return 3
  844. } else if scale <= 4 {
  845. return 4
  846. } else {
  847. return 5
  848. }
  849. }
  850. // writes time value into a field buffer
  851. // buffer should be at least calcTimeSize long
  852. func encodeTimeInt(seconds, ns, scale int, buf []byte) {
  853. ns_total := int64(seconds)*1000*1000*1000 + int64(ns)
  854. t := ns_total / int64(math.Pow10(int(scale)*-1)*1e9)
  855. buf[0] = byte(t)
  856. buf[1] = byte(t >> 8)
  857. buf[2] = byte(t >> 16)
  858. buf[3] = byte(t >> 24)
  859. buf[4] = byte(t >> 32)
  860. }
  861. func decodeTime(scale uint8, buf []byte) time.Time {
  862. sec, ns := decodeTimeInt(scale, buf)
  863. return time.Date(1, 1, 1, 0, 0, sec, ns, time.UTC)
  864. }
  865. func encodeTime(hour, minute, second, ns, scale int) (buf []byte) {
  866. seconds := hour*3600 + minute*60 + second
  867. buf = make([]byte, calcTimeSize(scale))
  868. encodeTimeInt(seconds, ns, scale, buf)
  869. return
  870. }
  871. func decodeDateTime2(scale uint8, buf []byte) time.Time {
  872. timesize := len(buf) - 3
  873. sec, ns := decodeTimeInt(scale, buf[:timesize])
  874. days := decodeDateInt(buf[timesize:])
  875. return time.Date(1, 1, 1+days, 0, 0, sec, ns, time.UTC)
  876. }
  877. func encodeDateTime2(val time.Time, scale int) (buf []byte) {
  878. days, seconds, ns := dateTime2(val)
  879. timesize := calcTimeSize(scale)
  880. buf = make([]byte, 3+timesize)
  881. encodeTimeInt(seconds, ns, scale, buf)
  882. buf[timesize] = byte(days)
  883. buf[timesize+1] = byte(days >> 8)
  884. buf[timesize+2] = byte(days >> 16)
  885. return
  886. }
  887. func decodeDateTimeOffset(scale uint8, buf []byte) time.Time {
  888. timesize := len(buf) - 3 - 2
  889. sec, ns := decodeTimeInt(scale, buf[:timesize])
  890. buf = buf[timesize:]
  891. days := decodeDateInt(buf[:3])
  892. buf = buf[3:]
  893. offset := int(int16(binary.LittleEndian.Uint16(buf))) // in mins
  894. return time.Date(1, 1, 1+days, 0, 0, sec+offset*60, ns,
  895. time.FixedZone("", offset*60))
  896. }
  897. func encodeDateTimeOffset(val time.Time, scale int) (buf []byte) {
  898. timesize := calcTimeSize(scale)
  899. buf = make([]byte, timesize+2+3)
  900. days, seconds, ns := dateTime2(val.In(time.UTC))
  901. encodeTimeInt(seconds, ns, scale, buf)
  902. buf[timesize] = byte(days)
  903. buf[timesize+1] = byte(days >> 8)
  904. buf[timesize+2] = byte(days >> 16)
  905. _, offset := val.Zone()
  906. offset /= 60
  907. buf[timesize+3] = byte(offset)
  908. buf[timesize+4] = byte(offset >> 8)
  909. return
  910. }
  911. // returns days since Jan 1st 0001 in Gregorian calendar
  912. func gregorianDays(year, yearday int) int {
  913. year0 := year - 1
  914. return year0*365 + year0/4 - year0/100 + year0/400 + yearday - 1
  915. }
  916. func dateTime2(t time.Time) (days int, seconds int, ns int) {
  917. // days since Jan 1 1 (in same TZ as t)
  918. days = gregorianDays(t.Year(), t.YearDay())
  919. seconds = t.Second() + t.Minute()*60 + t.Hour()*60*60
  920. ns = t.Nanosecond()
  921. if days < 0 {
  922. days = 0
  923. seconds = 0
  924. ns = 0
  925. }
  926. max := gregorianDays(9999, 365)
  927. if days > max {
  928. days = max
  929. seconds = 59 + 59*60 + 23*60*60
  930. ns = 999999900
  931. }
  932. return
  933. }
  934. func decodeChar(col cp.Collation, buf []byte) string {
  935. return cp.CharsetToUTF8(col, buf)
  936. }
  937. func decodeUcs2(buf []byte) string {
  938. res, err := ucs22str(buf)
  939. if err != nil {
  940. badStreamPanicf("Invalid UCS2 encoding: %s", err.Error())
  941. }
  942. return res
  943. }
  944. func decodeNChar(buf []byte) string {
  945. return decodeUcs2(buf)
  946. }
  947. func decodeXml(ti typeInfo, buf []byte) string {
  948. return decodeUcs2(buf)
  949. }
  950. func decodeUdt(ti typeInfo, buf []byte) []byte {
  951. return buf
  952. }
  953. // makes go/sql type instance as described below
  954. // It should return
  955. // the value type that can be used to scan types into. For example, the database
  956. // column type "bigint" this should return "reflect.TypeOf(int64(0))".
  957. func makeGoLangScanType(ti typeInfo) reflect.Type {
  958. switch ti.TypeId {
  959. case typeInt1:
  960. return reflect.TypeOf(int64(0))
  961. case typeInt2:
  962. return reflect.TypeOf(int64(0))
  963. case typeInt4:
  964. return reflect.TypeOf(int64(0))
  965. case typeInt8:
  966. return reflect.TypeOf(int64(0))
  967. case typeFlt4:
  968. return reflect.TypeOf(float64(0))
  969. case typeIntN:
  970. switch ti.Size {
  971. case 1:
  972. return reflect.TypeOf(int64(0))
  973. case 2:
  974. return reflect.TypeOf(int64(0))
  975. case 4:
  976. return reflect.TypeOf(int64(0))
  977. case 8:
  978. return reflect.TypeOf(int64(0))
  979. default:
  980. panic("invalid size of INTNTYPE")
  981. }
  982. case typeFlt8:
  983. return reflect.TypeOf(float64(0))
  984. case typeFltN:
  985. switch ti.Size {
  986. case 4:
  987. return reflect.TypeOf(float64(0))
  988. case 8:
  989. return reflect.TypeOf(float64(0))
  990. default:
  991. panic("invalid size of FLNNTYPE")
  992. }
  993. case typeBigVarBin:
  994. return reflect.TypeOf([]byte{})
  995. case typeVarChar:
  996. return reflect.TypeOf("")
  997. case typeNVarChar:
  998. return reflect.TypeOf("")
  999. case typeBit, typeBitN:
  1000. return reflect.TypeOf(true)
  1001. case typeDecimalN, typeNumericN:
  1002. return reflect.TypeOf([]byte{})
  1003. case typeMoney, typeMoney4, typeMoneyN:
  1004. switch ti.Size {
  1005. case 4:
  1006. return reflect.TypeOf([]byte{})
  1007. case 8:
  1008. return reflect.TypeOf([]byte{})
  1009. default:
  1010. panic("invalid size of MONEYN")
  1011. }
  1012. case typeDateTim4:
  1013. return reflect.TypeOf(time.Time{})
  1014. case typeDateTime:
  1015. return reflect.TypeOf(time.Time{})
  1016. case typeDateTimeN:
  1017. switch ti.Size {
  1018. case 4:
  1019. return reflect.TypeOf(time.Time{})
  1020. case 8:
  1021. return reflect.TypeOf(time.Time{})
  1022. default:
  1023. panic("invalid size of DATETIMEN")
  1024. }
  1025. case typeDateTime2N:
  1026. return reflect.TypeOf(time.Time{})
  1027. case typeDateN:
  1028. return reflect.TypeOf(time.Time{})
  1029. case typeTimeN:
  1030. return reflect.TypeOf(time.Time{})
  1031. case typeDateTimeOffsetN:
  1032. return reflect.TypeOf(time.Time{})
  1033. case typeBigVarChar:
  1034. return reflect.TypeOf("")
  1035. case typeBigChar:
  1036. return reflect.TypeOf("")
  1037. case typeNChar:
  1038. return reflect.TypeOf("")
  1039. case typeGuid:
  1040. return reflect.TypeOf([]byte{})
  1041. case typeXml:
  1042. return reflect.TypeOf("")
  1043. case typeText:
  1044. return reflect.TypeOf("")
  1045. case typeNText:
  1046. return reflect.TypeOf("")
  1047. case typeImage:
  1048. return reflect.TypeOf([]byte{})
  1049. case typeBigBinary:
  1050. return reflect.TypeOf([]byte{})
  1051. case typeVariant:
  1052. return reflect.TypeOf(nil)
  1053. default:
  1054. panic(fmt.Sprintf("not implemented makeGoLangScanType for type %d", ti.TypeId))
  1055. }
  1056. }
  1057. func makeDecl(ti typeInfo) string {
  1058. switch ti.TypeId {
  1059. case typeNull:
  1060. // maybe we should use something else here
  1061. // this is tested in TestNull
  1062. return "nvarchar(1)"
  1063. case typeInt1:
  1064. return "tinyint"
  1065. case typeBigBinary:
  1066. return fmt.Sprintf("binary(%d)", ti.Size)
  1067. case typeInt2:
  1068. return "smallint"
  1069. case typeInt4:
  1070. return "int"
  1071. case typeInt8:
  1072. return "bigint"
  1073. case typeFlt4:
  1074. return "real"
  1075. case typeIntN:
  1076. switch ti.Size {
  1077. case 1:
  1078. return "tinyint"
  1079. case 2:
  1080. return "smallint"
  1081. case 4:
  1082. return "int"
  1083. case 8:
  1084. return "bigint"
  1085. default:
  1086. panic("invalid size of INTNTYPE")
  1087. }
  1088. case typeFlt8:
  1089. return "float"
  1090. case typeFltN:
  1091. switch ti.Size {
  1092. case 4:
  1093. return "real"
  1094. case 8:
  1095. return "float"
  1096. default:
  1097. panic("invalid size of FLNNTYPE")
  1098. }
  1099. case typeDecimal, typeDecimalN:
  1100. return fmt.Sprintf("decimal(%d, %d)", ti.Prec, ti.Scale)
  1101. case typeNumeric, typeNumericN:
  1102. return fmt.Sprintf("numeric(%d, %d)", ti.Prec, ti.Scale)
  1103. case typeMoney4:
  1104. return "smallmoney"
  1105. case typeMoney:
  1106. return "money"
  1107. case typeMoneyN:
  1108. switch ti.Size {
  1109. case 4:
  1110. return "smallmoney"
  1111. case 8:
  1112. return "money"
  1113. default:
  1114. panic("invalid size of MONEYNTYPE")
  1115. }
  1116. case typeBigVarBin:
  1117. if ti.Size > 8000 || ti.Size == 0 {
  1118. return "varbinary(max)"
  1119. } else {
  1120. return fmt.Sprintf("varbinary(%d)", ti.Size)
  1121. }
  1122. case typeNChar:
  1123. return fmt.Sprintf("nchar(%d)", ti.Size/2)
  1124. case typeBigChar, typeChar:
  1125. return fmt.Sprintf("char(%d)", ti.Size)
  1126. case typeBigVarChar, typeVarChar:
  1127. if ti.Size > 4000 || ti.Size == 0 {
  1128. return fmt.Sprintf("varchar(max)")
  1129. } else {
  1130. return fmt.Sprintf("varchar(%d)", ti.Size)
  1131. }
  1132. case typeNVarChar:
  1133. if ti.Size > 8000 || ti.Size == 0 {
  1134. return "nvarchar(max)"
  1135. } else {
  1136. return fmt.Sprintf("nvarchar(%d)", ti.Size/2)
  1137. }
  1138. case typeBit, typeBitN:
  1139. return "bit"
  1140. case typeDateN:
  1141. return "date"
  1142. case typeDateTim4:
  1143. return "smalldatetime"
  1144. case typeDateTime:
  1145. return "datetime"
  1146. case typeDateTimeN:
  1147. switch ti.Size {
  1148. case 4:
  1149. return "smalldatetime"
  1150. case 8:
  1151. return "datetime"
  1152. default:
  1153. panic("invalid size of DATETIMNTYPE")
  1154. }
  1155. case typeTimeN:
  1156. return "time"
  1157. case typeDateTime2N:
  1158. return fmt.Sprintf("datetime2(%d)", ti.Scale)
  1159. case typeDateTimeOffsetN:
  1160. return fmt.Sprintf("datetimeoffset(%d)", ti.Scale)
  1161. case typeText:
  1162. return "text"
  1163. case typeNText:
  1164. return "ntext"
  1165. case typeUdt:
  1166. return ti.UdtInfo.TypeName
  1167. case typeGuid:
  1168. return "uniqueidentifier"
  1169. case typeTvp:
  1170. if ti.UdtInfo.SchemaName != "" {
  1171. return fmt.Sprintf("%s.%s READONLY", ti.UdtInfo.SchemaName, ti.UdtInfo.TypeName)
  1172. }
  1173. return fmt.Sprintf("%s READONLY", ti.UdtInfo.TypeName)
  1174. default:
  1175. panic(fmt.Sprintf("not implemented makeDecl for type %#x", ti.TypeId))
  1176. }
  1177. }
  1178. // makes go/sql type name as described below
  1179. // RowsColumnTypeDatabaseTypeName may be implemented by Rows. It should return the
  1180. // database system type name without the length. Type names should be uppercase.
  1181. // Examples of returned types: "VARCHAR", "NVARCHAR", "VARCHAR2", "CHAR", "TEXT",
  1182. // "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT", "JSONB", "XML",
  1183. // "TIMESTAMP".
  1184. func makeGoLangTypeName(ti typeInfo) string {
  1185. switch ti.TypeId {
  1186. case typeInt1:
  1187. return "TINYINT"
  1188. case typeInt2:
  1189. return "SMALLINT"
  1190. case typeInt4:
  1191. return "INT"
  1192. case typeInt8:
  1193. return "BIGINT"
  1194. case typeFlt4:
  1195. return "REAL"
  1196. case typeIntN:
  1197. switch ti.Size {
  1198. case 1:
  1199. return "TINYINT"
  1200. case 2:
  1201. return "SMALLINT"
  1202. case 4:
  1203. return "INT"
  1204. case 8:
  1205. return "BIGINT"
  1206. default:
  1207. panic("invalid size of INTNTYPE")
  1208. }
  1209. case typeFlt8:
  1210. return "FLOAT"
  1211. case typeFltN:
  1212. switch ti.Size {
  1213. case 4:
  1214. return "REAL"
  1215. case 8:
  1216. return "FLOAT"
  1217. default:
  1218. panic("invalid size of FLNNTYPE")
  1219. }
  1220. case typeBigVarBin:
  1221. return "VARBINARY"
  1222. case typeVarChar:
  1223. return "VARCHAR"
  1224. case typeNVarChar:
  1225. return "NVARCHAR"
  1226. case typeBit, typeBitN:
  1227. return "BIT"
  1228. case typeDecimalN, typeNumericN:
  1229. return "DECIMAL"
  1230. case typeMoney, typeMoney4, typeMoneyN:
  1231. switch ti.Size {
  1232. case 4:
  1233. return "SMALLMONEY"
  1234. case 8:
  1235. return "MONEY"
  1236. default:
  1237. panic("invalid size of MONEYN")
  1238. }
  1239. case typeDateTim4:
  1240. return "SMALLDATETIME"
  1241. case typeDateTime:
  1242. return "DATETIME"
  1243. case typeDateTimeN:
  1244. switch ti.Size {
  1245. case 4:
  1246. return "SMALLDATETIME"
  1247. case 8:
  1248. return "DATETIME"
  1249. default:
  1250. panic("invalid size of DATETIMEN")
  1251. }
  1252. case typeDateTime2N:
  1253. return "DATETIME2"
  1254. case typeDateN:
  1255. return "DATE"
  1256. case typeTimeN:
  1257. return "TIME"
  1258. case typeDateTimeOffsetN:
  1259. return "DATETIMEOFFSET"
  1260. case typeBigVarChar:
  1261. return "VARCHAR"
  1262. case typeBigChar:
  1263. return "CHAR"
  1264. case typeNChar:
  1265. return "NCHAR"
  1266. case typeGuid:
  1267. return "UNIQUEIDENTIFIER"
  1268. case typeXml:
  1269. return "XML"
  1270. case typeText:
  1271. return "TEXT"
  1272. case typeNText:
  1273. return "NTEXT"
  1274. case typeImage:
  1275. return "IMAGE"
  1276. case typeVariant:
  1277. return "SQL_VARIANT"
  1278. case typeBigBinary:
  1279. return "BINARY"
  1280. default:
  1281. panic(fmt.Sprintf("not implemented makeGoLangTypeName for type %d", ti.TypeId))
  1282. }
  1283. }
  1284. // makes go/sql type length as described below
  1285. // It should return the length
  1286. // of the column type if the column is a variable length type. If the column is
  1287. // not a variable length type ok should return false.
  1288. // If length is not limited other than system limits, it should return math.MaxInt64.
  1289. // The following are examples of returned values for various types:
  1290. // TEXT (math.MaxInt64, true)
  1291. // varchar(10) (10, true)
  1292. // nvarchar(10) (10, true)
  1293. // decimal (0, false)
  1294. // int (0, false)
  1295. // bytea(30) (30, true)
  1296. func makeGoLangTypeLength(ti typeInfo) (int64, bool) {
  1297. switch ti.TypeId {
  1298. case typeInt1:
  1299. return 0, false
  1300. case typeInt2:
  1301. return 0, false
  1302. case typeInt4:
  1303. return 0, false
  1304. case typeInt8:
  1305. return 0, false
  1306. case typeFlt4:
  1307. return 0, false
  1308. case typeIntN:
  1309. switch ti.Size {
  1310. case 1:
  1311. return 0, false
  1312. case 2:
  1313. return 0, false
  1314. case 4:
  1315. return 0, false
  1316. case 8:
  1317. return 0, false
  1318. default:
  1319. panic("invalid size of INTNTYPE")
  1320. }
  1321. case typeFlt8:
  1322. return 0, false
  1323. case typeFltN:
  1324. switch ti.Size {
  1325. case 4:
  1326. return 0, false
  1327. case 8:
  1328. return 0, false
  1329. default:
  1330. panic("invalid size of FLNNTYPE")
  1331. }
  1332. case typeBit, typeBitN:
  1333. return 0, false
  1334. case typeDecimalN, typeNumericN:
  1335. return 0, false
  1336. case typeMoney, typeMoney4, typeMoneyN:
  1337. switch ti.Size {
  1338. case 4:
  1339. return 0, false
  1340. case 8:
  1341. return 0, false
  1342. default:
  1343. panic("invalid size of MONEYN")
  1344. }
  1345. case typeDateTim4, typeDateTime:
  1346. return 0, false
  1347. case typeDateTimeN:
  1348. switch ti.Size {
  1349. case 4:
  1350. return 0, false
  1351. case 8:
  1352. return 0, false
  1353. default:
  1354. panic("invalid size of DATETIMEN")
  1355. }
  1356. case typeDateTime2N:
  1357. return 0, false
  1358. case typeDateN:
  1359. return 0, false
  1360. case typeTimeN:
  1361. return 0, false
  1362. case typeDateTimeOffsetN:
  1363. return 0, false
  1364. case typeBigVarBin:
  1365. if ti.Size == 0xffff {
  1366. return 2147483645, true
  1367. } else {
  1368. return int64(ti.Size), true
  1369. }
  1370. case typeVarChar:
  1371. return int64(ti.Size), true
  1372. case typeBigVarChar:
  1373. if ti.Size == 0xffff {
  1374. return 2147483645, true
  1375. } else {
  1376. return int64(ti.Size), true
  1377. }
  1378. case typeBigChar:
  1379. return int64(ti.Size), true
  1380. case typeNVarChar:
  1381. if ti.Size == 0xffff {
  1382. return 2147483645 / 2, true
  1383. } else {
  1384. return int64(ti.Size) / 2, true
  1385. }
  1386. case typeNChar:
  1387. return int64(ti.Size) / 2, true
  1388. case typeGuid:
  1389. return 0, false
  1390. case typeXml:
  1391. return 1073741822, true
  1392. case typeText:
  1393. return 2147483647, true
  1394. case typeNText:
  1395. return 1073741823, true
  1396. case typeImage:
  1397. return 2147483647, true
  1398. case typeVariant:
  1399. return 0, false
  1400. case typeBigBinary:
  1401. return 0, false
  1402. default:
  1403. panic(fmt.Sprintf("not implemented makeGoLangTypeLength for type %d", ti.TypeId))
  1404. }
  1405. }
  1406. // makes go/sql type precision and scale as described below
  1407. // It should return the length
  1408. // of the column type if the column is a variable length type. If the column is
  1409. // not a variable length type ok should return false.
  1410. // If length is not limited other than system limits, it should return math.MaxInt64.
  1411. // The following are examples of returned values for various types:
  1412. // TEXT (math.MaxInt64, true)
  1413. // varchar(10) (10, true)
  1414. // nvarchar(10) (10, true)
  1415. // decimal (0, false)
  1416. // int (0, false)
  1417. // bytea(30) (30, true)
  1418. func makeGoLangTypePrecisionScale(ti typeInfo) (int64, int64, bool) {
  1419. switch ti.TypeId {
  1420. case typeInt1:
  1421. return 0, 0, false
  1422. case typeInt2:
  1423. return 0, 0, false
  1424. case typeInt4:
  1425. return 0, 0, false
  1426. case typeInt8:
  1427. return 0, 0, false
  1428. case typeFlt4:
  1429. return 0, 0, false
  1430. case typeIntN:
  1431. switch ti.Size {
  1432. case 1:
  1433. return 0, 0, false
  1434. case 2:
  1435. return 0, 0, false
  1436. case 4:
  1437. return 0, 0, false
  1438. case 8:
  1439. return 0, 0, false
  1440. default:
  1441. panic("invalid size of INTNTYPE")
  1442. }
  1443. case typeFlt8:
  1444. return 0, 0, false
  1445. case typeFltN:
  1446. switch ti.Size {
  1447. case 4:
  1448. return 0, 0, false
  1449. case 8:
  1450. return 0, 0, false
  1451. default:
  1452. panic("invalid size of FLNNTYPE")
  1453. }
  1454. case typeBit, typeBitN:
  1455. return 0, 0, false
  1456. case typeDecimalN, typeNumericN:
  1457. return int64(ti.Prec), int64(ti.Scale), true
  1458. case typeMoney, typeMoney4, typeMoneyN:
  1459. switch ti.Size {
  1460. case 4:
  1461. return 0, 0, false
  1462. case 8:
  1463. return 0, 0, false
  1464. default:
  1465. panic("invalid size of MONEYN")
  1466. }
  1467. case typeDateTim4, typeDateTime:
  1468. return 0, 0, false
  1469. case typeDateTimeN:
  1470. switch ti.Size {
  1471. case 4:
  1472. return 0, 0, false
  1473. case 8:
  1474. return 0, 0, false
  1475. default:
  1476. panic("invalid size of DATETIMEN")
  1477. }
  1478. case typeDateTime2N:
  1479. return 0, 0, false
  1480. case typeDateN:
  1481. return 0, 0, false
  1482. case typeTimeN:
  1483. return 0, 0, false
  1484. case typeDateTimeOffsetN:
  1485. return 0, 0, false
  1486. case typeBigVarBin:
  1487. return 0, 0, false
  1488. case typeVarChar:
  1489. return 0, 0, false
  1490. case typeBigVarChar:
  1491. return 0, 0, false
  1492. case typeBigChar:
  1493. return 0, 0, false
  1494. case typeNVarChar:
  1495. return 0, 0, false
  1496. case typeNChar:
  1497. return 0, 0, false
  1498. case typeGuid:
  1499. return 0, 0, false
  1500. case typeXml:
  1501. return 0, 0, false
  1502. case typeText:
  1503. return 0, 0, false
  1504. case typeNText:
  1505. return 0, 0, false
  1506. case typeImage:
  1507. return 0, 0, false
  1508. case typeVariant:
  1509. return 0, 0, false
  1510. case typeBigBinary:
  1511. return 0, 0, false
  1512. default:
  1513. panic(fmt.Sprintf("not implemented makeGoLangTypePrecisionScale for type %d", ti.TypeId))
  1514. }
  1515. }