array.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. package pq
  2. import (
  3. "bytes"
  4. "database/sql"
  5. "database/sql/driver"
  6. "encoding/hex"
  7. "fmt"
  8. "reflect"
  9. "strconv"
  10. "strings"
  11. )
  12. var typeByteSlice = reflect.TypeOf([]byte{})
  13. var typeDriverValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
  14. var typeSQLScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
  15. // Array returns the optimal driver.Valuer and sql.Scanner for an array or
  16. // slice of any dimension.
  17. //
  18. // For example:
  19. // db.Query(`SELECT * FROM t WHERE id = ANY($1)`, pq.Array([]int{235, 401}))
  20. //
  21. // var x []sql.NullInt64
  22. // db.QueryRow('SELECT ARRAY[235, 401]').Scan(pq.Array(&x))
  23. //
  24. // Scanning multi-dimensional arrays is not supported. Arrays where the lower
  25. // bound is not one (such as `[0:0]={1}') are not supported.
  26. func Array(a interface{}) interface {
  27. driver.Valuer
  28. sql.Scanner
  29. } {
  30. switch a := a.(type) {
  31. case []bool:
  32. return (*BoolArray)(&a)
  33. case []float64:
  34. return (*Float64Array)(&a)
  35. case []float32:
  36. return (*Float32Array)(&a)
  37. case []int64:
  38. return (*Int64Array)(&a)
  39. case []int32:
  40. return (*Int32Array)(&a)
  41. case []string:
  42. return (*StringArray)(&a)
  43. case [][]byte:
  44. return (*ByteaArray)(&a)
  45. case *[]bool:
  46. return (*BoolArray)(a)
  47. case *[]float64:
  48. return (*Float64Array)(a)
  49. case *[]float32:
  50. return (*Float32Array)(a)
  51. case *[]int64:
  52. return (*Int64Array)(a)
  53. case *[]int32:
  54. return (*Int32Array)(a)
  55. case *[]string:
  56. return (*StringArray)(a)
  57. case *[][]byte:
  58. return (*ByteaArray)(a)
  59. }
  60. return GenericArray{a}
  61. }
  62. // ArrayDelimiter may be optionally implemented by driver.Valuer or sql.Scanner
  63. // to override the array delimiter used by GenericArray.
  64. type ArrayDelimiter interface {
  65. // ArrayDelimiter returns the delimiter character(s) for this element's type.
  66. ArrayDelimiter() string
  67. }
  68. // BoolArray represents a one-dimensional array of the PostgreSQL boolean type.
  69. type BoolArray []bool
  70. // Scan implements the sql.Scanner interface.
  71. func (a *BoolArray) Scan(src interface{}) error {
  72. switch src := src.(type) {
  73. case []byte:
  74. return a.scanBytes(src)
  75. case string:
  76. return a.scanBytes([]byte(src))
  77. case nil:
  78. *a = nil
  79. return nil
  80. }
  81. return fmt.Errorf("pq: cannot convert %T to BoolArray", src)
  82. }
  83. func (a *BoolArray) scanBytes(src []byte) error {
  84. elems, err := scanLinearArray(src, []byte{','}, "BoolArray")
  85. if err != nil {
  86. return err
  87. }
  88. if *a != nil && len(elems) == 0 {
  89. *a = (*a)[:0]
  90. } else {
  91. b := make(BoolArray, len(elems))
  92. for i, v := range elems {
  93. if len(v) != 1 {
  94. return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v)
  95. }
  96. switch v[0] {
  97. case 't':
  98. b[i] = true
  99. case 'f':
  100. b[i] = false
  101. default:
  102. return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v)
  103. }
  104. }
  105. *a = b
  106. }
  107. return nil
  108. }
  109. // Value implements the driver.Valuer interface.
  110. func (a BoolArray) Value() (driver.Value, error) {
  111. if a == nil {
  112. return nil, nil
  113. }
  114. if n := len(a); n > 0 {
  115. // There will be exactly two curly brackets, N bytes of values,
  116. // and N-1 bytes of delimiters.
  117. b := make([]byte, 1+2*n)
  118. for i := 0; i < n; i++ {
  119. b[2*i] = ','
  120. if a[i] {
  121. b[1+2*i] = 't'
  122. } else {
  123. b[1+2*i] = 'f'
  124. }
  125. }
  126. b[0] = '{'
  127. b[2*n] = '}'
  128. return string(b), nil
  129. }
  130. return "{}", nil
  131. }
  132. // ByteaArray represents a one-dimensional array of the PostgreSQL bytea type.
  133. type ByteaArray [][]byte
  134. // Scan implements the sql.Scanner interface.
  135. func (a *ByteaArray) Scan(src interface{}) error {
  136. switch src := src.(type) {
  137. case []byte:
  138. return a.scanBytes(src)
  139. case string:
  140. return a.scanBytes([]byte(src))
  141. case nil:
  142. *a = nil
  143. return nil
  144. }
  145. return fmt.Errorf("pq: cannot convert %T to ByteaArray", src)
  146. }
  147. func (a *ByteaArray) scanBytes(src []byte) error {
  148. elems, err := scanLinearArray(src, []byte{','}, "ByteaArray")
  149. if err != nil {
  150. return err
  151. }
  152. if *a != nil && len(elems) == 0 {
  153. *a = (*a)[:0]
  154. } else {
  155. b := make(ByteaArray, len(elems))
  156. for i, v := range elems {
  157. b[i], err = parseBytea(v)
  158. if err != nil {
  159. return fmt.Errorf("could not parse bytea array index %d: %s", i, err.Error())
  160. }
  161. }
  162. *a = b
  163. }
  164. return nil
  165. }
  166. // Value implements the driver.Valuer interface. It uses the "hex" format which
  167. // is only supported on PostgreSQL 9.0 or newer.
  168. func (a ByteaArray) Value() (driver.Value, error) {
  169. if a == nil {
  170. return nil, nil
  171. }
  172. if n := len(a); n > 0 {
  173. // There will be at least two curly brackets, 2*N bytes of quotes,
  174. // 3*N bytes of hex formatting, and N-1 bytes of delimiters.
  175. size := 1 + 6*n
  176. for _, x := range a {
  177. size += hex.EncodedLen(len(x))
  178. }
  179. b := make([]byte, size)
  180. for i, s := 0, b; i < n; i++ {
  181. o := copy(s, `,"\\x`)
  182. o += hex.Encode(s[o:], a[i])
  183. s[o] = '"'
  184. s = s[o+1:]
  185. }
  186. b[0] = '{'
  187. b[size-1] = '}'
  188. return string(b), nil
  189. }
  190. return "{}", nil
  191. }
  192. // Float64Array represents a one-dimensional array of the PostgreSQL double
  193. // precision type.
  194. type Float64Array []float64
  195. // Scan implements the sql.Scanner interface.
  196. func (a *Float64Array) Scan(src interface{}) error {
  197. switch src := src.(type) {
  198. case []byte:
  199. return a.scanBytes(src)
  200. case string:
  201. return a.scanBytes([]byte(src))
  202. case nil:
  203. *a = nil
  204. return nil
  205. }
  206. return fmt.Errorf("pq: cannot convert %T to Float64Array", src)
  207. }
  208. func (a *Float64Array) scanBytes(src []byte) error {
  209. elems, err := scanLinearArray(src, []byte{','}, "Float64Array")
  210. if err != nil {
  211. return err
  212. }
  213. if *a != nil && len(elems) == 0 {
  214. *a = (*a)[:0]
  215. } else {
  216. b := make(Float64Array, len(elems))
  217. for i, v := range elems {
  218. if b[i], err = strconv.ParseFloat(string(v), 64); err != nil {
  219. return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
  220. }
  221. }
  222. *a = b
  223. }
  224. return nil
  225. }
  226. // Value implements the driver.Valuer interface.
  227. func (a Float64Array) Value() (driver.Value, error) {
  228. if a == nil {
  229. return nil, nil
  230. }
  231. if n := len(a); n > 0 {
  232. // There will be at least two curly brackets, N bytes of values,
  233. // and N-1 bytes of delimiters.
  234. b := make([]byte, 1, 1+2*n)
  235. b[0] = '{'
  236. b = strconv.AppendFloat(b, a[0], 'f', -1, 64)
  237. for i := 1; i < n; i++ {
  238. b = append(b, ',')
  239. b = strconv.AppendFloat(b, a[i], 'f', -1, 64)
  240. }
  241. return string(append(b, '}')), nil
  242. }
  243. return "{}", nil
  244. }
  245. // Float32Array represents a one-dimensional array of the PostgreSQL double
  246. // precision type.
  247. type Float32Array []float32
  248. // Scan implements the sql.Scanner interface.
  249. func (a *Float32Array) Scan(src interface{}) error {
  250. switch src := src.(type) {
  251. case []byte:
  252. return a.scanBytes(src)
  253. case string:
  254. return a.scanBytes([]byte(src))
  255. case nil:
  256. *a = nil
  257. return nil
  258. }
  259. return fmt.Errorf("pq: cannot convert %T to Float32Array", src)
  260. }
  261. func (a *Float32Array) scanBytes(src []byte) error {
  262. elems, err := scanLinearArray(src, []byte{','}, "Float32Array")
  263. if err != nil {
  264. return err
  265. }
  266. if *a != nil && len(elems) == 0 {
  267. *a = (*a)[:0]
  268. } else {
  269. b := make(Float32Array, len(elems))
  270. for i, v := range elems {
  271. var x float64
  272. if x, err = strconv.ParseFloat(string(v), 32); err != nil {
  273. return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
  274. }
  275. b[i] = float32(x)
  276. }
  277. *a = b
  278. }
  279. return nil
  280. }
  281. // Value implements the driver.Valuer interface.
  282. func (a Float32Array) Value() (driver.Value, error) {
  283. if a == nil {
  284. return nil, nil
  285. }
  286. if n := len(a); n > 0 {
  287. // There will be at least two curly brackets, N bytes of values,
  288. // and N-1 bytes of delimiters.
  289. b := make([]byte, 1, 1+2*n)
  290. b[0] = '{'
  291. b = strconv.AppendFloat(b, float64(a[0]), 'f', -1, 32)
  292. for i := 1; i < n; i++ {
  293. b = append(b, ',')
  294. b = strconv.AppendFloat(b, float64(a[i]), 'f', -1, 32)
  295. }
  296. return string(append(b, '}')), nil
  297. }
  298. return "{}", nil
  299. }
  300. // GenericArray implements the driver.Valuer and sql.Scanner interfaces for
  301. // an array or slice of any dimension.
  302. type GenericArray struct{ A interface{} }
  303. func (GenericArray) evaluateDestination(rt reflect.Type) (reflect.Type, func([]byte, reflect.Value) error, string) {
  304. var assign func([]byte, reflect.Value) error
  305. var del = ","
  306. // TODO calculate the assign function for other types
  307. // TODO repeat this section on the element type of arrays or slices (multidimensional)
  308. {
  309. if reflect.PtrTo(rt).Implements(typeSQLScanner) {
  310. // dest is always addressable because it is an element of a slice.
  311. assign = func(src []byte, dest reflect.Value) (err error) {
  312. ss := dest.Addr().Interface().(sql.Scanner)
  313. if src == nil {
  314. err = ss.Scan(nil)
  315. } else {
  316. err = ss.Scan(src)
  317. }
  318. return
  319. }
  320. goto FoundType
  321. }
  322. assign = func([]byte, reflect.Value) error {
  323. return fmt.Errorf("pq: scanning to %s is not implemented; only sql.Scanner", rt)
  324. }
  325. }
  326. FoundType:
  327. if ad, ok := reflect.Zero(rt).Interface().(ArrayDelimiter); ok {
  328. del = ad.ArrayDelimiter()
  329. }
  330. return rt, assign, del
  331. }
  332. // Scan implements the sql.Scanner interface.
  333. func (a GenericArray) Scan(src interface{}) error {
  334. dpv := reflect.ValueOf(a.A)
  335. switch {
  336. case dpv.Kind() != reflect.Ptr:
  337. return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A)
  338. case dpv.IsNil():
  339. return fmt.Errorf("pq: destination %T is nil", a.A)
  340. }
  341. dv := dpv.Elem()
  342. switch dv.Kind() {
  343. case reflect.Slice:
  344. case reflect.Array:
  345. default:
  346. return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A)
  347. }
  348. switch src := src.(type) {
  349. case []byte:
  350. return a.scanBytes(src, dv)
  351. case string:
  352. return a.scanBytes([]byte(src), dv)
  353. case nil:
  354. if dv.Kind() == reflect.Slice {
  355. dv.Set(reflect.Zero(dv.Type()))
  356. return nil
  357. }
  358. }
  359. return fmt.Errorf("pq: cannot convert %T to %s", src, dv.Type())
  360. }
  361. func (a GenericArray) scanBytes(src []byte, dv reflect.Value) error {
  362. dtype, assign, del := a.evaluateDestination(dv.Type().Elem())
  363. dims, elems, err := parseArray(src, []byte(del))
  364. if err != nil {
  365. return err
  366. }
  367. // TODO allow multidimensional
  368. if len(dims) > 1 {
  369. return fmt.Errorf("pq: scanning from multidimensional ARRAY%s is not implemented",
  370. strings.Replace(fmt.Sprint(dims), " ", "][", -1))
  371. }
  372. // Treat a zero-dimensional array like an array with a single dimension of zero.
  373. if len(dims) == 0 {
  374. dims = append(dims, 0)
  375. }
  376. for i, rt := 0, dv.Type(); i < len(dims); i, rt = i+1, rt.Elem() {
  377. switch rt.Kind() {
  378. case reflect.Slice:
  379. case reflect.Array:
  380. if rt.Len() != dims[i] {
  381. return fmt.Errorf("pq: cannot convert ARRAY%s to %s",
  382. strings.Replace(fmt.Sprint(dims), " ", "][", -1), dv.Type())
  383. }
  384. default:
  385. // TODO handle multidimensional
  386. }
  387. }
  388. values := reflect.MakeSlice(reflect.SliceOf(dtype), len(elems), len(elems))
  389. for i, e := range elems {
  390. if err := assign(e, values.Index(i)); err != nil {
  391. return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
  392. }
  393. }
  394. // TODO handle multidimensional
  395. switch dv.Kind() {
  396. case reflect.Slice:
  397. dv.Set(values.Slice(0, dims[0]))
  398. case reflect.Array:
  399. for i := 0; i < dims[0]; i++ {
  400. dv.Index(i).Set(values.Index(i))
  401. }
  402. }
  403. return nil
  404. }
  405. // Value implements the driver.Valuer interface.
  406. func (a GenericArray) Value() (driver.Value, error) {
  407. if a.A == nil {
  408. return nil, nil
  409. }
  410. rv := reflect.ValueOf(a.A)
  411. switch rv.Kind() {
  412. case reflect.Slice:
  413. if rv.IsNil() {
  414. return nil, nil
  415. }
  416. case reflect.Array:
  417. default:
  418. return nil, fmt.Errorf("pq: Unable to convert %T to array", a.A)
  419. }
  420. if n := rv.Len(); n > 0 {
  421. // There will be at least two curly brackets, N bytes of values,
  422. // and N-1 bytes of delimiters.
  423. b := make([]byte, 0, 1+2*n)
  424. b, _, err := appendArray(b, rv, n)
  425. return string(b), err
  426. }
  427. return "{}", nil
  428. }
  429. // Int64Array represents a one-dimensional array of the PostgreSQL integer types.
  430. type Int64Array []int64
  431. // Scan implements the sql.Scanner interface.
  432. func (a *Int64Array) Scan(src interface{}) error {
  433. switch src := src.(type) {
  434. case []byte:
  435. return a.scanBytes(src)
  436. case string:
  437. return a.scanBytes([]byte(src))
  438. case nil:
  439. *a = nil
  440. return nil
  441. }
  442. return fmt.Errorf("pq: cannot convert %T to Int64Array", src)
  443. }
  444. func (a *Int64Array) scanBytes(src []byte) error {
  445. elems, err := scanLinearArray(src, []byte{','}, "Int64Array")
  446. if err != nil {
  447. return err
  448. }
  449. if *a != nil && len(elems) == 0 {
  450. *a = (*a)[:0]
  451. } else {
  452. b := make(Int64Array, len(elems))
  453. for i, v := range elems {
  454. if b[i], err = strconv.ParseInt(string(v), 10, 64); err != nil {
  455. return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
  456. }
  457. }
  458. *a = b
  459. }
  460. return nil
  461. }
  462. // Value implements the driver.Valuer interface.
  463. func (a Int64Array) Value() (driver.Value, error) {
  464. if a == nil {
  465. return nil, nil
  466. }
  467. if n := len(a); n > 0 {
  468. // There will be at least two curly brackets, N bytes of values,
  469. // and N-1 bytes of delimiters.
  470. b := make([]byte, 1, 1+2*n)
  471. b[0] = '{'
  472. b = strconv.AppendInt(b, a[0], 10)
  473. for i := 1; i < n; i++ {
  474. b = append(b, ',')
  475. b = strconv.AppendInt(b, a[i], 10)
  476. }
  477. return string(append(b, '}')), nil
  478. }
  479. return "{}", nil
  480. }
  481. // Int32Array represents a one-dimensional array of the PostgreSQL integer types.
  482. type Int32Array []int32
  483. // Scan implements the sql.Scanner interface.
  484. func (a *Int32Array) Scan(src interface{}) error {
  485. switch src := src.(type) {
  486. case []byte:
  487. return a.scanBytes(src)
  488. case string:
  489. return a.scanBytes([]byte(src))
  490. case nil:
  491. *a = nil
  492. return nil
  493. }
  494. return fmt.Errorf("pq: cannot convert %T to Int32Array", src)
  495. }
  496. func (a *Int32Array) scanBytes(src []byte) error {
  497. elems, err := scanLinearArray(src, []byte{','}, "Int32Array")
  498. if err != nil {
  499. return err
  500. }
  501. if *a != nil && len(elems) == 0 {
  502. *a = (*a)[:0]
  503. } else {
  504. b := make(Int32Array, len(elems))
  505. for i, v := range elems {
  506. var x int
  507. if x, err = strconv.Atoi(string(v)); err != nil {
  508. return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
  509. }
  510. b[i] = int32(x)
  511. }
  512. *a = b
  513. }
  514. return nil
  515. }
  516. // Value implements the driver.Valuer interface.
  517. func (a Int32Array) Value() (driver.Value, error) {
  518. if a == nil {
  519. return nil, nil
  520. }
  521. if n := len(a); n > 0 {
  522. // There will be at least two curly brackets, N bytes of values,
  523. // and N-1 bytes of delimiters.
  524. b := make([]byte, 1, 1+2*n)
  525. b[0] = '{'
  526. b = strconv.AppendInt(b, int64(a[0]), 10)
  527. for i := 1; i < n; i++ {
  528. b = append(b, ',')
  529. b = strconv.AppendInt(b, int64(a[i]), 10)
  530. }
  531. return string(append(b, '}')), nil
  532. }
  533. return "{}", nil
  534. }
  535. // StringArray represents a one-dimensional array of the PostgreSQL character types.
  536. type StringArray []string
  537. // Scan implements the sql.Scanner interface.
  538. func (a *StringArray) Scan(src interface{}) error {
  539. switch src := src.(type) {
  540. case []byte:
  541. return a.scanBytes(src)
  542. case string:
  543. return a.scanBytes([]byte(src))
  544. case nil:
  545. *a = nil
  546. return nil
  547. }
  548. return fmt.Errorf("pq: cannot convert %T to StringArray", src)
  549. }
  550. func (a *StringArray) scanBytes(src []byte) error {
  551. elems, err := scanLinearArray(src, []byte{','}, "StringArray")
  552. if err != nil {
  553. return err
  554. }
  555. if *a != nil && len(elems) == 0 {
  556. *a = (*a)[:0]
  557. } else {
  558. b := make(StringArray, len(elems))
  559. for i, v := range elems {
  560. if b[i] = string(v); v == nil {
  561. return fmt.Errorf("pq: parsing array element index %d: cannot convert nil to string", i)
  562. }
  563. }
  564. *a = b
  565. }
  566. return nil
  567. }
  568. // Value implements the driver.Valuer interface.
  569. func (a StringArray) Value() (driver.Value, error) {
  570. if a == nil {
  571. return nil, nil
  572. }
  573. if n := len(a); n > 0 {
  574. // There will be at least two curly brackets, 2*N bytes of quotes,
  575. // and N-1 bytes of delimiters.
  576. b := make([]byte, 1, 1+3*n)
  577. b[0] = '{'
  578. b = appendArrayQuotedBytes(b, []byte(a[0]))
  579. for i := 1; i < n; i++ {
  580. b = append(b, ',')
  581. b = appendArrayQuotedBytes(b, []byte(a[i]))
  582. }
  583. return string(append(b, '}')), nil
  584. }
  585. return "{}", nil
  586. }
  587. // appendArray appends rv to the buffer, returning the extended buffer and
  588. // the delimiter used between elements.
  589. //
  590. // It panics when n <= 0 or rv's Kind is not reflect.Array nor reflect.Slice.
  591. func appendArray(b []byte, rv reflect.Value, n int) ([]byte, string, error) {
  592. var del string
  593. var err error
  594. b = append(b, '{')
  595. if b, del, err = appendArrayElement(b, rv.Index(0)); err != nil {
  596. return b, del, err
  597. }
  598. for i := 1; i < n; i++ {
  599. b = append(b, del...)
  600. if b, del, err = appendArrayElement(b, rv.Index(i)); err != nil {
  601. return b, del, err
  602. }
  603. }
  604. return append(b, '}'), del, nil
  605. }
  606. // appendArrayElement appends rv to the buffer, returning the extended buffer
  607. // and the delimiter to use before the next element.
  608. //
  609. // When rv's Kind is neither reflect.Array nor reflect.Slice, it is converted
  610. // using driver.DefaultParameterConverter and the resulting []byte or string
  611. // is double-quoted.
  612. //
  613. // See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO
  614. func appendArrayElement(b []byte, rv reflect.Value) ([]byte, string, error) {
  615. if k := rv.Kind(); k == reflect.Array || k == reflect.Slice {
  616. if t := rv.Type(); t != typeByteSlice && !t.Implements(typeDriverValuer) {
  617. if n := rv.Len(); n > 0 {
  618. return appendArray(b, rv, n)
  619. }
  620. return b, "", nil
  621. }
  622. }
  623. var del = ","
  624. var err error
  625. var iv interface{} = rv.Interface()
  626. if ad, ok := iv.(ArrayDelimiter); ok {
  627. del = ad.ArrayDelimiter()
  628. }
  629. if iv, err = driver.DefaultParameterConverter.ConvertValue(iv); err != nil {
  630. return b, del, err
  631. }
  632. switch v := iv.(type) {
  633. case nil:
  634. return append(b, "NULL"...), del, nil
  635. case []byte:
  636. return appendArrayQuotedBytes(b, v), del, nil
  637. case string:
  638. return appendArrayQuotedBytes(b, []byte(v)), del, nil
  639. }
  640. b, err = appendValue(b, iv)
  641. return b, del, err
  642. }
  643. func appendArrayQuotedBytes(b, v []byte) []byte {
  644. b = append(b, '"')
  645. for {
  646. i := bytes.IndexAny(v, `"\`)
  647. if i < 0 {
  648. b = append(b, v...)
  649. break
  650. }
  651. if i > 0 {
  652. b = append(b, v[:i]...)
  653. }
  654. b = append(b, '\\', v[i])
  655. v = v[i+1:]
  656. }
  657. return append(b, '"')
  658. }
  659. func appendValue(b []byte, v driver.Value) ([]byte, error) {
  660. return append(b, encode(nil, v, 0)...), nil
  661. }
  662. // parseArray extracts the dimensions and elements of an array represented in
  663. // text format. Only representations emitted by the backend are supported.
  664. // Notably, whitespace around brackets and delimiters is significant, and NULL
  665. // is case-sensitive.
  666. //
  667. // See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO
  668. func parseArray(src, del []byte) (dims []int, elems [][]byte, err error) {
  669. var depth, i int
  670. if len(src) < 1 || src[0] != '{' {
  671. return nil, nil, fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '{', 0)
  672. }
  673. Open:
  674. for i < len(src) {
  675. switch src[i] {
  676. case '{':
  677. depth++
  678. i++
  679. case '}':
  680. elems = make([][]byte, 0)
  681. goto Close
  682. default:
  683. break Open
  684. }
  685. }
  686. dims = make([]int, i)
  687. Element:
  688. for i < len(src) {
  689. switch src[i] {
  690. case '{':
  691. if depth == len(dims) {
  692. break Element
  693. }
  694. depth++
  695. dims[depth-1] = 0
  696. i++
  697. case '"':
  698. var elem = []byte{}
  699. var escape bool
  700. for i++; i < len(src); i++ {
  701. if escape {
  702. elem = append(elem, src[i])
  703. escape = false
  704. } else {
  705. switch src[i] {
  706. default:
  707. elem = append(elem, src[i])
  708. case '\\':
  709. escape = true
  710. case '"':
  711. elems = append(elems, elem)
  712. i++
  713. break Element
  714. }
  715. }
  716. }
  717. default:
  718. for start := i; i < len(src); i++ {
  719. if bytes.HasPrefix(src[i:], del) || src[i] == '}' {
  720. elem := src[start:i]
  721. if len(elem) == 0 {
  722. return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i)
  723. }
  724. if bytes.Equal(elem, []byte("NULL")) {
  725. elem = nil
  726. }
  727. elems = append(elems, elem)
  728. break Element
  729. }
  730. }
  731. }
  732. }
  733. for i < len(src) {
  734. if bytes.HasPrefix(src[i:], del) && depth > 0 {
  735. dims[depth-1]++
  736. i += len(del)
  737. goto Element
  738. } else if src[i] == '}' && depth > 0 {
  739. dims[depth-1]++
  740. depth--
  741. i++
  742. } else {
  743. return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i)
  744. }
  745. }
  746. Close:
  747. for i < len(src) {
  748. if src[i] == '}' && depth > 0 {
  749. depth--
  750. i++
  751. } else {
  752. return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i)
  753. }
  754. }
  755. if depth > 0 {
  756. err = fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '}', i)
  757. }
  758. if err == nil {
  759. for _, d := range dims {
  760. if (len(elems) % d) != 0 {
  761. err = fmt.Errorf("pq: multidimensional arrays must have elements with matching dimensions")
  762. }
  763. }
  764. }
  765. return
  766. }
  767. func scanLinearArray(src, del []byte, typ string) (elems [][]byte, err error) {
  768. dims, elems, err := parseArray(src, del)
  769. if err != nil {
  770. return nil, err
  771. }
  772. if len(dims) > 1 {
  773. return nil, fmt.Errorf("pq: cannot convert ARRAY%s to %s", strings.Replace(fmt.Sprint(dims), " ", "][", -1), typ)
  774. }
  775. return elems, err
  776. }