singlestoredb 1.16.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. singlestoredb/__init__.py +75 -0
  2. singlestoredb/ai/__init__.py +2 -0
  3. singlestoredb/ai/chat.py +139 -0
  4. singlestoredb/ai/embeddings.py +128 -0
  5. singlestoredb/alchemy/__init__.py +90 -0
  6. singlestoredb/apps/__init__.py +3 -0
  7. singlestoredb/apps/_cloud_functions.py +90 -0
  8. singlestoredb/apps/_config.py +72 -0
  9. singlestoredb/apps/_connection_info.py +18 -0
  10. singlestoredb/apps/_dashboards.py +47 -0
  11. singlestoredb/apps/_process.py +32 -0
  12. singlestoredb/apps/_python_udfs.py +100 -0
  13. singlestoredb/apps/_stdout_supress.py +30 -0
  14. singlestoredb/apps/_uvicorn_util.py +36 -0
  15. singlestoredb/auth.py +245 -0
  16. singlestoredb/config.py +484 -0
  17. singlestoredb/connection.py +1487 -0
  18. singlestoredb/converters.py +950 -0
  19. singlestoredb/docstring/__init__.py +33 -0
  20. singlestoredb/docstring/attrdoc.py +126 -0
  21. singlestoredb/docstring/common.py +230 -0
  22. singlestoredb/docstring/epydoc.py +267 -0
  23. singlestoredb/docstring/google.py +412 -0
  24. singlestoredb/docstring/numpydoc.py +562 -0
  25. singlestoredb/docstring/parser.py +100 -0
  26. singlestoredb/docstring/py.typed +1 -0
  27. singlestoredb/docstring/rest.py +256 -0
  28. singlestoredb/docstring/tests/__init__.py +1 -0
  29. singlestoredb/docstring/tests/_pydoctor.py +21 -0
  30. singlestoredb/docstring/tests/test_epydoc.py +729 -0
  31. singlestoredb/docstring/tests/test_google.py +1007 -0
  32. singlestoredb/docstring/tests/test_numpydoc.py +1100 -0
  33. singlestoredb/docstring/tests/test_parse_from_object.py +109 -0
  34. singlestoredb/docstring/tests/test_parser.py +248 -0
  35. singlestoredb/docstring/tests/test_rest.py +547 -0
  36. singlestoredb/docstring/tests/test_util.py +70 -0
  37. singlestoredb/docstring/util.py +141 -0
  38. singlestoredb/exceptions.py +120 -0
  39. singlestoredb/functions/__init__.py +16 -0
  40. singlestoredb/functions/decorator.py +201 -0
  41. singlestoredb/functions/dtypes.py +1793 -0
  42. singlestoredb/functions/ext/__init__.py +1 -0
  43. singlestoredb/functions/ext/arrow.py +375 -0
  44. singlestoredb/functions/ext/asgi.py +2133 -0
  45. singlestoredb/functions/ext/json.py +420 -0
  46. singlestoredb/functions/ext/mmap.py +413 -0
  47. singlestoredb/functions/ext/rowdat_1.py +724 -0
  48. singlestoredb/functions/ext/timer.py +89 -0
  49. singlestoredb/functions/ext/utils.py +218 -0
  50. singlestoredb/functions/signature.py +1578 -0
  51. singlestoredb/functions/typing/__init__.py +41 -0
  52. singlestoredb/functions/typing/numpy.py +20 -0
  53. singlestoredb/functions/typing/pandas.py +2 -0
  54. singlestoredb/functions/typing/polars.py +2 -0
  55. singlestoredb/functions/typing/pyarrow.py +2 -0
  56. singlestoredb/functions/utils.py +421 -0
  57. singlestoredb/fusion/__init__.py +11 -0
  58. singlestoredb/fusion/graphql.py +213 -0
  59. singlestoredb/fusion/handler.py +916 -0
  60. singlestoredb/fusion/handlers/__init__.py +0 -0
  61. singlestoredb/fusion/handlers/export.py +525 -0
  62. singlestoredb/fusion/handlers/files.py +690 -0
  63. singlestoredb/fusion/handlers/job.py +660 -0
  64. singlestoredb/fusion/handlers/models.py +250 -0
  65. singlestoredb/fusion/handlers/stage.py +502 -0
  66. singlestoredb/fusion/handlers/utils.py +324 -0
  67. singlestoredb/fusion/handlers/workspace.py +956 -0
  68. singlestoredb/fusion/registry.py +249 -0
  69. singlestoredb/fusion/result.py +399 -0
  70. singlestoredb/http/__init__.py +27 -0
  71. singlestoredb/http/connection.py +1267 -0
  72. singlestoredb/magics/__init__.py +34 -0
  73. singlestoredb/magics/run_personal.py +137 -0
  74. singlestoredb/magics/run_shared.py +134 -0
  75. singlestoredb/management/__init__.py +9 -0
  76. singlestoredb/management/billing_usage.py +148 -0
  77. singlestoredb/management/cluster.py +462 -0
  78. singlestoredb/management/export.py +295 -0
  79. singlestoredb/management/files.py +1102 -0
  80. singlestoredb/management/inference_api.py +105 -0
  81. singlestoredb/management/job.py +887 -0
  82. singlestoredb/management/manager.py +373 -0
  83. singlestoredb/management/organization.py +226 -0
  84. singlestoredb/management/region.py +169 -0
  85. singlestoredb/management/utils.py +423 -0
  86. singlestoredb/management/workspace.py +1927 -0
  87. singlestoredb/mysql/__init__.py +177 -0
  88. singlestoredb/mysql/_auth.py +298 -0
  89. singlestoredb/mysql/charset.py +214 -0
  90. singlestoredb/mysql/connection.py +2032 -0
  91. singlestoredb/mysql/constants/CLIENT.py +38 -0
  92. singlestoredb/mysql/constants/COMMAND.py +32 -0
  93. singlestoredb/mysql/constants/CR.py +78 -0
  94. singlestoredb/mysql/constants/ER.py +474 -0
  95. singlestoredb/mysql/constants/EXTENDED_TYPE.py +3 -0
  96. singlestoredb/mysql/constants/FIELD_TYPE.py +48 -0
  97. singlestoredb/mysql/constants/FLAG.py +15 -0
  98. singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
  99. singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
  100. singlestoredb/mysql/constants/__init__.py +0 -0
  101. singlestoredb/mysql/converters.py +271 -0
  102. singlestoredb/mysql/cursors.py +896 -0
  103. singlestoredb/mysql/err.py +92 -0
  104. singlestoredb/mysql/optionfile.py +20 -0
  105. singlestoredb/mysql/protocol.py +450 -0
  106. singlestoredb/mysql/tests/__init__.py +19 -0
  107. singlestoredb/mysql/tests/base.py +126 -0
  108. singlestoredb/mysql/tests/conftest.py +37 -0
  109. singlestoredb/mysql/tests/test_DictCursor.py +132 -0
  110. singlestoredb/mysql/tests/test_SSCursor.py +141 -0
  111. singlestoredb/mysql/tests/test_basic.py +452 -0
  112. singlestoredb/mysql/tests/test_connection.py +851 -0
  113. singlestoredb/mysql/tests/test_converters.py +58 -0
  114. singlestoredb/mysql/tests/test_cursor.py +141 -0
  115. singlestoredb/mysql/tests/test_err.py +16 -0
  116. singlestoredb/mysql/tests/test_issues.py +514 -0
  117. singlestoredb/mysql/tests/test_load_local.py +75 -0
  118. singlestoredb/mysql/tests/test_nextset.py +88 -0
  119. singlestoredb/mysql/tests/test_optionfile.py +27 -0
  120. singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
  121. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
  122. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
  123. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
  124. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
  125. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
  126. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
  127. singlestoredb/mysql/times.py +23 -0
  128. singlestoredb/notebook/__init__.py +16 -0
  129. singlestoredb/notebook/_objects.py +213 -0
  130. singlestoredb/notebook/_portal.py +352 -0
  131. singlestoredb/py.typed +0 -0
  132. singlestoredb/pytest.py +352 -0
  133. singlestoredb/server/__init__.py +0 -0
  134. singlestoredb/server/docker.py +452 -0
  135. singlestoredb/server/free_tier.py +267 -0
  136. singlestoredb/tests/__init__.py +0 -0
  137. singlestoredb/tests/alltypes.sql +307 -0
  138. singlestoredb/tests/alltypes_no_nulls.sql +208 -0
  139. singlestoredb/tests/empty.sql +0 -0
  140. singlestoredb/tests/ext_funcs/__init__.py +702 -0
  141. singlestoredb/tests/local_infile.csv +3 -0
  142. singlestoredb/tests/test.ipynb +18 -0
  143. singlestoredb/tests/test.sql +680 -0
  144. singlestoredb/tests/test2.ipynb +18 -0
  145. singlestoredb/tests/test2.sql +1 -0
  146. singlestoredb/tests/test_basics.py +1332 -0
  147. singlestoredb/tests/test_config.py +318 -0
  148. singlestoredb/tests/test_connection.py +3103 -0
  149. singlestoredb/tests/test_dbapi.py +27 -0
  150. singlestoredb/tests/test_exceptions.py +45 -0
  151. singlestoredb/tests/test_ext_func.py +1472 -0
  152. singlestoredb/tests/test_ext_func_data.py +1101 -0
  153. singlestoredb/tests/test_fusion.py +1527 -0
  154. singlestoredb/tests/test_http.py +288 -0
  155. singlestoredb/tests/test_management.py +1599 -0
  156. singlestoredb/tests/test_plugin.py +33 -0
  157. singlestoredb/tests/test_results.py +171 -0
  158. singlestoredb/tests/test_types.py +132 -0
  159. singlestoredb/tests/test_udf.py +737 -0
  160. singlestoredb/tests/test_udf_returns.py +459 -0
  161. singlestoredb/tests/test_vectorstore.py +51 -0
  162. singlestoredb/tests/test_xdict.py +333 -0
  163. singlestoredb/tests/utils.py +141 -0
  164. singlestoredb/types.py +373 -0
  165. singlestoredb/utils/__init__.py +0 -0
  166. singlestoredb/utils/config.py +950 -0
  167. singlestoredb/utils/convert_rows.py +69 -0
  168. singlestoredb/utils/debug.py +13 -0
  169. singlestoredb/utils/dtypes.py +205 -0
  170. singlestoredb/utils/events.py +65 -0
  171. singlestoredb/utils/mogrify.py +151 -0
  172. singlestoredb/utils/results.py +585 -0
  173. singlestoredb/utils/xdict.py +425 -0
  174. singlestoredb/vectorstore.py +192 -0
  175. singlestoredb/warnings.py +5 -0
  176. singlestoredb-1.16.1.dist-info/METADATA +165 -0
  177. singlestoredb-1.16.1.dist-info/RECORD +183 -0
  178. singlestoredb-1.16.1.dist-info/WHEEL +5 -0
  179. singlestoredb-1.16.1.dist-info/entry_points.txt +2 -0
  180. singlestoredb-1.16.1.dist-info/licenses/LICENSE +201 -0
  181. singlestoredb-1.16.1.dist-info/top_level.txt +3 -0
  182. sqlx/__init__.py +4 -0
  183. sqlx/magic.py +113 -0
