rows_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package pq
  2. import (
  3. "math"
  4. "reflect"
  5. "testing"
  6. "github.com/lib/pq/oid"
  7. )
  8. func TestDataTypeName(t *testing.T) {
  9. tts := []struct {
  10. typ oid.Oid
  11. name string
  12. }{
  13. {oid.T_int8, "INT8"},
  14. {oid.T_int4, "INT4"},
  15. {oid.T_int2, "INT2"},
  16. {oid.T_varchar, "VARCHAR"},
  17. {oid.T_text, "TEXT"},
  18. {oid.T_bool, "BOOL"},
  19. {oid.T_numeric, "NUMERIC"},
  20. {oid.T_date, "DATE"},
  21. {oid.T_time, "TIME"},
  22. {oid.T_timetz, "TIMETZ"},
  23. {oid.T_timestamp, "TIMESTAMP"},
  24. {oid.T_timestamptz, "TIMESTAMPTZ"},
  25. {oid.T_bytea, "BYTEA"},
  26. }
  27. for i, tt := range tts {
  28. dt := fieldDesc{OID: tt.typ}
  29. if name := dt.Name(); name != tt.name {
  30. t.Errorf("(%d) got: %s want: %s", i, name, tt.name)
  31. }
  32. }
  33. }
  34. func TestDataType(t *testing.T) {
  35. tts := []struct {
  36. typ oid.Oid
  37. kind reflect.Kind
  38. }{
  39. {oid.T_int8, reflect.Int64},
  40. {oid.T_int4, reflect.Int32},
  41. {oid.T_int2, reflect.Int16},
  42. {oid.T_varchar, reflect.String},
  43. {oid.T_text, reflect.String},
  44. {oid.T_bool, reflect.Bool},
  45. {oid.T_date, reflect.Struct},
  46. {oid.T_time, reflect.Struct},
  47. {oid.T_timetz, reflect.Struct},
  48. {oid.T_timestamp, reflect.Struct},
  49. {oid.T_timestamptz, reflect.Struct},
  50. {oid.T_bytea, reflect.Slice},
  51. }
  52. for i, tt := range tts {
  53. dt := fieldDesc{OID: tt.typ}
  54. if kind := dt.Type().Kind(); kind != tt.kind {
  55. t.Errorf("(%d) got: %s want: %s", i, kind, tt.kind)
  56. }
  57. }
  58. }
  59. func TestDataTypeLength(t *testing.T) {
  60. tts := []struct {
  61. typ oid.Oid
  62. len int
  63. mod int
  64. length int64
  65. ok bool
  66. }{
  67. {oid.T_int4, 0, -1, 0, false},
  68. {oid.T_varchar, 65535, 9, 5, true},
  69. {oid.T_text, 65535, -1, math.MaxInt64, true},
  70. {oid.T_bytea, 65535, -1, math.MaxInt64, true},
  71. }
  72. for i, tt := range tts {
  73. dt := fieldDesc{OID: tt.typ, Len: tt.len, Mod: tt.mod}
  74. if l, k := dt.Length(); k != tt.ok || l != tt.length {
  75. t.Errorf("(%d) got: %d, %t want: %d, %t", i, l, k, tt.length, tt.ok)
  76. }
  77. }
  78. }
  79. func TestDataTypePrecisionScale(t *testing.T) {
  80. tts := []struct {
  81. typ oid.Oid
  82. mod int
  83. precision, scale int64
  84. ok bool
  85. }{
  86. {oid.T_int4, -1, 0, 0, false},
  87. {oid.T_numeric, 589830, 9, 2, true},
  88. {oid.T_text, -1, 0, 0, false},
  89. }
  90. for i, tt := range tts {
  91. dt := fieldDesc{OID: tt.typ, Mod: tt.mod}
  92. p, s, k := dt.PrecisionScale()
  93. if k != tt.ok {
  94. t.Errorf("(%d) got: %t want: %t", i, k, tt.ok)
  95. }
  96. if p != tt.precision {
  97. t.Errorf("(%d) wrong precision got: %d want: %d", i, p, tt.precision)
  98. }
  99. if s != tt.scale {
  100. t.Errorf("(%d) wrong scale got: %d want: %d", i, s, tt.scale)
  101. }
  102. }
  103. }
  104. func TestRowsColumnTypes(t *testing.T) {
  105. columnTypesTests := []struct {
  106. Name string
  107. TypeName string
  108. Length struct {
  109. Len int64
  110. OK bool
  111. }
  112. DecimalSize struct {
  113. Precision int64
  114. Scale int64
  115. OK bool
  116. }
  117. ScanType reflect.Type
  118. }{
  119. {
  120. Name: "a",
  121. TypeName: "INT4",
  122. Length: struct {
  123. Len int64
  124. OK bool
  125. }{
  126. Len: 0,
  127. OK: false,
  128. },
  129. DecimalSize: struct {
  130. Precision int64
  131. Scale int64
  132. OK bool
  133. }{
  134. Precision: 0,
  135. Scale: 0,
  136. OK: false,
  137. },
  138. ScanType: reflect.TypeOf(int32(0)),
  139. }, {
  140. Name: "bar",
  141. TypeName: "TEXT",
  142. Length: struct {
  143. Len int64
  144. OK bool
  145. }{
  146. Len: math.MaxInt64,
  147. OK: true,
  148. },
  149. DecimalSize: struct {
  150. Precision int64
  151. Scale int64
  152. OK bool
  153. }{
  154. Precision: 0,
  155. Scale: 0,
  156. OK: false,
  157. },
  158. ScanType: reflect.TypeOf(""),
  159. },
  160. }
  161. db := openTestConn(t)
  162. defer db.Close()
  163. rows, err := db.Query("SELECT 1 AS a, text 'bar' AS bar, 1.28::numeric(9, 2) AS dec")
  164. if err != nil {
  165. t.Fatal(err)
  166. }
  167. columns, err := rows.ColumnTypes()
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. if len(columns) != 3 {
  172. t.Errorf("expected 3 columns found %d", len(columns))
  173. }
  174. for i, tt := range columnTypesTests {
  175. c := columns[i]
  176. if c.Name() != tt.Name {
  177. t.Errorf("(%d) got: %s, want: %s", i, c.Name(), tt.Name)
  178. }
  179. if c.DatabaseTypeName() != tt.TypeName {
  180. t.Errorf("(%d) got: %s, want: %s", i, c.DatabaseTypeName(), tt.TypeName)
  181. }
  182. l, ok := c.Length()
  183. if l != tt.Length.Len {
  184. t.Errorf("(%d) got: %d, want: %d", i, l, tt.Length.Len)
  185. }
  186. if ok != tt.Length.OK {
  187. t.Errorf("(%d) got: %t, want: %t", i, ok, tt.Length.OK)
  188. }
  189. p, s, ok := c.DecimalSize()
  190. if p != tt.DecimalSize.Precision {
  191. t.Errorf("(%d) got: %d, want: %d", i, p, tt.DecimalSize.Precision)
  192. }
  193. if s != tt.DecimalSize.Scale {
  194. t.Errorf("(%d) got: %d, want: %d", i, s, tt.DecimalSize.Scale)
  195. }
  196. if ok != tt.DecimalSize.OK {
  197. t.Errorf("(%d) got: %t, want: %t", i, ok, tt.DecimalSize.OK)
  198. }
  199. if c.ScanType() != tt.ScanType {
  200. t.Errorf("(%d) got: %v, want: %v", i, c.ScanType(), tt.ScanType)
  201. }
  202. }
  203. }