types.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. package mssql
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. "math"
  8. "strconv"
  9. "time"
  10. "reflect"
  11. )
  12. // fixed-length data types
  13. // http://msdn.microsoft.com/en-us/library/dd341171.aspx
  14. const (
  15. typeNull = 0x1f
  16. typeInt1 = 0x30
  17. typeBit = 0x32
  18. typeInt2 = 0x34
  19. typeInt4 = 0x38
  20. typeDateTim4 = 0x3a
  21. typeFlt4 = 0x3b
  22. typeMoney = 0x3c
  23. typeDateTime = 0x3d
  24. typeFlt8 = 0x3e
  25. typeMoney4 = 0x7a
  26. typeInt8 = 0x7f
  27. )
  28. // variable-length data types
  29. // http://msdn.microsoft.com/en-us/library/dd358341.aspx
  30. const (
  31. // byte len types
  32. typeGuid = 0x24
  33. typeIntN = 0x26
  34. typeDecimal = 0x37 // legacy
  35. typeNumeric = 0x3f // legacy
  36. typeBitN = 0x68
  37. typeDecimalN = 0x6a
  38. typeNumericN = 0x6c
  39. typeFltN = 0x6d
  40. typeMoneyN = 0x6e
  41. typeDateTimeN = 0x6f
  42. typeDateN = 0x28
  43. typeTimeN = 0x29
  44. typeDateTime2N = 0x2a
  45. typeDateTimeOffsetN = 0x2b
  46. typeChar = 0x2f // legacy
  47. typeVarChar = 0x27 // legacy
  48. typeBinary = 0x2d // legacy
  49. typeVarBinary = 0x25 // legacy
  50. // short length types
  51. typeBigVarBin = 0xa5
  52. typeBigVarChar = 0xa7
  53. typeBigBinary = 0xad
  54. typeBigChar = 0xaf
  55. typeNVarChar = 0xe7
  56. typeNChar = 0xef
  57. typeXml = 0xf1
  58. typeUdt = 0xf0
  59. // long length types
  60. typeText = 0x23
  61. typeImage = 0x22
  62. typeNText = 0x63
  63. typeVariant = 0x62
  64. )
  65. // TYPE_INFO rule
  66. // http://msdn.microsoft.com/en-us/library/dd358284.aspx
  67. type typeInfo struct {
  68. TypeId uint8
  69. Size int
  70. Scale uint8
  71. Prec uint8
  72. Buffer []byte
  73. Collation collation
  74. Reader func(ti *typeInfo, r *tdsBuffer) (res interface{})
  75. Writer func(w io.Writer, ti typeInfo, buf []byte) (err error)
  76. }
  77. func readTypeInfo(r *tdsBuffer) (res typeInfo) {
  78. res.TypeId = r.byte()
  79. switch res.TypeId {
  80. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  81. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  82. // those are fixed length types
  83. switch res.TypeId {
  84. case typeNull:
  85. res.Size = 0
  86. case typeInt1, typeBit:
  87. res.Size = 1
  88. case typeInt2:
  89. res.Size = 2
  90. case typeInt4, typeDateTim4, typeFlt4, typeMoney4:
  91. res.Size = 4
  92. case typeMoney, typeDateTime, typeFlt8, typeInt8:
  93. res.Size = 8
  94. }
  95. res.Reader = readFixedType
  96. res.Buffer = make([]byte, res.Size)
  97. default: // all others are VARLENTYPE
  98. readVarLen(&res, r)
  99. }
  100. return
  101. }
  102. func writeTypeInfo(w io.Writer, ti *typeInfo) (err error) {
  103. err = binary.Write(w, binary.LittleEndian, ti.TypeId)
  104. if err != nil {
  105. return
  106. }
  107. switch ti.TypeId {
  108. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  109. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  110. // those are fixed length types
  111. default: // all others are VARLENTYPE
  112. err = writeVarLen(w, ti)
  113. if err != nil {
  114. return
  115. }
  116. }
  117. return
  118. }
  119. func writeVarLen(w io.Writer, ti *typeInfo) (err error) {
  120. switch ti.TypeId {
  121. case typeDateN:
  122. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  123. if err = binary.Write(w, binary.LittleEndian, ti.Scale); err != nil {
  124. return
  125. }
  126. ti.Writer = writeByteLenType
  127. case typeIntN, typeDecimal, typeNumeric,
  128. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  129. typeMoneyN, typeDateTimeN, typeChar,
  130. typeVarChar, typeBinary, typeVarBinary:
  131. // byle len types
  132. if ti.Size > 0xff {
  133. panic("Invalid size for BYLELEN_TYPE")
  134. }
  135. if err = binary.Write(w, binary.LittleEndian, uint8(ti.Size)); err != nil {
  136. return
  137. }
  138. switch ti.TypeId {
  139. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  140. err = binary.Write(w, binary.LittleEndian, ti.Prec)
  141. if err != nil {
  142. return
  143. }
  144. err = binary.Write(w, binary.LittleEndian, ti.Scale)
  145. if err != nil {
  146. return
  147. }
  148. }
  149. ti.Writer = writeByteLenType
  150. case typeGuid:
  151. if !(ti.Size == 0x10 || ti.Size == 0x00) {
  152. panic("Invalid size for BYLELEN_TYPE")
  153. }
  154. if err = binary.Write(w, binary.LittleEndian, uint8(ti.Size)); err != nil {
  155. return
  156. }
  157. ti.Writer = writeByteLenType
  158. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  159. typeNVarChar, typeNChar, typeXml, typeUdt:
  160. // short len types
  161. if ti.Size > 8000 || ti.Size == 0 {
  162. if err = binary.Write(w, binary.LittleEndian, uint16(0xffff)); err != nil {
  163. return
  164. }
  165. ti.Writer = writePLPType
  166. } else {
  167. if err = binary.Write(w, binary.LittleEndian, uint16(ti.Size)); err != nil {
  168. return
  169. }
  170. ti.Writer = writeShortLenType
  171. }
  172. switch ti.TypeId {
  173. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  174. if err = writeCollation(w, ti.Collation); err != nil {
  175. return
  176. }
  177. case typeXml:
  178. var schemapresent uint8 = 0
  179. if err = binary.Write(w, binary.LittleEndian, schemapresent); err != nil {
  180. return
  181. }
  182. }
  183. case typeText, typeImage, typeNText, typeVariant:
  184. // LONGLEN_TYPE
  185. panic("LONGLEN_TYPE not implemented")
  186. default:
  187. panic("Invalid type")
  188. }
  189. return
  190. }
  191. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  192. func decodeDateTim4(buf []byte) time.Time {
  193. days := binary.LittleEndian.Uint16(buf)
  194. mins := binary.LittleEndian.Uint16(buf[2:])
  195. return time.Date(1900, 1, 1+int(days),
  196. 0, int(mins), 0, 0, time.UTC)
  197. }
  198. func decodeDateTime(buf []byte) time.Time {
  199. days := int32(binary.LittleEndian.Uint32(buf))
  200. tm := binary.LittleEndian.Uint32(buf[4:])
  201. ns := int(math.Trunc(float64(tm%300)/0.3+0.5)) * 1000000
  202. secs := int(tm / 300)
  203. return time.Date(1900, 1, 1+int(days),
  204. 0, 0, secs, ns, time.UTC)
  205. }
  206. func readFixedType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  207. r.ReadFull(ti.Buffer)
  208. buf := ti.Buffer
  209. switch ti.TypeId {
  210. case typeNull:
  211. return nil
  212. case typeInt1:
  213. return int64(buf[0])
  214. case typeBit:
  215. return buf[0] != 0
  216. case typeInt2:
  217. return int64(int16(binary.LittleEndian.Uint16(buf)))
  218. case typeInt4:
  219. return int64(int32(binary.LittleEndian.Uint32(buf)))
  220. case typeDateTim4:
  221. return decodeDateTim4(buf)
  222. case typeFlt4:
  223. return math.Float32frombits(binary.LittleEndian.Uint32(buf))
  224. case typeMoney4:
  225. return decodeMoney4(buf)
  226. case typeMoney:
  227. return decodeMoney(buf)
  228. case typeDateTime:
  229. return decodeDateTime(buf)
  230. case typeFlt8:
  231. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  232. case typeInt8:
  233. return int64(binary.LittleEndian.Uint64(buf))
  234. default:
  235. badStreamPanicf("Invalid typeid")
  236. }
  237. panic("shoulnd't get here")
  238. }
  239. func readByteLenType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  240. size := r.byte()
  241. if size == 0 {
  242. return nil
  243. }
  244. r.ReadFull(ti.Buffer[:size])
  245. buf := ti.Buffer[:size]
  246. switch ti.TypeId {
  247. case typeDateN:
  248. if len(buf) != 3 {
  249. badStreamPanicf("Invalid size for DATENTYPE")
  250. }
  251. return decodeDate(buf)
  252. case typeTimeN:
  253. return decodeTime(ti.Scale, buf)
  254. case typeDateTime2N:
  255. return decodeDateTime2(ti.Scale, buf)
  256. case typeDateTimeOffsetN:
  257. return decodeDateTimeOffset(ti.Scale, buf)
  258. case typeGuid:
  259. return decodeGuid(buf)
  260. case typeIntN:
  261. switch len(buf) {
  262. case 1:
  263. return int64(buf[0])
  264. case 2:
  265. return int64(int16((binary.LittleEndian.Uint16(buf))))
  266. case 4:
  267. return int64(int32(binary.LittleEndian.Uint32(buf)))
  268. case 8:
  269. return int64(binary.LittleEndian.Uint64(buf))
  270. default:
  271. badStreamPanicf("Invalid size for INTNTYPE")
  272. }
  273. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  274. return decodeDecimal(ti.Prec, ti.Scale, buf)
  275. case typeBitN:
  276. if len(buf) != 1 {
  277. badStreamPanicf("Invalid size for BITNTYPE")
  278. }
  279. return buf[0] != 0
  280. case typeFltN:
  281. switch len(buf) {
  282. case 4:
  283. return float64(math.Float32frombits(binary.LittleEndian.Uint32(buf)))
  284. case 8:
  285. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  286. default:
  287. badStreamPanicf("Invalid size for FLTNTYPE")
  288. }
  289. case typeMoneyN:
  290. switch len(buf) {
  291. case 4:
  292. return decodeMoney4(buf)
  293. case 8:
  294. return decodeMoney(buf)
  295. default:
  296. badStreamPanicf("Invalid size for MONEYNTYPE")
  297. }
  298. case typeDateTimeN:
  299. switch len(buf) {
  300. case 4:
  301. return decodeDateTim4(buf)
  302. case 8:
  303. return decodeDateTime(buf)
  304. default:
  305. badStreamPanicf("Invalid size for DATETIMENTYPE")
  306. }
  307. case typeChar, typeVarChar:
  308. return decodeChar(ti.Collation, buf)
  309. case typeBinary, typeVarBinary:
  310. // a copy, because the backing array for ti.Buffer is reused
  311. // and can be overwritten by the next row while this row waits
  312. // in a buffered chan
  313. cpy := make([]byte, len(buf))
  314. copy(cpy, buf)
  315. return cpy
  316. default:
  317. badStreamPanicf("Invalid typeid")
  318. }
  319. panic("shoulnd't get here")
  320. }
  321. func writeByteLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  322. if ti.Size > 0xff {
  323. panic("Invalid size for BYTELEN_TYPE")
  324. }
  325. err = binary.Write(w, binary.LittleEndian, uint8(ti.Size))
  326. if err != nil {
  327. return
  328. }
  329. _, err = w.Write(buf)
  330. return
  331. }
  332. func readShortLenType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  333. size := r.uint16()
  334. if size == 0xffff {
  335. return nil
  336. }
  337. r.ReadFull(ti.Buffer[:size])
  338. buf := ti.Buffer[:size]
  339. switch ti.TypeId {
  340. case typeBigVarChar, typeBigChar:
  341. return decodeChar(ti.Collation, buf)
  342. case typeBigVarBin, typeBigBinary:
  343. // a copy, because the backing array for ti.Buffer is reused
  344. // and can be overwritten by the next row while this row waits
  345. // in a buffered chan
  346. cpy := make([]byte, len(buf))
  347. copy(cpy, buf)
  348. return cpy
  349. case typeNVarChar, typeNChar:
  350. return decodeNChar(buf)
  351. case typeUdt:
  352. return decodeUdt(*ti, buf)
  353. default:
  354. badStreamPanicf("Invalid typeid")
  355. }
  356. panic("shoulnd't get here")
  357. }
  358. func writeShortLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  359. if buf == nil {
  360. err = binary.Write(w, binary.LittleEndian, uint16(0xffff))
  361. return
  362. }
  363. if ti.Size > 0xfffe {
  364. panic("Invalid size for USHORTLEN_TYPE")
  365. }
  366. err = binary.Write(w, binary.LittleEndian, uint16(ti.Size))
  367. if err != nil {
  368. return
  369. }
  370. _, err = w.Write(buf)
  371. return
  372. }
  373. func readLongLenType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  374. // information about this format can be found here:
  375. // http://msdn.microsoft.com/en-us/library/dd304783.aspx
  376. // and here:
  377. // http://msdn.microsoft.com/en-us/library/dd357254.aspx
  378. textptrsize := int(r.byte())
  379. if textptrsize == 0 {
  380. return nil
  381. }
  382. textptr := make([]byte, textptrsize)
  383. r.ReadFull(textptr)
  384. timestamp := r.uint64()
  385. _ = timestamp // ignore timestamp
  386. size := r.int32()
  387. if size == -1 {
  388. return nil
  389. }
  390. buf := make([]byte, size)
  391. r.ReadFull(buf)
  392. switch ti.TypeId {
  393. case typeText:
  394. return decodeChar(ti.Collation, buf)
  395. case typeImage:
  396. return buf
  397. case typeNText:
  398. return decodeNChar(buf)
  399. default:
  400. badStreamPanicf("Invalid typeid")
  401. }
  402. panic("shoulnd't get here")
  403. }
  404. // reads variant value
  405. // http://msdn.microsoft.com/en-us/library/dd303302.aspx
  406. func readVariantType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  407. size := r.int32()
  408. if size == 0 {
  409. return nil
  410. }
  411. vartype := r.byte()
  412. propbytes := int32(r.byte())
  413. switch vartype {
  414. case typeGuid:
  415. buf := make([]byte, size-2-propbytes)
  416. r.ReadFull(buf)
  417. return buf
  418. case typeBit:
  419. return r.byte() != 0
  420. case typeInt1:
  421. return int64(r.byte())
  422. case typeInt2:
  423. return int64(int16(r.uint16()))
  424. case typeInt4:
  425. return int64(r.int32())
  426. case typeInt8:
  427. return int64(r.uint64())
  428. case typeDateTime:
  429. buf := make([]byte, size-2-propbytes)
  430. r.ReadFull(buf)
  431. return decodeDateTime(buf)
  432. case typeDateTim4:
  433. buf := make([]byte, size-2-propbytes)
  434. r.ReadFull(buf)
  435. return decodeDateTim4(buf)
  436. case typeFlt4:
  437. return float64(math.Float32frombits(r.uint32()))
  438. case typeFlt8:
  439. return math.Float64frombits(r.uint64())
  440. case typeMoney4:
  441. buf := make([]byte, size-2-propbytes)
  442. r.ReadFull(buf)
  443. return decodeMoney4(buf)
  444. case typeMoney:
  445. buf := make([]byte, size-2-propbytes)
  446. r.ReadFull(buf)
  447. return decodeMoney(buf)
  448. case typeDateN:
  449. buf := make([]byte, size-2-propbytes)
  450. r.ReadFull(buf)
  451. return decodeDate(buf)
  452. case typeTimeN:
  453. scale := r.byte()
  454. buf := make([]byte, size-2-propbytes)
  455. r.ReadFull(buf)
  456. return decodeTime(scale, buf)
  457. case typeDateTime2N:
  458. scale := r.byte()
  459. buf := make([]byte, size-2-propbytes)
  460. r.ReadFull(buf)
  461. return decodeDateTime2(scale, buf)
  462. case typeDateTimeOffsetN:
  463. scale := r.byte()
  464. buf := make([]byte, size-2-propbytes)
  465. r.ReadFull(buf)
  466. return decodeDateTimeOffset(scale, buf)
  467. case typeBigVarBin, typeBigBinary:
  468. r.uint16() // max length, ignoring
  469. buf := make([]byte, size-2-propbytes)
  470. r.ReadFull(buf)
  471. return buf
  472. case typeDecimalN, typeNumericN:
  473. prec := r.byte()
  474. scale := r.byte()
  475. buf := make([]byte, size-2-propbytes)
  476. r.ReadFull(buf)
  477. return decodeDecimal(prec, scale, buf)
  478. case typeBigVarChar, typeBigChar:
  479. col := readCollation(r)
  480. r.uint16() // max length, ignoring
  481. buf := make([]byte, size-2-propbytes)
  482. r.ReadFull(buf)
  483. return decodeChar(col, buf)
  484. case typeNVarChar, typeNChar:
  485. _ = readCollation(r)
  486. r.uint16() // max length, ignoring
  487. buf := make([]byte, size-2-propbytes)
  488. r.ReadFull(buf)
  489. return decodeNChar(buf)
  490. default:
  491. badStreamPanicf("Invalid variant typeid")
  492. }
  493. panic("shoulnd't get here")
  494. }
  495. // partially length prefixed stream
  496. // http://msdn.microsoft.com/en-us/library/dd340469.aspx
  497. func readPLPType(ti *typeInfo, r *tdsBuffer) (interface{}) {
  498. size := r.uint64()
  499. var buf *bytes.Buffer
  500. switch size {
  501. case 0xffffffffffffffff:
  502. // null
  503. return nil
  504. case 0xfffffffffffffffe:
  505. // size unknown
  506. buf = bytes.NewBuffer(make([]byte, 0, 1000))
  507. default:
  508. buf = bytes.NewBuffer(make([]byte, 0, size))
  509. }
  510. for true {
  511. chunksize := r.uint32()
  512. if chunksize == 0 {
  513. break
  514. }
  515. if _, err := io.CopyN(buf, r, int64(chunksize)); err != nil {
  516. badStreamPanicf("Reading PLP type failed: %s", err.Error())
  517. }
  518. }
  519. switch ti.TypeId {
  520. case typeXml:
  521. return decodeXml(*ti, buf.Bytes())
  522. case typeBigVarChar, typeBigChar, typeText:
  523. return decodeChar(ti.Collation, buf.Bytes())
  524. case typeBigVarBin, typeBigBinary, typeImage:
  525. return buf.Bytes()
  526. case typeNVarChar, typeNChar, typeNText:
  527. return decodeNChar(buf.Bytes())
  528. case typeUdt:
  529. return decodeUdt(*ti, buf.Bytes())
  530. }
  531. panic("shoulnd't get here")
  532. }
  533. func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  534. if err = binary.Write(w, binary.LittleEndian, uint64(len(buf))); err != nil {
  535. return
  536. }
  537. for {
  538. chunksize := uint32(len(buf))
  539. if err = binary.Write(w, binary.LittleEndian, chunksize); err != nil {
  540. return
  541. }
  542. if chunksize == 0 {
  543. return
  544. }
  545. if _, err = w.Write(buf[:chunksize]); err != nil {
  546. return
  547. }
  548. buf = buf[chunksize:]
  549. }
  550. }
  551. func readVarLen(ti *typeInfo, r *tdsBuffer) {
  552. switch ti.TypeId {
  553. case typeDateN:
  554. ti.Size = 3
  555. ti.Reader = readByteLenType
  556. ti.Buffer = make([]byte, ti.Size)
  557. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  558. ti.Scale = r.byte()
  559. switch ti.Scale {
  560. case 0, 1, 2:
  561. ti.Size = 3
  562. case 3, 4:
  563. ti.Size = 4
  564. case 5, 6, 7:
  565. ti.Size = 5
  566. default:
  567. badStreamPanicf("Invalid scale for TIME/DATETIME2/DATETIMEOFFSET type")
  568. }
  569. switch ti.TypeId {
  570. case typeDateTime2N:
  571. ti.Size += 3
  572. case typeDateTimeOffsetN:
  573. ti.Size += 5
  574. }
  575. ti.Reader = readByteLenType
  576. ti.Buffer = make([]byte, ti.Size)
  577. case typeGuid, typeIntN, typeDecimal, typeNumeric,
  578. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  579. typeMoneyN, typeDateTimeN, typeChar,
  580. typeVarChar, typeBinary, typeVarBinary:
  581. // byle len types
  582. ti.Size = int(r.byte())
  583. ti.Buffer = make([]byte, ti.Size)
  584. switch ti.TypeId {
  585. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  586. ti.Prec = r.byte()
  587. ti.Scale = r.byte()
  588. }
  589. ti.Reader = readByteLenType
  590. case typeXml:
  591. schemapresent := r.byte()
  592. if schemapresent != 0 {
  593. // just ignore this for now
  594. // dbname
  595. r.BVarChar()
  596. // owning schema
  597. r.BVarChar()
  598. // xml schema collection
  599. r.UsVarChar()
  600. }
  601. ti.Reader = readPLPType
  602. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  603. typeNVarChar, typeNChar, typeUdt:
  604. // short len types
  605. ti.Size = int(r.uint16())
  606. switch ti.TypeId {
  607. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  608. ti.Collation = readCollation(r)
  609. }
  610. if ti.Size == 0xffff {
  611. ti.Reader = readPLPType
  612. } else {
  613. ti.Buffer = make([]byte, ti.Size)
  614. ti.Reader = readShortLenType
  615. }
  616. case typeText, typeImage, typeNText, typeVariant:
  617. // LONGLEN_TYPE
  618. ti.Size = int(r.int32())
  619. switch ti.TypeId {
  620. case typeText, typeNText:
  621. ti.Collation = readCollation(r)
  622. // ignore tablenames
  623. numparts := int(r.byte())
  624. for i := 0; i < numparts; i++ {
  625. r.UsVarChar()
  626. }
  627. ti.Reader = readLongLenType
  628. case typeImage:
  629. // ignore tablenames
  630. numparts := int(r.byte())
  631. for i := 0; i < numparts; i++ {
  632. r.UsVarChar()
  633. }
  634. ti.Reader = readLongLenType
  635. case typeVariant:
  636. ti.Reader = readVariantType
  637. }
  638. default:
  639. badStreamPanicf("Invalid type %d", ti.TypeId)
  640. }
  641. return
  642. }
  643. func decodeMoney(buf []byte) []byte {
  644. money := int64(uint64(buf[4]) |
  645. uint64(buf[5])<<8 |
  646. uint64(buf[6])<<16 |
  647. uint64(buf[7])<<24 |
  648. uint64(buf[0])<<32 |
  649. uint64(buf[1])<<40 |
  650. uint64(buf[2])<<48 |
  651. uint64(buf[3])<<56)
  652. return scaleBytes(strconv.FormatInt(money, 10), 4)
  653. }
  654. func decodeMoney4(buf []byte) []byte {
  655. money := int32(binary.LittleEndian.Uint32(buf[0:4]))
  656. return scaleBytes(strconv.FormatInt(int64(money), 10), 4)
  657. }
  658. func decodeGuid(buf []byte) []byte {
  659. res := make([]byte, 16)
  660. copy(res, buf)
  661. return res
  662. }
  663. func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
  664. var sign uint8
  665. sign = buf[0]
  666. dec := Decimal{
  667. positive: sign != 0,
  668. prec: prec,
  669. scale: scale,
  670. }
  671. buf = buf[1:]
  672. l := len(buf) / 4
  673. for i := 0; i < l; i++ {
  674. dec.integer[i] = binary.LittleEndian.Uint32(buf[0:4])
  675. buf = buf[4:]
  676. }
  677. return dec.Bytes()
  678. }
  679. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  680. func decodeDateInt(buf []byte) (days int) {
  681. days = int(buf[0]) + int(buf[1])*256 + int(buf[2])*256*256
  682. return
  683. }
  684. func decodeDate(buf []byte) time.Time {
  685. return time.Date(1, 1, 1+decodeDateInt(buf), 0, 0, 0, 0, time.UTC)
  686. }
  687. func decodeTimeInt(scale uint8, buf []byte) (sec int, ns int) {
  688. var acc uint64 = 0
  689. for i := len(buf) - 1; i >= 0; i-- {
  690. acc <<= 8
  691. acc |= uint64(buf[i])
  692. }
  693. for i := 0; i < 7-int(scale); i++ {
  694. acc *= 10
  695. }
  696. nsbig := acc * 100
  697. sec = int(nsbig / 1000000000)
  698. ns = int(nsbig % 1000000000)
  699. return
  700. }
  701. func decodeTime(scale uint8, buf []byte) time.Time {
  702. sec, ns := decodeTimeInt(scale, buf)
  703. return time.Date(1, 1, 1, 0, 0, sec, ns, time.UTC)
  704. }
  705. func decodeDateTime2(scale uint8, buf []byte) time.Time {
  706. timesize := len(buf) - 3
  707. sec, ns := decodeTimeInt(scale, buf[:timesize])
  708. days := decodeDateInt(buf[timesize:])
  709. return time.Date(1, 1, 1+days, 0, 0, sec, ns, time.UTC)
  710. }
  711. func decodeDateTimeOffset(scale uint8, buf []byte) time.Time {
  712. timesize := len(buf) - 3 - 2
  713. sec, ns := decodeTimeInt(scale, buf[:timesize])
  714. buf = buf[timesize:]
  715. days := decodeDateInt(buf[:3])
  716. buf = buf[3:]
  717. offset := int(int16(binary.LittleEndian.Uint16(buf))) // in mins
  718. return time.Date(1, 1, 1+days, 0, 0, sec+offset*60, ns,
  719. time.FixedZone("", offset*60))
  720. }
  721. func divFloor(x int64, y int64) int64 {
  722. q := x / y
  723. r := x % y
  724. if r != 0 && ((r < 0) != (y < 0)) {
  725. q--
  726. }
  727. return q
  728. }
  729. func dateTime2(t time.Time) (days int32, ns int64) {
  730. // number of days since Jan 1 1970 UTC
  731. days64 := divFloor(t.Unix(), 24*60*60)
  732. // number of days since Jan 1 1 UTC
  733. days = int32(days64) + 1969*365 + 1969/4 - 1969/100 + 1969/400
  734. // number of seconds within day
  735. secs := t.Unix() - days64*24*60*60
  736. // number of nanoseconds within day
  737. ns = secs*1e9 + int64(t.Nanosecond())
  738. return
  739. }
  740. func decodeChar(col collation, buf []byte) string {
  741. return charset2utf8(col, buf)
  742. }
  743. func decodeUcs2(buf []byte) string {
  744. res, err := ucs22str(buf)
  745. if err != nil {
  746. badStreamPanicf("Invalid UCS2 encoding: %s", err.Error())
  747. }
  748. return res
  749. }
  750. func decodeNChar(buf []byte) string {
  751. return decodeUcs2(buf)
  752. }
  753. func decodeXml(ti typeInfo, buf []byte) string {
  754. return decodeUcs2(buf)
  755. }
  756. func decodeUdt(ti typeInfo, buf []byte) int {
  757. panic("Not implemented")
  758. }
  759. // makes go/sql type instance as described below
  760. // It should return
  761. // the value type that can be used to scan types into. For example, the database
  762. // column type "bigint" this should return "reflect.TypeOf(int64(0))".
  763. func makeGoLangScanType(ti typeInfo) reflect.Type {
  764. switch ti.TypeId {
  765. case typeInt4:
  766. return reflect.TypeOf(int64(0))
  767. case typeInt8:
  768. return reflect.TypeOf(int64(0))
  769. case typeFlt4:
  770. return reflect.TypeOf(float64(0))
  771. case typeIntN:
  772. switch ti.Size {
  773. case 1:
  774. return reflect.TypeOf(int64(0))
  775. case 2:
  776. return reflect.TypeOf(int64(0))
  777. case 4:
  778. return reflect.TypeOf(int64(0))
  779. case 8:
  780. return reflect.TypeOf(int64(0))
  781. default:
  782. panic("invalid size of INTNTYPE")
  783. }
  784. case typeFlt8:
  785. return reflect.TypeOf(float64(0))
  786. case typeFltN:
  787. switch ti.Size {
  788. case 4:
  789. return reflect.TypeOf(float64(0))
  790. case 8:
  791. return reflect.TypeOf(float64(0))
  792. default:
  793. panic("invalid size of FLNNTYPE")
  794. }
  795. case typeBigVarBin:
  796. return reflect.TypeOf([]byte{})
  797. case typeVarChar:
  798. return reflect.TypeOf("")
  799. case typeNVarChar:
  800. return reflect.TypeOf("")
  801. case typeBit, typeBitN:
  802. return reflect.TypeOf(true)
  803. case typeDecimalN, typeNumericN:
  804. return reflect.TypeOf([]byte{})
  805. case typeMoneyN:
  806. switch ti.Size {
  807. case 4:
  808. return reflect.TypeOf([]byte{})
  809. case 8:
  810. return reflect.TypeOf([]byte{})
  811. default:
  812. panic("invalid size of MONEYN")
  813. }
  814. case typeDateTimeN:
  815. switch ti.Size {
  816. case 4:
  817. return reflect.TypeOf(time.Time{})
  818. case 8:
  819. return reflect.TypeOf(time.Time{})
  820. default:
  821. panic("invalid size of DATETIMEN")
  822. }
  823. case typeDateTime2N:
  824. return reflect.TypeOf(time.Time{})
  825. case typeDateN:
  826. return reflect.TypeOf(time.Time{})
  827. case typeTimeN:
  828. return reflect.TypeOf(time.Time{})
  829. case typeDateTimeOffsetN:
  830. return reflect.TypeOf(time.Time{})
  831. case typeBigVarChar:
  832. return reflect.TypeOf("")
  833. case typeBigChar:
  834. return reflect.TypeOf("")
  835. case typeNChar:
  836. return reflect.TypeOf("")
  837. case typeGuid:
  838. return reflect.TypeOf([]byte{})
  839. case typeXml:
  840. return reflect.TypeOf("")
  841. case typeText:
  842. return reflect.TypeOf("")
  843. case typeNText:
  844. return reflect.TypeOf("")
  845. case typeImage:
  846. return reflect.TypeOf([]byte{})
  847. case typeVariant:
  848. return reflect.TypeOf(nil)
  849. default:
  850. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  851. }
  852. }
  853. func makeDecl(ti typeInfo) string {
  854. switch ti.TypeId {
  855. case typeInt8:
  856. return "bigint"
  857. case typeFlt4:
  858. return "real"
  859. case typeIntN:
  860. switch ti.Size {
  861. case 1:
  862. return "tinyint"
  863. case 2:
  864. return "smallint"
  865. case 4:
  866. return "int"
  867. case 8:
  868. return "bigint"
  869. default:
  870. panic("invalid size of INTNTYPE")
  871. }
  872. case typeFlt8:
  873. return "float"
  874. case typeFltN:
  875. switch ti.Size {
  876. case 4:
  877. return "real"
  878. case 8:
  879. return "float"
  880. default:
  881. panic("invalid size of FLNNTYPE")
  882. }
  883. case typeBigVarBin:
  884. if ti.Size > 8000 || ti.Size == 0 {
  885. return "varbinary(max)"
  886. } else {
  887. return fmt.Sprintf("varbinary(%d)", ti.Size)
  888. }
  889. case typeNVarChar:
  890. if ti.Size > 8000 || ti.Size == 0 {
  891. return "nvarchar(max)"
  892. } else {
  893. return fmt.Sprintf("nvarchar(%d)", ti.Size/2)
  894. }
  895. case typeBit, typeBitN:
  896. return "bit"
  897. case typeDateTimeN:
  898. return "datetime"
  899. case typeDateTimeOffsetN:
  900. return fmt.Sprintf("datetimeoffset(%d)", ti.Scale)
  901. default:
  902. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  903. }
  904. }
  905. // makes go/sql type name as described below
  906. // RowsColumnTypeDatabaseTypeName may be implemented by Rows. It should return the
  907. // database system type name without the length. Type names should be uppercase.
  908. // Examples of returned types: "VARCHAR", "NVARCHAR", "VARCHAR2", "CHAR", "TEXT",
  909. // "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT", "JSONB", "XML",
  910. // "TIMESTAMP".
  911. func makeGoLangTypeName(ti typeInfo) string {
  912. switch ti.TypeId {
  913. case typeInt4:
  914. return "INT"
  915. case typeInt8:
  916. return "BIGINT"
  917. case typeFlt4:
  918. return "REAL"
  919. case typeIntN:
  920. switch ti.Size {
  921. case 1:
  922. return "TINYINT"
  923. case 2:
  924. return "SMALLINT"
  925. case 4:
  926. return "INT"
  927. case 8:
  928. return "BIGINT"
  929. default:
  930. panic("invalid size of INTNTYPE")
  931. }
  932. case typeFlt8:
  933. return "FLOAT"
  934. case typeFltN:
  935. switch ti.Size {
  936. case 4:
  937. return "REAL"
  938. case 8:
  939. return "FLOAT"
  940. default:
  941. panic("invalid size of FLNNTYPE")
  942. }
  943. case typeBigVarBin:
  944. return "VARBINARY"
  945. case typeVarChar:
  946. return "VARCHAR"
  947. case typeNVarChar:
  948. return "NVARCHAR"
  949. case typeBit, typeBitN:
  950. return "BIT"
  951. case typeDecimalN, typeNumericN:
  952. return "DECIMAL"
  953. case typeMoneyN:
  954. switch ti.Size {
  955. case 4:
  956. return "SMALLMONEY"
  957. case 8:
  958. return "MONEY"
  959. default:
  960. panic("invalid size of MONEYN")
  961. }
  962. case typeDateTimeN:
  963. switch ti.Size {
  964. case 4:
  965. return "SMALLDATETIME"
  966. case 8:
  967. return "DATETIME"
  968. default:
  969. panic("invalid size of DATETIMEN")
  970. }
  971. case typeDateTime2N:
  972. return "DATETIME2"
  973. case typeDateN:
  974. return "DATE"
  975. case typeTimeN:
  976. return "TIME"
  977. case typeDateTimeOffsetN:
  978. return "DATETIMEOFFSET"
  979. case typeBigVarChar:
  980. return "VARCHAR"
  981. case typeBigChar:
  982. return "CHAR"
  983. case typeNChar:
  984. return "NCHAR"
  985. case typeGuid:
  986. return "UNIQUEIDENTIFIER"
  987. case typeXml:
  988. return "XML"
  989. case typeText:
  990. return "TEXT"
  991. case typeNText:
  992. return "NTEXT"
  993. case typeImage:
  994. return "IMAGE"
  995. case typeVariant:
  996. return "SQL_VARIANT"
  997. default:
  998. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  999. }
  1000. }
  1001. // makes go/sql type length as described below
  1002. // It should return the length
  1003. // of the column type if the column is a variable length type. If the column is
  1004. // not a variable length type ok should return false.
  1005. // If length is not limited other than system limits, it should return math.MaxInt64.
  1006. // The following are examples of returned values for various types:
  1007. // TEXT (math.MaxInt64, true)
  1008. // varchar(10) (10, true)
  1009. // nvarchar(10) (10, true)
  1010. // decimal (0, false)
  1011. // int (0, false)
  1012. // bytea(30) (30, true)
  1013. func makeGoLangTypeLength(ti typeInfo) (int64, bool) {
  1014. switch ti.TypeId {
  1015. case typeInt4:
  1016. return 0, false
  1017. case typeInt8:
  1018. return 0, false
  1019. case typeFlt4:
  1020. return 0, false
  1021. case typeIntN:
  1022. switch ti.Size {
  1023. case 1:
  1024. return 0, false
  1025. case 2:
  1026. return 0, false
  1027. case 4:
  1028. return 0, false
  1029. case 8:
  1030. return 0, false
  1031. default:
  1032. panic("invalid size of INTNTYPE")
  1033. }
  1034. case typeFlt8:
  1035. return 0, false
  1036. case typeFltN:
  1037. switch ti.Size {
  1038. case 4:
  1039. return 0, false
  1040. case 8:
  1041. return 0, false
  1042. default:
  1043. panic("invalid size of FLNNTYPE")
  1044. }
  1045. case typeBit, typeBitN:
  1046. return 0, false
  1047. case typeDecimalN, typeNumericN:
  1048. return 0, false
  1049. case typeMoneyN:
  1050. switch ti.Size {
  1051. case 4:
  1052. return 0, false
  1053. case 8:
  1054. return 0, false
  1055. default:
  1056. panic("invalid size of MONEYN")
  1057. }
  1058. case typeDateTimeN:
  1059. switch ti.Size {
  1060. case 4:
  1061. return 0, false
  1062. case 8:
  1063. return 0, false
  1064. default:
  1065. panic("invalid size of DATETIMEN")
  1066. }
  1067. case typeDateTime2N:
  1068. return 0, false
  1069. case typeDateN:
  1070. return 0, false
  1071. case typeTimeN:
  1072. return 0, false
  1073. case typeDateTimeOffsetN:
  1074. return 0, false
  1075. case typeBigVarBin:
  1076. if ti.Size == 0xffff {
  1077. return 2147483645, true
  1078. } else {
  1079. return int64(ti.Size), true
  1080. }
  1081. case typeVarChar:
  1082. return int64(ti.Size), true
  1083. case typeBigVarChar:
  1084. if ti.Size == 0xffff {
  1085. return 2147483645, true
  1086. } else {
  1087. return int64(ti.Size), true
  1088. }
  1089. case typeBigChar:
  1090. return int64(ti.Size), true
  1091. case typeNVarChar:
  1092. if ti.Size == 0xffff {
  1093. return 2147483645 / 2, true
  1094. } else {
  1095. return int64(ti.Size) / 2, true
  1096. }
  1097. case typeNChar:
  1098. return int64(ti.Size) / 2, true
  1099. case typeGuid:
  1100. return 0, false
  1101. case typeXml:
  1102. return 1073741822, true
  1103. case typeText:
  1104. return 2147483647, true
  1105. case typeNText:
  1106. return 1073741823, true
  1107. case typeImage:
  1108. return 2147483647, true
  1109. case typeVariant:
  1110. return 0, false
  1111. default:
  1112. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  1113. }
  1114. }
  1115. // makes go/sql type precision and scale as described below
  1116. // It should return the length
  1117. // of the column type if the column is a variable length type. If the column is
  1118. // not a variable length type ok should return false.
  1119. // If length is not limited other than system limits, it should return math.MaxInt64.
  1120. // The following are examples of returned values for various types:
  1121. // TEXT (math.MaxInt64, true)
  1122. // varchar(10) (10, true)
  1123. // nvarchar(10) (10, true)
  1124. // decimal (0, false)
  1125. // int (0, false)
  1126. // bytea(30) (30, true)
  1127. func makeGoLangTypePrecisionScale(ti typeInfo) (int64, int64, bool) {
  1128. switch ti.TypeId {
  1129. case typeInt4:
  1130. return 0, 0, false
  1131. case typeInt8:
  1132. return 0, 0, false
  1133. case typeFlt4:
  1134. return 0, 0, false
  1135. case typeIntN:
  1136. switch ti.Size {
  1137. case 1:
  1138. return 0, 0, false
  1139. case 2:
  1140. return 0, 0, false
  1141. case 4:
  1142. return 0, 0, false
  1143. case 8:
  1144. return 0, 0, false
  1145. default:
  1146. panic("invalid size of INTNTYPE")
  1147. }
  1148. case typeFlt8:
  1149. return 0, 0, false
  1150. case typeFltN:
  1151. switch ti.Size {
  1152. case 4:
  1153. return 0, 0, false
  1154. case 8:
  1155. return 0, 0, false
  1156. default:
  1157. panic("invalid size of FLNNTYPE")
  1158. }
  1159. case typeBit, typeBitN:
  1160. return 0, 0, false
  1161. case typeDecimalN, typeNumericN:
  1162. return int64(ti.Prec), int64(ti.Scale), true
  1163. case typeMoneyN:
  1164. switch ti.Size {
  1165. case 4:
  1166. return 0, 0, false
  1167. case 8:
  1168. return 0, 0, false
  1169. default:
  1170. panic("invalid size of MONEYN")
  1171. }
  1172. case typeDateTimeN:
  1173. switch ti.Size {
  1174. case 4:
  1175. return 0, 0, false
  1176. case 8:
  1177. return 0, 0, false
  1178. default:
  1179. panic("invalid size of DATETIMEN")
  1180. }
  1181. case typeDateTime2N:
  1182. return 0, 0, false
  1183. case typeDateN:
  1184. return 0, 0, false
  1185. case typeTimeN:
  1186. return 0, 0, false
  1187. case typeDateTimeOffsetN:
  1188. return 0, 0, false
  1189. case typeBigVarBin:
  1190. return 0, 0, false
  1191. case typeVarChar:
  1192. return 0, 0, false
  1193. case typeBigVarChar:
  1194. return 0, 0, false
  1195. case typeBigChar:
  1196. return 0, 0, false
  1197. case typeNVarChar:
  1198. return 0, 0, false
  1199. case typeNChar:
  1200. return 0, 0, false
  1201. case typeGuid:
  1202. return 0, 0, false
  1203. case typeXml:
  1204. return 0, 0, false
  1205. case typeText:
  1206. return 0, 0, false
  1207. case typeNText:
  1208. return 0, 0, false
  1209. case typeImage:
  1210. return 0, 0, false
  1211. case typeVariant:
  1212. return 0, 0, false
  1213. default:
  1214. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  1215. }
  1216. }