@@ -0,0 +1,3103 @@
1
+ #!/usr/bin/env python
2
+ # type: ignore
3
+ """Basic SingleStoreDB connection testing."""
4
+ import datetime
5
+ import decimal
6
+ import os
7
+ import unittest
8
+ import uuid
9
+
10
+ import singlestoredb as s2
11
+ from singlestoredb import connection as sc
12
+ from singlestoredb.tests import utils
13
+ # import pandas as pd
14
+ # import traceback
15
+
16
+ try:
17
+ import numpy as np
18
+ has_numpy = True
19
+ except ImportError:
20
+ has_numpy = False
21
+
22
+ try:
23
+ import pandas as pd
24
+ has_pandas = True
25
+ except ImportError:
26
+ has_pandas = False
27
+
28
+
29
+ class TestConnection(unittest.TestCase):
30
+
31
+ dbname: str = ''
32
+ dbexisted: bool = False
33
+
34
+ @classmethod
35
+ def setUpClass(cls):
36
+ sql_file = os.path.join(os.path.dirname(__file__), 'test.sql')
37
+ cls.dbname, cls.dbexisted = utils.load_sql(sql_file)
38
+
39
+ @classmethod
40
+ def tearDownClass(cls):
41
+ if not cls.dbexisted:
42
+ utils.drop_database(cls.dbname)
43
+
44
+ def setUp(self):
45
+ self.conn = s2.connect(database=type(self).dbname, local_infile=True)
46
+ self.cur = self.conn.cursor()
47
+
48
+ def tearDown(self):
49
+ try:
50
+ if self.cur is not None:
51
+ self.cur.close()
52
+ except Exception:
53
+ # traceback.print_exc()
54
+ pass
55
+
56
+ try:
57
+ if self.conn is not None:
58
+ self.conn.close()
59
+ except Exception:
60
+ # traceback.print_exc()
61
+ pass
62
+
63
+ def test_connection(self):
64
+ self.cur.execute('show databases')
65
+ dbs = set([x[0] for x in self.cur.fetchall()])
66
+ assert type(self).dbname in dbs, dbs
67
+
68
+ def test_cast_bool_param(self):
69
+ cbp = sc.cast_bool_param
70
+
71
+ assert cbp(0) is False, cbp(0)
72
+ assert cbp(1) is True, cbp(1)
73
+ with self.assertRaises(ValueError):
74
+ cbp(10)
75
+
76
+ assert cbp(True) is True, cbp(True)
77
+ assert cbp(False) is False, cbp(False)
78
+ assert cbp(None) is False, cbp(None)
79
+
80
+ assert cbp('true') is True, cbp('true')
81
+ assert cbp('t') is True, cbp('t')
82
+ assert cbp('True') is True, cbp('True')
83
+ assert cbp('T') is True, cbp('T')
84
+ assert cbp('TRUE') is True, cbp('TRUE')
85
+
86
+ assert cbp('on') is True, cbp('on')
87
+ assert cbp('yes') is True, cbp('yes')
88
+ assert cbp('enable') is True, cbp('enable')
89
+ assert cbp('enabled') is True, cbp('enabled')
90
+
91
+ assert cbp('false') is False, cbp('false')
92
+ assert cbp('f') is False, cbp('f')
93
+ assert cbp('False') is False, cbp('False')
94
+ assert cbp('F') is False, cbp('F')
95
+ assert cbp('FALSE') is False, cbp('FALSE')
96
+
97
+ assert cbp('off') is False, cbp('off')
98
+ assert cbp('no') is False, cbp('no')
99
+ assert cbp('disable') is False, cbp('disable')
100
+ assert cbp('disabled') is False, cbp('disabled')
101
+
102
+ with self.assertRaises(ValueError):
103
+ cbp('nein')
104
+
105
+ with self.assertRaises(ValueError):
106
+ cbp(b'no')
107
+
108
+ with self.assertRaises(ValueError):
109
+ cbp(['no'])
110
+
111
+ def test_fetchall(self):
112
+ self.cur.execute('select * from data')
113
+
114
+ out = self.cur.fetchall()
115
+
116
+ desc = self.cur.description
117
+ rowcount = self.cur.rowcount
118
+ rownumber = self.cur.rownumber
119
+ lastrowid = self.cur.lastrowid
120
+
121
+ assert sorted(out) == sorted([
122
+ ('a', 'antelopes', 2),
123
+ ('b', 'bears', 2),
124
+ ('c', 'cats', 5),
125
+ ('d', 'dogs', 4),
126
+ ('e', 'elephants', 0),
127
+ ]), out
128
+
129
+ assert rowcount in (5, -1), rowcount
130
+ assert rownumber == 5, rownumber
131
+ assert lastrowid is None, lastrowid
132
+ assert len(desc) == 3, desc
133
+ assert desc[0].name == 'id', desc[0].name
134
+ assert desc[0].type_code in [253, 15], desc[0].type_code
135
+ assert desc[1].name == 'name', desc[1].name
136
+ assert desc[1].type_code in [253, 15], desc[1].type_code
137
+ assert desc[2].name == 'value', desc[2].name
138
+ assert desc[2].type_code == 8, desc[2].type_code
139
+
140
+ def test_fetchone(self):
141
+ self.cur.execute('select * from data')
142
+
143
+ out = []
144
+ while True:
145
+ row = self.cur.fetchone()
146
+ if row is None:
147
+ break
148
+ out.append(row)
149
+ assert self.cur.rownumber == len(out), self.cur.rownumber
150
+
151
+ desc = self.cur.description
152
+ rowcount = self.cur.rowcount
153
+ rownumber = self.cur.rownumber
154
+ lastrowid = self.cur.lastrowid
155
+
156
+ assert sorted(out) == sorted([
157
+ ('a', 'antelopes', 2),
158
+ ('b', 'bears', 2),
159
+ ('c', 'cats', 5),
160
+ ('d', 'dogs', 4),
161
+ ('e', 'elephants', 0),
162
+ ]), out
163
+
164
+ assert rowcount in (5, -1), rowcount
165
+ assert rownumber == 5, rownumber
166
+ assert lastrowid is None, lastrowid
167
+ assert len(desc) == 3, desc
168
+ assert desc[0].name == 'id', desc[0].name
169
+ assert desc[0].type_code in [253, 15], desc[0].type_code
170
+ assert desc[1].name == 'name', desc[1].name
171
+ assert desc[1].type_code in [253, 15], desc[1].type_code
172
+ assert desc[2].name == 'value', desc[2].name
173
+ assert desc[2].type_code == 8, desc[2].type_code
174
+
175
+ def test_fetchmany(self):
176
+ self.cur.execute('select * from data')
177
+
178
+ out = []
179
+ while True:
180
+ rows = self.cur.fetchmany(size=3)
181
+ assert len(rows) <= 3, rows
182
+ if not rows:
183
+ break
184
+ out.extend(rows)
185
+ assert self.cur.rownumber == len(out), self.cur.rownumber
186
+
187
+ desc = self.cur.description
188
+ rowcount = self.cur.rowcount
189
+ rownumber = self.cur.rownumber
190
+ lastrowid = self.cur.lastrowid
191
+
192
+ assert sorted(out) == sorted([
193
+ ('a', 'antelopes', 2),
194
+ ('b', 'bears', 2),
195
+ ('c', 'cats', 5),
196
+ ('d', 'dogs', 4),
197
+ ('e', 'elephants', 0),
198
+ ]), out
199
+
200
+ assert rowcount in (5, -1), rowcount
201
+ assert rownumber == 5, rownumber
202
+ assert lastrowid is None, lastrowid
203
+ assert len(desc) == 3, desc
204
+ assert desc[0].name == 'id'
205
+ assert desc[0].type_code in [253, 15]
206
+ assert desc[1].name == 'name'
207
+ assert desc[1].type_code in [253, 15]
208
+ assert desc[2].name == 'value'
209
+ assert desc[2].type_code == 8
210
+
211
+ def test_arraysize(self):
212
+ self.cur.execute('select * from data')
213
+
214
+ self.cur.arraysize = 3
215
+ assert self.cur.arraysize == 3
216
+
217
+ rows = self.cur.fetchmany()
218
+ assert len(rows) == 3, rows
219
+ assert self.cur.rownumber == 3, self.cur.rownumber
220
+
221
+ self.cur.arraysize = 1
222
+ assert self.cur.arraysize == 1
223
+
224
+ rows = self.cur.fetchmany()
225
+ assert len(rows) == 1, rows
226
+ assert self.cur.rownumber == 4, self.cur.rownumber
227
+
228
+ rows = self.cur.fetchmany()
229
+ assert len(rows) == 1, rows
230
+ assert self.cur.rownumber == 5, self.cur.rownumber
231
+
232
+ rows = self.cur.fetchall()
233
+ assert len(rows) == 0, rows
234
+ assert self.cur.rownumber == 5, self.cur.rownumber
235
+
236
+ def test_execute_with_dict_params(self):
237
+ self.cur.execute('select * from data where id < %(name)s', dict(name='d'))
238
+ out = self.cur.fetchall()
239
+
240
+ desc = self.cur.description
241
+ rowcount = self.cur.rowcount
242
+ lastrowid = self.cur.lastrowid
243
+
244
+ assert sorted(out) == sorted([
245
+ ('a', 'antelopes', 2),
246
+ ('b', 'bears', 2),
247
+ ('c', 'cats', 5),
248
+ ]), out
249
+
250
+ assert rowcount in (3, -1), rowcount
251
+ assert lastrowid is None, lastrowid
252
+ assert len(desc) == 3, desc
253
+ assert desc[0].name == 'id', desc[0].name
254
+ assert desc[0].type_code in [253, 15], desc[0].type_code
255
+ assert desc[1].name == 'name', desc[1].name
256
+ assert desc[1].type_code in [253, 15], desc[1].type_code
257
+ assert desc[2].name == 'value', desc[2].name
258
+ assert desc[2].type_code == 8, desc[2].type_code
259
+
260
+ def test_execute_with_positional_params(self):
261
+ self.cur.execute('select * from data where id < %s', ['d'])
262
+ out = self.cur.fetchall()
263
+
264
+ desc = self.cur.description
265
+ rowcount = self.cur.rowcount
266
+ lastrowid = self.cur.lastrowid
267
+
268
+ assert sorted(out) == sorted([
269
+ ('a', 'antelopes', 2),
270
+ ('b', 'bears', 2),
271
+ ('c', 'cats', 5),
272
+ ]), out
273
+
274
+ assert rowcount in (3, -1), rowcount
275
+ assert lastrowid is None, lastrowid
276
+ assert len(desc) == 3, desc
277
+ assert desc[0].name == 'id', desc[0].name
278
+ assert desc[0].type_code in [253, 15], desc[0].type_code
279
+ assert desc[1].name == 'name', desc[1].name
280
+ assert desc[1].type_code in [253, 15], desc[1].type_code
281
+ assert desc[2].name == 'value', desc[2].name
282
+ assert desc[2].type_code == 8, desc[2].type_code
283
+
284
+ def test_execute_with_escaped_positional_substitutions(self):
285
+ self.cur.execute(
286
+ 'select `id`, `time` from alltypes where `time` = %s', [
287
+ '00:07:00',
288
+ ],
289
+ )
290
+ out = self.cur.fetchall()
291
+ assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
292
+
293
+ self.cur.execute(
294
+ 'select `id`, `time` from alltypes where `time` = "00:07:00"',
295
+ )
296
+ out = self.cur.fetchall()
297
+ assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
298
+
299
+ # with self.assertRaises(IndexError):
300
+ # self.cur.execute(
301
+ # 'select `id`, `time` from alltypes where `id` = %1s '
302
+ # 'or `time` = "00:07:00"', [0],
303
+ # )
304
+
305
+ self.cur.execute(
306
+ 'select `id`, `time` from alltypes where `id` = %s '
307
+ 'or `time` = "00:07:00"', [0],
308
+ )
309
+ out = self.cur.fetchall()
310
+ assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
311
+
312
+ def test_execute_with_escaped_substitutions(self):
313
+ self.cur.execute(
314
+ 'select `id`, `time` from alltypes where `time` = %(time)s',
315
+ dict(time='00:07:00'),
316
+ )
317
+ out = self.cur.fetchall()
318
+ assert out[0] == (0, datetime.timedelta(seconds=420)), out[0]
319
+
320
+ self.cur.execute(
321
+ 'select `id`, `time` from alltypes where `time` = %(time)s',
322
+ dict(time='00:07:00'),
323
+ )
324
+ out = self.cur.fetchall()
325
+ assert len(out) == 1, out
326
+
327
+ with self.assertRaises(KeyError):
328
+ self.cur.execute(
329
+ 'select `id`, `time`, `char_100` from alltypes '
330
+ 'where `time` = %(time)s or `char_100` like "foo:bar"',
331
+ dict(x='00:07:00'),
332
+ )
333
+
334
+ self.cur.execute(
335
+ 'select `id`, `time`, `char_100` from alltypes '
336
+ 'where `time` = %(time)s or `char_100` like "foo::bar"',
337
+ dict(time='00:07:00'),
338
+ )
339
+ out = self.cur.fetchall()
340
+ assert out[0][:2] == (0, datetime.timedelta(seconds=420)), out[0]
341
+
342
+ def test_is_connected(self):
343
+ assert self.conn.is_connected()
344
+ assert self.cur.is_connected()
345
+ self.cur.close()
346
+ assert not self.cur.is_connected()
347
+ assert self.conn.is_connected()
348
+ self.conn.close()
349
+ assert not self.cur.is_connected()
350
+ assert not self.conn.is_connected()
351
+
352
+ def test_connection_attr(self):
353
+ # Use context manager to get to underlying object (self.conn is a weakref.proxy)
354
+ with self.conn as conn:
355
+ assert conn is self.conn
356
+
357
+ def test_executemany(self):
358
+ # NOTE: Doesn't actually do anything since no rows match
359
+ self.cur.executemany(
360
+ 'delete from data where id > %(name)s',
361
+ [dict(name='z'), dict(name='y')],
362
+ )
363
+
364
+ def test_executemany_no_args(self):
365
+ self.cur.executemany('select * from data where id > "z"')
366
+
367
+ def test_context_managers(self):
368
+ with s2.connect() as conn:
369
+ with conn.cursor() as cur:
370
+ assert cur.is_connected()
371
+ assert conn.is_connected()
372
+ assert not cur.is_connected()
373
+ assert not conn.is_connected()
374
+
375
+ def test_iterator(self):
376
+ self.cur.execute('select * from data')
377
+
378
+ out = []
379
+ for row in self.cur:
380
+ out.append(row)
381
+
382
+ assert sorted(out) == sorted([
383
+ ('a', 'antelopes', 2),
384
+ ('b', 'bears', 2),
385
+ ('c', 'cats', 5),
386
+ ('d', 'dogs', 4),
387
+ ('e', 'elephants', 0),
388
+ ]), out
389
+
390
+ def test_urls(self):
391
+ from singlestoredb.connection import build_params
392
+ from singlestoredb.config import get_option
393
+
394
+ # Full URL (without scheme)
395
+ url = 'me:p455w0rd@s2host.com:3307/mydb'
396
+ out = build_params(host=url)
397
+ assert out['driver'] == get_option('driver'), out['driver']
398
+ assert out['host'] == 's2host.com', out['host']
399
+ assert out['port'] == 3307, out['port']
400
+ assert out['database'] == 'mydb', out['database']
401
+ assert out['user'] == 'me', out['user']
402
+ assert out['password'] == 'p455w0rd', out['password']
403
+
404
+ # Full URL (with scheme)
405
+ url = 'http://me:p455w0rd@s2host.com:3307/mydb'
406
+ out = build_params(host=url)
407
+ assert out['driver'] == 'http', out['driver']
408
+ assert out['host'] == 's2host.com', out['host']
409
+ assert out['port'] == 3307, out['port']
410
+ assert out['database'] == 'mydb', out['database']
411
+ assert out['user'] == 'me', out['user']
412
+ assert out['password'] == 'p455w0rd', out['password']
413
+
414
+ # No port
415
+ url = 'me:p455w0rd@s2host.com/mydb'
416
+ out = build_params(host=url)
417
+ assert out['driver'] == get_option('driver'), out['driver']
418
+ assert out['host'] == 's2host.com', out['host']
419
+ if out['driver'] in ['http', 'https']:
420
+ assert out['port'] in [
421
+ get_option(
422
+ 'http_port',
423
+ ), 80, 443,
424
+ ], out['port']
425
+ else:
426
+ assert out['port'] in [get_option('port'), 3306], out['port']
427
+ assert out['database'] == 'mydb', out['database']
428
+ assert out['user'] == 'me', out['user']
429
+ assert out['password'] == 'p455w0rd', out['password']
430
+
431
+ # No http port
432
+ url = 'http://me:p455w0rd@s2host.com/mydb'
433
+ out = build_params(host=url)
434
+ assert out['driver'] == 'http', out['driver']
435
+ assert out['host'] == 's2host.com', out['host']
436
+ assert out['port'] in [get_option('http_port'), 80], out['port']
437
+ assert out['database'] == 'mydb', out['database']
438
+ assert out['user'] == 'me', out['user']
439
+ assert out['password'] == 'p455w0rd', out['password']
440
+
441
+ # No https port
442
+ url = 'https://me:p455w0rd@s2host.com/mydb'
443
+ out = build_params(host=url)
444
+ assert out['driver'] == 'https', out['driver']
445
+ assert out['host'] == 's2host.com', out['host']
446
+ assert out['port'] in [get_option('http_port'), 443], out['port']
447
+ assert out['database'] == 'mydb', out['database']
448
+ assert out['user'] == 'me', out['user']
449
+ assert out['password'] == 'p455w0rd', out['password']
450
+
451
+ # Invalid port
452
+ url = 'https://me:p455w0rd@s2host.com:foo/mydb'
453
+ with self.assertRaises(ValueError):
454
+ build_params(host=url)
455
+
456
+ # Empty password
457
+ url = 'me:@s2host.com/mydb'
458
+ out = build_params(host=url)
459
+ assert out['driver'] == get_option('driver'), out['driver']
460
+ assert out['host'] == 's2host.com', out['host']
461
+ if out['driver'] in ['http', 'https']:
462
+ assert out['port'] in [
463
+ get_option(
464
+ 'http_port',
465
+ ), 80, 443,
466
+ ], out['port']
467
+ else:
468
+ assert out['port'] in [get_option('port'), 3306], out['port']
469
+ assert out['database'] == 'mydb', out['database']
470
+ assert out['user'] == 'me', out['user']
471
+ assert out['password'] == '', out['password']
472
+
473
+ # No user/password
474
+ url = 's2host.com/mydb'
475
+ out = build_params(host=url)
476
+ assert out['driver'] == get_option('driver'), out['driver']
477
+ assert out['host'] == 's2host.com', out['host']
478
+ if out['driver'] in ['http', 'https']:
479
+ assert out['port'] in [
480
+ get_option(
481
+ 'http_port',
482
+ ), 80, 443,
483
+ ], out['port']
484
+ else:
485
+ assert out['port'] in [get_option('port'), 3306], out['port']
486
+ assert out['database'] == 'mydb', out['database']
487
+ assert 'user' not in out or out['user'] == get_option(
488
+ 'user',
489
+ ), out['user']
490
+ assert 'password' not in out or out['password'] == get_option(
491
+ 'password',
492
+ ), out['password']
493
+
494
+ # Just hostname
495
+ url = 's2host.com'
496
+ out = build_params(host=url)
497
+ assert out['driver'] == get_option('driver'), out['driver']
498
+ assert out['host'] == 's2host.com', out['host']
499
+ if out['driver'] in ['http', 'https']:
500
+ assert out['port'] in [
501
+ get_option(
502
+ 'http_port',
503
+ ), 80, 443,
504
+ ], out['port']
505
+ else:
506
+ assert out['port'] in [get_option('port'), 3306], out['port']
507
+ assert 'database' not in out
508
+ assert 'user' not in out or out['user'] == get_option(
509
+ 'user',
510
+ ), out['user']
511
+ assert 'password' not in out or out['password'] == get_option(
512
+ 'password',
513
+ ), out['password']
514
+
515
+ # Just hostname and port
516
+ url = 's2host.com:1000'
517
+ out = build_params(host=url)
518
+ assert out['driver'] == get_option('driver'), out['driver']
519
+ assert out['host'] == 's2host.com', out['host']
520
+ assert out['port'] == 1000, out['port']
521
+ assert 'database' not in out
522
+ assert 'user' not in out or out['user'] == get_option(
523
+ 'user',
524
+ ), out['user']
525
+ assert 'password' not in out or out['password'] == get_option(
526
+ 'password',
527
+ ), out['password']
528
+
529
+ # Query options
530
+ url = 's2host.com:1000?local_infile=1&charset=utf8'
531
+ out = build_params(host=url)
532
+ assert out['driver'] == get_option('driver'), out['driver']
533
+ assert out['host'] == 's2host.com', out['host']
534
+ assert out['port'] == 1000, out['port']
535
+ assert 'database' not in out
536
+ assert 'user' not in out or out['user'] == get_option(
537
+ 'user',
538
+ ), out['user']
539
+ assert 'password' not in out or out['password'] == get_option(
540
+ 'password',
541
+ ), out['password']
542
+ assert out['local_infile'] is True, out['local_infile']
543
+ assert out['charset'] == 'utf8', out['charset']
544
+
545
+ def test_exception(self):
546
+ with self.assertRaises(s2.ProgrammingError) as cm:
547
+ self.cur.execute('garbage syntax')
548
+ exc = cm.exception
549
+ assert 'You have an error in your SQL syntax' in exc.errmsg, exc.errmsg
550
+
551
+ def test_alltypes(self):
552
+ self.cur.execute('select * from alltypes where id = 0')
553
+ names = [x[0] for x in self.cur.description]
554
+ types = [x[1] for x in self.cur.description]
555
+ out = self.cur.fetchone()
556
+ row = dict(zip(names, out))
557
+ typ = dict(zip(names, types))
558
+
559
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
560
+
561
+ def otype(x):
562
+ return x
563
+
564
+ assert row['id'] == 0, row['id']
565
+ assert typ['id'] == otype(3), typ['id']
566
+
567
+ assert row['tinyint'] == 80, row['tinyint']
568
+ assert typ['tinyint'] == otype(1), typ['tinyint']
569
+
570
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
571
+ assert typ['unsigned_tinyint'] == otype(1), typ['unsigned_tinyint']
572
+
573
+ assert row['bool'] == 0, row['bool']
574
+ assert typ['bool'] == otype(1), typ['bool']
575
+
576
+ assert row['boolean'] == 1, row['boolean']
577
+ assert typ['boolean'] == otype(1), typ['boolean']
578
+
579
+ assert row['smallint'] == -27897, row['smallint']
580
+ assert typ['smallint'] == otype(2), typ['smallint']
581
+
582
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
583
+ assert typ['unsigned_smallint'] == otype(2), typ['unsigned_smallint']
584
+
585
+ assert row['mediumint'] == 104729, row['mediumint']
586
+ assert typ['mediumint'] == otype(9), typ['mediumint']
587
+
588
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
589
+ assert typ['unsigned_mediumint'] == otype(9), typ['unsigned_mediumint']
590
+
591
+ assert row['int24'] == -200899, row['int24']
592
+ assert typ['int24'] == otype(9), typ['int24']
593
+
594
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
595
+ assert typ['unsigned_int24'] == otype(9), typ['unsigned_int24']
596
+
597
+ assert row['int'] == -1295369311, row['int']
598
+ assert typ['int'] == otype(3), typ['int']
599
+
600
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
601
+ assert typ['unsigned_int'] == otype(3), typ['unsigned_int']
602
+
603
+ assert row['integer'] == -1741727421, row['integer']
604
+ assert typ['integer'] == otype(3), typ['integer']
605
+
606
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
607
+ assert typ['unsigned_integer'] == otype(3), typ['unsigned_integer']
608
+
609
+ assert row['bigint'] == -266883847, row['bigint']
610
+ assert typ['bigint'] == otype(8), typ['bigint']
611
+
612
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
613
+ assert typ['unsigned_bigint'] == otype(8), typ['unsigned_bigint']
614
+
615
+ assert row['float'] == -146487000.0, row['float']
616
+ assert typ['float'] == otype(4), typ['float']
617
+
618
+ assert row['double'] == -474646154.719356, row['double']
619
+ assert typ['double'] == otype(5), typ['double']
620
+
621
+ assert row['real'] == -901409776.279346, row['real']
622
+ assert typ['real'] == otype(5), typ['real']
623
+
624
+ assert row['decimal'] == decimal.Decimal(
625
+ '28111097.610822',
626
+ ), row['decimal']
627
+ assert typ['decimal'] == otype(246), typ['decimal']
628
+
629
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
630
+ assert typ['dec'] == otype(246), typ['dec']
631
+
632
+ assert row['fixed'] == decimal.Decimal(
633
+ '-143773416.044092',
634
+ ), row['fixed']
635
+ assert typ['fixed'] == otype(246), typ['fixed']
636
+
637
+ assert row['numeric'] == decimal.Decimal(
638
+ '866689461.300046',
639
+ ), row['numeric']
640
+ assert typ['numeric'] == otype(246), typ['numeric']
641
+
642
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
643
+ assert typ['date'] == 10, typ['date']
644
+
645
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
646
+ assert typ['time'] == 11, typ['time']
647
+
648
+ assert typ['time_6'] == 11, typ['time_6']
649
+
650
+ assert row['datetime'] == datetime.datetime(
651
+ 9948, 3, 11, 15, 29, 22,
652
+ ), row['datetime']
653
+ assert typ['datetime'] == 12, typ['datetime']
654
+
655
+ assert row['datetime_6'] == datetime.datetime(
656
+ 1756, 10, 29, 2, 2, 42, 8,
657
+ ), row['datetime_6']
658
+ assert typ['datetime_6'] == 12, typ['datetime_6']
659
+
660
+ assert row['timestamp'] == datetime.datetime(
661
+ 1980, 12, 31, 1, 10, 23,
662
+ ), row['timestamp']
663
+ assert typ['timestamp'] == otype(7), typ['timestamp']
664
+
665
+ assert row['timestamp_6'] == datetime.datetime(
666
+ 1991, 1, 2, 22, 15, 10, 6,
667
+ ), row['timestamp_6']
668
+ assert typ['timestamp_6'] == otype(7), typ['timestamp_6']
669
+
670
+ assert row['year'] == 1923, row['year']
671
+ assert typ['year'] == otype(13), typ['year']
672
+
673
+ assert row['char_100'] == \
674
+ 'This is a test of a 100 character column.', row['char_100']
675
+ assert typ['char_100'] == otype(254), typ['char_100']
676
+
677
+ assert row['binary_100'] == bytearray(
678
+ bits + [0] * 84,
679
+ ), row['binary_100']
680
+ assert typ['binary_100'] == otype(254), typ['binary_100']
681
+
682
+ assert row['varchar_200'] == \
683
+ 'This is a test of a variable character column.', row['varchar_200']
684
+ assert typ['varchar_200'] == otype(
685
+ 253,
686
+ ), typ['varchar_200'] # why not 15?
687
+
688
+ assert row['varbinary_200'] == bytearray(
689
+ bits * 2,
690
+ ), row['varbinary_200']
691
+ assert typ['varbinary_200'] == otype(
692
+ 253,
693
+ ), typ['varbinary_200'] # why not 15?
694
+
695
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
696
+ assert typ['longtext'] == otype(251), typ['longtext']
697
+
698
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
699
+ assert typ['mediumtext'] == otype(250), typ['mediumtext']
700
+
701
+ assert row['text'] == 'This is a text column.', row['text']
702
+ assert typ['text'] == otype(252), typ['text']
703
+
704
+ assert row['tinytext'] == 'This is a tinytext column.'
705
+ assert typ['tinytext'] == otype(249), typ['tinytext']
706
+
707
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
708
+ assert typ['longblob'] == otype(251), typ['longblob']
709
+
710
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
711
+ assert typ['mediumblob'] == otype(250), typ['mediumblob']
712
+
713
+ assert row['blob'] == bytearray(bits), row['blob']
714
+ assert typ['blob'] == otype(252), typ['blob']
715
+
716
+ assert row['tinyblob'] == bytearray(
717
+ [10, 11, 12, 13, 14, 15],
718
+ ), row['tinyblob']
719
+ assert typ['tinyblob'] == otype(249), typ['tinyblob']
720
+
721
+ assert row['json'] == {
722
+ 'a': 10, 'b': 2.75,
723
+ 'c': 'hello world',
724
+ }, row['json']
725
+ assert typ['json'] == otype(245), typ['json']
726
+
727
+ assert row['enum'] == 'one', row['enum']
728
+ assert typ['enum'] == otype(253), typ['enum'] # mysql code: 247
729
+
730
+ assert row['set'] == 'two', row['set']
731
+ assert typ['set'] == otype(253), typ['set'] # mysql code: 248
732
+
733
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
734
+ assert typ['bit'] == otype(16), typ['bit']
735
+
736
+ def test_alltypes_numpy(self):
737
+ conn = s2.connect(database=type(self).dbname, results_type='numpy')
738
+ cur = conn.cursor()
739
+
740
+ cur.execute('select * from alltypes where id = 0')
741
+ names = [x[0] for x in cur.description]
742
+ out = cur.fetchone()
743
+ row = dict(zip(names, out[0]))
744
+
745
+ dtypes = [
746
+ ('id', '<f8'),
747
+ ('tinyint', '<f4'),
748
+ ('unsigned_tinyint', '<f4'),
749
+ ('bool', '<f4'),
750
+ ('boolean', '<f4'),
751
+ ('smallint', '<f4'),
752
+ ('unsigned_smallint', '<f4'),
753
+ ('mediumint', '<f8'),
754
+ ('unsigned_mediumint', '<f8'),
755
+ ('int24', '<f8'),
756
+ ('unsigned_int24', '<f8'),
757
+ ('int', '<f8'),
758
+ ('unsigned_int', '<f8'),
759
+ ('integer', '<f8'),
760
+ ('unsigned_integer', '<f8'),
761
+ ('bigint', '<f8'),
762
+ ('unsigned_bigint', '<f8'),
763
+ ('float', '<f4'),
764
+ ('double', '<f8'),
765
+ ('real', '<f8'),
766
+ ('decimal', 'O'),
767
+ ('dec', 'O'),
768
+ ('fixed', 'O'),
769
+ ('numeric', 'O'),
770
+ ('date', '<M8[D]'),
771
+ ('time', '<m8[us]'),
772
+ ('time_6', '<m8[us]'),
773
+ ('datetime', '<M8[us]'),
774
+ ('datetime_6', '<M8[us]'),
775
+ ('timestamp', '<M8[us]'),
776
+ ('timestamp_6', '<M8[us]'),
777
+ ('year', '<f8'),
778
+ ('char_100', 'O'),
779
+ ('binary_100', 'O'),
780
+ ('varchar_200', 'O'),
781
+ ('varbinary_200', 'O'),
782
+ ('longtext', 'O'),
783
+ ('mediumtext', 'O'),
784
+ ('text', 'O'),
785
+ ('tinytext', 'O'),
786
+ ('longblob', 'O'),
787
+ ('mediumblob', 'O'),
788
+ ('blob', 'O'),
789
+ ('tinyblob', 'O'),
790
+ ('json', 'O'),
791
+ ('enum', 'O'),
792
+ ('set', 'O'),
793
+ ('bit', 'O'),
794
+ ]
795
+
796
+ assert out.dtype == dtypes
797
+
798
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
799
+
800
+ assert row['id'] == 0, row['id']
801
+ assert row['tinyint'] == 80, row['tinyint']
802
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
803
+ assert row['bool'] == 0, row['bool']
804
+ assert row['boolean'] == 1, row['boolean']
805
+ assert row['smallint'] == -27897, row['smallint']
806
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
807
+ assert row['mediumint'] == 104729, row['mediumint']
808
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
809
+ assert row['int24'] == -200899, row['int24']
810
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
811
+ assert row['int'] == -1295369311, row['int']
812
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
813
+ assert row['integer'] == -1741727421, row['integer']
814
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
815
+ assert row['bigint'] == -266883847, row['bigint']
816
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
817
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
818
+ assert row['double'] == -474646154.719356, row['double']
819
+ assert row['real'] == -901409776.279346, row['real']
820
+ assert row['decimal'] == decimal.Decimal(
821
+ '28111097.610822',
822
+ ), row['decimal']
823
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
824
+ assert row['fixed'] == decimal.Decimal(
825
+ '-143773416.044092',
826
+ ), row['fixed']
827
+ assert row['numeric'] == decimal.Decimal(
828
+ '866689461.300046',
829
+ ), row['numeric']
830
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
831
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
832
+ assert row['datetime'] == datetime.datetime(
833
+ 9948, 3, 11, 15, 29, 22,
834
+ ), row['datetime']
835
+ assert row['datetime_6'] == datetime.datetime(
836
+ 1756, 10, 29, 2, 2, 42, 8,
837
+ ), row['datetime_6']
838
+ assert row['timestamp'] == datetime.datetime(
839
+ 1980, 12, 31, 1, 10, 23,
840
+ ), row['timestamp']
841
+ assert row['timestamp_6'] == datetime.datetime(
842
+ 1991, 1, 2, 22, 15, 10, 6,
843
+ ), row['timestamp_6']
844
+ assert row['year'] == 1923, row['year']
845
+ assert row['char_100'] == \
846
+ 'This is a test of a 100 character column.', row['char_100']
847
+ assert row['binary_100'] == bytearray(
848
+ bits + [0] * 84,
849
+ ), row['binary_100']
850
+ assert row['varchar_200'] == \
851
+ 'This is a test of a variable character column.', row['varchar_200']
852
+ assert row['varbinary_200'] == bytearray(
853
+ bits * 2,
854
+ ), row['varbinary_200']
855
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
856
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
857
+ assert row['text'] == 'This is a text column.', row['text']
858
+ assert row['tinytext'] == 'This is a tinytext column.'
859
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
860
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
861
+ assert row['blob'] == bytearray(bits), row['blob']
862
+ assert row['tinyblob'] == bytearray(
863
+ [10, 11, 12, 13, 14, 15],
864
+ ), row['tinyblob']
865
+ assert row['json'] == {
866
+ 'a': 10, 'b': 2.75,
867
+ 'c': 'hello world',
868
+ }, row['json']
869
+ assert row['enum'] == 'one', row['enum']
870
+ assert row['set'] == 'two', row['set']
871
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
872
+
873
+ conn.close()
874
+
875
+ def test_alltypes_no_nulls_numpy(self):
876
+ if self.conn.driver in ['http', 'https']:
877
+ self.skipTest('Data API does not surface unsigned int information')
878
+
879
+ conn = s2.connect(database=type(self).dbname, results_type='numpy')
880
+ cur = conn.cursor()
881
+
882
+ cur.execute('select * from alltypes_no_nulls where id = 0')
883
+ names = [x[0] for x in cur.description]
884
+ out = cur.fetchone()
885
+ row = dict(zip(names, out[0]))
886
+
887
+ dtypes = [
888
+ ('id', '<i4'),
889
+ ('tinyint', 'i1'),
890
+ ('unsigned_tinyint', 'u1'),
891
+ ('bool', 'i1'),
892
+ ('boolean', 'i1'),
893
+ ('smallint', '<i2'),
894
+ ('unsigned_smallint', '<u2'),
895
+ ('mediumint', '<i4'),
896
+ ('unsigned_mediumint', '<u4'),
897
+ ('int24', '<i4'),
898
+ ('unsigned_int24', '<u4'),
899
+ ('int', '<i4'),
900
+ ('unsigned_int', '<u4'),
901
+ ('integer', '<i4'),
902
+ ('unsigned_integer', '<u4'),
903
+ ('bigint', '<i8'),
904
+ ('unsigned_bigint', '<u8'),
905
+ ('float', '<f4'),
906
+ ('double', '<f8'),
907
+ ('real', '<f8'),
908
+ ('decimal', 'O'),
909
+ ('dec', 'O'),
910
+ ('fixed', 'O'),
911
+ ('numeric', 'O'),
912
+ ('date', '<M8[D]'),
913
+ ('time', '<m8[us]'),
914
+ ('time_6', '<m8[us]'),
915
+ ('datetime', '<M8[us]'),
916
+ ('datetime_6', '<M8[us]'),
917
+ ('timestamp', '<M8[us]'),
918
+ ('timestamp_6', '<M8[us]'),
919
+ ('year', '<i2'),
920
+ ('char_100', 'O'),
921
+ ('binary_100', 'O'),
922
+ ('varchar_200', 'O'),
923
+ ('varbinary_200', 'O'),
924
+ ('longtext', 'O'),
925
+ ('mediumtext', 'O'),
926
+ ('text', 'O'),
927
+ ('tinytext', 'O'),
928
+ ('longblob', 'O'),
929
+ ('mediumblob', 'O'),
930
+ ('blob', 'O'),
931
+ ('tinyblob', 'O'),
932
+ ('json', 'O'),
933
+ ('enum', 'O'),
934
+ ('set', 'O'),
935
+ ('bit', 'O'),
936
+ ]
937
+
938
+ assert out.dtype == dtypes
939
+
940
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
941
+
942
+ assert row['id'] == 0, row['id']
943
+ assert row['tinyint'] == 80, row['tinyint']
944
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
945
+ assert row['bool'] == 0, row['bool']
946
+ assert row['boolean'] == 1, row['boolean']
947
+ assert row['smallint'] == -27897, row['smallint']
948
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
949
+ assert row['mediumint'] == 104729, row['mediumint']
950
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
951
+ assert row['int24'] == -200899, row['int24']
952
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
953
+ assert row['int'] == -1295369311, row['int']
954
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
955
+ assert row['integer'] == -1741727421, row['integer']
956
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
957
+ assert row['bigint'] == -266883847, row['bigint']
958
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
959
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
960
+ assert row['double'] == -474646154.719356, row['double']
961
+ assert row['real'] == -901409776.279346, row['real']
962
+ assert row['decimal'] == decimal.Decimal(
963
+ '28111097.610822',
964
+ ), row['decimal']
965
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
966
+ assert row['fixed'] == decimal.Decimal(
967
+ '-143773416.044092',
968
+ ), row['fixed']
969
+ assert row['numeric'] == decimal.Decimal(
970
+ '866689461.300046',
971
+ ), row['numeric']
972
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
973
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
974
+ assert row['datetime'] == datetime.datetime(
975
+ 9948, 3, 11, 15, 29, 22,
976
+ ), row['datetime']
977
+ assert row['datetime_6'] == datetime.datetime(
978
+ 1756, 10, 29, 2, 2, 42, 8,
979
+ ), row['datetime_6']
980
+ assert row['timestamp'] == datetime.datetime(
981
+ 1980, 12, 31, 1, 10, 23,
982
+ ), row['timestamp']
983
+ assert row['timestamp_6'] == datetime.datetime(
984
+ 1991, 1, 2, 22, 15, 10, 6,
985
+ ), row['timestamp_6']
986
+ assert row['year'] == 1923, row['year']
987
+ assert row['char_100'] == \
988
+ 'This is a test of a 100 character column.', row['char_100']
989
+ assert row['binary_100'] == bytearray(
990
+ bits + [0] * 84,
991
+ ), row['binary_100']
992
+ assert row['varchar_200'] == \
993
+ 'This is a test of a variable character column.', row['varchar_200']
994
+ assert row['varbinary_200'] == bytearray(
995
+ bits * 2,
996
+ ), row['varbinary_200']
997
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
998
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
999
+ assert row['text'] == 'This is a text column.', row['text']
1000
+ assert row['tinytext'] == 'This is a tinytext column.'
1001
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1002
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1003
+ assert row['blob'] == bytearray(bits), row['blob']
1004
+ assert row['tinyblob'] == bytearray(
1005
+ [10, 11, 12, 13, 14, 15],
1006
+ ), row['tinyblob']
1007
+ assert row['json'] == {
1008
+ 'a': 10, 'b': 2.75,
1009
+ 'c': 'hello world',
1010
+ }, row['json']
1011
+ assert row['enum'] == 'one', row['enum']
1012
+ assert row['set'] == 'two', row['set']
1013
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1014
+
1015
+ conn.close()
1016
+
1017
+ def test_alltypes_min_max_numpy(self):
1018
+ if self.conn.driver in ['http', 'https']:
1019
+ self.skipTest('Data API does not surface unsigned int information')
1020
+
1021
+ conn = s2.connect(database=type(self).dbname, results_type='numpy')
1022
+ cur = conn.cursor()
1023
+
1024
+ cur.execute('select * from alltypes_no_nulls')
1025
+ cur.fetchall()
1026
+
1027
+ cur.execute('select * from alltypes')
1028
+ cur.fetchall()
1029
+
1030
+ conn.close()
1031
+
1032
+ def test_alltypes_nulls_numpy(self):
1033
+ conn = s2.connect(database=type(self).dbname, results_type='numpy')
1034
+ cur = conn.cursor()
1035
+
1036
+ cur.execute('select * from alltypes where id = 1')
1037
+ names = [x[0] for x in cur.description]
1038
+ out = cur.fetchone()
1039
+ row = dict(zip(names, out[0]))
1040
+
1041
+ assert row['id'] == 1, row['id']
1042
+ assert np.isnan(row['tinyint']), row['tinyint']
1043
+ assert np.isnan(row['bool']), row['bool']
1044
+ assert np.isnan(row['boolean']), row['boolean']
1045
+ assert np.isnan(row['smallint']), row['smallint']
1046
+ assert np.isnan(row['mediumint']), row['mediumint']
1047
+ assert np.isnan(row['int24']), row['int24']
1048
+ assert np.isnan(row['int']), row['int']
1049
+ assert np.isnan(row['integer']), row['integer']
1050
+ assert np.isnan(row['bigint']), row['bigint']
1051
+ assert np.isnan(row['float']), row['float']
1052
+ assert np.isnan(row['double']), row['double']
1053
+ assert np.isnan(row['real']), row['real']
1054
+ assert row['decimal'] is None, row['decimal']
1055
+ assert row['dec'] is None, row['dec']
1056
+ assert row['fixed'] is None, row['fixed']
1057
+ assert row['numeric'] is None, row['numeric']
1058
+ assert np.isnat(row['date']), row['date']
1059
+ assert np.isnat(row['time']), row['time']
1060
+ assert np.isnat(row['time']), row['time']
1061
+ assert np.isnat(row['datetime']), row['datetime']
1062
+ assert np.isnat(row['datetime_6']), row['datetime_6']
1063
+ assert np.isnat(row['timestamp']), row['timestamp']
1064
+ assert np.isnat(row['timestamp_6']), row['timestamp_6']
1065
+ assert np.isnan(row['year']), row['year']
1066
+ assert row['char_100'] is None, row['char_100']
1067
+ assert row['binary_100'] is None, row['binary_100']
1068
+ assert row['varchar_200'] is None, row['varchar_200']
1069
+ assert row['varbinary_200'] is None, row['varbinary_200']
1070
+ assert row['longtext'] is None, row['longtext']
1071
+ assert row['mediumtext'] is None, row['mediumtext']
1072
+ assert row['text'] is None, row['text']
1073
+ assert row['tinytext'] is None, row['tinytext']
1074
+ assert row['longblob'] is None, row['longblob']
1075
+ assert row['mediumblob'] is None, row['mediumblob']
1076
+ assert row['blob'] is None, row['blob']
1077
+ assert row['tinyblob'] is None, row['tinyblob']
1078
+ assert row['json'] is None, row['json']
1079
+ assert row['enum'] is None, row['enum']
1080
+ assert row['set'] is None, row['set']
1081
+ assert row['bit'] is None, row['bit']
1082
+
1083
+ conn.close()
1084
+
1085
+ def test_alltypes_pandas(self):
1086
+ conn = s2.connect(database=type(self).dbname, results_type='pandas')
1087
+ cur = conn.cursor()
1088
+
1089
+ cur.execute('select * from alltypes where id = 0')
1090
+ names = [x[0] for x in cur.description]
1091
+ out = cur.fetchone()
1092
+ row = dict(zip(names, out.iloc[0]))
1093
+
1094
+ dtypes = [
1095
+ ('id', 'float64'),
1096
+ ('tinyint', 'float32'),
1097
+ ('unsigned_tinyint', 'float32'),
1098
+ ('bool', 'float32'),
1099
+ ('boolean', 'float32'),
1100
+ ('smallint', 'float32'),
1101
+ ('unsigned_smallint', 'float32'),
1102
+ ('mediumint', 'float64'),
1103
+ ('unsigned_mediumint', 'float64'),
1104
+ ('int24', 'float64'),
1105
+ ('unsigned_int24', 'float64'),
1106
+ ('int', 'float64'),
1107
+ ('unsigned_int', 'float64'),
1108
+ ('integer', 'float64'),
1109
+ ('unsigned_integer', 'float64'),
1110
+ ('bigint', 'float64'),
1111
+ ('unsigned_bigint', 'float64'),
1112
+ ('float', 'float32'),
1113
+ ('double', 'float64'),
1114
+ ('real', 'float64'),
1115
+ ('decimal', 'object'),
1116
+ ('dec', 'object'),
1117
+ ('fixed', 'object'),
1118
+ ('numeric', 'object'),
1119
+ ('date', 'datetime64[s]'),
1120
+ ('time', 'timedelta64[us]'),
1121
+ ('time_6', 'timedelta64[us]'),
1122
+ ('datetime', 'datetime64[us]'),
1123
+ ('datetime_6', 'datetime64[us]'),
1124
+ ('timestamp', 'datetime64[us]'),
1125
+ ('timestamp_6', 'datetime64[us]'),
1126
+ ('year', 'float64'),
1127
+ ('char_100', 'object'),
1128
+ ('binary_100', 'object'),
1129
+ ('varchar_200', 'object'),
1130
+ ('varbinary_200', 'object'),
1131
+ ('longtext', 'object'),
1132
+ ('mediumtext', 'object'),
1133
+ ('text', 'object'),
1134
+ ('tinytext', 'object'),
1135
+ ('longblob', 'object'),
1136
+ ('mediumblob', 'object'),
1137
+ ('blob', 'object'),
1138
+ ('tinyblob', 'object'),
1139
+ ('json', 'object'),
1140
+ ('enum', 'object'),
1141
+ ('set', 'object'),
1142
+ ('bit', 'object'),
1143
+ ]
1144
+
1145
+ assert [(x[0], str(x[1])) for x in out.dtypes.items()] == dtypes
1146
+
1147
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1148
+
1149
+ assert row['id'] == 0, row['id']
1150
+ assert row['tinyint'] == 80, row['tinyint']
1151
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
1152
+ assert row['bool'] == 0, row['bool']
1153
+ assert row['boolean'] == 1, row['boolean']
1154
+ assert row['smallint'] == -27897, row['smallint']
1155
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
1156
+ assert row['mediumint'] == 104729, row['mediumint']
1157
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
1158
+ assert row['int24'] == -200899, row['int24']
1159
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
1160
+ assert row['int'] == -1295369311, row['int']
1161
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
1162
+ assert row['integer'] == -1741727421, row['integer']
1163
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
1164
+ assert row['bigint'] == -266883847, row['bigint']
1165
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
1166
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
1167
+ assert row['double'] == -474646154.719356, row['double']
1168
+ assert row['real'] == -901409776.279346, row['real']
1169
+ assert row['decimal'] == decimal.Decimal(
1170
+ '28111097.610822',
1171
+ ), row['decimal']
1172
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
1173
+ assert row['fixed'] == decimal.Decimal(
1174
+ '-143773416.044092',
1175
+ ), row['fixed']
1176
+ assert row['numeric'] == decimal.Decimal(
1177
+ '866689461.300046',
1178
+ ), row['numeric']
1179
+ assert row['date'] == datetime.datetime(8524, 11, 10), row['date']
1180
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
1181
+ assert row['datetime'] == datetime.datetime(
1182
+ 9948, 3, 11, 15, 29, 22,
1183
+ ), row['datetime']
1184
+ assert row['datetime_6'] == datetime.datetime(
1185
+ 1756, 10, 29, 2, 2, 42, 8,
1186
+ ), row['datetime_6']
1187
+ assert row['timestamp'] == datetime.datetime(
1188
+ 1980, 12, 31, 1, 10, 23,
1189
+ ), row['timestamp']
1190
+ assert row['timestamp_6'] == datetime.datetime(
1191
+ 1991, 1, 2, 22, 15, 10, 6,
1192
+ ), row['timestamp_6']
1193
+ assert row['year'] == 1923, row['year']
1194
+ assert row['char_100'] == \
1195
+ 'This is a test of a 100 character column.', row['char_100']
1196
+ assert row['binary_100'] == bytearray(
1197
+ bits + [0] * 84,
1198
+ ), row['binary_100']
1199
+ assert row['varchar_200'] == \
1200
+ 'This is a test of a variable character column.', row['varchar_200']
1201
+ assert row['varbinary_200'] == bytearray(
1202
+ bits * 2,
1203
+ ), row['varbinary_200']
1204
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
1205
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
1206
+ assert row['text'] == 'This is a text column.', row['text']
1207
+ assert row['tinytext'] == 'This is a tinytext column.'
1208
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1209
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1210
+ assert row['blob'] == bytearray(bits), row['blob']
1211
+ assert row['tinyblob'] == bytearray(
1212
+ [10, 11, 12, 13, 14, 15],
1213
+ ), row['tinyblob']
1214
+ assert row['json'] == {
1215
+ 'a': 10, 'b': 2.75,
1216
+ 'c': 'hello world',
1217
+ }, row['json']
1218
+ assert row['enum'] == 'one', row['enum']
1219
+ assert row['set'] == 'two', row['set']
1220
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1221
+
1222
+ conn.close()
1223
+
1224
+ def test_alltypes_no_nulls_pandas(self):
1225
+ if self.conn.driver in ['http', 'https']:
1226
+ self.skipTest('Data API does not surface unsigned int information')
1227
+
1228
+ conn = s2.connect(database=type(self).dbname, results_type='pandas')
1229
+ cur = conn.cursor()
1230
+
1231
+ cur.execute('select * from alltypes_no_nulls where id = 0')
1232
+ names = [x[0] for x in cur.description]
1233
+ out = cur.fetchone()
1234
+ row = dict(zip(names, out.iloc[0]))
1235
+
1236
+ dtypes = [
1237
+ ('id', 'int32'),
1238
+ ('tinyint', 'int8'),
1239
+ ('unsigned_tinyint', 'uint8'),
1240
+ ('bool', 'int8'),
1241
+ ('boolean', 'int8'),
1242
+ ('smallint', 'int16'),
1243
+ ('unsigned_smallint', 'uint16'),
1244
+ ('mediumint', 'int32'),
1245
+ ('unsigned_mediumint', 'uint32'),
1246
+ ('int24', 'int32'),
1247
+ ('unsigned_int24', 'uint32'),
1248
+ ('int', 'int32'),
1249
+ ('unsigned_int', 'uint32'),
1250
+ ('integer', 'int32'),
1251
+ ('unsigned_integer', 'uint32'),
1252
+ ('bigint', 'int64'),
1253
+ ('unsigned_bigint', 'uint64'),
1254
+ ('float', 'float32'),
1255
+ ('double', 'float64'),
1256
+ ('real', 'float64'),
1257
+ ('decimal', 'object'),
1258
+ ('dec', 'object'),
1259
+ ('fixed', 'object'),
1260
+ ('numeric', 'object'),
1261
+ ('date', 'datetime64[s]'),
1262
+ ('time', 'timedelta64[us]'),
1263
+ ('time_6', 'timedelta64[us]'),
1264
+ ('datetime', 'datetime64[us]'),
1265
+ ('datetime_6', 'datetime64[us]'),
1266
+ ('timestamp', 'datetime64[us]'),
1267
+ ('timestamp_6', 'datetime64[us]'),
1268
+ ('year', 'int16'),
1269
+ ('char_100', 'object'),
1270
+ ('binary_100', 'object'),
1271
+ ('varchar_200', 'object'),
1272
+ ('varbinary_200', 'object'),
1273
+ ('longtext', 'object'),
1274
+ ('mediumtext', 'object'),
1275
+ ('text', 'object'),
1276
+ ('tinytext', 'object'),
1277
+ ('longblob', 'object'),
1278
+ ('mediumblob', 'object'),
1279
+ ('blob', 'object'),
1280
+ ('tinyblob', 'object'),
1281
+ ('json', 'object'),
1282
+ ('enum', 'object'),
1283
+ ('set', 'object'),
1284
+ ('bit', 'object'),
1285
+ ]
1286
+
1287
+ assert [(x[0], str(x[1])) for x in out.dtypes.items()] == dtypes
1288
+
1289
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1290
+
1291
+ assert row['id'] == 0, row['id']
1292
+ assert row['tinyint'] == 80, row['tinyint']
1293
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
1294
+ assert row['bool'] == 0, row['bool']
1295
+ assert row['boolean'] == 1, row['boolean']
1296
+ assert row['smallint'] == -27897, row['smallint']
1297
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
1298
+ assert row['mediumint'] == 104729, row['mediumint']
1299
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
1300
+ assert row['int24'] == -200899, row['int24']
1301
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
1302
+ assert row['int'] == -1295369311, row['int']
1303
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
1304
+ assert row['integer'] == -1741727421, row['integer']
1305
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
1306
+ assert row['bigint'] == -266883847, row['bigint']
1307
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
1308
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
1309
+ assert row['double'] == -474646154.719356, row['double']
1310
+ assert row['real'] == -901409776.279346, row['real']
1311
+ assert row['decimal'] == decimal.Decimal(
1312
+ '28111097.610822',
1313
+ ), row['decimal']
1314
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
1315
+ assert row['fixed'] == decimal.Decimal(
1316
+ '-143773416.044092',
1317
+ ), row['fixed']
1318
+ assert row['numeric'] == decimal.Decimal(
1319
+ '866689461.300046',
1320
+ ), row['numeric']
1321
+ assert row['date'] == datetime.datetime(8524, 11, 10), row['date']
1322
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
1323
+ assert row['datetime'] == datetime.datetime(
1324
+ 9948, 3, 11, 15, 29, 22,
1325
+ ), row['datetime']
1326
+ assert row['datetime_6'] == datetime.datetime(
1327
+ 1756, 10, 29, 2, 2, 42, 8,
1328
+ ), row['datetime_6']
1329
+ assert row['timestamp'] == datetime.datetime(
1330
+ 1980, 12, 31, 1, 10, 23,
1331
+ ), row['timestamp']
1332
+ assert row['timestamp_6'] == datetime.datetime(
1333
+ 1991, 1, 2, 22, 15, 10, 6,
1334
+ ), row['timestamp_6']
1335
+ assert row['year'] == 1923, row['year']
1336
+ assert row['char_100'] == \
1337
+ 'This is a test of a 100 character column.', row['char_100']
1338
+ assert row['binary_100'] == bytearray(
1339
+ bits + [0] * 84,
1340
+ ), row['binary_100']
1341
+ assert row['varchar_200'] == \
1342
+ 'This is a test of a variable character column.', row['varchar_200']
1343
+ assert row['varbinary_200'] == bytearray(
1344
+ bits * 2,
1345
+ ), row['varbinary_200']
1346
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
1347
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
1348
+ assert row['text'] == 'This is a text column.', row['text']
1349
+ assert row['tinytext'] == 'This is a tinytext column.'
1350
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1351
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1352
+ assert row['blob'] == bytearray(bits), row['blob']
1353
+ assert row['tinyblob'] == bytearray(
1354
+ [10, 11, 12, 13, 14, 15],
1355
+ ), row['tinyblob']
1356
+ assert row['json'] == {
1357
+ 'a': 10, 'b': 2.75,
1358
+ 'c': 'hello world',
1359
+ }, row['json']
1360
+ assert row['enum'] == 'one', row['enum']
1361
+ assert row['set'] == 'two', row['set']
1362
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1363
+
1364
+ conn.close()
1365
+
1366
+ def test_alltypes_min_max_pandas(self):
1367
+ if self.conn.driver in ['http', 'https']:
1368
+ self.skipTest('Data API does not surface unsigned int information')
1369
+
1370
+ conn = s2.connect(database=type(self).dbname, results_type='pandas')
1371
+ cur = conn.cursor()
1372
+
1373
+ cur.execute('select * from alltypes_no_nulls')
1374
+ cur.fetchall()
1375
+
1376
+ cur.execute('select * from alltypes')
1377
+ cur.fetchall()
1378
+
1379
+ conn.close()
1380
+
1381
+ def test_alltypes_nulls_pandas(self):
1382
+ conn = s2.connect(database=type(self).dbname, results_type='pandas')
1383
+ cur = conn.cursor()
1384
+
1385
+ cur.execute('select * from alltypes where id = 1')
1386
+ names = [x[0] for x in cur.description]
1387
+ out = cur.fetchone()
1388
+ row = dict(zip(names, out.iloc[0]))
1389
+
1390
+ assert row['id'] == 1, row['id']
1391
+ assert np.isnan(row['tinyint']), row['tinyint']
1392
+ assert np.isnan(row['bool']), row['bool']
1393
+ assert np.isnan(row['boolean']), row['boolean']
1394
+ assert np.isnan(row['smallint']), row['smallint']
1395
+ assert np.isnan(row['mediumint']), row['mediumint']
1396
+ assert np.isnan(row['int24']), row['int24']
1397
+ assert np.isnan(row['int']), row['int']
1398
+ assert np.isnan(row['integer']), row['integer']
1399
+ assert np.isnan(row['bigint']), row['bigint']
1400
+ assert np.isnan(row['float']), row['float']
1401
+ assert np.isnan(row['double']), row['double']
1402
+ assert np.isnan(row['real']), row['real']
1403
+ assert row['decimal'] is None, row['decimal']
1404
+ assert row['dec'] is None, row['dec']
1405
+ assert row['fixed'] is None, row['fixed']
1406
+ assert row['numeric'] is None, row['numeric']
1407
+ assert row['date'] is pd.NaT, row['date']
1408
+ assert row['time'] is pd.NaT, row['time']
1409
+ assert row['time'] is pd.NaT, row['time']
1410
+ assert row['datetime'] is pd.NaT, row['datetime']
1411
+ assert row['datetime_6'] is pd.NaT, row['datetime_6']
1412
+ assert row['timestamp'] is pd.NaT, row['timestamp']
1413
+ assert row['timestamp_6'] is pd.NaT, row['timestamp_6']
1414
+ assert np.isnan(row['year']), row['year']
1415
+ assert row['char_100'] is None, row['char_100']
1416
+ assert row['binary_100'] is None, row['binary_100']
1417
+ assert row['varchar_200'] is None, row['varchar_200']
1418
+ assert row['varbinary_200'] is None, row['varbinary_200']
1419
+ assert row['longtext'] is None, row['longtext']
1420
+ assert row['mediumtext'] is None, row['mediumtext']
1421
+ assert row['text'] is None, row['text']
1422
+ assert row['tinytext'] is None, row['tinytext']
1423
+ assert row['longblob'] is None, row['longblob']
1424
+ assert row['mediumblob'] is None, row['mediumblob']
1425
+ assert row['blob'] is None, row['blob']
1426
+ assert row['tinyblob'] is None, row['tinyblob']
1427
+ assert row['json'] is None, row['json']
1428
+ assert row['enum'] is None, row['enum']
1429
+ assert row['set'] is None, row['set']
1430
+ assert row['bit'] is None, row['bit']
1431
+
1432
+ conn.close()
1433
+
1434
+ def test_alltypes_polars(self):
1435
+ if self.conn.driver in ['http', 'https']:
1436
+ self.skipTest('Data API does not surface unsigned int information')
1437
+
1438
+ conn = s2.connect(database=type(self).dbname, results_type='polars')
1439
+ cur = conn.cursor()
1440
+
1441
+ cur.execute('select * from alltypes where id = 0')
1442
+ names = [x[0] for x in cur.description]
1443
+ out = cur.fetchone()
1444
+ row = dict(zip(names, out.row(0)))
1445
+
1446
+ # Recent versions of polars have a problem with decimals
1447
+ class FixCompare(str):
1448
+ def __eq__(self, other):
1449
+ return super().__eq__(other.replace('precision=None', 'precision=20'))
1450
+
1451
+ dtypes = [
1452
+ ('id', 'Int32'),
1453
+ ('tinyint', 'Int8'),
1454
+ ('unsigned_tinyint', 'UInt8'),
1455
+ ('bool', 'Int8'),
1456
+ ('boolean', 'Int8'),
1457
+ ('smallint', 'Int16'),
1458
+ ('unsigned_smallint', 'UInt16'),
1459
+ ('mediumint', 'Int32'),
1460
+ ('unsigned_mediumint', 'UInt32'),
1461
+ ('int24', 'Int32'),
1462
+ ('unsigned_int24', 'UInt32'),
1463
+ ('int', 'Int32'),
1464
+ ('unsigned_int', 'UInt32'),
1465
+ ('integer', 'Int32'),
1466
+ ('unsigned_integer', 'UInt32'),
1467
+ ('bigint', 'Int64'),
1468
+ ('unsigned_bigint', 'UInt64'),
1469
+ ('float', 'Float32'),
1470
+ ('double', 'Float64'),
1471
+ ('real', 'Float64'),
1472
+ ('decimal', FixCompare('Decimal(precision=20, scale=6)')),
1473
+ ('dec', FixCompare('Decimal(precision=20, scale=6)')),
1474
+ ('fixed', FixCompare('Decimal(precision=20, scale=6)')),
1475
+ ('numeric', FixCompare('Decimal(precision=20, scale=6)')),
1476
+ ('date', 'Date'),
1477
+ ('time', "Duration(time_unit='us')"),
1478
+ ('time_6', "Duration(time_unit='us')"),
1479
+ ('datetime', "Datetime(time_unit='us', time_zone=None)"),
1480
+ ('datetime_6', "Datetime(time_unit='us', time_zone=None)"),
1481
+ ('timestamp', "Datetime(time_unit='us', time_zone=None)"),
1482
+ ('timestamp_6', "Datetime(time_unit='us', time_zone=None)"),
1483
+ ('year', 'Int16'),
1484
+ ('char_100', 'String'),
1485
+ ('binary_100', 'Binary'),
1486
+ ('varchar_200', 'String'),
1487
+ ('varbinary_200', 'Binary'),
1488
+ ('longtext', 'String'),
1489
+ ('mediumtext', 'String'),
1490
+ ('text', 'String'),
1491
+ ('tinytext', 'String'),
1492
+ ('longblob', 'Binary'),
1493
+ ('mediumblob', 'Binary'),
1494
+ ('blob', 'Binary'),
1495
+ ('tinyblob', 'Binary'),
1496
+ ('json', 'Object'),
1497
+ ('enum', 'String'),
1498
+ ('set', 'String'),
1499
+ ('bit', 'Binary'),
1500
+ ]
1501
+
1502
+ assert [(x, str(y)) for x, y in zip(out.columns, out.dtypes)] == dtypes
1503
+
1504
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1505
+
1506
+ assert row['id'] == 0, row['id']
1507
+ assert row['tinyint'] == 80, row['tinyint']
1508
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
1509
+ assert row['bool'] == 0, row['bool']
1510
+ assert row['boolean'] == 1, row['boolean']
1511
+ assert row['smallint'] == -27897, row['smallint']
1512
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
1513
+ assert row['mediumint'] == 104729, row['mediumint']
1514
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
1515
+ assert row['int24'] == -200899, row['int24']
1516
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
1517
+ assert row['int'] == -1295369311, row['int']
1518
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
1519
+ assert row['integer'] == -1741727421, row['integer']
1520
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
1521
+ assert row['bigint'] == -266883847, row['bigint']
1522
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
1523
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
1524
+ assert row['double'] == -474646154.719356, row['double']
1525
+ assert row['real'] == -901409776.279346, row['real']
1526
+ assert row['decimal'] == decimal.Decimal(
1527
+ '28111097.610822',
1528
+ ), row['decimal']
1529
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
1530
+ assert row['fixed'] == decimal.Decimal(
1531
+ '-143773416.044092',
1532
+ ), row['fixed']
1533
+ assert row['numeric'] == decimal.Decimal(
1534
+ '866689461.300046',
1535
+ ), row['numeric']
1536
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
1537
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
1538
+ assert row['datetime'] == datetime.datetime(
1539
+ 9948, 3, 11, 15, 29, 22,
1540
+ ), row['datetime']
1541
+ assert row['datetime_6'] == datetime.datetime(
1542
+ 1756, 10, 29, 2, 2, 42, 8,
1543
+ ), row['datetime_6']
1544
+ assert row['timestamp'] == datetime.datetime(
1545
+ 1980, 12, 31, 1, 10, 23,
1546
+ ), row['timestamp']
1547
+ assert row['timestamp_6'] == datetime.datetime(
1548
+ 1991, 1, 2, 22, 15, 10, 6,
1549
+ ), row['timestamp_6']
1550
+ assert row['year'] == 1923, row['year']
1551
+ assert row['char_100'] == \
1552
+ 'This is a test of a 100 character column.', row['char_100']
1553
+ assert row['binary_100'] == bytearray(
1554
+ bits + [0] * 84,
1555
+ ), row['binary_100']
1556
+ assert row['varchar_200'] == \
1557
+ 'This is a test of a variable character column.', row['varchar_200']
1558
+ assert row['varbinary_200'] == bytearray(
1559
+ bits * 2,
1560
+ ), row['varbinary_200']
1561
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
1562
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
1563
+ assert row['text'] == 'This is a text column.', row['text']
1564
+ assert row['tinytext'] == 'This is a tinytext column.'
1565
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1566
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1567
+ assert row['blob'] == bytearray(bits), row['blob']
1568
+ assert row['tinyblob'] == bytearray(
1569
+ [10, 11, 12, 13, 14, 15],
1570
+ ), row['tinyblob']
1571
+ assert row['json'] == {
1572
+ 'a': 10, 'b': 2.75,
1573
+ 'c': 'hello world',
1574
+ }, row['json']
1575
+ assert row['enum'] == 'one', row['enum']
1576
+ assert row['set'] == 'two', row['set']
1577
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1578
+
1579
+ conn.close()
1580
+
1581
+ def test_alltypes_no_nulls_polars(self):
1582
+ if self.conn.driver in ['http', 'https']:
1583
+ self.skipTest('Data API does not surface unsigned int information')
1584
+
1585
+ conn = s2.connect(database=type(self).dbname, results_type='polars')
1586
+ cur = conn.cursor()
1587
+
1588
+ cur.execute('select * from alltypes_no_nulls where id = 0')
1589
+ names = [x[0] for x in cur.description]
1590
+ out = cur.fetchone()
1591
+ row = dict(zip(names, out.row(0)))
1592
+
1593
+ # Recent versions of polars have a problem with decimals
1594
+ class FixCompare(str):
1595
+ def __eq__(self, other):
1596
+ return super().__eq__(other.replace('precision=None', 'precision=20'))
1597
+
1598
+ dtypes = [
1599
+ ('id', 'Int32'),
1600
+ ('tinyint', 'Int8'),
1601
+ ('unsigned_tinyint', 'UInt8'),
1602
+ ('bool', 'Int8'),
1603
+ ('boolean', 'Int8'),
1604
+ ('smallint', 'Int16'),
1605
+ ('unsigned_smallint', 'UInt16'),
1606
+ ('mediumint', 'Int32'),
1607
+ ('unsigned_mediumint', 'UInt32'),
1608
+ ('int24', 'Int32'),
1609
+ ('unsigned_int24', 'UInt32'),
1610
+ ('int', 'Int32'),
1611
+ ('unsigned_int', 'UInt32'),
1612
+ ('integer', 'Int32'),
1613
+ ('unsigned_integer', 'UInt32'),
1614
+ ('bigint', 'Int64'),
1615
+ ('unsigned_bigint', 'UInt64'),
1616
+ ('float', 'Float32'),
1617
+ ('double', 'Float64'),
1618
+ ('real', 'Float64'),
1619
+ ('decimal', FixCompare('Decimal(precision=20, scale=6)')),
1620
+ ('dec', FixCompare('Decimal(precision=20, scale=6)')),
1621
+ ('fixed', FixCompare('Decimal(precision=20, scale=6)')),
1622
+ ('numeric', FixCompare('Decimal(precision=20, scale=6)')),
1623
+ ('date', 'Date'),
1624
+ ('time', "Duration(time_unit='us')"),
1625
+ ('time_6', "Duration(time_unit='us')"),
1626
+ ('datetime', "Datetime(time_unit='us', time_zone=None)"),
1627
+ ('datetime_6', "Datetime(time_unit='us', time_zone=None)"),
1628
+ ('timestamp', "Datetime(time_unit='us', time_zone=None)"),
1629
+ ('timestamp_6', "Datetime(time_unit='us', time_zone=None)"),
1630
+ ('year', 'Int16'),
1631
+ ('char_100', 'String'),
1632
+ ('binary_100', 'Binary'),
1633
+ ('varchar_200', 'String'),
1634
+ ('varbinary_200', 'Binary'),
1635
+ ('longtext', 'String'),
1636
+ ('mediumtext', 'String'),
1637
+ ('text', 'String'),
1638
+ ('tinytext', 'String'),
1639
+ ('longblob', 'Binary'),
1640
+ ('mediumblob', 'Binary'),
1641
+ ('blob', 'Binary'),
1642
+ ('tinyblob', 'Binary'),
1643
+ ('json', 'Object'),
1644
+ ('enum', 'String'),
1645
+ ('set', 'String'),
1646
+ ('bit', 'Binary'),
1647
+ ]
1648
+
1649
+ assert [(x, str(y)) for x, y in zip(out.columns, out.dtypes)] == dtypes
1650
+
1651
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1652
+
1653
+ assert row['id'] == 0, row['id']
1654
+ assert row['tinyint'] == 80, row['tinyint']
1655
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
1656
+ assert row['bool'] == 0, row['bool']
1657
+ assert row['boolean'] == 1, row['boolean']
1658
+ assert row['smallint'] == -27897, row['smallint']
1659
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
1660
+ assert row['mediumint'] == 104729, row['mediumint']
1661
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
1662
+ assert row['int24'] == -200899, row['int24']
1663
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
1664
+ assert row['int'] == -1295369311, row['int']
1665
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
1666
+ assert row['integer'] == -1741727421, row['integer']
1667
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
1668
+ assert row['bigint'] == -266883847, row['bigint']
1669
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
1670
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
1671
+ assert row['double'] == -474646154.719356, row['double']
1672
+ assert row['real'] == -901409776.279346, row['real']
1673
+ assert row['decimal'] == decimal.Decimal(
1674
+ '28111097.610822',
1675
+ ), row['decimal']
1676
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
1677
+ assert row['fixed'] == decimal.Decimal(
1678
+ '-143773416.044092',
1679
+ ), row['fixed']
1680
+ assert row['numeric'] == decimal.Decimal(
1681
+ '866689461.300046',
1682
+ ), row['numeric']
1683
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
1684
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
1685
+ assert row['datetime'] == datetime.datetime(
1686
+ 9948, 3, 11, 15, 29, 22,
1687
+ ), row['datetime']
1688
+ assert row['datetime_6'] == datetime.datetime(
1689
+ 1756, 10, 29, 2, 2, 42, 8,
1690
+ ), row['datetime_6']
1691
+ assert row['timestamp'] == datetime.datetime(
1692
+ 1980, 12, 31, 1, 10, 23,
1693
+ ), row['timestamp']
1694
+ assert row['timestamp_6'] == datetime.datetime(
1695
+ 1991, 1, 2, 22, 15, 10, 6,
1696
+ ), row['timestamp_6']
1697
+ assert row['year'] == 1923, row['year']
1698
+ assert row['char_100'] == \
1699
+ 'This is a test of a 100 character column.', row['char_100']
1700
+ assert row['binary_100'] == bytearray(
1701
+ bits + [0] * 84,
1702
+ ), row['binary_100']
1703
+ assert row['varchar_200'] == \
1704
+ 'This is a test of a variable character column.', row['varchar_200']
1705
+ assert row['varbinary_200'] == bytearray(
1706
+ bits * 2,
1707
+ ), row['varbinary_200']
1708
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
1709
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
1710
+ assert row['text'] == 'This is a text column.', row['text']
1711
+ assert row['tinytext'] == 'This is a tinytext column.'
1712
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1713
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1714
+ assert row['blob'] == bytearray(bits), row['blob']
1715
+ assert row['tinyblob'] == bytearray(
1716
+ [10, 11, 12, 13, 14, 15],
1717
+ ), row['tinyblob']
1718
+ assert row['json'] == {
1719
+ 'a': 10, 'b': 2.75,
1720
+ 'c': 'hello world',
1721
+ }, row['json']
1722
+ assert row['enum'] == 'one', row['enum']
1723
+ assert row['set'] == 'two', row['set']
1724
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1725
+
1726
+ conn.close()
1727
+
1728
+ def test_alltypes_min_max_polars(self):
1729
+ if self.conn.driver in ['http', 'https']:
1730
+ self.skipTest('Data API does not surface unsigned int information')
1731
+
1732
+ conn = s2.connect(database=type(self).dbname, results_type='polars')
1733
+ cur = conn.cursor()
1734
+
1735
+ cur.execute('select * from alltypes_no_nulls')
1736
+ cur.fetchall()
1737
+
1738
+ cur.execute('select * from alltypes')
1739
+ cur.fetchall()
1740
+
1741
+ conn.close()
1742
+
1743
+ def test_alltypes_nulls_polars(self):
1744
+ conn = s2.connect(database=type(self).dbname, results_type='polars')
1745
+ cur = conn.cursor()
1746
+
1747
+ cur.execute('select * from alltypes where id = 1')
1748
+ names = [x[0] for x in cur.description]
1749
+ out = cur.fetchone()
1750
+ row = dict(zip(names, out.row(0)))
1751
+
1752
+ assert row['id'] == 1, row['id']
1753
+ assert row['tinyint'] is None, row['tinyint']
1754
+ assert row['bool'] is None, row['bool']
1755
+ assert row['boolean'] is None, row['boolean']
1756
+ assert row['smallint'] is None, row['smallint']
1757
+ assert row['mediumint'] is None, row['mediumint']
1758
+ assert row['int24'] is None, row['int24']
1759
+ assert row['int'] is None, row['int']
1760
+ assert row['integer'] is None, row['integer']
1761
+ assert row['bigint'] is None, row['bigint']
1762
+ assert row['float'] is None, row['float']
1763
+ assert row['double'] is None, row['double']
1764
+ assert row['real'] is None, row['real']
1765
+ assert row['decimal'] is None, row['decimal']
1766
+ assert row['dec'] is None, row['dec']
1767
+ assert row['fixed'] is None, row['fixed']
1768
+ assert row['numeric'] is None, row['numeric']
1769
+ assert row['date'] is None, row['date']
1770
+ assert row['time'] is None, row['time']
1771
+ assert row['time'] is None, row['time']
1772
+ assert row['datetime'] is None, row['datetime']
1773
+ assert row['datetime_6'] is None, row['datetime_6']
1774
+ assert row['timestamp'] is None, row['timestamp']
1775
+ assert row['timestamp_6'] is None, row['timestamp_6']
1776
+ assert row['year'] is None, row['year']
1777
+ assert row['char_100'] is None, row['char_100']
1778
+ assert row['binary_100'] is None, row['binary_100']
1779
+ assert row['varchar_200'] is None, row['varchar_200']
1780
+ assert row['varbinary_200'] is None, row['varbinary_200']
1781
+ assert row['longtext'] is None, row['longtext']
1782
+ assert row['mediumtext'] is None, row['mediumtext']
1783
+ assert row['text'] is None, row['text']
1784
+ assert row['tinytext'] is None, row['tinytext']
1785
+ assert row['longblob'] is None, row['longblob']
1786
+ assert row['mediumblob'] is None, row['mediumblob']
1787
+ assert row['blob'] is None, row['blob']
1788
+ assert row['tinyblob'] is None, row['tinyblob']
1789
+ assert row['json'] is None, row['json']
1790
+ assert row['enum'] is None, row['enum']
1791
+ assert row['set'] is None, row['set']
1792
+ assert row['bit'] is None, row['bit']
1793
+
1794
+ conn.close()
1795
+
1796
+ def test_alltypes_arrow(self):
1797
+ if self.conn.driver in ['http', 'https']:
1798
+ self.skipTest('Data API does not surface unsigned int information')
1799
+
1800
+ conn = s2.connect(database=type(self).dbname, results_type='arrow')
1801
+ cur = conn.cursor()
1802
+
1803
+ cur.execute('select * from alltypes where id = 0')
1804
+ out = cur.fetchone()
1805
+ row = out.to_pylist()[0]
1806
+
1807
+ dtypes = [
1808
+ ('id', 'int32'),
1809
+ ('tinyint', 'int8'),
1810
+ ('unsigned_tinyint', 'uint8'),
1811
+ ('bool', 'int8'),
1812
+ ('boolean', 'int8'),
1813
+ ('smallint', 'int16'),
1814
+ ('unsigned_smallint', 'uint16'),
1815
+ ('mediumint', 'int32'),
1816
+ ('unsigned_mediumint', 'uint32'),
1817
+ ('int24', 'int32'),
1818
+ ('unsigned_int24', 'uint32'),
1819
+ ('int', 'int32'),
1820
+ ('unsigned_int', 'uint32'),
1821
+ ('integer', 'int32'),
1822
+ ('unsigned_integer', 'uint32'),
1823
+ ('bigint', 'int64'),
1824
+ ('unsigned_bigint', 'uint64'),
1825
+ ('float', 'float'),
1826
+ ('double', 'double'),
1827
+ ('real', 'double'),
1828
+ ('decimal', 'decimal128(20, 6)'),
1829
+ ('dec', 'decimal128(20, 6)'),
1830
+ ('fixed', 'decimal128(20, 6)'),
1831
+ ('numeric', 'decimal128(20, 6)'),
1832
+ ('date', 'date64[ms]'),
1833
+ ('time', 'duration[us]'),
1834
+ ('time_6', 'duration[us]'),
1835
+ ('datetime', 'timestamp[us]'),
1836
+ ('datetime_6', 'timestamp[us]'),
1837
+ ('timestamp', 'timestamp[us]'),
1838
+ ('timestamp_6', 'timestamp[us]'),
1839
+ ('year', 'int16'),
1840
+ ('char_100', 'string'),
1841
+ ('binary_100', 'binary'),
1842
+ ('varchar_200', 'string'),
1843
+ ('varbinary_200', 'binary'),
1844
+ ('longtext', 'string'),
1845
+ ('mediumtext', 'string'),
1846
+ ('text', 'string'),
1847
+ ('tinytext', 'string'),
1848
+ ('longblob', 'binary'),
1849
+ ('mediumblob', 'binary'),
1850
+ ('blob', 'binary'),
1851
+ ('tinyblob', 'binary'),
1852
+ ('json', 'string'),
1853
+ ('enum', 'string'),
1854
+ ('set', 'string'),
1855
+ ('bit', 'binary'),
1856
+ ]
1857
+
1858
+ assert [(x.name, str(x.type)) for x in out.schema] == dtypes
1859
+
1860
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1861
+
1862
+ assert row['id'] == 0, row['id']
1863
+ assert row['tinyint'] == 80, row['tinyint']
1864
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
1865
+ assert row['bool'] == 0, row['bool']
1866
+ assert row['boolean'] == 1, row['boolean']
1867
+ assert row['smallint'] == -27897, row['smallint']
1868
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
1869
+ assert row['mediumint'] == 104729, row['mediumint']
1870
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
1871
+ assert row['int24'] == -200899, row['int24']
1872
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
1873
+ assert row['int'] == -1295369311, row['int']
1874
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
1875
+ assert row['integer'] == -1741727421, row['integer']
1876
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
1877
+ assert row['bigint'] == -266883847, row['bigint']
1878
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
1879
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
1880
+ assert row['double'] == -474646154.719356, row['double']
1881
+ assert row['real'] == -901409776.279346, row['real']
1882
+ assert row['decimal'] == decimal.Decimal(
1883
+ '28111097.610822',
1884
+ ), row['decimal']
1885
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
1886
+ assert row['fixed'] == decimal.Decimal(
1887
+ '-143773416.044092',
1888
+ ), row['fixed']
1889
+ assert row['numeric'] == decimal.Decimal(
1890
+ '866689461.300046',
1891
+ ), row['numeric']
1892
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
1893
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
1894
+ assert row['datetime'] == datetime.datetime(
1895
+ 9948, 3, 11, 15, 29, 22,
1896
+ ), row['datetime']
1897
+ assert row['datetime_6'] == datetime.datetime(
1898
+ 1756, 10, 29, 2, 2, 42, 8,
1899
+ ), row['datetime_6']
1900
+ assert row['timestamp'] == datetime.datetime(
1901
+ 1980, 12, 31, 1, 10, 23,
1902
+ ), row['timestamp']
1903
+ assert row['timestamp_6'] == datetime.datetime(
1904
+ 1991, 1, 2, 22, 15, 10, 6,
1905
+ ), row['timestamp_6']
1906
+ assert row['year'] == 1923, row['year']
1907
+ assert row['char_100'] == \
1908
+ 'This is a test of a 100 character column.', row['char_100']
1909
+ assert row['binary_100'] == bytearray(
1910
+ bits + [0] * 84,
1911
+ ), row['binary_100']
1912
+ assert row['varchar_200'] == \
1913
+ 'This is a test of a variable character column.', row['varchar_200']
1914
+ assert row['varbinary_200'] == bytearray(
1915
+ bits * 2,
1916
+ ), row['varbinary_200']
1917
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
1918
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
1919
+ assert row['text'] == 'This is a text column.', row['text']
1920
+ assert row['tinytext'] == 'This is a tinytext column.'
1921
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
1922
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
1923
+ assert row['blob'] == bytearray(bits), row['blob']
1924
+ assert row['tinyblob'] == bytearray(
1925
+ [10, 11, 12, 13, 14, 15],
1926
+ ), row['tinyblob']
1927
+ assert row['json'] == '{"a":10,"b":2.75,"c":"hello world"}', row['json']
1928
+ assert row['enum'] == 'one', row['enum']
1929
+ assert row['set'] == 'two', row['set']
1930
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
1931
+
1932
+ conn.close()
1933
+
1934
+ def test_alltypes_no_nulls_arrow(self):
1935
+ if self.conn.driver in ['http', 'https']:
1936
+ self.skipTest('Data API does not surface unsigned int information')
1937
+
1938
+ conn = s2.connect(database=type(self).dbname, results_type='arrow')
1939
+ cur = conn.cursor()
1940
+
1941
+ cur.execute('select * from alltypes_no_nulls where id = 0')
1942
+ out = cur.fetchone()
1943
+
1944
+ row = out.to_pylist()[0]
1945
+
1946
+ dtypes = [
1947
+ ('id', 'int32'),
1948
+ ('tinyint', 'int8'),
1949
+ ('unsigned_tinyint', 'uint8'),
1950
+ ('bool', 'int8'),
1951
+ ('boolean', 'int8'),
1952
+ ('smallint', 'int16'),
1953
+ ('unsigned_smallint', 'uint16'),
1954
+ ('mediumint', 'int32'),
1955
+ ('unsigned_mediumint', 'uint32'),
1956
+ ('int24', 'int32'),
1957
+ ('unsigned_int24', 'uint32'),
1958
+ ('int', 'int32'),
1959
+ ('unsigned_int', 'uint32'),
1960
+ ('integer', 'int32'),
1961
+ ('unsigned_integer', 'uint32'),
1962
+ ('bigint', 'int64'),
1963
+ ('unsigned_bigint', 'uint64'),
1964
+ ('float', 'float'),
1965
+ ('double', 'double'),
1966
+ ('real', 'double'),
1967
+ ('decimal', 'decimal128(20, 6)'),
1968
+ ('dec', 'decimal128(20, 6)'),
1969
+ ('fixed', 'decimal128(20, 6)'),
1970
+ ('numeric', 'decimal128(20, 6)'),
1971
+ ('date', 'date64[ms]'),
1972
+ ('time', 'duration[us]'),
1973
+ ('time_6', 'duration[us]'),
1974
+ ('datetime', 'timestamp[us]'),
1975
+ ('datetime_6', 'timestamp[us]'),
1976
+ ('timestamp', 'timestamp[us]'),
1977
+ ('timestamp_6', 'timestamp[us]'),
1978
+ ('year', 'int16'),
1979
+ ('char_100', 'string'),
1980
+ ('binary_100', 'binary'),
1981
+ ('varchar_200', 'string'),
1982
+ ('varbinary_200', 'binary'),
1983
+ ('longtext', 'string'),
1984
+ ('mediumtext', 'string'),
1985
+ ('text', 'string'),
1986
+ ('tinytext', 'string'),
1987
+ ('longblob', 'binary'),
1988
+ ('mediumblob', 'binary'),
1989
+ ('blob', 'binary'),
1990
+ ('tinyblob', 'binary'),
1991
+ ('json', 'string'),
1992
+ ('enum', 'string'),
1993
+ ('set', 'string'),
1994
+ ('bit', 'binary'),
1995
+ ]
1996
+
1997
+ assert [(x.name, str(x.type)) for x in out.schema] == dtypes
1998
+
1999
+ bits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
2000
+
2001
+ assert row['id'] == 0, row['id']
2002
+ assert row['tinyint'] == 80, row['tinyint']
2003
+ assert row['unsigned_tinyint'] == 85, row['unsigned_tinyint']
2004
+ assert row['bool'] == 0, row['bool']
2005
+ assert row['boolean'] == 1, row['boolean']
2006
+ assert row['smallint'] == -27897, row['smallint']
2007
+ assert row['unsigned_smallint'] == 27897, row['unsigned_smallint']
2008
+ assert row['mediumint'] == 104729, row['mediumint']
2009
+ assert row['unsigned_mediumint'] == 120999, row['unsigned_mediumint']
2010
+ assert row['int24'] == -200899, row['int24']
2011
+ assert row['unsigned_int24'] == 407709, row['unsigned_int24']
2012
+ assert row['int'] == -1295369311, row['int']
2013
+ assert row['unsigned_int'] == 3872362332, row['unsigned_int']
2014
+ assert row['integer'] == -1741727421, row['integer']
2015
+ assert row['unsigned_integer'] == 3198387363, row['unsigned_integer']
2016
+ assert row['bigint'] == -266883847, row['bigint']
2017
+ assert row['unsigned_bigint'] == 980007287362, row['unsigned_bigint']
2018
+ assert row['float'] - -146487000.0 < 0.00001, row['float']
2019
+ assert row['double'] == -474646154.719356, row['double']
2020
+ assert row['real'] == -901409776.279346, row['real']
2021
+ assert row['decimal'] == decimal.Decimal(
2022
+ '28111097.610822',
2023
+ ), row['decimal']
2024
+ assert row['dec'] == decimal.Decimal('389451155.931428'), row['dec']
2025
+ assert row['fixed'] == decimal.Decimal(
2026
+ '-143773416.044092',
2027
+ ), row['fixed']
2028
+ assert row['numeric'] == decimal.Decimal(
2029
+ '866689461.300046',
2030
+ ), row['numeric']
2031
+ assert row['date'] == datetime.date(8524, 11, 10), row['date']
2032
+ assert row['time'] == datetime.timedelta(minutes=7), row['time']
2033
+ assert row['datetime'] == datetime.datetime(
2034
+ 9948, 3, 11, 15, 29, 22,
2035
+ ), row['datetime']
2036
+ assert row['datetime_6'] == datetime.datetime(
2037
+ 1756, 10, 29, 2, 2, 42, 8,
2038
+ ), row['datetime_6']
2039
+ assert row['timestamp'] == datetime.datetime(
2040
+ 1980, 12, 31, 1, 10, 23,
2041
+ ), row['timestamp']
2042
+ assert row['timestamp_6'] == datetime.datetime(
2043
+ 1991, 1, 2, 22, 15, 10, 6,
2044
+ ), row['timestamp_6']
2045
+ assert row['year'] == 1923, row['year']
2046
+ assert row['char_100'] == \
2047
+ 'This is a test of a 100 character column.', row['char_100']
2048
+ assert row['binary_100'] == bytearray(
2049
+ bits + [0] * 84,
2050
+ ), row['binary_100']
2051
+ assert row['varchar_200'] == \
2052
+ 'This is a test of a variable character column.', row['varchar_200']
2053
+ assert row['varbinary_200'] == bytearray(
2054
+ bits * 2,
2055
+ ), row['varbinary_200']
2056
+ assert row['longtext'] == 'This is a longtext column.', row['longtext']
2057
+ assert row['mediumtext'] == 'This is a mediumtext column.', row['mediumtext']
2058
+ assert row['text'] == 'This is a text column.', row['text']
2059
+ assert row['tinytext'] == 'This is a tinytext column.'
2060
+ assert row['longblob'] == bytearray(bits * 3), row['longblob']
2061
+ assert row['mediumblob'] == bytearray(bits * 2), row['mediumblob']
2062
+ assert row['blob'] == bytearray(bits), row['blob']
2063
+ assert row['tinyblob'] == bytearray(
2064
+ [10, 11, 12, 13, 14, 15],
2065
+ ), row['tinyblob']
2066
+ assert row['json'] == '{"a":10,"b":2.75,"c":"hello world"}', row['json']
2067
+ assert row['enum'] == 'one', row['enum']
2068
+ assert row['set'] == 'two', row['set']
2069
+ assert row['bit'] == b'\x00\x00\x00\x00\x00\x00\x00\x80', row['bit']
2070
+
2071
+ conn.close()
2072
+
2073
+ def test_alltypes_min_max_arrow(self):
2074
+ if self.conn.driver in ['http', 'https']:
2075
+ self.skipTest('Data API does not surface unsigned int information')
2076
+
2077
+ conn = s2.connect(database=type(self).dbname, results_type='arrow')
2078
+ cur = conn.cursor()
2079
+
2080
+ cur.execute('select * from alltypes_no_nulls')
2081
+ cur.fetchall()
2082
+
2083
+ cur.execute('select * from alltypes')
2084
+ cur.fetchall()
2085
+
2086
+ conn.close()
2087
+
2088
+ def test_alltypes_nulls_arrow(self):
2089
+ conn = s2.connect(database=type(self).dbname, results_type='arrow')
2090
+ cur = conn.cursor()
2091
+
2092
+ cur.execute('select * from alltypes where id = 1')
2093
+ out = cur.fetchone()
2094
+ row = out.to_pylist()[0]
2095
+
2096
+ assert row['id'] == 1, row['id']
2097
+ assert row['tinyint'] is None, row['tinyint']
2098
+ assert row['bool'] is None, row['bool']
2099
+ assert row['boolean'] is None, row['boolean']
2100
+ assert row['smallint'] is None, row['smallint']
2101
+ assert row['mediumint'] is None, row['mediumint']
2102
+ assert row['int24'] is None, row['int24']
2103
+ assert row['int'] is None, row['int']
2104
+ assert row['integer'] is None, row['integer']
2105
+ assert row['bigint'] is None, row['bigint']
2106
+ assert row['float'] is None, row['float']
2107
+ assert row['double'] is None, row['double']
2108
+ assert row['real'] is None, row['real']
2109
+ assert row['decimal'] is None, row['decimal']
2110
+ assert row['dec'] is None, row['dec']
2111
+ assert row['fixed'] is None, row['fixed']
2112
+ assert row['numeric'] is None, row['numeric']
2113
+ assert row['date'] is None, row['date']
2114
+ assert row['time'] is None, row['time']
2115
+ assert row['time'] is None, row['time']
2116
+ assert row['datetime'] is None, row['datetime']
2117
+ assert row['datetime_6'] is None, row['datetime_6']
2118
+ assert row['timestamp'] is None, row['timestamp']
2119
+ assert row['timestamp_6'] is None, row['timestamp_6']
2120
+ assert row['year'] is None, row['year']
2121
+ assert row['char_100'] is None, row['char_100']
2122
+ assert row['binary_100'] is None, row['binary_100']
2123
+ assert row['varchar_200'] is None, row['varchar_200']
2124
+ assert row['varbinary_200'] is None, row['varbinary_200']
2125
+ assert row['longtext'] is None, row['longtext']
2126
+ assert row['mediumtext'] is None, row['mediumtext']
2127
+ assert row['text'] is None, row['text']
2128
+ assert row['tinytext'] is None, row['tinytext']
2129
+ assert row['longblob'] is None, row['longblob']
2130
+ assert row['mediumblob'] is None, row['mediumblob']
2131
+ assert row['blob'] is None, row['blob']
2132
+ assert row['tinyblob'] is None, row['tinyblob']
2133
+ assert row['json'] is None, row['json']
2134
+ assert row['enum'] is None, row['enum']
2135
+ assert row['set'] is None, row['set']
2136
+ assert row['bit'] is None, row['bit']
2137
+
2138
+ conn.close()
2139
+
2140
+ def test_alltypes_nulls(self):
2141
+ self.cur.execute('select * from alltypes where id = 1')
2142
+ names = [x[0] for x in self.cur.description]
2143
+ types = [x[1] for x in self.cur.description]
2144
+ out = self.cur.fetchone()
2145
+ row = dict(zip(names, out))
2146
+ typ = dict(zip(names, types))
2147
+
2148
+ def otype(x):
2149
+ return x
2150
+
2151
+ assert row['id'] == 1, row['id']
2152
+ assert typ['id'] == otype(3), typ['id']
2153
+
2154
+ assert row['tinyint'] is None, row['tinyint']
2155
+ assert typ['tinyint'] == otype(1), typ['tinyint']
2156
+
2157
+ assert row['bool'] is None, row['bool']
2158
+ assert typ['bool'] == otype(1), typ['bool']
2159
+
2160
+ assert row['boolean'] is None, row['boolean']
2161
+ assert typ['boolean'] == otype(1), typ['boolean']
2162
+
2163
+ assert row['smallint'] is None, row['smallint']
2164
+ assert typ['smallint'] == otype(2), typ['smallint']
2165
+
2166
+ assert row['mediumint'] is None, row['mediumint']
2167
+ assert typ['mediumint'] == otype(9), typ['mediumint']
2168
+
2169
+ assert row['int24'] is None, row['int24']
2170
+ assert typ['int24'] == otype(9), typ['int24']
2171
+
2172
+ assert row['int'] is None, row['int']
2173
+ assert typ['int'] == otype(3), typ['int']
2174
+
2175
+ assert row['integer'] is None, row['integer']
2176
+ assert typ['integer'] == otype(3), typ['integer']
2177
+
2178
+ assert row['bigint'] is None, row['bigint']
2179
+ assert typ['bigint'] == otype(8), typ['bigint']
2180
+
2181
+ assert row['float'] is None, row['float']
2182
+ assert typ['float'] == otype(4), typ['float']
2183
+
2184
+ assert row['double'] is None, row['double']
2185
+ assert typ['double'] == otype(5), typ['double']
2186
+
2187
+ assert row['real'] is None, row['real']
2188
+ assert typ['real'] == otype(5), typ['real']
2189
+
2190
+ assert row['decimal'] is None, row['decimal']
2191
+ assert typ['decimal'] == otype(246), typ['decimal']
2192
+
2193
+ assert row['dec'] is None, row['dec']
2194
+ assert typ['dec'] == otype(246), typ['dec']
2195
+
2196
+ assert row['fixed'] is None, row['fixed']
2197
+ assert typ['fixed'] == otype(246), typ['fixed']
2198
+
2199
+ assert row['numeric'] is None, row['numeric']
2200
+ assert typ['numeric'] == otype(246), typ['numeric']
2201
+
2202
+ assert row['date'] is None, row['date']
2203
+ assert typ['date'] == 10, typ['date']
2204
+
2205
+ assert row['time'] is None, row['time']
2206
+ assert typ['time'] == 11, typ['time']
2207
+
2208
+ assert row['time'] is None, row['time']
2209
+ assert typ['time_6'] == 11, typ['time_6']
2210
+
2211
+ assert row['datetime'] is None, row['datetime']
2212
+ assert typ['datetime'] == 12, typ['datetime']
2213
+
2214
+ assert row['datetime_6'] is None, row['datetime_6']
2215
+ assert typ['datetime'] == 12, typ['datetime']
2216
+
2217
+ assert row['timestamp'] is None, row['timestamp']
2218
+ assert typ['timestamp'] == otype(7), typ['timestamp']
2219
+
2220
+ assert row['timestamp_6'] is None, row['timestamp_6']
2221
+ assert typ['timestamp_6'] == otype(7), typ['timestamp_6']
2222
+
2223
+ assert row['year'] is None, row['year']
2224
+ assert typ['year'] == otype(13), typ['year']
2225
+
2226
+ assert row['char_100'] is None, row['char_100']
2227
+ assert typ['char_100'] == otype(254), typ['char_100']
2228
+
2229
+ assert row['binary_100'] is None, row['binary_100']
2230
+ assert typ['binary_100'] == otype(254), typ['binary_100']
2231
+
2232
+ assert row['varchar_200'] is None, typ['varchar_200']
2233
+ assert typ['varchar_200'] == otype(
2234
+ 253,
2235
+ ), typ['varchar_200'] # why not 15?
2236
+
2237
+ assert row['varbinary_200'] is None, row['varbinary_200']
2238
+ assert typ['varbinary_200'] == otype(
2239
+ 253,
2240
+ ), typ['varbinary_200'] # why not 15?
2241
+
2242
+ assert row['longtext'] is None, row['longtext']
2243
+ assert typ['longtext'] == otype(251), typ['longtext']
2244
+
2245
+ assert row['mediumtext'] is None, row['mediumtext']
2246
+ assert typ['mediumtext'] == otype(250), typ['mediumtext']
2247
+
2248
+ assert row['text'] is None, row['text']
2249
+ assert typ['text'] == otype(252), typ['text']
2250
+
2251
+ assert row['tinytext'] is None, row['tinytext']
2252
+ assert typ['tinytext'] == otype(249), typ['tinytext']
2253
+
2254
+ assert row['longblob'] is None, row['longblob']
2255
+ assert typ['longblob'] == otype(251), typ['longblob']
2256
+
2257
+ assert row['mediumblob'] is None, row['mediumblob']
2258
+ assert typ['mediumblob'] == otype(250), typ['mediumblob']
2259
+
2260
+ assert row['blob'] is None, row['blob']
2261
+ assert typ['blob'] == otype(252), typ['blob']
2262
+
2263
+ assert row['tinyblob'] is None, row['tinyblob']
2264
+ assert typ['tinyblob'] == otype(249), typ['tinyblob']
2265
+
2266
+ assert row['json'] is None, row['json']
2267
+ assert typ['json'] == otype(245), typ['json']
2268
+
2269
+ assert row['enum'] is None, row['enum']
2270
+ assert typ['enum'] == otype(253), typ['enum'] # mysql code: 247
2271
+
2272
+ assert row['set'] is None, row['set']
2273
+ assert typ['set'] == otype(253), typ['set'] # mysql code: 248
2274
+
2275
+ assert row['bit'] is None, row['bit']
2276
+ assert typ['bit'] == otype(16), typ['bit']
2277
+
2278
+ def test_name_check(self):
2279
+ nc = sc._name_check
2280
+ assert nc('foo') == 'foo'
2281
+ assert nc('Foo') == 'Foo'
2282
+ assert nc('Foo_Bar') == 'Foo_Bar'
2283
+ assert nc('Foo_Bar2') == 'Foo_Bar2'
2284
+
2285
+ with self.assertRaises(ValueError):
2286
+ assert nc('foo.bar')
2287
+
2288
+ with self.assertRaises(ValueError):
2289
+ assert nc('2foo')
2290
+
2291
+ with self.assertRaises(ValueError):
2292
+ assert nc('')
2293
+
2294
+ def test_echo(self):
2295
+ self.cur.execute('echo return_int()')
2296
+
2297
+ out = self.cur.fetchall()
2298
+ assert list(out) == [(1234567890,)], out
2299
+
2300
+ out = self.cur.nextset()
2301
+ assert out is None, out
2302
+
2303
+ def test_echo_with_result_set(self):
2304
+ self.cur.execute('echo result_set_and_return_int()')
2305
+
2306
+ out = self.cur.fetchall()
2307
+ assert list(out) == [(5,)], out
2308
+
2309
+ out = self.cur.nextset()
2310
+ assert out is True, out
2311
+
2312
+ out = self.cur.fetchall()
2313
+ assert list(out) == [(1, 2, 3)], out
2314
+
2315
+ out = self.cur.nextset()
2316
+ assert out is True, out
2317
+
2318
+ out = self.cur.fetchall()
2319
+ assert list(out) == [(1234567890,)], out
2320
+
2321
+ out = self.cur.nextset()
2322
+ assert out is None, out
2323
+
2324
+ def test_callproc(self):
2325
+ self.cur.callproc('get_animal', ['cats'])
2326
+
2327
+ out = self.cur.fetchall()
2328
+ assert list(out) == [(5,)], out
2329
+
2330
+ out = self.cur.nextset()
2331
+ assert out is True, out
2332
+
2333
+ out = self.cur.fetchall()
2334
+ assert list(out) == [(1, 2, 3)], out
2335
+
2336
+ out = self.cur.nextset()
2337
+ assert out is True, out
2338
+
2339
+ # Always get an empty set at the end
2340
+ out = self.cur.fetchall()
2341
+ assert list(out) == [], out
2342
+
2343
+ out = self.cur.nextset()
2344
+ assert out is None, out
2345
+
2346
+ def test_callproc_no_args(self):
2347
+ self.cur.callproc('no_args')
2348
+
2349
+ out = self.cur.fetchall()
2350
+ assert list(out) == [(4, 5, 6)], out
2351
+
2352
+ out = self.cur.nextset()
2353
+ assert out is True, out
2354
+
2355
+ # Always get an empty set at the end
2356
+ out = self.cur.fetchall()
2357
+ assert list(out) == [], out
2358
+
2359
+ out = self.cur.nextset()
2360
+ assert out is None, out
2361
+
2362
+ def test_callproc_return_int(self):
2363
+ self.cur.callproc('result_set_and_return_int')
2364
+
2365
+ out = self.cur.fetchall()
2366
+ assert list(out) == [(5,)], out
2367
+
2368
+ out = self.cur.nextset()
2369
+ assert out is True, out
2370
+
2371
+ out = self.cur.fetchall()
2372
+ assert list(out) == [(1, 2, 3)], out
2373
+
2374
+ out = self.cur.nextset()
2375
+ assert out is True, out
2376
+
2377
+ # Always get an empty set at the end
2378
+ out = self.cur.fetchall()
2379
+ assert list(out) == [], out
2380
+
2381
+ out = self.cur.nextset()
2382
+ assert out is None, out
2383
+
2384
+ def test_callproc_bad_args(self):
2385
+ self.cur.callproc('get_animal', [10])
2386
+
2387
+ out = self.cur.fetchall()
2388
+ assert list(out) == [], out
2389
+
2390
+ out = self.cur.nextset()
2391
+ assert out is True, out
2392
+
2393
+ out = self.cur.fetchall()
2394
+ assert list(out) == [(1, 2, 3)], out
2395
+
2396
+ out = self.cur.nextset()
2397
+ assert out is True, out
2398
+
2399
+ # Always get an empty set at the end
2400
+ out = self.cur.fetchall()
2401
+ assert list(out) == [], out
2402
+
2403
+ out = self.cur.nextset()
2404
+ assert out is None, out
2405
+
2406
+ def test_callproc_too_many_args(self):
2407
+ with self.assertRaises((
2408
+ s2.ProgrammingError,
2409
+ s2.OperationalError,
2410
+ s2.InternalError,
2411
+ TypeError,
2412
+ )):
2413
+ self.cur.callproc('get_animal', ['cats', 'dogs'])
2414
+
2415
+ with self.assertRaises((
2416
+ s2.ProgrammingError,
2417
+ s2.OperationalError,
2418
+ s2.InternalError,
2419
+ TypeError,
2420
+ )):
2421
+ self.cur.callproc('get_animal', [])
2422
+
2423
+ with self.assertRaises((
2424
+ s2.ProgrammingError,
2425
+ s2.OperationalError,
2426
+ s2.InternalError,
2427
+ TypeError,
2428
+ )):
2429
+ self.cur.callproc('get_animal')
2430
+
2431
+ def test_cursor_close(self):
2432
+ self.cur.close()
2433
+
2434
+ self.cur.close()
2435
+
2436
+ with self.assertRaises(s2.ProgrammingError):
2437
+ self.cur.callproc('foo')
2438
+
2439
+ with self.assertRaises(s2.ProgrammingError):
2440
+ self.cur.execute('select 1')
2441
+
2442
+ # with self.assertRaises(s2.ProgrammingError):
2443
+ # self.cur.executemany('select 1')
2444
+
2445
+ with self.assertRaises(s2.ProgrammingError):
2446
+ self.cur.fetchone()
2447
+
2448
+ with self.assertRaises(s2.ProgrammingError):
2449
+ self.cur.fetchall()
2450
+
2451
+ with self.assertRaises(s2.ProgrammingError):
2452
+ self.cur.fetchmany()
2453
+
2454
+ with self.assertRaises(s2.ProgrammingError):
2455
+ self.cur.nextset()
2456
+
2457
+ # with self.assertRaises(s2.ProgrammingError):
2458
+ # self.cur.setinputsizes([])
2459
+
2460
+ # with self.assertRaises(s2.ProgrammingError):
2461
+ # self.cur.setoutputsize(10)
2462
+
2463
+ with self.assertRaises(s2.ProgrammingError):
2464
+ self.cur.scroll(2)
2465
+
2466
+ with self.assertRaises(s2.InterfaceError):
2467
+ self.cur.next()
2468
+
2469
+ # The following attributes are still accessible after close.
2470
+
2471
+ assert isinstance(self.cur.messages, list), self.cur.messages
2472
+
2473
+ assert isinstance(self.cur.rowcount, (int, type(None))), self.cur.rowcount
2474
+
2475
+ assert isinstance(self.cur.lastrowid, (int, type(None))), self.cur.lastrowid
2476
+
2477
+ def test_setinputsizes(self):
2478
+ self.cur.setinputsizes([10, 20, 30])
2479
+
2480
+ def test_setoutputsize(self):
2481
+ self.cur.setoutputsize(100)
2482
+
2483
+ def test_scroll(self):
2484
+ self.cur.execute('select * from data order by name')
2485
+
2486
+ out = self.cur.fetchone()
2487
+ assert out[1] == 'antelopes', out[1]
2488
+ assert self.cur.rownumber == 1, self.cur.rownumber
2489
+
2490
+ self.cur.scroll(3)
2491
+
2492
+ out = self.cur.fetchone()
2493
+ assert out[1] == 'elephants', out[1]
2494
+ assert self.cur.rownumber == 5, self.cur.rownumber
2495
+
2496
+ try:
2497
+ self.cur.scroll(0, mode='absolute')
2498
+ assert self.cur.rownumber == 0, self.cur.rownumber
2499
+
2500
+ out = self.cur.fetchone()
2501
+ assert out[1] == 'antelopes', out[1]
2502
+ assert self.cur.rownumber == 1, self.cur.rownumber
2503
+ except s2.NotSupportedError:
2504
+ pass
2505
+
2506
+ with self.assertRaises((ValueError, s2.ProgrammingError)):
2507
+ self.cur.scroll(0, mode='badmode')
2508
+
2509
+ def test_autocommit(self):
2510
+ if self.conn.driver in ['http', 'https']:
2511
+ self.skipTest('Can not set autocommit in HTTP')
2512
+
2513
+ orig = self.conn.locals.autocommit
2514
+
2515
+ self.conn.autocommit(True)
2516
+ val = self.conn.locals.autocommit
2517
+ assert val is True, val
2518
+
2519
+ self.conn.autocommit(False)
2520
+ val = self.conn.locals.autocommit
2521
+ assert val is False, val
2522
+
2523
+ self.conn.locals.autocommit = orig
2524
+
2525
+ def test_conn_close(self):
2526
+ self.conn.close()
2527
+
2528
+ with self.assertRaises(s2.Error):
2529
+ self.conn.close()
2530
+
2531
+ with self.assertRaises(s2.InterfaceError):
2532
+ self.conn.autocommit(False)
2533
+
2534
+ with self.assertRaises(s2.InterfaceError):
2535
+ self.conn.commit()
2536
+
2537
+ with self.assertRaises(s2.InterfaceError):
2538
+ self.conn.rollback()
2539
+
2540
+ # with self.assertRaises(s2.InterfaceError):
2541
+ # self.conn.cursor()
2542
+
2543
+ # with self.assertRaises(s2.InterfaceError):
2544
+ # self.conn.messages
2545
+
2546
+ with self.assertRaises(s2.InterfaceError):
2547
+ self.conn.globals.autocommit = True
2548
+
2549
+ with self.assertRaises(s2.InterfaceError):
2550
+ self.conn.globals.autocommit
2551
+
2552
+ with self.assertRaises(s2.InterfaceError):
2553
+ self.conn.locals.autocommit = True
2554
+
2555
+ with self.assertRaises(s2.InterfaceError):
2556
+ self.conn.locals.autocommit
2557
+
2558
+ with self.assertRaises(s2.InterfaceError):
2559
+ self.conn.enable_data_api()
2560
+
2561
+ with self.assertRaises(s2.InterfaceError):
2562
+ self.conn.disable_data_api()
2563
+
2564
+ def test_rollback(self):
2565
+ if self.conn.driver in ['http', 'https']:
2566
+ self.skipTest('Can not set autocommit in HTTP')
2567
+
2568
+ self.conn.autocommit(False)
2569
+
2570
+ self.cur.execute('select * from data')
2571
+ out = self.cur.fetchall()
2572
+ assert len(out) == 5, len(out)
2573
+
2574
+ self.cur.execute("INSERT INTO data SET id='f', name='frogs', value=3")
2575
+
2576
+ self.cur.execute('select * from data')
2577
+ out = self.cur.fetchall()
2578
+ assert len(out) == 6, len(out)
2579
+
2580
+ self.conn.rollback()
2581
+
2582
+ self.cur.execute('select * from data')
2583
+ out = self.cur.fetchall()
2584
+ assert len(out) == 5, len(out)
2585
+
2586
+ def test_commit(self):
2587
+ if self.conn.driver in ['http', 'https']:
2588
+ self.skipTest('Can not set autocommit in HTTP')
2589
+
2590
+ self.conn.autocommit(False)
2591
+
2592
+ self.cur.execute('select * from data')
2593
+ out = self.cur.fetchall()
2594
+ assert len(out) == 5, len(out)
2595
+
2596
+ self.cur.execute("INSERT INTO data SET id='f', name='frogs', value=3")
2597
+
2598
+ self.cur.execute('select * from data')
2599
+ out = self.cur.fetchall()
2600
+ assert len(out) == 6, len(out)
2601
+
2602
+ self.conn.commit()
2603
+
2604
+ self.cur.execute('select * from data')
2605
+ out = self.cur.fetchall()
2606
+ assert len(out) == 6, len(out)
2607
+
2608
+ self.cur.execute("delete from data where id='f'")
2609
+
2610
+ self.cur.execute('select * from data')
2611
+ out = self.cur.fetchall()
2612
+ assert len(out) == 5, len(out)
2613
+
2614
+ self.conn.commit()
2615
+
2616
+ self.cur.execute('select * from data')
2617
+ out = self.cur.fetchall()
2618
+ assert len(out) == 5, len(out)
2619
+
2620
+ def test_global_var(self):
2621
+ orig = self.conn.globals.enable_external_functions
2622
+
2623
+ self.conn.globals.enable_external_functions = True
2624
+ val = self.conn.globals.enable_external_functions
2625
+ assert val is True, val
2626
+
2627
+ self.conn.globals.enable_external_functions = False
2628
+ val = self.conn.globals.enable_external_functions
2629
+ assert val is False, val
2630
+
2631
+ self.conn.globals.enable_external_functions = orig
2632
+ val = self.conn.globals.enable_external_functions
2633
+ assert val == orig, val
2634
+
2635
+ def test_session_var(self):
2636
+ if self.conn.driver in ['http', 'https']:
2637
+ self.skipTest('Can not change session variable in HTTP')
2638
+
2639
+ orig = self.conn.locals.enable_multipartition_queries
2640
+
2641
+ self.conn.locals.enable_multipartition_queries = True
2642
+ val = self.conn.locals.enable_multipartition_queries
2643
+ assert val is True, val
2644
+
2645
+ self.conn.locals.enable_multipartition_queries = False
2646
+ val = self.conn.locals.enable_multipartition_queries
2647
+ assert val is False, val
2648
+
2649
+ self.conn.locals.enable_multipartition_queries = orig
2650
+ val = self.conn.locals.enable_multipartition_queries
2651
+ assert val == orig, val
2652
+
2653
+ def test_local_infile(self):
2654
+ if self.conn.driver in ['http', 'https']:
2655
+ self.skipTest('Can not load local files in HTTP')
2656
+
2657
+ path = os.path.join(os.path.dirname(__file__), 'local_infile.csv')
2658
+ tblname = ('TEST_' + str(uuid.uuid4())).replace('-', '_')
2659
+
2660
+ self.cur.execute(f'''
2661
+ create table `{tblname}` (
2662
+ first_name char(20) not null,
2663
+ last_name char(30) not null,
2664
+ age int not null
2665
+ ) collate="utf8_unicode_ci";
2666
+ ''')
2667
+
2668
+ try:
2669
+ self.cur.execute(
2670
+ f'load data local infile %s into table {tblname} '
2671
+ 'fields terminated by "," lines terminated by "\n";', [path],
2672
+ )
2673
+
2674
+ self.cur.execute(f'select * from {tblname} order by first_name')
2675
+ out = list(self.cur)
2676
+ assert out == [
2677
+ ('John', 'Doe', 34),
2678
+ ('Patty', 'Jones', 57),
2679
+ ('Sandy', 'Smith', 24),
2680
+ ], out
2681
+
2682
+ finally:
2683
+ self.cur.execute(f'drop table {tblname};')
2684
+
2685
+ def test_converters(self):
2686
+ def upper(x):
2687
+ if isinstance(x, str):
2688
+ return x.upper()
2689
+ return x
2690
+
2691
+ convs = {
2692
+ 15: upper,
2693
+ 249: upper,
2694
+ 250: upper,
2695
+ 251: upper,
2696
+ 252: upper,
2697
+ 253: upper,
2698
+ 254: upper,
2699
+ }
2700
+
2701
+ with s2.connect(database=type(self).dbname, conv=convs) as conn:
2702
+ with conn.cursor() as cur:
2703
+ cur.execute('select * from alltypes where id = 0')
2704
+ names = [x[0] for x in cur.description]
2705
+ out = cur.fetchone()
2706
+ row = dict(zip(names, out))
2707
+ assert row['longtext'] == 'THIS IS A LONGTEXT COLUMN.', \
2708
+ row['longtext']
2709
+ assert row['mediumtext'] == 'THIS IS A MEDIUMTEXT COLUMN.', \
2710
+ row['mediumtext']
2711
+ assert row['text'] == 'THIS IS A TEXT COLUMN.', \
2712
+ row['text']
2713
+ assert row['tinytext'] == 'THIS IS A TINYTEXT COLUMN.', \
2714
+ row['tinytext']
2715
+
2716
+ with s2.connect(database=type(self).dbname) as conn:
2717
+ with conn.cursor() as cur:
2718
+ cur.execute('select * from alltypes where id = 0')
2719
+ names = [x[0] for x in cur.description]
2720
+ out = cur.fetchone()
2721
+ row = dict(zip(names, out))
2722
+ assert row['longtext'] == 'This is a longtext column.', \
2723
+ row['longtext']
2724
+ assert row['mediumtext'] == 'This is a mediumtext column.', \
2725
+ row['mediumtext']
2726
+ assert row['text'] == 'This is a text column.', \
2727
+ row['text']
2728
+ assert row['tinytext'] == 'This is a tinytext column.', \
2729
+ row['tinytext']
2730
+
2731
+ def test_results_type(self):
2732
+ columns = [
2733
+ 'id', 'tinyint', 'unsigned_tinyint', 'bool', 'boolean',
2734
+ 'smallint', 'unsigned_smallint', 'mediumint', 'unsigned_mediumint',
2735
+ 'int24', 'unsigned_int24', 'int', 'unsigned_int',
2736
+ 'integer', 'unsigned_integer', 'bigint', 'unsigned_bigint',
2737
+ 'float', 'double', 'real', 'decimal', 'dec', 'fixed', 'numeric',
2738
+ 'date', 'time', 'time_6', 'datetime', 'datetime_6', 'timestamp',
2739
+ 'timestamp_6', 'year', 'char_100', 'binary_100', 'varchar_200',
2740
+ 'varbinary_200', 'longtext', 'mediumtext', 'text', 'tinytext',
2741
+ 'longblob', 'mediumblob', 'blob', 'tinyblob', 'json', 'enum',
2742
+ 'set', 'bit',
2743
+ ]
2744
+
2745
+ with s2.connect(database=type(self).dbname, results_type='tuples') as conn:
2746
+ with conn.cursor() as cur:
2747
+ cur.execute('select * from alltypes')
2748
+ out = cur.fetchall()
2749
+ assert type(out[0]) is tuple, type(out[0])
2750
+ assert len(out[0]) == len(columns), len(out[0])
2751
+
2752
+ with s2.connect(database=type(self).dbname, results_type='namedtuples') as conn:
2753
+ with conn.cursor() as cur:
2754
+ cur.execute('select * from alltypes')
2755
+ out = cur.fetchall()
2756
+ assert type(out[0]).__name__ == 'Row', type(out)
2757
+ for i, name in enumerate(columns):
2758
+ assert hasattr(out[0], name)
2759
+ assert out[0][i] == getattr(out[0], name)
2760
+
2761
+ with s2.connect(database=type(self).dbname, results_type='dicts') as conn:
2762
+ with conn.cursor() as cur:
2763
+ cur.execute('select * from alltypes')
2764
+ out = cur.fetchall()
2765
+ assert type(out[0]) is dict, type(out)
2766
+ assert list(out[0].keys()) == columns, out[0].keys()
2767
+
2768
+ def test_results_format(self):
2769
+ with self.assertWarns(DeprecationWarning):
2770
+ with s2.connect(database=type(self).dbname, results_format='dicts') as conn:
2771
+ with conn.cursor() as cur:
2772
+ cur.execute('select * from alltypes')
2773
+ out = cur.fetchall()
2774
+ assert type(out[0]) is dict, type(out)
2775
+
2776
+ def test_multi_statements(self):
2777
+ if self.conn.driver not in ['http', 'https']:
2778
+ with s2.connect(database=type(self).dbname, multi_statements=True) as conn:
2779
+ with conn.cursor() as cur:
2780
+ cur.execute('SELECT 1; SELECT 2;')
2781
+ self.assertEqual([(1,)], list(cur))
2782
+
2783
+ r = cur.nextset()
2784
+ self.assertTrue(r)
2785
+
2786
+ self.assertEqual([(2,)], list(cur))
2787
+ self.assertIsNone(cur.nextset())
2788
+
2789
+ def test_client_found_rows(self):
2790
+ if self.conn.driver not in ['http', 'https']:
2791
+ with s2.connect(database=type(self).dbname, client_found_rows=False) as conn:
2792
+ with conn.cursor() as cur:
2793
+ tag = str(uuid.uuid4()).replace('-', '_')
2794
+ table_name = f'test_client_found_rows_{tag}'
2795
+ cur.execute(f"CREATE TABLE {table_name} (id BIGINT \
2796
+ PRIMARY KEY, s TEXT DEFAULT 'def');")
2797
+ cur.execute(f'INSERT INTO {table_name} (id) \
2798
+ VALUES (1), (2), (3);')
2799
+ cur.execute(f"UPDATE {table_name} SET s = 'def' \
2800
+ WHERE id = 1;")
2801
+ # UPDATE statement above is not changing any rows,
2802
+ # so affected_rows is 0 if client_found_rows is False (default)
2803
+ self.assertEqual(0, conn.affected_rows())
2804
+ cur.execute(f'DROP TABLE {table_name};')
2805
+
2806
+ with s2.connect(database=type(self).dbname, client_found_rows=True) as conn:
2807
+ with conn.cursor() as cur:
2808
+ tag = str(uuid.uuid4()).replace('-', '_')
2809
+ table_name = f'test_client_found_rows_{tag}'
2810
+ cur.execute(f"CREATE TABLE {table_name} (id BIGINT \
2811
+ PRIMARY KEY, s TEXT DEFAULT 'def');")
2812
+ cur.execute(f'INSERT INTO {table_name} (id) \
2813
+ VALUES (1), (2), (3);')
2814
+ cur.execute(f"UPDATE {table_name} SET s = 'def' \
2815
+ WHERE id = 1;")
2816
+ # UPDATE statement above is not changing any rows,
2817
+ # but affected_rows is 1 as 1 row is subject to update, and
2818
+ # this is what affected_rows return when client_found_rows is True
2819
+ self.assertEqual(1, conn.affected_rows())
2820
+ cur.execute(f'DROP TABLE {table_name};')
2821
+
2822
+ def test_connect_timeout(self):
2823
+ with s2.connect(database=type(self).dbname, connect_timeout=8) as conn:
2824
+ with conn.cursor() as cur:
2825
+ cur.execute('SELECT 1')
2826
+ self.assertEqual([(1,)], list(cur))
2827
+
2828
+ def test_show_accessors(self):
2829
+ out = self.conn.show.columns('data')
2830
+ assert out.columns == [
2831
+ 'Name', 'Type', 'Null',
2832
+ 'Key', 'Default', 'Extra',
2833
+ ], out.columns
2834
+ assert out.Name == ['id', 'name', 'value'], out.Name
2835
+ assert out.Type == ['varchar(255)', 'varchar(255)', 'bigint(20)'], out.Type
2836
+ assert str(out).count('varchar(255)') == 2, out
2837
+
2838
+ html = out._repr_html_()
2839
+ assert html.count('varchar(255)') == 2
2840
+ assert html.count('bigint(20)') == 1
2841
+ assert '<table' in html
2842
+
2843
+ out = self.conn.show.tables()
2844
+ assert out.columns == ['Name'], out.columns
2845
+ assert 'data' in out.Name, out.Name
2846
+ assert 'alltypes' in out.Name, out.Name
2847
+
2848
+ out = self.conn.show.warnings()
2849
+
2850
+ out = self.conn.show.errors()
2851
+
2852
+ out = self.conn.show.databases()
2853
+ assert out.columns == ['Name'], out.columns
2854
+ assert 'information_schema' in out.Name
2855
+
2856
+ out = self.conn.show.database_status()
2857
+ assert out.columns == ['Name', 'Value'], out.columns
2858
+ assert 'database' in out.Name
2859
+
2860
+ out = self.conn.show.global_status()
2861
+ assert out.columns == ['Name', 'Value'], out.columns
2862
+
2863
+ out = self.conn.show.indexes('data')
2864
+ assert 'Name' in out.columns, out.columns
2865
+ assert 'KeyName' in out.columns, out.columns
2866
+ assert out.Name == ['data'], out.Name
2867
+
2868
+ out = self.conn.show.functions()
2869
+
2870
+ out = self.conn.show.partitions()
2871
+ assert 'Name' in out.columns, out.columns
2872
+ assert 'Role' in out.columns, out.columns
2873
+
2874
+ out = self.conn.show.pipelines()
2875
+
2876
+ # out = self.conn.show.plan(1)
2877
+
2878
+ # out = self.conn.show.plancache()
2879
+
2880
+ out = self.conn.show.processlist()
2881
+ assert 'Name' in out.columns, out.columns
2882
+ assert 'Command' in out.columns, out.columns
2883
+
2884
+ # out = self.conn.show.reproduction()
2885
+
2886
+ out = self.conn.show.schemas()
2887
+ assert out.columns == ['Name'], out.columns
2888
+ assert 'information_schema' in out.Name
2889
+
2890
+ out = self.conn.show.session_status()
2891
+ assert out.columns == ['Name', 'Value']
2892
+
2893
+ out = self.conn.show.status()
2894
+ assert out.columns == ['Name', 'Value']
2895
+
2896
+ out = self.conn.show.table_status()
2897
+ assert 'Name' in out.columns, out.columns
2898
+ assert 'alltypes' in out.Name, out.Name
2899
+ assert 'data' in out.Name, out.Name
2900
+
2901
+ out = self.conn.show.procedures()
2902
+
2903
+ out = self.conn.show.aggregates()
2904
+
2905
+ # out = self.conn.show.create_aggregate('aname')
2906
+
2907
+ # out = self.conn.show.create_function('fname')
2908
+
2909
+ # out = self.conn.show.create_pipeline('pname')
2910
+
2911
+ out = self.conn.show.create_table('data')
2912
+ assert 'Name' in out.columns, out.columns
2913
+ assert 'CreateTable' in out.columns, out.columns
2914
+ assert '`id` varchar(255)' in out.CreateTable[0], out.CreateTable[0]
2915
+ assert '`name` varchar(255)' in out.CreateTable[0], out.CreateTable[0]
2916
+ assert '`value` bigint(20)' in out.CreateTable[0], out.CreateTable[0]
2917
+
2918
+ # out = self.conn.show.create_view('vname')
2919
+
2920
+ def test_f32_vectors(self):
2921
+ if self.conn.driver in ['http', 'https']:
2922
+ self.skipTest('Data API does not surface vector information')
2923
+
2924
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
2925
+ out = list(self.cur)
2926
+ if not out or out[0][1].lower() == 'off':
2927
+ self.skipTest('Database engine does not support extended types metadata')
2928
+
2929
+ self.cur.execute('select a from f32_vectors order by id')
2930
+ out = list(self.cur)
2931
+
2932
+ if hasattr(out[0][0], 'dtype'):
2933
+ assert out[0][0].dtype is np.dtype('float32')
2934
+ assert out[1][0].dtype is np.dtype('float32')
2935
+ assert out[2][0].dtype is np.dtype('float32')
2936
+
2937
+ np.testing.assert_array_equal(
2938
+ out[0][0],
2939
+ np.array([0.267261237, 0.534522474, 0.801783681], dtype=np.float32),
2940
+ )
2941
+ np.testing.assert_array_equal(
2942
+ out[1][0],
2943
+ np.array([0.371390671, 0.557085991, 0.742781341], dtype=np.float32),
2944
+ )
2945
+ np.testing.assert_array_equal(
2946
+ out[2][0],
2947
+ np.array([-0.424264073, -0.565685451, 0.707106829], dtype=np.float32),
2948
+ )
2949
+
2950
+ def test_f64_vectors(self):
2951
+ if self.conn.driver in ['http', 'https']:
2952
+ self.skipTest('Data API does not surface vector information')
2953
+
2954
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
2955
+ out = list(self.cur)
2956
+ if not out or out[0][1].lower() == 'off':
2957
+ self.skipTest('Database engine does not support extended types metadata')
2958
+
2959
+ self.cur.execute('select a from f64_vectors order by id')
2960
+ out = list(self.cur)
2961
+
2962
+ if hasattr(out[0][0], 'dtype'):
2963
+ assert out[0][0].dtype is np.dtype('float64')
2964
+ assert out[1][0].dtype is np.dtype('float64')
2965
+ assert out[2][0].dtype is np.dtype('float64')
2966
+
2967
+ np.testing.assert_array_equal(
2968
+ out[0][0],
2969
+ np.array([0.267261237, 0.534522474, 0.801783681], dtype=np.float64),
2970
+ )
2971
+ np.testing.assert_array_equal(
2972
+ out[1][0],
2973
+ np.array([0.371390671, 0.557085991, 0.742781341], dtype=np.float64),
2974
+ )
2975
+ np.testing.assert_array_equal(
2976
+ out[2][0],
2977
+ np.array([-0.424264073, -0.565685451, 0.707106829], dtype=np.float64),
2978
+ )
2979
+
2980
+ def test_i8_vectors(self):
2981
+ if self.conn.driver in ['http', 'https']:
2982
+ self.skipTest('Data API does not surface vector information')
2983
+
2984
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
2985
+ out = list(self.cur)
2986
+ if not out or out[0][1].lower() == 'off':
2987
+ self.skipTest('Database engine does not support extended types metadata')
2988
+
2989
+ self.cur.execute('select a from i8_vectors order by id')
2990
+ out = list(self.cur)
2991
+
2992
+ if hasattr(out[0][0], 'dtype'):
2993
+ assert out[0][0].dtype is np.dtype('int8')
2994
+ assert out[1][0].dtype is np.dtype('int8')
2995
+ assert out[2][0].dtype is np.dtype('int8')
2996
+
2997
+ np.testing.assert_array_equal(
2998
+ out[0][0],
2999
+ np.array([1, 2, 3], dtype=np.int8),
3000
+ )
3001
+ np.testing.assert_array_equal(
3002
+ out[1][0],
3003
+ np.array([4, 5, 6], dtype=np.int8),
3004
+ )
3005
+ np.testing.assert_array_equal(
3006
+ out[2][0],
3007
+ np.array([-1, -4, 8], dtype=np.int8),
3008
+ )
3009
+
3010
+ def test_i16_vectors(self):
3011
+ if self.conn.driver in ['http', 'https']:
3012
+ self.skipTest('Data API does not surface vector information')
3013
+
3014
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
3015
+ out = list(self.cur)
3016
+ if not out or out[0][1].lower() == 'off':
3017
+ self.skipTest('Database engine does not support extended types metadata')
3018
+
3019
+ self.cur.execute('select a from i16_vectors order by id')
3020
+ out = list(self.cur)
3021
+
3022
+ if hasattr(out[0][0], 'dtype'):
3023
+ assert out[0][0].dtype is np.dtype('int16')
3024
+ assert out[1][0].dtype is np.dtype('int16')
3025
+ assert out[2][0].dtype is np.dtype('int16')
3026
+
3027
+ np.testing.assert_array_equal(
3028
+ out[0][0],
3029
+ np.array([1, 2, 3], dtype=np.int16),
3030
+ )
3031
+ np.testing.assert_array_equal(
3032
+ out[1][0],
3033
+ np.array([4, 5, 6], dtype=np.int16),
3034
+ )
3035
+ np.testing.assert_array_equal(
3036
+ out[2][0],
3037
+ np.array([-1, -4, 8], dtype=np.int16),
3038
+ )
3039
+
3040
+ def test_i32_vectors(self):
3041
+ if self.conn.driver in ['http', 'https']:
3042
+ self.skipTest('Data API does not surface vector information')
3043
+
3044
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
3045
+ out = list(self.cur)
3046
+ if not out or out[0][1].lower() == 'off':
3047
+ self.skipTest('Database engine does not support extended types metadata')
3048
+
3049
+ self.cur.execute('select a from i32_vectors order by id')
3050
+ out = list(self.cur)
3051
+
3052
+ if hasattr(out[0][0], 'dtype'):
3053
+ assert out[0][0].dtype is np.dtype('int32')
3054
+ assert out[1][0].dtype is np.dtype('int32')
3055
+ assert out[2][0].dtype is np.dtype('int32')
3056
+
3057
+ np.testing.assert_array_equal(
3058
+ out[0][0],
3059
+ np.array([1, 2, 3], dtype=np.int32),
3060
+ )
3061
+ np.testing.assert_array_equal(
3062
+ out[1][0],
3063
+ np.array([4, 5, 6], dtype=np.int32),
3064
+ )
3065
+ np.testing.assert_array_equal(
3066
+ out[2][0],
3067
+ np.array([-1, -4, 8], dtype=np.int32),
3068
+ )
3069
+
3070
+ def test_i64_vectors(self):
3071
+ if self.conn.driver in ['http', 'https']:
3072
+ self.skipTest('Data API does not surface vector information')
3073
+
3074
+ self.cur.execute('show variables like "enable_extended_types_metadata"')
3075
+ out = list(self.cur)
3076
+ if not out or out[0][1].lower() == 'off':
3077
+ self.skipTest('Database engine does not support extended types metadata')
3078
+
3079
+ self.cur.execute('select a from i64_vectors order by id')
3080
+ out = list(self.cur)
3081
+
3082
+ if hasattr(out[0][0], 'dtype'):
3083
+ assert out[0][0].dtype is np.dtype('int64')
3084
+ assert out[1][0].dtype is np.dtype('int64')
3085
+ assert out[2][0].dtype is np.dtype('int64')
3086
+
3087
+ np.testing.assert_array_equal(
3088
+ out[0][0],
3089
+ np.array([1, 2, 3], dtype=np.int64),
3090
+ )
3091
+ np.testing.assert_array_equal(
3092
+ out[1][0],
3093
+ np.array([4, 5, 6], dtype=np.int64),
3094
+ )
3095
+ np.testing.assert_array_equal(
3096
+ out[2][0],
3097
+ np.array([-1, -4, 8], dtype=np.int64),
3098
+ )
3099
+
3100
+
3101
+ if __name__ == '__main__':
3102
+ import nose2
3103
+ nose2.main()