singlestoredb 0.8.8__cp36-abi3-win_amd64.whl → 0.9.0__cp36-abi3-win_amd64.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_accel.pyd +0 -0
- singlestoredb/__init__.py +1 -1
- singlestoredb/config.py +6 -0
- singlestoredb/exceptions.py +24 -0
- singlestoredb/functions/__init__.py +1 -0
- singlestoredb/functions/decorator.py +165 -0
- singlestoredb/functions/dtypes.py +1396 -0
- singlestoredb/functions/ext/__init__.py +2 -0
- singlestoredb/functions/ext/asgi.py +357 -0
- singlestoredb/functions/ext/json.py +49 -0
- singlestoredb/functions/ext/rowdat_1.py +111 -0
- singlestoredb/functions/signature.py +607 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/manager.py +42 -1
- singlestoredb/management/organization.py +85 -0
- singlestoredb/management/utils.py +118 -1
- singlestoredb/management/workspace.py +881 -5
- singlestoredb/mysql/__init__.py +12 -10
- singlestoredb/mysql/_auth.py +3 -1
- singlestoredb/mysql/charset.py +12 -11
- singlestoredb/mysql/connection.py +4 -3
- singlestoredb/mysql/constants/CLIENT.py +0 -1
- singlestoredb/mysql/constants/COMMAND.py +0 -1
- singlestoredb/mysql/constants/CR.py +0 -2
- singlestoredb/mysql/constants/ER.py +0 -1
- singlestoredb/mysql/constants/FIELD_TYPE.py +0 -1
- singlestoredb/mysql/constants/FLAG.py +0 -1
- singlestoredb/mysql/constants/SERVER_STATUS.py +0 -1
- singlestoredb/mysql/converters.py +49 -28
- singlestoredb/mysql/err.py +3 -3
- singlestoredb/mysql/optionfile.py +4 -4
- singlestoredb/mysql/protocol.py +2 -1
- singlestoredb/mysql/times.py +3 -4
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_management.py +393 -3
- singlestoredb/tests/test_udf.py +698 -0
- {singlestoredb-0.8.8.dist-info → singlestoredb-0.9.0.dist-info}/METADATA +1 -1
- {singlestoredb-0.8.8.dist-info → singlestoredb-0.9.0.dist-info}/RECORD +41 -29
- {singlestoredb-0.8.8.dist-info → singlestoredb-0.9.0.dist-info}/LICENSE +0 -0
- {singlestoredb-0.8.8.dist-info → singlestoredb-0.9.0.dist-info}/WHEEL +0 -0
- {singlestoredb-0.8.8.dist-info → singlestoredb-0.9.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,698 @@
|
|
|
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 NOT NULL'
|
|
327
|
+
|
|
328
|
+
# Override return value with string
|
|
329
|
+
@udf(returns=dt.SMALLINT(nullable=True))
|
|
330
|
+
def foo(x: int) -> int: ...
|
|
331
|
+
assert to_sql(foo) == '`foo`(`x` BIGINT NOT NULL) RETURNS SMALLINT NULL'
|
|
332
|
+
|
|
333
|
+
# Override multiple params with one type
|
|
334
|
+
@udf(args=dt.SMALLINT(nullable=True))
|
|
335
|
+
def foo(x: int, y: float, z: np.int8) -> int: ...
|
|
336
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NULL, ' \
|
|
337
|
+
'`y` SMALLINT NULL, ' \
|
|
338
|
+
'`z` SMALLINT 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 NOT NULL, ' \
|
|
344
|
+
'`y` FLOAT NOT NULL, ' \
|
|
345
|
+
'`z` CHAR(30) NOT 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 NOT NULL, ' \
|
|
363
|
+
'`y` FLOAT NOT NULL, ' \
|
|
364
|
+
'`z` CHAR(30) NOT 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 NOT NULL, ' \
|
|
370
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
371
|
+
'`z` CHAR(30) NOT 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=True))
|
|
389
|
+
def foo(x: int, y: float, z: str) -> int: ...
|
|
390
|
+
assert to_sql(foo) == '`foo`(`x` SMALLINT NOT NULL, ' \
|
|
391
|
+
'`y` DOUBLE NOT NULL, ' \
|
|
392
|
+
'`z` CHAR(30) NOT NULL) RETURNS SMALLINT 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
|
+
# Add database name
|
|
416
|
+
@udf(database='mydb')
|
|
417
|
+
def foo(x: int) -> int: ...
|
|
418
|
+
assert to_sql(foo) == '`mydb`.`foo`(`x` BIGINT NOT NULL) ' \
|
|
419
|
+
'RETURNS BIGINT NOT NULL'
|
|
420
|
+
|
|
421
|
+
@udf(database='my`db')
|
|
422
|
+
def foo(x: int) -> int: ...
|
|
423
|
+
assert to_sql(foo) == '`my``db`.`foo`(`x` BIGINT NOT NULL) ' \
|
|
424
|
+
'RETURNS BIGINT NOT NULL'
|
|
425
|
+
|
|
426
|
+
def test_dtypes(self):
|
|
427
|
+
assert dt.BOOL() == 'BOOL NOT NULL'
|
|
428
|
+
assert dt.BOOL(nullable=True) == 'BOOL NULL'
|
|
429
|
+
assert dt.BOOL(default=False) == 'BOOL NOT NULL DEFAULT 0'
|
|
430
|
+
assert dt.BOOL(default=True) == 'BOOL NOT NULL DEFAULT 1'
|
|
431
|
+
assert dt.BOOL(default='a') == 'BOOL NOT NULL DEFAULT 1'
|
|
432
|
+
|
|
433
|
+
assert dt.BOOLEAN() == 'BOOLEAN NOT NULL'
|
|
434
|
+
assert dt.BOOLEAN(nullable=True) == 'BOOLEAN NULL'
|
|
435
|
+
assert dt.BOOLEAN(default=False) == 'BOOLEAN NOT NULL DEFAULT 0'
|
|
436
|
+
assert dt.BOOLEAN(default=True) == 'BOOLEAN NOT NULL DEFAULT 1'
|
|
437
|
+
assert dt.BOOLEAN(default='a') == 'BOOLEAN NOT NULL DEFAULT 1'
|
|
438
|
+
|
|
439
|
+
assert dt.BIT() == 'BIT NOT NULL'
|
|
440
|
+
assert dt.BIT(nullable=True) == 'BIT NULL'
|
|
441
|
+
assert dt.BIT(default=100) == 'BIT NOT NULL DEFAULT 100'
|
|
442
|
+
|
|
443
|
+
assert dt.TINYINT() == 'TINYINT NOT NULL'
|
|
444
|
+
assert dt.TINYINT(5) == 'TINYINT(5) NOT NULL'
|
|
445
|
+
assert dt.TINYINT(nullable=True) == 'TINYINT NULL'
|
|
446
|
+
assert dt.TINYINT(default=100) == 'TINYINT NOT NULL DEFAULT 100'
|
|
447
|
+
assert dt.TINYINT(unsigned=True, default=100) == \
|
|
448
|
+
'TINYINT UNSIGNED NOT NULL DEFAULT 100'
|
|
449
|
+
|
|
450
|
+
assert dt.TINYINT_UNSIGNED() == 'TINYINT UNSIGNED NOT NULL'
|
|
451
|
+
assert dt.TINYINT_UNSIGNED(5) == 'TINYINT(5) UNSIGNED NOT NULL'
|
|
452
|
+
assert dt.TINYINT_UNSIGNED(nullable=True) == 'TINYINT UNSIGNED NULL'
|
|
453
|
+
assert dt.TINYINT_UNSIGNED(default=100) == 'TINYINT UNSIGNED NOT NULL DEFAULT 100'
|
|
454
|
+
|
|
455
|
+
assert dt.SMALLINT() == 'SMALLINT NOT NULL'
|
|
456
|
+
assert dt.SMALLINT(5) == 'SMALLINT(5) NOT NULL'
|
|
457
|
+
assert dt.SMALLINT(nullable=True) == 'SMALLINT NULL'
|
|
458
|
+
assert dt.SMALLINT(default=100) == 'SMALLINT NOT NULL DEFAULT 100'
|
|
459
|
+
assert dt.SMALLINT(unsigned=True, default=100) == \
|
|
460
|
+
'SMALLINT UNSIGNED NOT NULL DEFAULT 100'
|
|
461
|
+
|
|
462
|
+
assert dt.SMALLINT_UNSIGNED() == 'SMALLINT UNSIGNED NOT NULL'
|
|
463
|
+
assert dt.SMALLINT_UNSIGNED(5) == 'SMALLINT(5) UNSIGNED NOT NULL'
|
|
464
|
+
assert dt.SMALLINT_UNSIGNED(nullable=True) == 'SMALLINT UNSIGNED NULL'
|
|
465
|
+
assert dt.SMALLINT_UNSIGNED(default=100) == \
|
|
466
|
+
'SMALLINT UNSIGNED NOT NULL DEFAULT 100'
|
|
467
|
+
|
|
468
|
+
assert dt.MEDIUMINT() == 'MEDIUMINT NOT NULL'
|
|
469
|
+
assert dt.MEDIUMINT(5) == 'MEDIUMINT(5) NOT NULL'
|
|
470
|
+
assert dt.MEDIUMINT(nullable=True) == 'MEDIUMINT NULL'
|
|
471
|
+
assert dt.MEDIUMINT(default=100) == 'MEDIUMINT NOT NULL DEFAULT 100'
|
|
472
|
+
assert dt.MEDIUMINT(unsigned=True, default=100) == \
|
|
473
|
+
'MEDIUMINT UNSIGNED NOT NULL DEFAULT 100'
|
|
474
|
+
|
|
475
|
+
assert dt.MEDIUMINT_UNSIGNED() == 'MEDIUMINT UNSIGNED NOT NULL'
|
|
476
|
+
assert dt.MEDIUMINT_UNSIGNED(5) == 'MEDIUMINT(5) UNSIGNED NOT NULL'
|
|
477
|
+
assert dt.MEDIUMINT_UNSIGNED(nullable=True) == 'MEDIUMINT UNSIGNED NULL'
|
|
478
|
+
assert dt.MEDIUMINT_UNSIGNED(default=100) == \
|
|
479
|
+
'MEDIUMINT UNSIGNED NOT NULL DEFAULT 100'
|
|
480
|
+
|
|
481
|
+
assert dt.INT() == 'INT NOT NULL'
|
|
482
|
+
assert dt.INT(5) == 'INT(5) NOT NULL'
|
|
483
|
+
assert dt.INT(nullable=True) == 'INT NULL'
|
|
484
|
+
assert dt.INT(default=100) == 'INT NOT NULL DEFAULT 100'
|
|
485
|
+
assert dt.INT(unsigned=True, default=100) == \
|
|
486
|
+
'INT UNSIGNED NOT NULL DEFAULT 100'
|
|
487
|
+
|
|
488
|
+
assert dt.INT_UNSIGNED() == 'INT UNSIGNED NOT NULL'
|
|
489
|
+
assert dt.INT_UNSIGNED(5) == 'INT(5) UNSIGNED NOT NULL'
|
|
490
|
+
assert dt.INT_UNSIGNED(nullable=True) == 'INT UNSIGNED NULL'
|
|
491
|
+
assert dt.INT_UNSIGNED(default=100) == \
|
|
492
|
+
'INT UNSIGNED NOT NULL DEFAULT 100'
|
|
493
|
+
|
|
494
|
+
assert dt.INTEGER() == 'INTEGER NOT NULL'
|
|
495
|
+
assert dt.INTEGER(5) == 'INTEGER(5) NOT NULL'
|
|
496
|
+
assert dt.INTEGER(nullable=True) == 'INTEGER NULL'
|
|
497
|
+
assert dt.INTEGER(default=100) == 'INTEGER NOT NULL DEFAULT 100'
|
|
498
|
+
assert dt.INTEGER(unsigned=True, default=100) == \
|
|
499
|
+
'INTEGER UNSIGNED NOT NULL DEFAULT 100'
|
|
500
|
+
|
|
501
|
+
assert dt.INTEGER_UNSIGNED() == 'INTEGER UNSIGNED NOT NULL'
|
|
502
|
+
assert dt.INTEGER_UNSIGNED(5) == 'INTEGER(5) UNSIGNED NOT NULL'
|
|
503
|
+
assert dt.INTEGER_UNSIGNED(nullable=True) == 'INTEGER UNSIGNED NULL'
|
|
504
|
+
assert dt.INTEGER_UNSIGNED(default=100) == \
|
|
505
|
+
'INTEGER UNSIGNED NOT NULL DEFAULT 100'
|
|
506
|
+
|
|
507
|
+
assert dt.BIGINT() == 'BIGINT NOT NULL'
|
|
508
|
+
assert dt.BIGINT(5) == 'BIGINT(5) NOT NULL'
|
|
509
|
+
assert dt.BIGINT(nullable=True) == 'BIGINT NULL'
|
|
510
|
+
assert dt.BIGINT(default=100) == 'BIGINT NOT NULL DEFAULT 100'
|
|
511
|
+
assert dt.BIGINT(unsigned=True, default=100) == \
|
|
512
|
+
'BIGINT UNSIGNED NOT NULL DEFAULT 100'
|
|
513
|
+
|
|
514
|
+
assert dt.BIGINT_UNSIGNED() == 'BIGINT UNSIGNED NOT NULL'
|
|
515
|
+
assert dt.BIGINT_UNSIGNED(5) == 'BIGINT(5) UNSIGNED NOT NULL'
|
|
516
|
+
assert dt.BIGINT_UNSIGNED(nullable=True) == 'BIGINT UNSIGNED NULL'
|
|
517
|
+
assert dt.BIGINT_UNSIGNED(default=100) == \
|
|
518
|
+
'BIGINT UNSIGNED NOT NULL DEFAULT 100'
|
|
519
|
+
|
|
520
|
+
assert dt.BIGINT() == 'BIGINT NOT NULL'
|
|
521
|
+
assert dt.BIGINT(5) == 'BIGINT(5) NOT NULL'
|
|
522
|
+
assert dt.BIGINT(nullable=True) == 'BIGINT NULL'
|
|
523
|
+
assert dt.BIGINT(default=100) == 'BIGINT NOT NULL DEFAULT 100'
|
|
524
|
+
assert dt.BIGINT(unsigned=True, default=100) == \
|
|
525
|
+
'BIGINT UNSIGNED NOT NULL DEFAULT 100'
|
|
526
|
+
|
|
527
|
+
assert dt.FLOAT() == 'FLOAT NOT NULL'
|
|
528
|
+
assert dt.FLOAT(5) == 'FLOAT(5) NOT NULL'
|
|
529
|
+
assert dt.FLOAT(nullable=True) == 'FLOAT NULL'
|
|
530
|
+
assert dt.FLOAT(default=1.234) == 'FLOAT NOT NULL DEFAULT 1.234e0'
|
|
531
|
+
|
|
532
|
+
assert dt.DOUBLE() == 'DOUBLE NOT NULL'
|
|
533
|
+
assert dt.DOUBLE(5) == 'DOUBLE(5) NOT NULL'
|
|
534
|
+
assert dt.DOUBLE(nullable=True) == 'DOUBLE NULL'
|
|
535
|
+
assert dt.DOUBLE(default=1.234) == 'DOUBLE NOT NULL DEFAULT 1.234e0'
|
|
536
|
+
|
|
537
|
+
assert dt.REAL() == 'REAL NOT NULL'
|
|
538
|
+
assert dt.REAL(5) == 'REAL(5) NOT NULL'
|
|
539
|
+
assert dt.REAL(nullable=True) == 'REAL NULL'
|
|
540
|
+
assert dt.REAL(default=1.234) == 'REAL NOT NULL DEFAULT 1.234e0'
|
|
541
|
+
|
|
542
|
+
with self.assertRaises(TypeError):
|
|
543
|
+
dt.DECIMAL()
|
|
544
|
+
with self.assertRaises(TypeError):
|
|
545
|
+
dt.DECIMAL(5)
|
|
546
|
+
assert dt.DECIMAL(10, 5) == 'DECIMAL(10, 5) NOT NULL'
|
|
547
|
+
assert dt.DECIMAL(10, 5, nullable=True) == 'DECIMAL(10, 5) NULL'
|
|
548
|
+
assert dt.DECIMAL(10, 5, default=1.234) == \
|
|
549
|
+
'DECIMAL(10, 5) NOT NULL DEFAULT 1.234e0'
|
|
550
|
+
|
|
551
|
+
with self.assertRaises(TypeError):
|
|
552
|
+
dt.DEC()
|
|
553
|
+
with self.assertRaises(TypeError):
|
|
554
|
+
dt.DEC(5)
|
|
555
|
+
assert dt.DEC(10, 5) == 'DEC(10, 5) NOT NULL'
|
|
556
|
+
assert dt.DEC(10, 5, nullable=True) == 'DEC(10, 5) NULL'
|
|
557
|
+
assert dt.DEC(10, 5, default=1.234) == \
|
|
558
|
+
'DEC(10, 5) NOT NULL DEFAULT 1.234e0'
|
|
559
|
+
|
|
560
|
+
with self.assertRaises(TypeError):
|
|
561
|
+
dt.FIXED()
|
|
562
|
+
with self.assertRaises(TypeError):
|
|
563
|
+
dt.FIXED(5)
|
|
564
|
+
assert dt.FIXED(10, 5) == 'FIXED(10, 5) NOT NULL'
|
|
565
|
+
assert dt.FIXED(10, 5, nullable=True) == 'FIXED(10, 5) NULL'
|
|
566
|
+
assert dt.FIXED(10, 5, default=1.234) == \
|
|
567
|
+
'FIXED(10, 5) NOT NULL DEFAULT 1.234e0'
|
|
568
|
+
|
|
569
|
+
with self.assertRaises(TypeError):
|
|
570
|
+
dt.NUMERIC()
|
|
571
|
+
with self.assertRaises(TypeError):
|
|
572
|
+
dt.NUMERIC(5)
|
|
573
|
+
assert dt.NUMERIC(10, 5) == 'NUMERIC(10, 5) NOT NULL'
|
|
574
|
+
assert dt.NUMERIC(10, 5, nullable=True) == 'NUMERIC(10, 5) NULL'
|
|
575
|
+
assert dt.NUMERIC(10, 5, default=1.234) == \
|
|
576
|
+
'NUMERIC(10, 5) NOT NULL DEFAULT 1.234e0'
|
|
577
|
+
|
|
578
|
+
assert dt.DATE() == 'DATE NOT NULL'
|
|
579
|
+
assert dt.DATE(nullable=True) == 'DATE NULL'
|
|
580
|
+
assert dt.DATE(default=datetime.date(2020, 1, 2)) == \
|
|
581
|
+
"DATE NOT NULL DEFAULT '2020-01-02'"
|
|
582
|
+
|
|
583
|
+
assert dt.TIME() == 'TIME NOT NULL'
|
|
584
|
+
assert dt.TIME(6) == 'TIME(6) NOT NULL'
|
|
585
|
+
assert dt.TIME(nullable=True) == 'TIME NULL'
|
|
586
|
+
assert dt.TIME(default=datetime.timedelta(seconds=1000)) == \
|
|
587
|
+
"TIME NOT NULL DEFAULT '00:16:40'"
|
|
588
|
+
|
|
589
|
+
assert dt.DATETIME() == 'DATETIME NOT NULL'
|
|
590
|
+
assert dt.DATETIME(6) == 'DATETIME(6) NOT NULL'
|
|
591
|
+
assert dt.DATETIME(nullable=True) == 'DATETIME NULL'
|
|
592
|
+
assert dt.DATETIME(default=datetime.datetime(2020, 1, 2, 3, 4, 5)) == \
|
|
593
|
+
"DATETIME NOT NULL DEFAULT '2020-01-02 03:04:05'"
|
|
594
|
+
|
|
595
|
+
assert dt.TIMESTAMP() == 'TIMESTAMP NOT NULL'
|
|
596
|
+
assert dt.TIMESTAMP(6) == 'TIMESTAMP(6) NOT NULL'
|
|
597
|
+
assert dt.TIMESTAMP(nullable=True) == 'TIMESTAMP NULL'
|
|
598
|
+
assert dt.TIMESTAMP(default=datetime.datetime(2020, 1, 2, 3, 4, 5)) == \
|
|
599
|
+
"TIMESTAMP NOT NULL DEFAULT '2020-01-02 03:04:05'"
|
|
600
|
+
|
|
601
|
+
assert dt.YEAR() == 'YEAR NOT NULL'
|
|
602
|
+
assert dt.YEAR(nullable=True) == 'YEAR NULL'
|
|
603
|
+
assert dt.YEAR(default=1961) == 'YEAR NOT NULL DEFAULT 1961'
|
|
604
|
+
|
|
605
|
+
assert dt.CHAR() == 'CHAR NOT NULL'
|
|
606
|
+
assert dt.CHAR(10) == 'CHAR(10) NOT NULL'
|
|
607
|
+
assert dt.CHAR(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
608
|
+
'CHAR CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
609
|
+
assert dt.CHAR(nullable=True) == 'CHAR NULL'
|
|
610
|
+
assert dt.CHAR(default='hi') == "CHAR NOT NULL DEFAULT 'hi'"
|
|
611
|
+
|
|
612
|
+
assert dt.VARCHAR() == 'VARCHAR NOT NULL'
|
|
613
|
+
assert dt.VARCHAR(10) == 'VARCHAR(10) NOT NULL'
|
|
614
|
+
assert dt.VARCHAR(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
615
|
+
'VARCHAR CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
616
|
+
assert dt.VARCHAR(nullable=True) == 'VARCHAR NULL'
|
|
617
|
+
assert dt.VARCHAR(default='hi') == "VARCHAR NOT NULL DEFAULT 'hi'"
|
|
618
|
+
|
|
619
|
+
assert dt.LONGTEXT() == 'LONGTEXT NOT NULL'
|
|
620
|
+
assert dt.LONGTEXT(10) == 'LONGTEXT(10) NOT NULL'
|
|
621
|
+
assert dt.LONGTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
622
|
+
'LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
623
|
+
assert dt.LONGTEXT(nullable=True) == 'LONGTEXT NULL'
|
|
624
|
+
assert dt.LONGTEXT(default='hi') == "LONGTEXT NOT NULL DEFAULT 'hi'"
|
|
625
|
+
|
|
626
|
+
assert dt.MEDIUMTEXT() == 'MEDIUMTEXT NOT NULL'
|
|
627
|
+
assert dt.MEDIUMTEXT(10) == 'MEDIUMTEXT(10) NOT NULL'
|
|
628
|
+
assert dt.MEDIUMTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
629
|
+
'MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
630
|
+
assert dt.MEDIUMTEXT(nullable=True) == 'MEDIUMTEXT NULL'
|
|
631
|
+
assert dt.MEDIUMTEXT(default='hi') == "MEDIUMTEXT NOT NULL DEFAULT 'hi'"
|
|
632
|
+
|
|
633
|
+
assert dt.TEXT() == 'TEXT NOT NULL'
|
|
634
|
+
assert dt.TEXT(10) == 'TEXT(10) NOT NULL'
|
|
635
|
+
assert dt.TEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
636
|
+
'TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
637
|
+
assert dt.TEXT(nullable=True) == 'TEXT NULL'
|
|
638
|
+
assert dt.TEXT(default='hi') == "TEXT NOT NULL DEFAULT 'hi'"
|
|
639
|
+
|
|
640
|
+
assert dt.TINYTEXT() == 'TINYTEXT NOT NULL'
|
|
641
|
+
assert dt.TINYTEXT(10) == 'TINYTEXT(10) NOT NULL'
|
|
642
|
+
assert dt.TINYTEXT(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
643
|
+
'TINYTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
644
|
+
assert dt.TINYTEXT(nullable=True) == 'TINYTEXT NULL'
|
|
645
|
+
assert dt.TINYTEXT(default='hi') == "TINYTEXT NOT NULL DEFAULT 'hi'"
|
|
646
|
+
|
|
647
|
+
assert dt.BINARY() == 'BINARY NOT NULL'
|
|
648
|
+
assert dt.BINARY(10) == 'BINARY(10) NOT NULL'
|
|
649
|
+
assert dt.BINARY(collate=dt.utf8_bin) == \
|
|
650
|
+
'BINARY COLLATE utf8_bin NOT NULL'
|
|
651
|
+
assert dt.BINARY(nullable=True) == 'BINARY NULL'
|
|
652
|
+
assert dt.BINARY(default='hi') == "BINARY NOT NULL DEFAULT 'hi'"
|
|
653
|
+
|
|
654
|
+
assert dt.VARBINARY() == 'VARBINARY NOT NULL'
|
|
655
|
+
assert dt.VARBINARY(10) == 'VARBINARY(10) NOT NULL'
|
|
656
|
+
assert dt.VARBINARY(collate=dt.utf8_bin) == \
|
|
657
|
+
'VARBINARY COLLATE utf8_bin NOT NULL'
|
|
658
|
+
assert dt.VARBINARY(nullable=True) == 'VARBINARY NULL'
|
|
659
|
+
assert dt.VARBINARY(default='hi') == "VARBINARY NOT NULL DEFAULT 'hi'"
|
|
660
|
+
|
|
661
|
+
assert dt.BLOB() == 'BLOB NOT NULL'
|
|
662
|
+
assert dt.BLOB(10) == 'BLOB(10) NOT NULL'
|
|
663
|
+
assert dt.BLOB(collate=dt.utf8_bin) == \
|
|
664
|
+
'BLOB COLLATE utf8_bin NOT NULL'
|
|
665
|
+
assert dt.BLOB(nullable=True) == 'BLOB NULL'
|
|
666
|
+
assert dt.BLOB(default='hi') == "BLOB NOT NULL DEFAULT 'hi'"
|
|
667
|
+
|
|
668
|
+
assert dt.TINYBLOB() == 'TINYBLOB NOT NULL'
|
|
669
|
+
assert dt.TINYBLOB(10) == 'TINYBLOB(10) NOT NULL'
|
|
670
|
+
assert dt.TINYBLOB(collate=dt.utf8_bin) == \
|
|
671
|
+
'TINYBLOB COLLATE utf8_bin NOT NULL'
|
|
672
|
+
assert dt.TINYBLOB(nullable=True) == 'TINYBLOB NULL'
|
|
673
|
+
assert dt.TINYBLOB(default='hi') == "TINYBLOB NOT NULL DEFAULT 'hi'"
|
|
674
|
+
|
|
675
|
+
assert dt.JSON() == 'JSON NOT NULL'
|
|
676
|
+
assert dt.JSON(10) == 'JSON(10) NOT NULL'
|
|
677
|
+
assert dt.JSON(charset=dt.utf8, collate=dt.utf8_bin) == \
|
|
678
|
+
'JSON CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'
|
|
679
|
+
assert dt.JSON(nullable=True) == 'JSON NULL'
|
|
680
|
+
assert dt.JSON(default='hi') == "JSON NOT NULL DEFAULT 'hi'"
|
|
681
|
+
|
|
682
|
+
assert dt.GEOGRAPHYPOINT() == 'GEOGRAPHYPOINT NOT NULL'
|
|
683
|
+
assert dt.GEOGRAPHYPOINT(nullable=True) == 'GEOGRAPHYPOINT NULL'
|
|
684
|
+
assert dt.GEOGRAPHYPOINT(default='hi') == "GEOGRAPHYPOINT NOT NULL DEFAULT 'hi'"
|
|
685
|
+
|
|
686
|
+
assert dt.GEOGRAPHY() == 'GEOGRAPHY NOT NULL'
|
|
687
|
+
assert dt.GEOGRAPHY(nullable=True) == 'GEOGRAPHY NULL'
|
|
688
|
+
assert dt.GEOGRAPHY(default='hi') == "GEOGRAPHY NOT NULL DEFAULT 'hi'"
|
|
689
|
+
|
|
690
|
+
with self.assertRaises(AssertionError):
|
|
691
|
+
dt.RECORD()
|
|
692
|
+
assert dt.RECORD(('a', dt.INT), ('b', dt.FLOAT)) == \
|
|
693
|
+
'RECORD(`a` INT NOT NULL, `b` FLOAT NOT NULL) NOT NULL'
|
|
694
|
+
assert dt.RECORD(('a', dt.INT), ('b', dt.FLOAT), nullable=True) == \
|
|
695
|
+
'RECORD(`a` INT NOT NULL, `b` FLOAT NOT NULL) NULL'
|
|
696
|
+
|
|
697
|
+
assert dt.ARRAY(dt.INT) == 'ARRAY(INT NOT NULL) NOT NULL'
|
|
698
|
+
assert dt.ARRAY(dt.INT, nullable=True) == 'ARRAY(INT NOT NULL) NULL'
|