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.

types.go 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. package mssql
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "io"
  7. "math"
  8. "strconv"
  9. "time"
  10. )
  11. // fixed-length data types
  12. // http://msdn.microsoft.com/en-us/library/dd341171.aspx
  13. const (
  14. typeNull = 0x1f
  15. typeInt1 = 0x30
  16. typeBit = 0x32
  17. typeInt2 = 0x34
  18. typeInt4 = 0x38
  19. typeDateTim4 = 0x3a
  20. typeFlt4 = 0x3b
  21. typeMoney = 0x3c
  22. typeDateTime = 0x3d
  23. typeFlt8 = 0x3e
  24. typeMoney4 = 0x7a
  25. typeInt8 = 0x7f
  26. )
  27. // variable-length data types
  28. // http://msdn.microsoft.com/en-us/library/dd358341.aspx
  29. const (
  30. // byte len types
  31. typeGuid = 0x24
  32. typeIntN = 0x26
  33. typeDecimal = 0x37 // legacy
  34. typeNumeric = 0x3f // legacy
  35. typeBitN = 0x68
  36. typeDecimalN = 0x6a
  37. typeNumericN = 0x6c
  38. typeFltN = 0x6d
  39. typeMoneyN = 0x6e
  40. typeDateTimeN = 0x6f
  41. typeDateN = 0x28
  42. typeTimeN = 0x29
  43. typeDateTime2N = 0x2a
  44. typeDateTimeOffsetN = 0x2b
  45. typeChar = 0x2f // legacy
  46. typeVarChar = 0x27 // legacy
  47. typeBinary = 0x2d // legacy
  48. typeVarBinary = 0x25 // legacy
  49. // short length types
  50. typeBigVarBin = 0xa5
  51. typeBigVarChar = 0xa7
  52. typeBigBinary = 0xad
  53. typeBigChar = 0xaf
  54. typeNVarChar = 0xe7
  55. typeNChar = 0xef
  56. typeXml = 0xf1
  57. typeUdt = 0xf0
  58. // long length types
  59. typeText = 0x23
  60. typeImage = 0x22
  61. typeNText = 0x63
  62. typeVariant = 0x62
  63. )
  64. // TYPE_INFO rule
  65. // http://msdn.microsoft.com/en-us/library/dd358284.aspx
  66. type typeInfo struct {
  67. TypeId uint8
  68. Size int
  69. Scale uint8
  70. Prec uint8
  71. Buffer []byte
  72. Collation collation
  73. Reader func(ti *typeInfo, r *tdsBuffer) (res interface{})
  74. Writer func(w io.Writer, ti typeInfo, buf []byte) (err error)
  75. }
  76. func readTypeInfo(r *tdsBuffer) (res typeInfo) {
  77. res.TypeId = r.byte()
  78. switch res.TypeId {
  79. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  80. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  81. // those are fixed length types
  82. switch res.TypeId {
  83. case typeNull:
  84. res.Size = 0
  85. case typeInt1, typeBit:
  86. res.Size = 1
  87. case typeInt2:
  88. res.Size = 2
  89. case typeInt4, typeDateTim4, typeFlt4, typeMoney4:
  90. res.Size = 4
  91. case typeMoney, typeDateTime, typeFlt8, typeInt8:
  92. res.Size = 8
  93. }
  94. res.Reader = readFixedType
  95. res.Buffer = make([]byte, res.Size)
  96. default: // all others are VARLENTYPE
  97. readVarLen(&res, r)
  98. }
  99. return
  100. }
  101. func writeTypeInfo(w io.Writer, ti *typeInfo) (err error) {
  102. err = binary.Write(w, binary.LittleEndian, ti.TypeId)
  103. if err != nil {
  104. return
  105. }
  106. switch ti.TypeId {
  107. case typeNull, typeInt1, typeBit, typeInt2, typeInt4, typeDateTim4,
  108. typeFlt4, typeMoney, typeDateTime, typeFlt8, typeMoney4, typeInt8:
  109. // those are fixed length types
  110. default: // all others are VARLENTYPE
  111. err = writeVarLen(w, ti)
  112. if err != nil {
  113. return
  114. }
  115. }
  116. return
  117. }
  118. func writeVarLen(w io.Writer, ti *typeInfo) (err error) {
  119. switch ti.TypeId {
  120. case typeDateN:
  121. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  122. if err = binary.Write(w, binary.LittleEndian, ti.Scale); err != nil {
  123. return
  124. }
  125. ti.Writer = writeByteLenType
  126. case typeGuid, typeIntN, typeDecimal, typeNumeric,
  127. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  128. typeMoneyN, typeDateTimeN, typeChar,
  129. typeVarChar, typeBinary, typeVarBinary:
  130. // byle len types
  131. if ti.Size > 0xff {
  132. panic("Invalid size for BYLELEN_TYPE")
  133. }
  134. if err = binary.Write(w, binary.LittleEndian, uint8(ti.Size)); err != nil {
  135. return
  136. }
  137. switch ti.TypeId {
  138. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  139. err = binary.Write(w, binary.LittleEndian, ti.Prec)
  140. if err != nil {
  141. return
  142. }
  143. err = binary.Write(w, binary.LittleEndian, ti.Scale)
  144. if err != nil {
  145. return
  146. }
  147. }
  148. ti.Writer = writeByteLenType
  149. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  150. typeNVarChar, typeNChar, typeXml, typeUdt:
  151. // short len types
  152. if ti.Size > 8000 || ti.Size == 0 {
  153. if err = binary.Write(w, binary.LittleEndian, uint16(0xffff)); err != nil {
  154. return
  155. }
  156. ti.Writer = writePLPType
  157. } else {
  158. if err = binary.Write(w, binary.LittleEndian, uint16(ti.Size)); err != nil {
  159. return
  160. }
  161. ti.Writer = writeShortLenType
  162. }
  163. switch ti.TypeId {
  164. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  165. if err = writeCollation(w, ti.Collation); err != nil {
  166. return
  167. }
  168. case typeXml:
  169. var schemapresent uint8 = 0
  170. if err = binary.Write(w, binary.LittleEndian, schemapresent); err != nil {
  171. return
  172. }
  173. }
  174. case typeText, typeImage, typeNText, typeVariant:
  175. // LONGLEN_TYPE
  176. panic("LONGLEN_TYPE not implemented")
  177. default:
  178. panic("Invalid type")
  179. }
  180. return
  181. }
  182. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  183. func decodeDateTim4(buf []byte) time.Time {
  184. days := binary.LittleEndian.Uint16(buf)
  185. mins := binary.LittleEndian.Uint16(buf[2:])
  186. return time.Date(1900, 1, 1+int(days),
  187. 0, int(mins), 0, 0, time.UTC)
  188. }
  189. func decodeDateTime(buf []byte) time.Time {
  190. days := int32(binary.LittleEndian.Uint32(buf))
  191. tm := binary.LittleEndian.Uint32(buf[4:])
  192. ns := int(math.Trunc(float64(tm%300)/0.3+0.5)) * 1000000
  193. secs := int(tm / 300)
  194. return time.Date(1900, 1, 1+int(days),
  195. 0, 0, secs, ns, time.UTC)
  196. }
  197. func readFixedType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  198. r.ReadFull(ti.Buffer)
  199. buf := ti.Buffer
  200. switch ti.TypeId {
  201. case typeNull:
  202. return nil
  203. case typeInt1:
  204. return int64(buf[0])
  205. case typeBit:
  206. return buf[0] != 0
  207. case typeInt2:
  208. return int64(int16(binary.LittleEndian.Uint16(buf)))
  209. case typeInt4:
  210. return int64(int32(binary.LittleEndian.Uint32(buf)))
  211. case typeDateTim4:
  212. return decodeDateTim4(buf)
  213. case typeFlt4:
  214. return math.Float32frombits(binary.LittleEndian.Uint32(buf))
  215. case typeMoney4:
  216. return decodeMoney4(buf)
  217. case typeMoney:
  218. return decodeMoney(buf)
  219. case typeDateTime:
  220. return decodeDateTime(buf)
  221. case typeFlt8:
  222. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  223. case typeInt8:
  224. return int64(binary.LittleEndian.Uint64(buf))
  225. default:
  226. badStreamPanicf("Invalid typeid")
  227. }
  228. panic("shoulnd't get here")
  229. }
  230. func writeFixedType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  231. _, err = w.Write(buf)
  232. return
  233. }
  234. func readByteLenType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  235. size := r.byte()
  236. if size == 0 {
  237. return nil
  238. }
  239. r.ReadFull(ti.Buffer[:size])
  240. buf := ti.Buffer[:size]
  241. switch ti.TypeId {
  242. case typeDateN:
  243. if len(buf) != 3 {
  244. badStreamPanicf("Invalid size for DATENTYPE")
  245. }
  246. return decodeDate(buf)
  247. case typeTimeN:
  248. return decodeTime(ti.Scale, buf)
  249. case typeDateTime2N:
  250. return decodeDateTime2(ti.Scale, buf)
  251. case typeDateTimeOffsetN:
  252. return decodeDateTimeOffset(ti.Scale, buf)
  253. case typeGuid:
  254. return decodeGuid(buf)
  255. case typeIntN:
  256. switch len(buf) {
  257. case 1:
  258. return int64(buf[0])
  259. case 2:
  260. return int64(int16((binary.LittleEndian.Uint16(buf))))
  261. case 4:
  262. return int64(int32(binary.LittleEndian.Uint32(buf)))
  263. case 8:
  264. return int64(binary.LittleEndian.Uint64(buf))
  265. default:
  266. badStreamPanicf("Invalid size for INTNTYPE")
  267. }
  268. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  269. return decodeDecimal(ti.Prec, ti.Scale, buf)
  270. case typeBitN:
  271. if len(buf) != 1 {
  272. badStreamPanicf("Invalid size for BITNTYPE")
  273. }
  274. return buf[0] != 0
  275. case typeFltN:
  276. switch len(buf) {
  277. case 4:
  278. return float64(math.Float32frombits(binary.LittleEndian.Uint32(buf)))
  279. case 8:
  280. return math.Float64frombits(binary.LittleEndian.Uint64(buf))
  281. default:
  282. badStreamPanicf("Invalid size for FLTNTYPE")
  283. }
  284. case typeMoneyN:
  285. switch len(buf) {
  286. case 4:
  287. return decodeMoney4(buf)
  288. case 8:
  289. return decodeMoney(buf)
  290. default:
  291. badStreamPanicf("Invalid size for MONEYNTYPE")
  292. }
  293. case typeDateTimeN:
  294. switch len(buf) {
  295. case 4:
  296. return decodeDateTim4(buf)
  297. case 8:
  298. return decodeDateTime(buf)
  299. default:
  300. badStreamPanicf("Invalid size for DATETIMENTYPE")
  301. }
  302. case typeChar, typeVarChar:
  303. return decodeChar(ti.Collation, buf)
  304. case typeBinary, typeVarBinary:
  305. // a copy, because the backing array for ti.Buffer is reused
  306. // and can be overwritten by the next row while this row waits
  307. // in a buffered chan
  308. cpy := make([]byte, len(buf))
  309. copy(cpy, buf)
  310. return cpy
  311. default:
  312. badStreamPanicf("Invalid typeid")
  313. }
  314. panic("shoulnd't get here")
  315. }
  316. func writeByteLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  317. if ti.Size > 0xff {
  318. panic("Invalid size for BYTELEN_TYPE")
  319. }
  320. err = binary.Write(w, binary.LittleEndian, uint8(ti.Size))
  321. if err != nil {
  322. return
  323. }
  324. _, err = w.Write(buf)
  325. return
  326. }
  327. func readShortLenType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  328. size := r.uint16()
  329. if size == 0xffff {
  330. return nil
  331. }
  332. r.ReadFull(ti.Buffer[:size])
  333. buf := ti.Buffer[:size]
  334. switch ti.TypeId {
  335. case typeBigVarChar, typeBigChar:
  336. return decodeChar(ti.Collation, buf)
  337. case typeBigVarBin, typeBigBinary:
  338. // a copy, because the backing array for ti.Buffer is reused
  339. // and can be overwritten by the next row while this row waits
  340. // in a buffered chan
  341. cpy := make([]byte, len(buf))
  342. copy(cpy, buf)
  343. return cpy
  344. case typeNVarChar, typeNChar:
  345. return decodeNChar(buf)
  346. case typeUdt:
  347. return decodeUdt(*ti, buf)
  348. default:
  349. badStreamPanicf("Invalid typeid")
  350. }
  351. panic("shoulnd't get here")
  352. }
  353. func writeShortLenType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  354. if buf == nil {
  355. err = binary.Write(w, binary.LittleEndian, uint16(0xffff))
  356. return
  357. }
  358. if ti.Size > 0xfffe {
  359. panic("Invalid size for USHORTLEN_TYPE")
  360. }
  361. err = binary.Write(w, binary.LittleEndian, uint16(ti.Size))
  362. if err != nil {
  363. return
  364. }
  365. _, err = w.Write(buf)
  366. return
  367. }
  368. func readLongLenType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  369. // information about this format can be found here:
  370. // http://msdn.microsoft.com/en-us/library/dd304783.aspx
  371. // and here:
  372. // http://msdn.microsoft.com/en-us/library/dd357254.aspx
  373. textptrsize := int(r.byte())
  374. if textptrsize == 0 {
  375. return nil
  376. }
  377. textptr := make([]byte, textptrsize)
  378. r.ReadFull(textptr)
  379. timestamp := r.uint64()
  380. _ = timestamp // ignore timestamp
  381. size := r.int32()
  382. if size == -1 {
  383. return nil
  384. }
  385. buf := make([]byte, size)
  386. r.ReadFull(buf)
  387. switch ti.TypeId {
  388. case typeText:
  389. return decodeChar(ti.Collation, buf)
  390. case typeImage:
  391. return buf
  392. case typeNText:
  393. return decodeNChar(buf)
  394. default:
  395. badStreamPanicf("Invalid typeid")
  396. }
  397. panic("shoulnd't get here")
  398. }
  399. // reads variant value
  400. // http://msdn.microsoft.com/en-us/library/dd303302.aspx
  401. func readVariantType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  402. size := r.int32()
  403. if size == 0 {
  404. return nil
  405. }
  406. vartype := r.byte()
  407. propbytes := int32(r.byte())
  408. switch vartype {
  409. case typeGuid:
  410. buf := make([]byte, size-2-propbytes)
  411. r.ReadFull(buf)
  412. return buf
  413. case typeBit:
  414. return r.byte() != 0
  415. case typeInt1:
  416. return int64(r.byte())
  417. case typeInt2:
  418. return int64(int16(r.uint16()))
  419. case typeInt4:
  420. return int64(r.int32())
  421. case typeInt8:
  422. return int64(r.uint64())
  423. case typeDateTime:
  424. buf := make([]byte, size-2-propbytes)
  425. r.ReadFull(buf)
  426. return decodeDateTime(buf)
  427. case typeDateTim4:
  428. buf := make([]byte, size-2-propbytes)
  429. r.ReadFull(buf)
  430. return decodeDateTim4(buf)
  431. case typeFlt4:
  432. return float64(math.Float32frombits(r.uint32()))
  433. case typeFlt8:
  434. return math.Float64frombits(r.uint64())
  435. case typeMoney4:
  436. buf := make([]byte, size-2-propbytes)
  437. r.ReadFull(buf)
  438. return decodeMoney4(buf)
  439. case typeMoney:
  440. buf := make([]byte, size-2-propbytes)
  441. r.ReadFull(buf)
  442. return decodeMoney(buf)
  443. case typeDateN:
  444. buf := make([]byte, size-2-propbytes)
  445. r.ReadFull(buf)
  446. return decodeDate(buf)
  447. case typeTimeN:
  448. scale := r.byte()
  449. buf := make([]byte, size-2-propbytes)
  450. r.ReadFull(buf)
  451. return decodeTime(scale, buf)
  452. case typeDateTime2N:
  453. scale := r.byte()
  454. buf := make([]byte, size-2-propbytes)
  455. r.ReadFull(buf)
  456. return decodeDateTime2(scale, buf)
  457. case typeDateTimeOffsetN:
  458. scale := r.byte()
  459. buf := make([]byte, size-2-propbytes)
  460. r.ReadFull(buf)
  461. return decodeDateTimeOffset(scale, buf)
  462. case typeBigVarBin, typeBigBinary:
  463. r.uint16() // max length, ignoring
  464. buf := make([]byte, size-2-propbytes)
  465. r.ReadFull(buf)
  466. return buf
  467. case typeDecimalN, typeNumericN:
  468. prec := r.byte()
  469. scale := r.byte()
  470. buf := make([]byte, size-2-propbytes)
  471. r.ReadFull(buf)
  472. return decodeDecimal(prec, scale, buf)
  473. case typeBigVarChar, typeBigChar:
  474. col := readCollation(r)
  475. r.uint16() // max length, ignoring
  476. buf := make([]byte, size-2-propbytes)
  477. r.ReadFull(buf)
  478. return decodeChar(col, buf)
  479. case typeNVarChar, typeNChar:
  480. _ = readCollation(r)
  481. r.uint16() // max length, ignoring
  482. buf := make([]byte, size-2-propbytes)
  483. r.ReadFull(buf)
  484. return decodeNChar(buf)
  485. default:
  486. badStreamPanicf("Invalid variant typeid")
  487. }
  488. panic("shoulnd't get here")
  489. }
  490. // partially length prefixed stream
  491. // http://msdn.microsoft.com/en-us/library/dd340469.aspx
  492. func readPLPType(ti *typeInfo, r *tdsBuffer) (res interface{}) {
  493. size := r.uint64()
  494. var buf *bytes.Buffer
  495. switch size {
  496. case 0xffffffffffffffff:
  497. // null
  498. return nil
  499. case 0xfffffffffffffffe:
  500. // size unknown
  501. buf = bytes.NewBuffer(make([]byte, 0, 1000))
  502. default:
  503. buf = bytes.NewBuffer(make([]byte, 0, size))
  504. }
  505. for true {
  506. chunksize := r.uint32()
  507. if chunksize == 0 {
  508. break
  509. }
  510. if _, err := io.CopyN(buf, r, int64(chunksize)); err != nil {
  511. badStreamPanicf("Reading PLP type failed: %s", err.Error())
  512. }
  513. }
  514. switch ti.TypeId {
  515. case typeXml:
  516. return decodeXml(*ti, buf.Bytes())
  517. case typeBigVarChar, typeBigChar, typeText:
  518. return decodeChar(ti.Collation, buf.Bytes())
  519. case typeBigVarBin, typeBigBinary, typeImage:
  520. return buf.Bytes()
  521. case typeNVarChar, typeNChar, typeNText:
  522. return decodeNChar(buf.Bytes())
  523. case typeUdt:
  524. return decodeUdt(*ti, buf.Bytes())
  525. }
  526. panic("shoulnd't get here")
  527. }
  528. func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
  529. if err = binary.Write(w, binary.LittleEndian, uint64(len(buf))); err != nil {
  530. return
  531. }
  532. for {
  533. chunksize := uint32(len(buf))
  534. if err = binary.Write(w, binary.LittleEndian, chunksize); err != nil {
  535. return
  536. }
  537. if chunksize == 0 {
  538. return
  539. }
  540. if _, err = w.Write(buf[:chunksize]); err != nil {
  541. return
  542. }
  543. buf = buf[chunksize:]
  544. }
  545. }
  546. func readVarLen(ti *typeInfo, r *tdsBuffer) {
  547. switch ti.TypeId {
  548. case typeDateN:
  549. ti.Size = 3
  550. ti.Reader = readByteLenType
  551. ti.Buffer = make([]byte, ti.Size)
  552. case typeTimeN, typeDateTime2N, typeDateTimeOffsetN:
  553. ti.Scale = r.byte()
  554. switch ti.Scale {
  555. case 0, 1, 2:
  556. ti.Size = 3
  557. case 3, 4:
  558. ti.Size = 4
  559. case 5, 6, 7:
  560. ti.Size = 5
  561. default:
  562. badStreamPanicf("Invalid scale for TIME/DATETIME2/DATETIMEOFFSET type")
  563. }
  564. switch ti.TypeId {
  565. case typeDateTime2N:
  566. ti.Size += 3
  567. case typeDateTimeOffsetN:
  568. ti.Size += 5
  569. }
  570. ti.Reader = readByteLenType
  571. ti.Buffer = make([]byte, ti.Size)
  572. case typeGuid, typeIntN, typeDecimal, typeNumeric,
  573. typeBitN, typeDecimalN, typeNumericN, typeFltN,
  574. typeMoneyN, typeDateTimeN, typeChar,
  575. typeVarChar, typeBinary, typeVarBinary:
  576. // byle len types
  577. ti.Size = int(r.byte())
  578. ti.Buffer = make([]byte, ti.Size)
  579. switch ti.TypeId {
  580. case typeDecimal, typeNumeric, typeDecimalN, typeNumericN:
  581. ti.Prec = r.byte()
  582. ti.Scale = r.byte()
  583. }
  584. ti.Reader = readByteLenType
  585. case typeXml:
  586. schemapresent := r.byte()
  587. if schemapresent != 0 {
  588. // just ignore this for now
  589. // dbname
  590. r.BVarChar()
  591. // owning schema
  592. r.BVarChar()
  593. // xml schema collection
  594. r.UsVarChar()
  595. }
  596. ti.Reader = readPLPType
  597. case typeBigVarBin, typeBigVarChar, typeBigBinary, typeBigChar,
  598. typeNVarChar, typeNChar, typeUdt:
  599. // short len types
  600. ti.Size = int(r.uint16())
  601. switch ti.TypeId {
  602. case typeBigVarChar, typeBigChar, typeNVarChar, typeNChar:
  603. ti.Collation = readCollation(r)
  604. }
  605. if ti.Size == 0xffff {
  606. ti.Reader = readPLPType
  607. } else {
  608. ti.Buffer = make([]byte, ti.Size)
  609. ti.Reader = readShortLenType
  610. }
  611. case typeText, typeImage, typeNText, typeVariant:
  612. // LONGLEN_TYPE
  613. ti.Size = int(r.int32())
  614. switch ti.TypeId {
  615. case typeText, typeNText:
  616. ti.Collation = readCollation(r)
  617. // ignore tablenames
  618. numparts := int(r.byte())
  619. for i := 0; i < numparts; i++ {
  620. r.UsVarChar()
  621. }
  622. ti.Reader = readLongLenType
  623. case typeImage:
  624. // ignore tablenames
  625. numparts := int(r.byte())
  626. for i := 0; i < numparts; i++ {
  627. r.UsVarChar()
  628. }
  629. ti.Reader = readLongLenType
  630. case typeVariant:
  631. ti.Reader = readVariantType
  632. }
  633. default:
  634. badStreamPanicf("Invalid type %d", ti.TypeId)
  635. }
  636. return
  637. }
  638. func decodeMoney(buf []byte) []byte {
  639. money := int64(uint64(buf[4]) |
  640. uint64(buf[5])<<8 |
  641. uint64(buf[6])<<16 |
  642. uint64(buf[7])<<24 |
  643. uint64(buf[0])<<32 |
  644. uint64(buf[1])<<40 |
  645. uint64(buf[2])<<48 |
  646. uint64(buf[3])<<56)
  647. return scaleBytes(strconv.FormatInt(money, 10), 4)
  648. }
  649. func decodeMoney4(buf []byte) []byte {
  650. money := int32(binary.LittleEndian.Uint32(buf[0:4]))
  651. return scaleBytes(strconv.FormatInt(int64(money), 10), 4)
  652. }
  653. func decodeGuid(buf []byte) []byte {
  654. res := make([]byte, 16)
  655. copy(res, buf)
  656. return res
  657. }
  658. func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
  659. var sign uint8
  660. sign = buf[0]
  661. dec := Decimal{
  662. positive: sign != 0,
  663. prec: prec,
  664. scale: scale,
  665. }
  666. buf = buf[1:]
  667. l := len(buf) / 4
  668. for i := 0; i < l; i++ {
  669. dec.integer[i] = binary.LittleEndian.Uint32(buf[0:4])
  670. buf = buf[4:]
  671. }
  672. return dec.Bytes()
  673. }
  674. // http://msdn.microsoft.com/en-us/library/ee780895.aspx
  675. func decodeDateInt(buf []byte) (days int) {
  676. return int(buf[0]) + int(buf[1])*256 + int(buf[2])*256*256
  677. }
  678. func decodeDate(buf []byte) time.Time {
  679. return time.Date(1, 1, 1+decodeDateInt(buf), 0, 0, 0, 0, time.UTC)
  680. }
  681. func decodeTimeInt(scale uint8, buf []byte) (sec int, ns int) {
  682. var acc uint64 = 0
  683. for i := len(buf) - 1; i >= 0; i-- {
  684. acc <<= 8
  685. acc |= uint64(buf[i])
  686. }
  687. for i := 0; i < 7-int(scale); i++ {
  688. acc *= 10
  689. }
  690. nsbig := acc * 100
  691. sec = int(nsbig / 1000000000)
  692. ns = int(nsbig % 1000000000)
  693. return
  694. }
  695. func decodeTime(scale uint8, buf []byte) time.Time {
  696. sec, ns := decodeTimeInt(scale, buf)
  697. return time.Date(1, 1, 1, 0, 0, sec, ns, time.UTC)
  698. }
  699. func decodeDateTime2(scale uint8, buf []byte) time.Time {
  700. timesize := len(buf) - 3
  701. sec, ns := decodeTimeInt(scale, buf[:timesize])
  702. days := decodeDateInt(buf[timesize:])
  703. return time.Date(1, 1, 1+days, 0, 0, sec, ns, time.UTC)
  704. }
  705. func decodeDateTimeOffset(scale uint8, buf []byte) time.Time {
  706. timesize := len(buf) - 3 - 2
  707. sec, ns := decodeTimeInt(scale, buf[:timesize])
  708. buf = buf[timesize:]
  709. days := decodeDateInt(buf[:3])
  710. buf = buf[3:]
  711. offset := int(int16(binary.LittleEndian.Uint16(buf))) // in mins
  712. return time.Date(1, 1, 1+days, 0, 0, sec+offset*60, ns,
  713. time.FixedZone("", offset*60))
  714. }
  715. func divFloor(x int64, y int64) int64 {
  716. q := x / y
  717. r := x % y
  718. if r != 0 && ((r < 0) != (y < 0)) {
  719. q--
  720. }
  721. return q
  722. }
  723. func dateTime2(t time.Time) (days int32, ns int64) {
  724. // number of days since Jan 1 1970 UTC
  725. days64 := divFloor(t.Unix(), 24*60*60)
  726. // number of days since Jan 1 1 UTC
  727. days = int32(days64) + 1969*365 + 1969/4 - 1969/100 + 1969/400
  728. // number of seconds within day
  729. secs := t.Unix() - days64*24*60*60
  730. // number of nanoseconds within day
  731. ns = secs*1e9 + int64(t.Nanosecond())
  732. return
  733. }
  734. func decodeChar(col collation, buf []byte) string {
  735. return charset2utf8(col, buf)
  736. }
  737. func decodeUcs2(buf []byte) string {
  738. res, err := ucs22str(buf)
  739. if err != nil {
  740. badStreamPanicf("Invalid UCS2 encoding: %s", err.Error())
  741. }
  742. return res
  743. }
  744. func decodeNChar(buf []byte) string {
  745. return decodeUcs2(buf)
  746. }
  747. func decodeXml(ti typeInfo, buf []byte) string {
  748. return decodeUcs2(buf)
  749. }
  750. func decodeUdt(ti typeInfo, buf []byte) int {
  751. panic("Not implemented")
  752. }
  753. func makeDecl(ti typeInfo) string {
  754. switch ti.TypeId {
  755. case typeInt8:
  756. return "bigint"
  757. case typeFlt4:
  758. return "real"
  759. case typeIntN:
  760. switch ti.Size {
  761. case 1:
  762. return "tinyint"
  763. case 2:
  764. return "smallint"
  765. case 4:
  766. return "int"
  767. case 8:
  768. return "bigint"
  769. default:
  770. panic("invalid size of INTNTYPE")
  771. }
  772. case typeFlt8:
  773. return "float"
  774. case typeFltN:
  775. switch ti.Size {
  776. case 4:
  777. return "real"
  778. case 8:
  779. return "float"
  780. default:
  781. panic("invalid size of FLNNTYPE")
  782. }
  783. case typeBigVarBin:
  784. if ti.Size > 8000 || ti.Size == 0 {
  785. return fmt.Sprintf("varbinary(max)")
  786. } else {
  787. return fmt.Sprintf("varbinary(%d)", ti.Size)
  788. }
  789. case typeNVarChar:
  790. if ti.Size > 8000 || ti.Size == 0 {
  791. return fmt.Sprintf("nvarchar(max)")
  792. } else {
  793. return fmt.Sprintf("nvarchar(%d)", ti.Size/2)
  794. }
  795. case typeBit, typeBitN:
  796. return "bit"
  797. case typeDateTimeN:
  798. return "datetime"
  799. case typeDateTimeOffsetN:
  800. return fmt.Sprintf("datetimeoffset(%d)", ti.Scale)
  801. default:
  802. panic(fmt.Sprintf("not implemented makeDecl for type %d", ti.TypeId))
  803. }
  804. }