singlestoredb 0.4.0__py3-none-any.whl → 1.0.4__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.
Potentially problematic release.
This version of singlestoredb might be problematic. Click here for more details.
- singlestoredb/__init__.py +33 -1
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/auth.py +5 -1
- singlestoredb/config.py +116 -14
- singlestoredb/connection.py +483 -516
- singlestoredb/converters.py +238 -135
- singlestoredb/exceptions.py +30 -2
- singlestoredb/functions/__init__.py +1 -0
- singlestoredb/functions/decorator.py +142 -0
- singlestoredb/functions/dtypes.py +1639 -0
- singlestoredb/functions/ext/__init__.py +2 -0
- singlestoredb/functions/ext/arrow.py +375 -0
- singlestoredb/functions/ext/asgi.py +661 -0
- singlestoredb/functions/ext/json.py +427 -0
- singlestoredb/functions/ext/mmap.py +306 -0
- singlestoredb/functions/ext/rowdat_1.py +744 -0
- singlestoredb/functions/signature.py +673 -0
- singlestoredb/fusion/__init__.py +11 -0
- singlestoredb/fusion/graphql.py +213 -0
- singlestoredb/fusion/handler.py +621 -0
- singlestoredb/fusion/handlers/stage.py +257 -0
- singlestoredb/fusion/handlers/utils.py +162 -0
- singlestoredb/fusion/handlers/workspace.py +412 -0
- singlestoredb/fusion/registry.py +164 -0
- singlestoredb/fusion/result.py +399 -0
- singlestoredb/http/__init__.py +27 -0
- singlestoredb/{http.py → http/connection.py} +555 -154
- singlestoredb/management/__init__.py +3 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +14 -6
- singlestoredb/management/manager.py +100 -38
- singlestoredb/management/organization.py +188 -0
- singlestoredb/management/region.py +5 -5
- singlestoredb/management/utils.py +281 -2
- singlestoredb/management/workspace.py +1344 -49
- singlestoredb/{clients/pymysqlsv → mysql}/__init__.py +16 -21
- singlestoredb/{clients/pymysqlsv → mysql}/_auth.py +39 -8
- singlestoredb/{clients/pymysqlsv → mysql}/charset.py +26 -23
- singlestoredb/{clients/pymysqlsv/connections.py → mysql/connection.py} +532 -165
- singlestoredb/{clients/pymysqlsv → mysql}/constants/CLIENT.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/COMMAND.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/CR.py +0 -2
- singlestoredb/{clients/pymysqlsv → mysql}/constants/ER.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/FIELD_TYPE.py +1 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/FLAG.py +0 -1
- singlestoredb/{clients/pymysqlsv → mysql}/constants/SERVER_STATUS.py +0 -1
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/{clients/pymysqlsv → mysql}/cursors.py +228 -112
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/{clients/pymysqlsv → mysql}/optionfile.py +5 -4
- singlestoredb/{clients/pymysqlsv → mysql}/protocol.py +49 -20
- singlestoredb/mysql/tests/__init__.py +19 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/base.py +32 -12
- singlestoredb/mysql/tests/conftest.py +37 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_DictCursor.py +11 -7
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_SSCursor.py +17 -12
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_basic.py +32 -24
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_connection.py +130 -119
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_converters.py +9 -7
- singlestoredb/mysql/tests/test_cursor.py +141 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_err.py +3 -2
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_issues.py +35 -27
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_load_local.py +13 -11
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_nextset.py +7 -3
- singlestoredb/{clients/pymysqlsv → mysql}/tests/test_optionfile.py +2 -1
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/__init__.py +1 -1
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/capabilities.py +19 -17
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/dbapi20.py +31 -22
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +3 -4
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +24 -20
- singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +4 -4
- singlestoredb/{clients/pymysqlsv → mysql}/times.py +3 -4
- singlestoredb/pytest.py +283 -0
- singlestoredb/tests/empty.sql +0 -0
- singlestoredb/tests/ext_funcs/__init__.py +385 -0
- singlestoredb/tests/test.sql +210 -0
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_basics.py +482 -115
- singlestoredb/tests/test_config.py +13 -13
- singlestoredb/tests/test_connection.py +241 -305
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_ext_func.py +1193 -0
- singlestoredb/tests/test_ext_func_data.py +1101 -0
- singlestoredb/tests/test_fusion.py +465 -0
- singlestoredb/tests/test_http.py +32 -26
- singlestoredb/tests/test_management.py +588 -8
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +11 -12
- singlestoredb/tests/test_udf.py +687 -0
- singlestoredb/tests/utils.py +3 -2
- singlestoredb/utils/config.py +58 -0
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +4 -1
- singlestoredb-1.0.4.dist-info/METADATA +139 -0
- singlestoredb-1.0.4.dist-info/RECORD +112 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/WHEEL +1 -1
- singlestoredb-1.0.4.dist-info/entry_points.txt +2 -0
- singlestoredb/clients/pymysqlsv/converters.py +0 -365
- singlestoredb/clients/pymysqlsv/err.py +0 -144
- singlestoredb/clients/pymysqlsv/tests/__init__.py +0 -19
- singlestoredb/clients/pymysqlsv/tests/test_cursor.py +0 -133
- singlestoredb/clients/pymysqlsv/tests/thirdparty/test_MySQLdb/__init__.py +0 -9
- singlestoredb/drivers/__init__.py +0 -45
- singlestoredb/drivers/base.py +0 -198
- singlestoredb/drivers/cymysql.py +0 -38
- singlestoredb/drivers/http.py +0 -47
- singlestoredb/drivers/mariadb.py +0 -40
- singlestoredb/drivers/mysqlconnector.py +0 -49
- singlestoredb/drivers/mysqldb.py +0 -60
- singlestoredb/drivers/pymysql.py +0 -37
- singlestoredb/drivers/pymysqlsv.py +0 -35
- singlestoredb/drivers/pyodbc.py +0 -65
- singlestoredb-0.4.0.dist-info/METADATA +0 -111
- singlestoredb-0.4.0.dist-info/RECORD +0 -86
- /singlestoredb/{clients → fusion/handlers}/__init__.py +0 -0
- /singlestoredb/{clients/pymysqlsv → mysql}/constants/__init__.py +0 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/LICENSE +0 -0
- {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# type: ignore
|
|
3
|
+
"""SingleStoreDB UDF testing."""
|
|
4
|
+
import datetime
|
|
5
|
+
import re
|
|
6
|
+
import unittest
|
|
7
|
+
from typing import List
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from typing import Tuple
|
|
10
|
+
from typing import TypeVar
|
|
11
|
+
from typing import Union
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
from ..functions import dtypes as dt
|
|
16
|
+
from ..functions import signature as sig
|
|
17
|
+
from ..functions import udf
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
A = TypeVar('A', bytearray, bytes, None)
|
|
21
|
+
B = TypeVar('B', int, float, np.int64, np.int32, np.uint16)
|
|
22
|
+
C = TypeVar('C', B, np.int8)
|
|
23
|
+
D = TypeVar('D', bound=str)
|
|
24
|
+
E = Optional[List[Optional[Union[float, int]]]]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def to_sql(x):
|
|
28
|
+
out = sig.signature_to_sql(sig.get_signature(x))
|
|
29
|
+
out = re.sub(r'^CREATE EXTERNAL FUNCTION ', r'', out)
|
|
30
|
+
out = re.sub(r' AS REMOTE SERVICE.+$', r'', out)
|
|
31
|
+
return out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TestUDF(unittest.TestCase):
|
|
35
|
+
|
|
36
|
+
def test_return_annotations(self):
|
|
37
|
+
|
|
38
|
+
# No annotations
|
|
39
|
+
def foo(): ...
|
|
40
|
+
with self.assertRaises(TypeError):
|
|
41
|
+
to_sql(foo)
|
|
42
|
+
|
|
43
|
+
# NULL return value
|
|
44
|
+
def foo() -> None: ...
|
|
45
|
+
assert to_sql(foo) == '`foo`() RETURNS NULL'
|
|
46
|
+
|
|
47
|
+
# Simple return value
|
|
48
|
+
def foo() -> int: ...
|
|
49
|
+
assert to_sql(foo) == '`foo`() RETURNS BIGINT NOT NULL'
|
|
50
|
+
|
|
51
|
+
# Simple return value
|
|
52
|
+
def foo() -> np.int8: ...
|
|
53
|
+
assert to_sql(foo) == '`foo`() RETURNS TINYINT NOT NULL'
|
|
54
|
+
|
|
55
|
+
# Optional return value
|
|
56
|
+
def foo() -> Optional[int]: ...
|
|
57
|
+
assert to_sql(foo) == '`foo`() RETURNS BIGINT NULL'
|
|
58
|
+
|
|
59
|
+
# Optional return value
|
|
60
|
+
def foo() -> Union[int, None]: ...
|
|
61
|
+
assert to_sql(foo) == '`foo`() RETURNS BIGINT NULL'
|
|
62
|
+
|
|
63
|
+
# Optional return value with multiple types
|
|
64
|
+
def foo() -> Union[int, float, None]: ...
|
|
65
|
+
assert to_sql(foo) == '`foo`() RETURNS DOUBLE NULL'
|
|
66
|
+
|
|
67
|
+
# Optional return value with custom type
|
|
68
|
+
def foo() -> Optional[B]: ...
|
|
69
|
+
assert to_sql(foo) == '`foo`() RETURNS DOUBLE NULL'
|
|
70
|
+
|
|
71
|
+
# Optional return value with nested custom type
|
|
72
|
+
def foo() -> Optional[C]: ...
|
|
73
|
+
assert to_sql(foo) == '`foo`() RETURNS DOUBLE NULL'
|
|
74
|
+
|
|
75
|
+
# Optional return value with collection type
|
|
76
|
+
def foo() -> Optional[List[str]]: ...
|
|
77
|
+
assert to_sql(foo) == '`foo`() RETURNS ARRAY(TEXT NOT NULL) NULL'
|
|
78
|
+
|
|
79
|
+
# Optional return value with nested collection type
|
|
80
|
+
def foo() -> Optional[List[List[str]]]: ...
|
|
81
|
+
assert to_sql(foo) == '`foo`() RETURNS ARRAY(ARRAY(TEXT NOT NULL) NOT NULL) NULL'
|
|
82
|
+
|
|
83
|
+
# Optional return value with collection type with nulls
|
|
84
|
+
def foo() -> Optional[List[Optional[str]]]: ...
|
|
85
|
+
assert to_sql(foo) == '`foo`() RETURNS ARRAY(TEXT NULL) NULL'
|
|
86
|
+
|
|
87
|
+
# Custom type with bound
|
|
88
|
+
def foo() -> D: ...
|
|
89
|
+
assert to_sql(foo) == '`foo`() RETURNS TEXT NOT NULL'
|
|
90
|
+
|
|
91
|
+
# Return value with custom collection type with nulls
|
|
92
|
+
def foo() -> E: ...
|
|
93
|
+
assert to_sql(foo) == '`foo`() RETURNS ARRAY(DOUBLE NULL) NULL'
|
|
94
|
+
|
|
95
|
+
# Incompatible types
|
|
96
|
+
def foo() -> Union[int, str]: ...
|
|
97
|
+
with self.assertRaises(TypeError):
|
|
98
|
+
to_sql(foo)
|
|
99
|
+
|
|
100
|
+
# Tuple
|
|
101
|
+
def foo() -> Tuple[int, float, str]: ...
|
|
102
|
+
assert to_sql(foo) == '`foo`() RETURNS RECORD(a BIGINT NOT NULL, ' \
|
|
103
|
+
'b DOUBLE NOT NULL, ' \
|
|
104
|
+
'c TEXT NOT NULL) NOT NULL'
|
|
105
|
+
|
|
106
|
+
# Optional tuple
|
|
107
|
+
def foo() -> Optional[Tuple[int, float, str]]: ...
|
|
108
|
+
assert to_sql(foo) == '`foo`() RETURNS RECORD(a BIGINT NOT NULL, ' \
|
|
109
|
+
'b DOUBLE NOT NULL, ' \
|
|
110
|
+
'c TEXT NOT NULL) NULL'
|
|
111
|
+
|
|
112
|
+
# Optional tuple with optional element
|
|
113
|
+
def foo() -> Optional[Tuple[int, float, Optional[str]]]: ...
|
|
114
|
+
assert to_sql(foo) == '`foo`() RETURNS RECORD(a BIGINT NOT NULL, ' \
|
|
115
|
+
'b DOUBLE NOT NULL, ' \
|
|
116
|
+
'c TEXT NULL) NULL'
|
|
117
|
+
|
|
118
|
+
# Optional tuple with optional union element
|
|
119
|
+
def foo() -> Optional[Tuple[int, Optional[Union[float, int]], str]]: ...
|
|
120
|
+
assert to_sql(foo) == '`foo`() RETURNS RECORD(a BIGINT NOT NULL, ' \
|
|
121
|
+
'b DOUBLE NULL, ' \
|
|
122
|
+
'c TEXT NOT NULL) NULL'
|
|
123
|
+
|
|
124
|
+
# Unknown type
|
|
125
|
+
def foo() -> set: ...
|
|
126
|
+
with self.assertRaises(TypeError) as exc:
|
|
127
|
+
to_sql(foo)
|
|
128
|
+
assert 'unsupported type annotation' in str(exc.exception)
|
|
129
|
+
|
|
130
|
+
def test_parameter_annotations(self):
|
|
131
|
+
|
|
132
|
+
# No annotations
|
|
133
|
+
def foo(x) -> None: ...
|
|
134
|
+
with self.assertRaises(TypeError):
|
|
135
|
+
to_sql(foo)
|
|
136
|
+
|
|
137
|
+
# Simple parameter
|
|
138
|
+
def foo(x: int) -> None: ...
|
|
139
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS NULL'
|
|
140
|
+
|
|
141
|
+
# Optional parameter
|
|
142
|
+
def foo(x: Optional[int]) -> None: ...
|
|
143
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NULL) RETURNS NULL'
|
|
144
|
+
|
|
145
|
+
# Optional parameter
|
|
146
|
+
def foo(x: Union[int, None]) -> None: ...
|
|
147
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NULL) RETURNS NULL'
|
|
148
|
+
|
|
149
|
+
# Optional multiple parameter types
|
|
150
|
+
def foo(x: Union[int, float, None]) -> None: ...
|
|
151
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NULL) RETURNS NULL'
|
|
152
|
+
|
|
153
|
+
# Optional parameter with custom type
|
|
154
|
+
def foo(x: Optional[B]) -> None: ...
|
|
155
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NULL) RETURNS NULL'
|
|
156
|
+
|
|
157
|
+
# Optional parameter with nested custom type
|
|
158
|
+
def foo(x: Optional[C]) -> None: ...
|
|
159
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NULL) RETURNS NULL'
|
|
160
|
+
|
|
161
|
+
# Optional parameter with collection type
|
|
162
|
+
def foo(x: Optional[List[str]]) -> None: ...
|
|
163
|
+
assert to_sql(foo) == '`foo`(`x` ARRAY(TEXT NOT NULL) NULL) RETURNS NULL'
|
|
164
|
+
|
|
165
|
+
# Optional parameter with nested collection type
|
|
166
|
+
def foo(x: Optional[List[List[str]]]) -> None: ...
|
|
167
|
+
assert to_sql(foo) == '`foo`(`x` ARRAY(ARRAY(TEXT NOT NULL) NOT NULL) NULL) ' \
|
|
168
|
+
'RETURNS NULL'
|
|
169
|
+
|
|
170
|
+
# Optional parameter with collection type with nulls
|
|
171
|
+
def foo(x: Optional[List[Optional[str]]]) -> None: ...
|
|
172
|
+
assert to_sql(foo) == '`foo`(`x` ARRAY(TEXT NULL) NULL) RETURNS NULL'
|
|
173
|
+
|
|
174
|
+
# Custom type with bound
|
|
175
|
+
def foo(x: D) -> None: ...
|
|
176
|
+
assert to_sql(foo) == '`foo`(`x` TEXT NOT NULL) RETURNS NULL'
|
|
177
|
+
|
|
178
|
+
# Incompatible types
|
|
179
|
+
def foo(x: Union[int, str]) -> None: ...
|
|
180
|
+
with self.assertRaises(TypeError):
|
|
181
|
+
to_sql(foo)
|
|
182
|
+
|
|
183
|
+
# Tuple
|
|
184
|
+
def foo(x: Tuple[int, float, str]) -> None: ...
|
|
185
|
+
assert to_sql(foo) == '`foo`(`x` RECORD(a BIGINT NOT NULL, ' \
|
|
186
|
+
'b DOUBLE NOT NULL, ' \
|
|
187
|
+
'c TEXT NOT NULL) NOT NULL) RETURNS NULL'
|
|
188
|
+
|
|
189
|
+
# Optional tuple with optional element
|
|
190
|
+
def foo(x: Optional[Tuple[int, float, Optional[str]]]) -> None: ...
|
|
191
|
+
assert to_sql(foo) == '`foo`(`x` RECORD(a BIGINT NOT NULL, ' \
|
|
192
|
+
'b DOUBLE NOT NULL, ' \
|
|
193
|
+
'c TEXT NULL) NULL) RETURNS NULL'
|
|
194
|
+
|
|
195
|
+
# Optional tuple with optional union element
|
|
196
|
+
def foo(x: Optional[Tuple[int, Optional[Union[float, int]], str]]) -> None: ...
|
|
197
|
+
assert to_sql(foo) == '`foo`(`x` RECORD(a BIGINT NOT NULL, ' \
|
|
198
|
+
'b DOUBLE NULL, ' \
|
|
199
|
+
'c TEXT NOT NULL) NULL) RETURNS NULL'
|
|
200
|
+
|
|
201
|
+
# Unknown type
|
|
202
|
+
def foo(x: set) -> None: ...
|
|
203
|
+
with self.assertRaises(TypeError) as exc:
|
|
204
|
+
to_sql(foo)
|
|
205
|
+
assert 'unsupported type annotation' in str(exc.exception)
|
|
206
|
+
|
|
207
|
+
def test_datetimes(self):
|
|
208
|
+
|
|
209
|
+
# Datetime
|
|
210
|
+
def foo(x: datetime.datetime) -> None: ...
|
|
211
|
+
assert to_sql(foo) == '`foo`(`x` DATETIME NOT NULL) RETURNS NULL'
|
|
212
|
+
|
|
213
|
+
# Date
|
|
214
|
+
def foo(x: datetime.date) -> None: ...
|
|
215
|
+
assert to_sql(foo) == '`foo`(`x` DATE NOT NULL) RETURNS NULL'
|
|
216
|
+
|
|
217
|
+
# Time
|
|
218
|
+
def foo(x: datetime.timedelta) -> None: ...
|
|
219
|
+
assert to_sql(foo) == '`foo`(`x` TIME NOT NULL) RETURNS NULL'
|
|
220
|
+
|
|
221
|
+
# Datetime + Date
|
|
222
|
+
def foo(x: Union[datetime.datetime, datetime.date]) -> None: ...
|
|
223
|
+
with self.assertRaises(TypeError):
|
|
224
|
+
to_sql(foo)
|
|
225
|
+
|
|
226
|
+
def test_numerics(self):
|
|
227
|
+
#
|
|
228
|
+
# Ints
|
|
229
|
+
#
|
|
230
|
+
def foo(x: int) -> None: ...
|
|
231
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS NULL'
|
|
232
|
+
|
|
233
|
+
def foo(x: np.int8) -> None: ...
|
|
234
|
+
assert to_sql(foo) == '`foo`(`x` TINYINT NOT NULL) RETURNS NULL'
|
|
235
|
+
|
|
236
|
+
def foo(x: np.int16) -> None: ...
|
|
237
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NOT NULL) RETURNS NULL'
|
|
238
|
+
|
|
239
|
+
def foo(x: np.int32) -> None: ...
|
|
240
|
+
assert to_sql(foo) == '`foo`(`x` INT NOT NULL) RETURNS NULL'
|
|
241
|
+
|
|
242
|
+
def foo(x: np.int64) -> None: ...
|
|
243
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS NULL'
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# Unsigned ints
|
|
247
|
+
#
|
|
248
|
+
def foo(x: np.uint8) -> None: ...
|
|
249
|
+
assert to_sql(foo) == '`foo`(`x` TINYINT UNSIGNED NOT NULL) RETURNS NULL'
|
|
250
|
+
|
|
251
|
+
def foo(x: np.uint16) -> None: ...
|
|
252
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT UNSIGNED NOT NULL) RETURNS NULL'
|
|
253
|
+
|
|
254
|
+
def foo(x: np.uint32) -> None: ...
|
|
255
|
+
assert to_sql(foo) == '`foo`(`x` INT UNSIGNED NOT NULL) RETURNS NULL'
|
|
256
|
+
|
|
257
|
+
def foo(x: np.uint64) -> None: ...
|
|
258
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT UNSIGNED NOT NULL) RETURNS NULL'
|
|
259
|
+
|
|
260
|
+
#
|
|
261
|
+
# Floats
|
|
262
|
+
#
|
|
263
|
+
def foo(x: float) -> None: ...
|
|
264
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NOT NULL) RETURNS NULL'
|
|
265
|
+
|
|
266
|
+
def foo(x: np.float32) -> None: ...
|
|
267
|
+
assert to_sql(foo) == '`foo`(`x` FLOAT NOT NULL) RETURNS NULL'
|
|
268
|
+
|
|
269
|
+
def foo(x: np.float64) -> None: ...
|
|
270
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NOT NULL) RETURNS NULL'
|
|
271
|
+
|
|
272
|
+
#
|
|
273
|
+
# Type collapsing
|
|
274
|
+
#
|
|
275
|
+
def foo(x: Union[np.int8, np.int16]) -> None: ...
|
|
276
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NOT NULL) RETURNS NULL'
|
|
277
|
+
|
|
278
|
+
def foo(x: Union[np.int64, np.double]) -> None: ...
|
|
279
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NOT NULL) RETURNS NULL'
|
|
280
|
+
|
|
281
|
+
def foo(x: Union[int, float]) -> None: ...
|
|
282
|
+
assert to_sql(foo) == '`foo`(`x` DOUBLE NOT NULL) RETURNS NULL'
|
|
283
|
+
|
|
284
|
+
def test_positional_and_keyword_parameters(self):
|
|
285
|
+
# Keyword only
|
|
286
|
+
def foo(x: int = 100) -> None: ...
|
|
287
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL DEFAULT 100) RETURNS NULL'
|
|
288
|
+
|
|
289
|
+
# Multiple keywords
|
|
290
|
+
def foo(x: int = 100, y: float = 3.14) -> None: ...
|
|
291
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL DEFAULT 100, ' \
|
|
292
|
+
'`y` DOUBLE NOT NULL DEFAULT 3.14e0) RETURNS NULL'
|
|
293
|
+
|
|
294
|
+
# Keywords and positional
|
|
295
|
+
def foo(a: str, b: str, x: int = 100, y: float = 3.14) -> None: ...
|
|
296
|
+
assert to_sql(foo) == '`foo`(`a` TEXT NOT NULL, ' \
|
|
297
|
+
'`b` TEXT NOT NULL, ' \
|
|
298
|
+
'`x` BIGINT NOT NULL DEFAULT 100, ' \
|
|
299
|
+
'`y` DOUBLE NOT NULL DEFAULT 3.14e0) RETURNS NULL'
|
|
300
|
+
|
|
301
|
+
# Variable positional
|
|
302
|
+
def foo(*args: int) -> None: ...
|
|
303
|
+
with self.assertRaises(TypeError):
|
|
304
|
+
to_sql(foo)
|
|
305
|
+
|
|
306
|
+
# Variable keywords
|
|
307
|
+
def foo(x: int = 100, **kwargs: float) -> None: ...
|
|
308
|
+
with self.assertRaises(TypeError):
|
|
309
|
+
to_sql(foo)
|
|
310
|
+
|
|
311
|
+
def test_udf(self):
|
|
312
|
+
|
|
313
|
+
# No parameters
|
|
314
|
+
@udf
|
|
315
|
+
def foo(x: int) -> int: ...
|
|
316
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS BIGINT NOT NULL'
|
|
317
|
+
|
|
318
|
+
# No parameters
|
|
319
|
+
@udf()
|
|
320
|
+
def foo(x: int) -> int: ...
|
|
321
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS BIGINT NOT NULL'
|
|
322
|
+
|
|
323
|
+
# Override return value with callable
|
|
324
|
+
@udf(returns=dt.SMALLINT)
|
|
325
|
+
def foo(x: int) -> int: ...
|
|
326
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS SMALLINT NULL'
|
|
327
|
+
|
|
328
|
+
# Override return value with string
|
|
329
|
+
@udf(returns=dt.SMALLINT(nullable=False))
|
|
330
|
+
def foo(x: int) -> int: ...
|
|
331
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS SMALLINT NOT NULL'
|
|
332
|
+
|
|
333
|
+
# Override multiple params with one type
|
|
334
|
+
@udf(args=dt.SMALLINT(nullable=False))
|
|
335
|
+
def foo(x: int, y: float, z: np.int8) -> int: ...
|
|
336
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NOT NULL, ' \
|
|
337
|
+
'`y` SMALLINT NOT NULL, ' \
|
|
338
|
+
'`z` SMALLINT NOT NULL) RETURNS BIGINT NOT NULL'
|
|
339
|
+
|
|
340
|
+
# Override with list
|
|
341
|
+
@udf(args=[dt.SMALLINT, dt.FLOAT, dt.CHAR(30)])
|
|
342
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
343
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NULL, ' \
|
|
344
|
+
'`y` FLOAT NULL, ' \
|
|
345
|
+
'`z` CHAR(30) NULL) RETURNS BIGINT NOT NULL'
|
|
346
|
+
|
|
347
|
+
# Override with too short of a list
|
|
348
|
+
@udf(args=[dt.SMALLINT, dt.FLOAT])
|
|
349
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
350
|
+
with self.assertRaises(TypeError):
|
|
351
|
+
to_sql(foo)
|
|
352
|
+
|
|
353
|
+
# Override with too long of a list
|
|
354
|
+
@udf(args=[dt.SMALLINT, dt.FLOAT, dt.CHAR(30), dt.TEXT])
|
|
355
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
356
|
+
with self.assertRaises(TypeError):
|
|
357
|
+
to_sql(foo)
|
|
358
|
+
|
|
359
|
+
# Override with list
|
|
360
|
+
@udf(args=[dt.SMALLINT, dt.FLOAT, dt.CHAR(30)])
|
|
361
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
362
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NULL, ' \
|
|
363
|
+
'`y` FLOAT NULL, ' \
|
|
364
|
+
'`z` CHAR(30) NULL) RETURNS BIGINT NOT NULL'
|
|
365
|
+
|
|
366
|
+
# Override with dict
|
|
367
|
+
@udf(args=dict(x=dt.SMALLINT, z=dt.CHAR(30)))
|
|
368
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
369
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NULL, ' \
|
|
370
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
371
|
+
'`z` CHAR(30) NULL) RETURNS BIGINT NOT NULL'
|
|
372
|
+
|
|
373
|
+
# Override with empty dict
|
|
374
|
+
@udf(args=dict())
|
|
375
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
376
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL, ' \
|
|
377
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
378
|
+
'`z` TEXT NOT NULL) RETURNS BIGINT NOT NULL'
|
|
379
|
+
|
|
380
|
+
# Override with dict with extra keys
|
|
381
|
+
@udf(args=dict(bar=dt.INT))
|
|
382
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
383
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL, ' \
|
|
384
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
385
|
+
'`z` TEXT NOT NULL) RETURNS BIGINT NOT NULL'
|
|
386
|
+
|
|
387
|
+
# Override parameters and return value
|
|
388
|
+
@udf(args=dict(x=dt.SMALLINT, z=dt.CHAR(30)), returns=dt.SMALLINT(nullable=False))
|
|
389
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
390
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NULL, ' \
|
|
391
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
392
|
+
'`z` CHAR(30) NULL) RETURNS SMALLINT NOT NULL'
|
|
393
|
+
|
|
394
|
+
# Override parameter with incorrect type
|
|
395
|
+
with self.assertRaises(TypeError):
|
|
396
|
+
@udf(args=dict(x=int))
|
|
397
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
398
|
+
|
|
399
|
+
# Override return value with incorrect type
|
|
400
|
+
with self.assertRaises(TypeError):
|
|
401
|
+
@udf(returns=int)
|
|
402
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
403
|
+
|
|
404
|
+
# Change function name
|
|
405
|
+
@udf(name='hello_world')
|
|
406
|
+
def foo(x: int) -> int: ...
|
|
407
|
+
assert to_sql(foo) == '`hello_world`(`x` BIGINT NOT NULL) ' \
|
|
408
|
+
'RETURNS BIGINT NOT NULL'
|
|
409
|
+
|
|
410
|
+
@udf(name='hello`_`world')
|
|
411
|
+
def foo(x: int) -> int: ...
|
|
412
|
+
assert to_sql(foo) == '`hello``_``world`(`x` BIGINT NOT NULL) ' \
|
|
413
|
+
'RETURNS BIGINT NOT NULL'
|
|
414
|
+
|
|
415
|
+
def test_dtypes(self):
|
|
416
|
+
assert dt.BOOL() == 'BOOL NULL'
|
|
417
|
+
assert dt.BOOL(nullable=False) == 'BOOL NOT NULL'
|
|
418
|
+
assert dt.BOOL(default=False) == 'BOOL NULL DEFAULT 0'
|
|
419
|
+
assert dt.BOOL(default=True) == 'BOOL NULL DEFAULT 1'
|
|
420
|
+
assert dt.BOOL(default='a') == 'BOOL NULL DEFAULT 1'
|
|
421
|
+
|
|
422
|
+
assert dt.BOOLEAN() == 'BOOLEAN NULL'
|
|
423
|
+
assert dt.BOOLEAN(nullable=False) == 'BOOLEAN NOT NULL'
|
|
424
|
+
assert dt.BOOLEAN(default=False) == 'BOOLEAN NULL DEFAULT 0'
|
|
425
|
+
assert dt.BOOLEAN(default=True) == 'BOOLEAN NULL DEFAULT 1'
|
|
426
|
+
assert dt.BOOLEAN(default='a') == 'BOOLEAN NULL DEFAULT 1'
|
|
427
|
+
|
|
428
|
+
assert dt.BIT() == 'BIT NULL'
|
|
429
|
+
assert dt.BIT(nullable=False) == 'BIT NOT NULL'
|
|
430
|
+
assert dt.BIT(default=100) == 'BIT NULL DEFAULT 100'
|
|
431
|
+
|
|
432
|
+
assert dt.TINYINT() == 'TINYINT NULL'
|
|
433
|
+
assert dt.TINYINT(5) == 'TINYINT(5) NULL'
|
|
434
|
+
assert dt.TINYINT(nullable=False) == 'TINYINT NOT NULL'
|
|
435
|
+
assert dt.TINYINT(default=100) == 'TINYINT NULL DEFAULT 100'
|
|
436
|
+
assert dt.TINYINT(unsigned=True, default=100) == \
|
|
437
|
+
'TINYINT UNSIGNED NULL DEFAULT 100'
|
|
438
|
+
|
|
439
|
+
assert dt.TINYINT_UNSIGNED() == 'TINYINT UNSIGNED NULL'
|
|
440
|
+
assert dt.TINYINT_UNSIGNED(5) == 'TINYINT(5) UNSIGNED NULL'
|
|
441
|
+
assert dt.TINYINT_UNSIGNED(nullable=False) == 'TINYINT UNSIGNED NOT NULL'
|
|
442
|
+
assert dt.TINYINT_UNSIGNED(default=100) == 'TINYINT UNSIGNED NULL DEFAULT 100'
|
|
443
|
+
|
|
444
|
+
assert dt.SMALLINT() == 'SMALLINT NULL'
|
|
445
|
+
assert dt.SMALLINT(5) == 'SMALLINT(5) NULL'
|
|
446
|
+
assert dt.SMALLINT(nullable=False) == 'SMALLINT NOT NULL'
|
|
447
|
+
assert dt.SMALLINT(default=100) == 'SMALLINT NULL DEFAULT 100'
|
|
448
|
+
assert dt.SMALLINT(unsigned=True, default=100) == \
|
|
449
|
+
'SMALLINT UNSIGNED NULL DEFAULT 100'
|
|
450
|
+
|
|
451
|
+
assert dt.SMALLINT_UNSIGNED() == 'SMALLINT UNSIGNED NULL'
|
|
452
|
+
assert dt.SMALLINT_UNSIGNED(5) == 'SMALLINT(5) UNSIGNED NULL'
|
|
453
|
+
assert dt.SMALLINT_UNSIGNED(nullable=False) == 'SMALLINT UNSIGNED NOT NULL'
|
|
454
|
+
assert dt.SMALLINT_UNSIGNED(default=100) == \
|
|
455
|
+
'SMALLINT UNSIGNED NULL DEFAULT 100'
|
|
456
|
+
|
|
457
|
+
assert dt.MEDIUMINT() == 'MEDIUMINT NULL'
|
|
458
|
+
assert dt.MEDIUMINT(5) == 'MEDIUMINT(5) NULL'
|
|
459
|
+
assert dt.MEDIUMINT(nullable=False) == 'MEDIUMINT NOT NULL'
|
|
460
|
+
assert dt.MEDIUMINT(default=100) == 'MEDIUMINT NULL DEFAULT 100'
|
|
461
|
+
assert dt.MEDIUMINT(unsigned=True, default=100) == \
|
|
462
|
+
'MEDIUMINT UNSIGNED NULL DEFAULT 100'
|
|
463
|
+
|
|
464
|
+
assert dt.MEDIUMINT_UNSIGNED() == 'MEDIUMINT UNSIGNED NULL'
|
|
465
|
+
assert dt.MEDIUMINT_UNSIGNED(5) == 'MEDIUMINT(5) UNSIGNED NULL'
|
|
466
|
+
assert dt.MEDIUMINT_UNSIGNED(nullable=False) == 'MEDIUMINT UNSIGNED NOT NULL'
|
|
467
|
+
assert dt.MEDIUMINT_UNSIGNED(default=100) == \
|
|
468
|
+
'MEDIUMINT UNSIGNED NULL DEFAULT 100'
|
|
469
|
+
|
|
470
|
+
assert dt.INT() == 'INT NULL'
|
|
471
|
+
assert dt.INT(5) == 'INT(5) NULL'
|
|
472
|
+
assert dt.INT(nullable=False) == 'INT NOT NULL'
|
|
473
|
+
assert dt.INT(default=100) == 'INT NULL DEFAULT 100'
|
|
474
|
+
assert dt.INT(unsigned=True, default=100) == \
|
|
475
|
+
'INT UNSIGNED NULL DEFAULT 100'
|
|
476
|
+
|
|
477
|
+
assert dt.INT_UNSIGNED() == 'INT UNSIGNED NULL'
|
|
478
|
+
assert dt.INT_UNSIGNED(5) == 'INT(5) UNSIGNED NULL'
|
|
479
|
+
assert dt.INT_UNSIGNED(nullable=False) == 'INT UNSIGNED NOT NULL'
|
|
480
|
+
assert dt.INT_UNSIGNED(default=100) == \
|
|
481
|
+
'INT UNSIGNED NULL DEFAULT 100'
|
|
482
|
+
|
|
483
|
+
assert dt.INTEGER() == 'INTEGER NULL'
|
|
484
|
+
assert dt.INTEGER(5) == 'INTEGER(5) NULL'
|
|
485
|
+
assert dt.INTEGER(nullable=False) == 'INTEGER NOT NULL'
|
|
486
|
+
assert dt.INTEGER(default=100) == 'INTEGER NULL DEFAULT 100'
|
|
487
|
+
assert dt.INTEGER(unsigned=True, default=100) == \
|
|
488
|
+
'INTEGER UNSIGNED NULL DEFAULT 100'
|
|
489
|
+
|
|
490
|
+
assert dt.INTEGER_UNSIGNED() == 'INTEGER UNSIGNED NULL'
|
|
491
|
+
assert dt.INTEGER_UNSIGNED(5) == 'INTEGER(5) UNSIGNED NULL'
|
|
492
|
+
assert dt.INTEGER_UNSIGNED(nullable=False) == 'INTEGER UNSIGNED NOT NULL'
|
|
493
|
+
assert dt.INTEGER_UNSIGNED(default=100) == \
|
|
494
|
+
'INTEGER UNSIGNED NULL DEFAULT 100'
|
|
495
|
+
|
|
496
|
+
assert dt.BIGINT() == 'BIGINT NULL'
|
|
497
|
+
assert dt.BIGINT(5) == 'BIGINT(5) NULL'
|
|
498
|
+
assert dt.BIGINT(nullable=False) == 'BIGINT NOT NULL'
|
|
499
|
+
assert dt.BIGINT(default=100) == 'BIGINT NULL DEFAULT 100'
|
|
500
|
+
assert dt.BIGINT(unsigned=True, default=100) == \
|
|
501
|
+
'BIGINT UNSIGNED NULL DEFAULT 100'
|
|
502
|
+
|
|
503
|
+
assert dt.BIGINT_UNSIGNED() == 'BIGINT UNSIGNED NULL'
|
|
504
|
+
assert dt.BIGINT_UNSIGNED(5) == 'BIGINT(5) UNSIGNED NULL'
|
|
505
|
+
assert dt.BIGINT_UNSIGNED(nullable=False) == 'BIGINT UNSIGNED NOT NULL'
|
|
506
|
+
assert dt.BIGINT_UNSIGNED(default=100) == \
|
|
507
|
+
'BIGINT UNSIGNED NULL DEFAULT 100'
|
|
508
|
+
|
|
509
|
+
assert dt.BIGINT() == 'BIGINT NULL'
|
|
510
|
+
assert dt.BIGINT(5) == 'BIGINT(5) NULL'
|
|
511
|
+
assert dt.BIGINT(nullable=False) == 'BIGINT NOT NULL'
|
|
512
|
+
assert dt.BIGINT(default=100) == 'BIGINT NULL DEFAULT 100'
|
|
513
|
+
assert dt.BIGINT(unsigned=True, default=100) == \
|
|
514
|
+
'BIGINT UNSIGNED NULL DEFAULT 100'
|
|
515
|
+
|
|
516
|
+
assert dt.FLOAT() == 'FLOAT NULL'
|
|
517
|
+
assert dt.FLOAT(5) == 'FLOAT(5) NULL'
|
|
518
|
+
assert dt.FLOAT(nullable=False) == 'FLOAT NOT NULL'
|
|
519
|
+
assert dt.FLOAT(default=1.234) == 'FLOAT NULL DEFAULT 1.234e0'
|
|
520
|
+
|
|
521
|
+
assert dt.DOUBLE() == 'DOUBLE NULL'
|
|
522
|
+
assert dt.DOUBLE(5) == 'DOUBLE(5) NULL'
|
|
523
|
+
assert dt.DOUBLE(nullable=False) == 'DOUBLE NOT NULL'
|
|
524
|
+
assert dt.DOUBLE(default=1.234) == 'DOUBLE NULL DEFAULT 1.234e0'
|
|
525
|
+
|
|
526
|
+
assert dt.REAL() == 'REAL NULL'
|
|
527
|
+
assert dt.REAL(5) == 'REAL(5) NULL'
|
|
528
|
+
assert dt.REAL(nullable=False) == 'REAL NOT NULL'
|
|
529
|
+
assert dt.REAL(default=1.234) == 'REAL NULL DEFAULT 1.234e0'
|
|
530
|
+
|
|
531
|
+
with self.assertRaises(TypeError):
|
|
532
|
+
dt.DECIMAL()
|
|
533
|
+
with self.assertRaises(TypeError):
|
|
534
|
+
dt.DECIMAL(5)
|
|
535
|
+
assert dt.DECIMAL(10, 5) == 'DECIMAL(10, 5) NULL'
|
|
536
|
+
assert dt.DECIMAL(10, 5, nullable=False) == 'DECIMAL(10, 5) NOT NULL'
|
|
537
|
+
assert dt.DECIMAL(10, 5, default=1.234) == \
|
|
538
|
+
'DECIMAL(10, 5) NULL DEFAULT 1.234e0'
|
|
539
|
+
|
|
540
|
+
with self.assertRaises(TypeError):
|
|
541
|
+
dt.DEC()
|
|
542
|
+
with self.assertRaises(TypeError):
|
|
543
|
+
dt.DEC(5)
|
|
544
|
+
assert dt.DEC(10, 5) == 'DEC(10, 5) NULL'
|
|
545
|
+
assert dt.DEC(10, 5, nullable=False) == 'DEC(10, 5) NOT NULL'
|
|
546
|
+
assert dt.DEC(10, 5, default=1.234) == \
|
|
547
|
+
'DEC(10, 5) NULL DEFAULT 1.234e0'
|
|
548
|
+
|
|
549
|
+
with self.assertRaises(TypeError):
|
|
550
|
+
dt.FIXED()
|
|
551
|
+
with self.assertRaises(TypeError):
|
|
552
|
+
dt.FIXED(5)
|
|
553
|
+
assert dt.FIXED(10, 5) == 'FIXED(10, 5) NULL'
|
|
554
|
+
assert dt.FIXED(10, 5, nullable=False) == 'FIXED(10, 5) NOT NULL'
|
|
555
|
+
assert dt.FIXED(10, 5, default=1.234) == \
|
|
556
|
+
'FIXED(10, 5) NULL DEFAULT 1.234e0'
|
|
557
|
+
|
|
558
|
+
with self.assertRaises(TypeError):
|
|
559
|
+
dt.NUMERIC()
|
|
560
|
+
with self.assertRaises(TypeError):
|
|
561
|
+
dt.NUMERIC(5)
|
|
562
|
+
assert dt.NUMERIC(10, 5) == 'NUMERIC(10, 5) NULL'
|
|
563
|
+
assert dt.NUMERIC(10, 5, nullable=False) == 'NUMERIC(10, 5) NOT NULL'
|
|
564
|
+
assert dt.NUMERIC(10, 5, default=1.234) == \
|
|
565
|
+
'NUMERIC(10, 5) NULL DEFAULT 1.234e0'
|
|
566
|
+
|
|
567
|
+
assert dt.DATE() == 'DATE NULL'
|
|
568
|
+
assert dt.DATE(nullable=False) == 'DATE NOT NULL'
|
|
569
|
+
assert dt.DATE(default=datetime.date(2020, 1, 2)) == \
|
|
570
|
+
"DATE NULL DEFAULT '2020-01-02'"
|
|
571
|
+
|
|
572
|
+
assert dt.TIME() == 'TIME NULL'
|
|
573
|
+
assert dt.TIME(6) == 'TIME(6) NULL'
|
|
574
|
+
assert dt.TIME(nullable=False) == 'TIME NOT NULL'
|
|
575
|
+
assert dt.TIME(default=datetime.timedelta(seconds=1000)) == \
|
|
576
|
+
"TIME NULL DEFAULT '00:16:40'"
|
|
577
|
+
|
|
578
|
+
assert dt.DATETIME() == 'DATETIME NULL'
|
|
579
|
+
assert dt.DATETIME(6) == 'DATETIME(6) NULL'
|
|
580
|
+
assert dt.DATETIME(nullable=False) == 'DATETIME NOT NULL'
|
|
581
|
+
assert dt.DATETIME(default=datetime.datetime(2020, 1, 2, 3, 4, 5)) == \
|
|
582
|
+
"DATETIME NULL DEFAULT '2020-01-02 03:04:05'"
|
|
583
|
+
|
|
584
|
+
assert dt.TIMESTAMP() == 'TIMESTAMP NULL'
|
|
585
|
+
assert dt.TIMESTAMP(6) == 'TIMESTAMP(6) NULL'
|
|
586
|
+
assert dt.TIMESTAMP(nullable=False) == 'TIMESTAMP NOT NULL'
|
|
587
|
+
assert dt.TIMESTAMP(default=datetime.datetime(2020, 1, 2, 3, 4, 5)) == \
|
|
588
|
+
"TIMESTAMP NULL DEFAULT '2020-01-02 03:04:05'"
|
|
589
|
+
|
|
590
|
+
assert dt.YEAR() == 'YEAR NULL'
|
|
591
|
+
assert dt.YEAR(nullable=False) == 'YEAR NOT NULL'
|
|
592
|
+
assert dt.YEAR(default=1961) == 'YEAR NULL DEFAULT 1961'
|
|
593
|
+
|
|
594
|
+
assert dt.CHAR() == 'CHAR NULL'
|
|
595
|
+
assert dt.CHAR(10) == 'CHAR(10) NULL'
|
|
596
|
+
assert dt.CHAR(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
597
|
+
'CHAR CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
598
|
+
assert dt.CHAR(nullable=False) == 'CHAR NOT NULL'
|
|
599
|
+
assert dt.CHAR(default='hi') == "CHAR NULL DEFAULT 'hi'"
|
|
600
|
+
|
|
601
|
+
assert dt.VARCHAR() == 'VARCHAR NULL'
|
|
602
|
+
assert dt.VARCHAR(10) == 'VARCHAR(10) NULL'
|
|
603
|
+
assert dt.VARCHAR(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
604
|
+
'VARCHAR CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
605
|
+
assert dt.VARCHAR(nullable=False) == 'VARCHAR NOT NULL'
|
|
606
|
+
assert dt.VARCHAR(default='hi') == "VARCHAR NULL DEFAULT 'hi'"
|
|
607
|
+
|
|
608
|
+
assert dt.LONGTEXT() == 'LONGTEXT NULL'
|
|
609
|
+
assert dt.LONGTEXT(10) == 'LONGTEXT(10) NULL'
|
|
610
|
+
assert dt.LONGTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
611
|
+
'LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
612
|
+
assert dt.LONGTEXT(nullable=False) == 'LONGTEXT NOT NULL'
|
|
613
|
+
assert dt.LONGTEXT(default='hi') == "LONGTEXT NULL DEFAULT 'hi'"
|
|
614
|
+
|
|
615
|
+
assert dt.MEDIUMTEXT() == 'MEDIUMTEXT NULL'
|
|
616
|
+
assert dt.MEDIUMTEXT(10) == 'MEDIUMTEXT(10) NULL'
|
|
617
|
+
assert dt.MEDIUMTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
618
|
+
'MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
619
|
+
assert dt.MEDIUMTEXT(nullable=False) == 'MEDIUMTEXT NOT NULL'
|
|
620
|
+
assert dt.MEDIUMTEXT(default='hi') == "MEDIUMTEXT NULL DEFAULT 'hi'"
|
|
621
|
+
|
|
622
|
+
assert dt.TEXT() == 'TEXT NULL'
|
|
623
|
+
assert dt.TEXT(10) == 'TEXT(10) NULL'
|
|
624
|
+
assert dt.TEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
625
|
+
'TEXT CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
626
|
+
assert dt.TEXT(nullable=False) == 'TEXT NOT NULL'
|
|
627
|
+
assert dt.TEXT(default='hi') == "TEXT NULL DEFAULT 'hi'"
|
|
628
|
+
|
|
629
|
+
assert dt.TINYTEXT() == 'TINYTEXT NULL'
|
|
630
|
+
assert dt.TINYTEXT(10) == 'TINYTEXT(10) NULL'
|
|
631
|
+
assert dt.TINYTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
632
|
+
'TINYTEXT CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
633
|
+
assert dt.TINYTEXT(nullable=False) == 'TINYTEXT NOT NULL'
|
|
634
|
+
assert dt.TINYTEXT(default='hi') == "TINYTEXT NULL DEFAULT 'hi'"
|
|
635
|
+
|
|
636
|
+
assert dt.BINARY() == 'BINARY NULL'
|
|
637
|
+
assert dt.BINARY(10) == 'BINARY(10) NULL'
|
|
638
|
+
assert dt.BINARY(collate=dt.utf8_bin) == \
|
|
639
|
+
'BINARY COLLATE utf8_bin NULL'
|
|
640
|
+
assert dt.BINARY(nullable=False) == 'BINARY NOT NULL'
|
|
641
|
+
assert dt.BINARY(default='hi') == "BINARY NULL DEFAULT 'hi'"
|
|
642
|
+
|
|
643
|
+
assert dt.VARBINARY() == 'VARBINARY NULL'
|
|
644
|
+
assert dt.VARBINARY(10) == 'VARBINARY(10) NULL'
|
|
645
|
+
assert dt.VARBINARY(collate=dt.utf8_bin) == \
|
|
646
|
+
'VARBINARY COLLATE utf8_bin NULL'
|
|
647
|
+
assert dt.VARBINARY(nullable=False) == 'VARBINARY NOT NULL'
|
|
648
|
+
assert dt.VARBINARY(default='hi') == "VARBINARY NULL DEFAULT 'hi'"
|
|
649
|
+
|
|
650
|
+
assert dt.BLOB() == 'BLOB NULL'
|
|
651
|
+
assert dt.BLOB(10) == 'BLOB(10) NULL'
|
|
652
|
+
assert dt.BLOB(collate=dt.utf8_bin) == \
|
|
653
|
+
'BLOB COLLATE utf8_bin NULL'
|
|
654
|
+
assert dt.BLOB(nullable=False) == 'BLOB NOT NULL'
|
|
655
|
+
assert dt.BLOB(default='hi') == "BLOB NULL DEFAULT 'hi'"
|
|
656
|
+
|
|
657
|
+
assert dt.TINYBLOB() == 'TINYBLOB NULL'
|
|
658
|
+
assert dt.TINYBLOB(10) == 'TINYBLOB(10) NULL'
|
|
659
|
+
assert dt.TINYBLOB(collate=dt.utf8_bin) == \
|
|
660
|
+
'TINYBLOB COLLATE utf8_bin NULL'
|
|
661
|
+
assert dt.TINYBLOB(nullable=False) == 'TINYBLOB NOT NULL'
|
|
662
|
+
assert dt.TINYBLOB(default='hi') == "TINYBLOB NULL DEFAULT 'hi'"
|
|
663
|
+
|
|
664
|
+
assert dt.JSON() == 'JSON NULL'
|
|
665
|
+
assert dt.JSON(10) == 'JSON(10) NULL'
|
|
666
|
+
assert dt.JSON(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
667
|
+
'JSON CHARACTER SET utf8 COLLATE utf8_bin NULL'
|
|
668
|
+
assert dt.JSON(nullable=False) == 'JSON NOT NULL'
|
|
669
|
+
assert dt.JSON(default='hi') == "JSON NULL DEFAULT 'hi'"
|
|
670
|
+
|
|
671
|
+
assert dt.GEOGRAPHYPOINT() == 'GEOGRAPHYPOINT NULL'
|
|
672
|
+
assert dt.GEOGRAPHYPOINT(nullable=False) == 'GEOGRAPHYPOINT NOT NULL'
|
|
673
|
+
assert dt.GEOGRAPHYPOINT(default='hi') == "GEOGRAPHYPOINT NULL DEFAULT 'hi'"
|
|
674
|
+
|
|
675
|
+
assert dt.GEOGRAPHY() == 'GEOGRAPHY NULL'
|
|
676
|
+
assert dt.GEOGRAPHY(nullable=False) == 'GEOGRAPHY NOT NULL'
|
|
677
|
+
assert dt.GEOGRAPHY(default='hi') == "GEOGRAPHY NULL DEFAULT 'hi'"
|
|
678
|
+
|
|
679
|
+
with self.assertRaises(AssertionError):
|
|
680
|
+
dt.RECORD()
|
|
681
|
+
assert dt.RECORD(('a', dt.INT), ('b', dt.FLOAT)) == \
|
|
682
|
+
'RECORD(`a` INT NULL, `b` FLOAT NULL) NULL'
|
|
683
|
+
assert dt.RECORD(('a', dt.INT), ('b', dt.FLOAT), nullable=False) == \
|
|
684
|
+
'RECORD(`a` INT NULL, `b` FLOAT NULL) NOT NULL'
|
|
685
|
+
|
|
686
|
+
assert dt.ARRAY(dt.INT) == 'ARRAY(INT NULL) NULL'
|
|
687
|
+
assert dt.ARRAY(dt.INT, nullable=False) == 'ARRAY(INT NULL) NOT NULL'
|