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.

Files changed (120) hide show
  1. singlestoredb/__init__.py +33 -1
  2. singlestoredb/alchemy/__init__.py +90 -0
  3. singlestoredb/auth.py +5 -1
  4. singlestoredb/config.py +116 -14
  5. singlestoredb/connection.py +483 -516
  6. singlestoredb/converters.py +238 -135
  7. singlestoredb/exceptions.py +30 -2
  8. singlestoredb/functions/__init__.py +1 -0
  9. singlestoredb/functions/decorator.py +142 -0
  10. singlestoredb/functions/dtypes.py +1639 -0
  11. singlestoredb/functions/ext/__init__.py +2 -0
  12. singlestoredb/functions/ext/arrow.py +375 -0
  13. singlestoredb/functions/ext/asgi.py +661 -0
  14. singlestoredb/functions/ext/json.py +427 -0
  15. singlestoredb/functions/ext/mmap.py +306 -0
  16. singlestoredb/functions/ext/rowdat_1.py +744 -0
  17. singlestoredb/functions/signature.py +673 -0
  18. singlestoredb/fusion/__init__.py +11 -0
  19. singlestoredb/fusion/graphql.py +213 -0
  20. singlestoredb/fusion/handler.py +621 -0
  21. singlestoredb/fusion/handlers/stage.py +257 -0
  22. singlestoredb/fusion/handlers/utils.py +162 -0
  23. singlestoredb/fusion/handlers/workspace.py +412 -0
  24. singlestoredb/fusion/registry.py +164 -0
  25. singlestoredb/fusion/result.py +399 -0
  26. singlestoredb/http/__init__.py +27 -0
  27. singlestoredb/{http.py → http/connection.py} +555 -154
  28. singlestoredb/management/__init__.py +3 -0
  29. singlestoredb/management/billing_usage.py +148 -0
  30. singlestoredb/management/cluster.py +14 -6
  31. singlestoredb/management/manager.py +100 -38
  32. singlestoredb/management/organization.py +188 -0
  33. singlestoredb/management/region.py +5 -5
  34. singlestoredb/management/utils.py +281 -2
  35. singlestoredb/management/workspace.py +1344 -49
  36. singlestoredb/{clients/pymysqlsv → mysql}/__init__.py +16 -21
  37. singlestoredb/{clients/pymysqlsv → mysql}/_auth.py +39 -8
  38. singlestoredb/{clients/pymysqlsv → mysql}/charset.py +26 -23
  39. singlestoredb/{clients/pymysqlsv/connections.py → mysql/connection.py} +532 -165
  40. singlestoredb/{clients/pymysqlsv → mysql}/constants/CLIENT.py +0 -1
  41. singlestoredb/{clients/pymysqlsv → mysql}/constants/COMMAND.py +0 -1
  42. singlestoredb/{clients/pymysqlsv → mysql}/constants/CR.py +0 -2
  43. singlestoredb/{clients/pymysqlsv → mysql}/constants/ER.py +0 -1
  44. singlestoredb/{clients/pymysqlsv → mysql}/constants/FIELD_TYPE.py +1 -1
  45. singlestoredb/{clients/pymysqlsv → mysql}/constants/FLAG.py +0 -1
  46. singlestoredb/{clients/pymysqlsv → mysql}/constants/SERVER_STATUS.py +0 -1
  47. singlestoredb/mysql/converters.py +271 -0
  48. singlestoredb/{clients/pymysqlsv → mysql}/cursors.py +228 -112
  49. singlestoredb/mysql/err.py +92 -0
  50. singlestoredb/{clients/pymysqlsv → mysql}/optionfile.py +5 -4
  51. singlestoredb/{clients/pymysqlsv → mysql}/protocol.py +49 -20
  52. singlestoredb/mysql/tests/__init__.py +19 -0
  53. singlestoredb/{clients/pymysqlsv → mysql}/tests/base.py +32 -12
  54. singlestoredb/mysql/tests/conftest.py +37 -0
  55. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_DictCursor.py +11 -7
  56. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_SSCursor.py +17 -12
  57. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_basic.py +32 -24
  58. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_connection.py +130 -119
  59. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_converters.py +9 -7
  60. singlestoredb/mysql/tests/test_cursor.py +141 -0
  61. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_err.py +3 -2
  62. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_issues.py +35 -27
  63. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_load_local.py +13 -11
  64. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_nextset.py +7 -3
  65. singlestoredb/{clients/pymysqlsv → mysql}/tests/test_optionfile.py +2 -1
  66. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/__init__.py +1 -1
  67. singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
  68. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/capabilities.py +19 -17
  69. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/dbapi20.py +31 -22
  70. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +3 -4
  71. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +24 -20
  72. singlestoredb/{clients/pymysqlsv → mysql}/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +4 -4
  73. singlestoredb/{clients/pymysqlsv → mysql}/times.py +3 -4
  74. singlestoredb/pytest.py +283 -0
  75. singlestoredb/tests/empty.sql +0 -0
  76. singlestoredb/tests/ext_funcs/__init__.py +385 -0
  77. singlestoredb/tests/test.sql +210 -0
  78. singlestoredb/tests/test2.sql +1 -0
  79. singlestoredb/tests/test_basics.py +482 -115
  80. singlestoredb/tests/test_config.py +13 -13
  81. singlestoredb/tests/test_connection.py +241 -305
  82. singlestoredb/tests/test_dbapi.py +27 -0
  83. singlestoredb/tests/test_ext_func.py +1193 -0
  84. singlestoredb/tests/test_ext_func_data.py +1101 -0
  85. singlestoredb/tests/test_fusion.py +465 -0
  86. singlestoredb/tests/test_http.py +32 -26
  87. singlestoredb/tests/test_management.py +588 -8
  88. singlestoredb/tests/test_plugin.py +33 -0
  89. singlestoredb/tests/test_results.py +11 -12
  90. singlestoredb/tests/test_udf.py +687 -0
  91. singlestoredb/tests/utils.py +3 -2
  92. singlestoredb/utils/config.py +58 -0
  93. singlestoredb/utils/debug.py +13 -0
  94. singlestoredb/utils/mogrify.py +151 -0
  95. singlestoredb/utils/results.py +4 -1
  96. singlestoredb-1.0.4.dist-info/METADATA +139 -0
  97. singlestoredb-1.0.4.dist-info/RECORD +112 -0
  98. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/WHEEL +1 -1
  99. singlestoredb-1.0.4.dist-info/entry_points.txt +2 -0
  100. singlestoredb/clients/pymysqlsv/converters.py +0 -365
  101. singlestoredb/clients/pymysqlsv/err.py +0 -144
  102. singlestoredb/clients/pymysqlsv/tests/__init__.py +0 -19
  103. singlestoredb/clients/pymysqlsv/tests/test_cursor.py +0 -133
  104. singlestoredb/clients/pymysqlsv/tests/thirdparty/test_MySQLdb/__init__.py +0 -9
  105. singlestoredb/drivers/__init__.py +0 -45
  106. singlestoredb/drivers/base.py +0 -198
  107. singlestoredb/drivers/cymysql.py +0 -38
  108. singlestoredb/drivers/http.py +0 -47
  109. singlestoredb/drivers/mariadb.py +0 -40
  110. singlestoredb/drivers/mysqlconnector.py +0 -49
  111. singlestoredb/drivers/mysqldb.py +0 -60
  112. singlestoredb/drivers/pymysql.py +0 -37
  113. singlestoredb/drivers/pymysqlsv.py +0 -35
  114. singlestoredb/drivers/pyodbc.py +0 -65
  115. singlestoredb-0.4.0.dist-info/METADATA +0 -111
  116. singlestoredb-0.4.0.dist-info/RECORD +0 -86
  117. /singlestoredb/{clients → fusion/handlers}/__init__.py +0 -0
  118. /singlestoredb/{clients/pymysqlsv → mysql}/constants/__init__.py +0 -0
  119. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/LICENSE +0 -0
  120. {singlestoredb-0.4.0.dist-info → singlestoredb-1.0.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1639 @@
1
+ #!/usr/bin/env python3
2
+ import datetime
3
+ import decimal
4
+ import re
5
+ from typing import Any
6
+ from typing import Callable
7
+ from typing import Optional
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ from ..converters import converters
12
+ from ..mysql.converters import escape_item # type: ignore
13
+
14
+ try:
15
+ import numpy as np
16
+ has_numpy = True
17
+ except ImportError:
18
+ has_numpy = False
19
+
20
+ try:
21
+ import polars as pl
22
+ has_polars = True
23
+ except ImportError:
24
+ has_polars = False
25
+
26
+ try:
27
+ import pyarrow as pa
28
+ has_pyarrow = True
29
+ except ImportError:
30
+ has_pyarrow = False
31
+
32
+
33
+ DataType = Union[str, Callable[..., Any]]
34
+
35
+
36
+ class NULL:
37
+ """NULL (for use in default values)."""
38
+ pass
39
+
40
+
41
+ def escape_name(name: str) -> str:
42
+ """Escape a function parameter name."""
43
+ if '`' in name:
44
+ name = name.replace('`', '``')
45
+ return f'`{name}`'
46
+
47
+
48
+ # charsets
49
+ utf8mb4 = 'utf8mb4'
50
+ utf8 = 'utf8'
51
+ binary = 'binary'
52
+
53
+ # collations
54
+ utf8_general_ci = 'utf8_general_ci'
55
+ utf8_bin = 'utf8_bin'
56
+ utf8_unicode_ci = 'utf8_unicode_ci'
57
+ utf8_icelandic_ci = 'utf8_icelandic_ci'
58
+ utf8_latvian_ci = 'utf8_latvian_ci'
59
+ utf8_romanian_ci = 'utf8_romanian_ci'
60
+ utf8_slovenian_ci = 'utf8_slovenian_ci'
61
+ utf8_polish_ci = 'utf8_polish_ci'
62
+ utf8_estonian_ci = 'utf8_estonian_ci'
63
+ utf8_spanish_ci = 'utf8_spanish_ci'
64
+ utf8_swedish_ci = 'utf8_swedish_ci'
65
+ utf8_turkish_ci = 'utf8_turkish_ci'
66
+ utf8_czech_ci = 'utf8_czech_ci'
67
+ utf8_danish_ci = 'utf8_danish_ci'
68
+ utf8_lithuanian_ci = 'utf8_lithuanian_ci'
69
+ utf8_slovak_ci = 'utf8_slovak_ci'
70
+ utf8_spanish2_ci = 'utf8_spanish2_ci'
71
+ utf8_roman_ci = 'utf8_roman_ci'
72
+ utf8_persian_ci = 'utf8_persian_ci'
73
+ utf8_esperanto_ci = 'utf8_esperanto_ci'
74
+ utf8_hungarian_ci = 'utf8_hungarian_ci'
75
+ utf8_sinhala_ci = 'utf8_sinhala_ci'
76
+ utf8mb4_general_ci = 'utf8mb4_general_ci'
77
+ utf8mb4_bin = 'utf8mb4_bin'
78
+ utf8mb4_unicode_ci = 'utf8mb4_unicode_ci'
79
+ utf8mb4_icelandic_ci = 'utf8mb4_icelandic_ci'
80
+ utf8mb4_latvian_ci = 'utf8mb4_latvian_ci'
81
+ utf8mb4_romanian_ci = 'utf8mb4_romanian_ci'
82
+ utf8mb4_slovenian_ci = 'utf8mb4_slovenian_ci'
83
+ utf8mb4_polish_ci = 'utf8mb4_polish_ci'
84
+ utf8mb4_estonian_ci = 'utf8mb4_estonian_ci'
85
+ utf8mb4_spanish_ci = 'utf8mb4_spanish_ci'
86
+ utf8mb4_swedish_ci = 'utf8mb4_swedish_ci'
87
+ utf8mb4_turkish_ci = 'utf8mb4_turkish_ci'
88
+ utf8mb4_czech_ci = 'utf8mb4_czech_ci'
89
+ utf8mb4_danish_ci = 'utf8mb4_danish_ci'
90
+ utf8mb4_lithuanian_ci = 'utf8mb4_lithuanian_ci'
91
+ utf8mb4_slovak_ci = 'utf8mb4_slovak_ci'
92
+ utf8mb4_spanish2_ci = 'utf8mb4_spanish2_ci'
93
+ utf8mb4_roman_ci = 'utf8mb4_roman_ci'
94
+ utf8mb4_persian_ci = 'utf8mb4_persian_ci'
95
+ utf8mb4_esperanto_ci = 'utf8mb4_esperanto_ci'
96
+ utf8mb4_hungarian_ci = 'utf8mb4_hungarian_ci'
97
+ utf8mb4_sinhala_ci = 'utf8mb4_sinhala_ci'
98
+
99
+
100
+ def identity(x: Any) -> Any:
101
+ return x
102
+
103
+
104
+ def utf8str(x: Any) -> Optional[str]:
105
+ if x is None:
106
+ return x
107
+ if isinstance(x, str):
108
+ return x
109
+ return str(x, 'utf-8')
110
+
111
+
112
+ def bytestr(x: Any) -> Optional[bytes]:
113
+ if x is None:
114
+ return x
115
+ if isinstance(x, bytes):
116
+ return x
117
+ return bytes.fromhex(x)
118
+
119
+
120
+ DEFAULT_VALUES = {
121
+ 0: 0, # Decimal
122
+ 1: 0, # Tiny
123
+ -1: 0, # Unsigned Tiny
124
+ 2: 0, # Short
125
+ -2: 0, # Unsigned Short
126
+ 3: 0, # Long
127
+ -3: 0, # Unsigned Long
128
+ 4: float('nan'), # Float
129
+ 5: float('nan'), # Double,
130
+ 6: None, # Null,
131
+ 7: 0, # Timestamp
132
+ 8: 0, # LongLong
133
+ -8: 0, # Unsigned Longlong
134
+ 9: 0, # Int24
135
+ -9: 0, # Unsigned Int24
136
+ 10: 0, # Date
137
+ 11: 0, # Time
138
+ 12: 0, # Datetime
139
+ 13: 0, # Year
140
+ 15: None, # Varchar
141
+ -15: None, # Varbinary
142
+ 16: 0, # Bit
143
+ 245: None, # JSON
144
+ 246: 0, # NewDecimal
145
+ 247: None, # Enum
146
+ 248: None, # Set
147
+ 249: None, # TinyText
148
+ -249: None, # TinyBlob
149
+ 250: None, # MediumText
150
+ -250: None, # MediumBlob
151
+ 251: None, # LongText
152
+ -251: None, # LongBlob
153
+ 252: None, # Text
154
+ -252: None, # Blob
155
+ 253: None, # VarString
156
+ -253: None, # VarBinary
157
+ 254: None, # String
158
+ -254: None, # Binary
159
+ 255: None, # Geometry
160
+ }
161
+
162
+ PYTHON_CONVERTERS = {
163
+ -1: converters[1],
164
+ -2: converters[2],
165
+ -3: converters[3],
166
+ -8: converters[8],
167
+ -9: converters[9],
168
+ 15: utf8str,
169
+ -15: bytestr,
170
+ 249: utf8str,
171
+ -249: bytestr,
172
+ 250: utf8str,
173
+ -250: bytestr,
174
+ 251: utf8str,
175
+ -251: bytestr,
176
+ 252: utf8str,
177
+ -252: bytestr,
178
+ 254: utf8str,
179
+ -254: bytestr,
180
+ 255: utf8str,
181
+ }
182
+
183
+ PYTHON_CONVERTERS = dict(list(converters.items()) + list(PYTHON_CONVERTERS.items()))
184
+
185
+
186
+ if has_numpy:
187
+ NUMPY_TYPE_MAP = {
188
+ 0: object, # Decimal
189
+ 1: np.int8, # Tiny
190
+ -1: np.uint8, # Unsigned Tiny
191
+ 2: np.int16, # Short
192
+ -2: np.uint16, # Unsigned Short
193
+ 3: np.int32, # Long
194
+ -3: np.uint32, # Unsigned Long
195
+ 4: np.single, # Float
196
+ 5: np.double, # Double,
197
+ 6: object, # Null,
198
+ 7: object, # Timestamp
199
+ 8: np.int64, # LongLong
200
+ -8: np.uint64, # Unsigned LongLong
201
+ 9: np.int32, # Int24
202
+ -9: np.uint32, # Unsigned Int24
203
+ 10: object, # Date
204
+ 11: object, # Time
205
+ 12: object, # Datetime
206
+ 13: np.int16, # Year
207
+ 15: object, # Varchar
208
+ -15: object, # Varbinary
209
+ 16: object, # Bit
210
+ 245: object, # JSON
211
+ 246: object, # NewDecimal
212
+ 247: object, # Enum
213
+ 248: object, # Set
214
+ 249: object, # TinyText
215
+ -249: object, # TinyBlob
216
+ 250: object, # MediumText
217
+ -250: object, # MediumBlob
218
+ 251: object, # LongText
219
+ -251: object, # LongBlob
220
+ 252: object, # Blob
221
+ -252: object, # Text
222
+ 253: object, # VarString
223
+ -253: object, # VarBlob
224
+ 254: object, # String
225
+ -254: object, # Binary
226
+ 255: object, # Geometry
227
+ }
228
+ else:
229
+ NUMPY_TYPE_MAP = {}
230
+
231
+ PANDAS_TYPE_MAP = NUMPY_TYPE_MAP
232
+
233
+ if has_pyarrow:
234
+ PYARROW_TYPE_MAP = {
235
+ 0: pa.string(), # Decimal
236
+ 1: pa.int8(), # Tiny
237
+ -1: pa.uint8(), # Unsigned Tiny
238
+ 2: pa.int16(), # Short
239
+ -2: pa.uint16(), # Unsigned Short
240
+ 3: pa.int32(), # Long
241
+ -3: pa.uint32(), # Unsigned Long
242
+ 4: pa.float32(), # Float
243
+ 5: pa.float64(), # Double,
244
+ 6: pa.null(), # Null,
245
+ 7: pa.timestamp('ns'), # Timestamp
246
+ 8: pa.int64(), # LongLong
247
+ -8: pa.uint64(), # Unsigned LongLong
248
+ 9: pa.int32(), # Int24
249
+ -9: pa.uint32(), # Unsigned Int24
250
+ 10: pa.date64(), # Date
251
+ 11: pa.duration('ns'), # Time
252
+ 12: pa.timestamp('ns'), # Datetime
253
+ 13: pa.int16(), # Year
254
+ 15: pa.string(), # Varchar
255
+ -15: pa.binary(), # Varbinary
256
+ 16: pa.binary(), # Bit
257
+ 245: pa.string(), # JSON
258
+ 246: pa.string(), # NewDecimal
259
+ 247: pa.string(), # Enum
260
+ 248: pa.string(), # Set
261
+ 249: pa.string(), # TinyText
262
+ -249: pa.binary(), # TinyBlob
263
+ 250: pa.string(), # MediumText
264
+ -250: pa.binary(), # MediumBlob
265
+ 251: pa.string(), # LongText
266
+ -251: pa.binary(), # LongBlob
267
+ 252: pa.string(), # Text
268
+ -252: pa.binary(), # Blob
269
+ 253: pa.string(), # VarString
270
+ -253: pa.binary(), # VarBinary
271
+ 254: pa.string(), # String
272
+ -254: pa.binary(), # Binary
273
+ 255: pa.string(), # Geometry
274
+ }
275
+ else:
276
+ PYARROW_TYPE_MAP = {}
277
+
278
+ if has_polars:
279
+ POLARS_TYPE_MAP = {
280
+ 0: pl.Utf8, # Decimal
281
+ 1: pl.Int8, # Tiny
282
+ -1: pl.UInt8, # Unsigned Tiny
283
+ 2: pl.Int16, # Short
284
+ -2: pl.UInt16, # Unsigned Short
285
+ 3: pl.Int32, # Long
286
+ -3: pl.UInt32, # Unsigned Long
287
+ 4: pl.Float32, # Float
288
+ 5: pl.Float64, # Double,
289
+ 6: pl.Null, # Null,
290
+ 7: pl.Datetime, # Timestamp
291
+ 8: pl.Int64, # LongLong
292
+ -8: pl.UInt64, # Unsigned LongLong
293
+ 9: pl.Int32, # Int24
294
+ -9: pl.UInt32, # Unsigned Int24
295
+ 10: pl.Date, # Date
296
+ 11: pl.Time, # Time
297
+ 12: pl.Datetime, # Datetime
298
+ 13: pl.Int16, # Year
299
+ 15: pl.Utf8, # Varchar
300
+ -15: pl.Utf8, # Varbinary
301
+ 16: pl.Binary, # Bit
302
+ 245: pl.Utf8, # JSON
303
+ 246: pl.Utf8, # NewDecimal
304
+ 247: pl.Utf8, # Enum
305
+ 248: pl.Utf8, # Set
306
+ 249: pl.Utf8, # TinyText
307
+ -249: pl.Utf8, # TinyBlob
308
+ 250: pl.Utf8, # MediumBlob
309
+ -250: pl.Utf8, # MediumText
310
+ 251: pl.Utf8, # LongBlob
311
+ -251: pl.Utf8, # LongText
312
+ 252: pl.Utf8, # Blob
313
+ -252: pl.Utf8, # Text
314
+ 253: pl.Utf8, # VarString
315
+ -253: pl.Utf8, # VarBinary
316
+ 254: pl.Utf8, # String
317
+ -254: pl.Utf8, # Binary
318
+ 255: pl.Utf8, # Geometry
319
+ }
320
+ else:
321
+ POLARS_TYPE_MAP = {}
322
+
323
+
324
+ def _modifiers(
325
+ *,
326
+ nullable: Optional[bool] = None,
327
+ charset: Optional[str] = None,
328
+ collate: Optional[str] = None,
329
+ default: Optional[Any] = None,
330
+ unsigned: Optional[bool] = None,
331
+ ) -> str:
332
+ """
333
+ Format type modifiers.
334
+
335
+ Parameters
336
+ ----------
337
+ nullable : bool, optional
338
+ Can the value be NULL?
339
+ charset : str, optional
340
+ Character set
341
+ collate : str, optional
342
+ Collation
343
+ default ; Any, optional
344
+ Default value
345
+ unsigned : bool, optional
346
+ Is the value unsigned? (ints only)
347
+
348
+ Returns
349
+ -------
350
+ str
351
+
352
+ """
353
+ out = []
354
+
355
+ if unsigned is not None:
356
+ if unsigned:
357
+ out.append('UNSIGNED')
358
+
359
+ if charset is not None:
360
+ if not re.match(r'^[A-Za-z0-9_]+$', charset):
361
+ raise ValueError(f'charset value is invalid: {charset}')
362
+ out.append(f'CHARACTER SET {charset}')
363
+
364
+ if collate is not None:
365
+ if not re.match(r'^[A-Za-z0-9_]+$', collate):
366
+ raise ValueError(f'collate value is invalid: {collate}')
367
+ out.append(f'COLLATE {collate}')
368
+
369
+ if nullable is not None:
370
+ if nullable:
371
+ out.append('NULL')
372
+ else:
373
+ out.append('NOT NULL')
374
+
375
+ if default is NULL:
376
+ out.append('DEFAULT NULL')
377
+ elif default is not None:
378
+ out.append(f'DEFAULT {escape_item(default, "utf-8")}')
379
+
380
+ return ' ' + ' '.join(out)
381
+
382
+
383
+ def _bool(x: Optional[bool] = None) -> Optional[bool]:
384
+ """Cast bool."""
385
+ if x is None:
386
+ return None
387
+ return bool(x)
388
+
389
+
390
+ def BOOL(*, nullable: bool = True, default: Optional[bool] = None) -> str:
391
+ """
392
+ BOOL type specification.
393
+
394
+ Parameters
395
+ ----------
396
+ nullable : bool, optional
397
+ Can the value be NULL?
398
+ default : bool, optional
399
+ Default value
400
+
401
+ Returns
402
+ -------
403
+ str
404
+
405
+ """
406
+ return 'BOOL' + _modifiers(nullable=nullable, default=_bool(default))
407
+
408
+
409
+ def BOOLEAN(*, nullable: bool = True, default: Optional[bool] = None) -> str:
410
+ """
411
+ BOOLEAN type specification.
412
+
413
+ Parameters
414
+ ----------
415
+ nullable : bool, optional
416
+ Can the value be NULL?
417
+ default : bool, optional
418
+ Default value
419
+
420
+ Returns
421
+ -------
422
+ str
423
+
424
+ """
425
+ return 'BOOLEAN' + _modifiers(nullable=nullable, default=_bool(default))
426
+
427
+
428
+ def BIT(*, nullable: bool = True, default: Optional[int] = None) -> str:
429
+ """
430
+ BIT type specification.
431
+
432
+ Parameters
433
+ ----------
434
+ nullable : bool, optional
435
+ Can the value be NULL?
436
+ default : int, optional
437
+ Default value
438
+
439
+ Returns
440
+ -------
441
+ str
442
+
443
+ """
444
+ return 'BIT' + _modifiers(nullable=nullable, default=default)
445
+
446
+
447
+ def TINYINT(
448
+ display_width: Optional[int] = None,
449
+ *,
450
+ nullable: bool = True,
451
+ default: Optional[int] = None,
452
+ unsigned: bool = False,
453
+ ) -> str:
454
+ """
455
+ TINYINT type specification.
456
+
457
+ Parameters
458
+ ----------
459
+ display_width : int, optional
460
+ Display width used by some clients
461
+ nullable : bool, optional
462
+ Can the value be NULL?
463
+ default : int, optional
464
+ Default value
465
+ unsigned : bool, optional
466
+ Is the int unsigned?
467
+
468
+ Returns
469
+ -------
470
+ str
471
+
472
+ """
473
+ out = f'TINYINT({display_width})' if display_width else 'TINYINT'
474
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
475
+
476
+
477
+ def TINYINT_UNSIGNED(
478
+ display_width: Optional[int] = None,
479
+ *,
480
+ nullable: bool = True,
481
+ default: Optional[int] = None,
482
+ ) -> str:
483
+ """
484
+ TINYINT UNSIGNED type specification.
485
+
486
+ Parameters
487
+ ----------
488
+ display_width : int, optional
489
+ Display width used by some clients
490
+ nullable : bool, optional
491
+ Can the value be NULL?
492
+ default : int, optional
493
+ Default value
494
+
495
+ Returns
496
+ -------
497
+ str
498
+
499
+ """
500
+ out = f'TINYINT({display_width})' if display_width else 'TINYINT'
501
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
502
+
503
+
504
+ def SMALLINT(
505
+ display_width: Optional[int] = None,
506
+ *,
507
+ nullable: bool = True,
508
+ default: Optional[int] = None,
509
+ unsigned: bool = False,
510
+ ) -> str:
511
+ """
512
+ SMALLINT type specification.
513
+
514
+ Parameters
515
+ ----------
516
+ display_width : int, optional
517
+ Display width used by some clients
518
+ nullable : bool, optional
519
+ Can the value be NULL?
520
+ default : int, optional
521
+ Default value
522
+ unsigned : bool, optional
523
+ Is the int unsigned?
524
+
525
+ Returns
526
+ -------
527
+ str
528
+
529
+ """
530
+ out = f'SMALLINT({display_width})' if display_width else 'SMALLINT'
531
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
532
+
533
+
534
+ def SMALLINT_UNSIGNED(
535
+ display_width: Optional[int] = None,
536
+ *,
537
+ nullable: bool = True,
538
+ default: Optional[int] = None,
539
+ ) -> str:
540
+ """
541
+ SMALLINT UNSIGNED type specification.
542
+
543
+ Parameters
544
+ ----------
545
+ display_width : int, optional
546
+ Display width used by some clients
547
+ nullable : bool, optional
548
+ Can the value be NULL?
549
+ default : int, optional
550
+ Default value
551
+
552
+ Returns
553
+ -------
554
+ str
555
+
556
+ """
557
+ out = f'SMALLINT({display_width})' if display_width else 'SMALLINT'
558
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
559
+
560
+
561
+ def MEDIUMINT(
562
+ display_width: Optional[int] = None,
563
+ *,
564
+ nullable: bool = True,
565
+ default: Optional[int] = None,
566
+ unsigned: bool = False,
567
+ ) -> str:
568
+ """
569
+ MEDIUMINT type specification.
570
+
571
+ Parameters
572
+ ----------
573
+ display_width : int, optional
574
+ Display width used by some clients
575
+ nullable : bool, optional
576
+ Can the value be NULL?
577
+ default : int, optional
578
+ Default value
579
+ unsigned : bool, optional
580
+ Is the int unsigned?
581
+
582
+ Returns
583
+ -------
584
+ str
585
+
586
+ """
587
+ out = f'MEDIUMINT({display_width})' if display_width else 'MEDIUMINT'
588
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
589
+
590
+
591
+ def MEDIUMINT_UNSIGNED(
592
+ display_width: Optional[int] = None,
593
+ *,
594
+ nullable: bool = True,
595
+ default: Optional[int] = None,
596
+ ) -> str:
597
+ """
598
+ MEDIUMINT UNSIGNED type specification.
599
+
600
+ Parameters
601
+ ----------
602
+ display_width : int, optional
603
+ Display width used by some clients
604
+ nullable : bool, optional
605
+ Can the value be NULL?
606
+ default : int, optional
607
+ Default value
608
+
609
+ Returns
610
+ -------
611
+ str
612
+
613
+ """
614
+ out = f'MEDIUMINT({display_width})' if display_width else 'MEDIUMINT'
615
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
616
+
617
+
618
+ def INT(
619
+ display_width: Optional[int] = None,
620
+ *,
621
+ nullable: bool = True,
622
+ default: Optional[int] = None,
623
+ unsigned: bool = False,
624
+ ) -> str:
625
+ """
626
+ INT type specification.
627
+
628
+ Parameters
629
+ ----------
630
+ display_width : int, optional
631
+ Display width used by some clients
632
+ nullable : bool, optional
633
+ Can the value be NULL?
634
+ default : int, optional
635
+ Default value
636
+ unsigned : bool, optional
637
+ Is the int unsigned?
638
+
639
+ Returns
640
+ -------
641
+ str
642
+
643
+ """
644
+ out = f'INT({display_width})' if display_width else 'INT'
645
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
646
+
647
+
648
+ def INT_UNSIGNED(
649
+ display_width: Optional[int] = None,
650
+ *,
651
+ nullable: bool = True,
652
+ default: Optional[int] = None,
653
+ ) -> str:
654
+ """
655
+ INT UNSIGNED type specification.
656
+
657
+ Parameters
658
+ ----------
659
+ display_width : int, optional
660
+ Display width used by some clients
661
+ nullable : bool, optional
662
+ Can the value be NULL?
663
+ default : int, optional
664
+ Default value
665
+
666
+ Returns
667
+ -------
668
+ str
669
+
670
+ """
671
+ out = f'INT({display_width})' if display_width else 'INT'
672
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
673
+
674
+
675
+ def INTEGER(
676
+ display_width: Optional[int] = None,
677
+ *,
678
+ nullable: bool = True,
679
+ default: Optional[int] = None,
680
+ unsigned: bool = False,
681
+ ) -> str:
682
+ """
683
+ INTEGER type specification.
684
+
685
+ Parameters
686
+ ----------
687
+ display_width : int, optional
688
+ Display width used by some clients
689
+ nullable : bool, optional
690
+ Can the value be NULL?
691
+ default : int, optional
692
+ Default value
693
+ unsigned : bool, optional
694
+ Is the int unsigned?
695
+
696
+ Returns
697
+ -------
698
+ str
699
+
700
+ """
701
+ out = f'INTEGER({display_width})' if display_width else 'INTEGER'
702
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
703
+
704
+
705
+ def INTEGER_UNSIGNED(
706
+ display_width: Optional[int] = None,
707
+ *,
708
+ nullable: bool = True,
709
+ default: Optional[int] = None,
710
+ ) -> str:
711
+ """
712
+ INTEGER UNSIGNED type specification.
713
+
714
+ Parameters
715
+ ----------
716
+ display_width : int, optional
717
+ Display width used by some clients
718
+ nullable : bool, optional
719
+ Can the value be NULL?
720
+ default : int, optional
721
+ Default value
722
+
723
+ Returns
724
+ -------
725
+ str
726
+
727
+ """
728
+ out = f'INTEGER({display_width})' if display_width else 'INTEGER'
729
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
730
+
731
+
732
+ def BIGINT(
733
+ display_width: Optional[int] = None,
734
+ *,
735
+ nullable: bool = True,
736
+ default: Optional[int] = None,
737
+ unsigned: bool = False,
738
+ ) -> str:
739
+ """
740
+ BIGINT type specification.
741
+
742
+ Parameters
743
+ ----------
744
+ display_width : int, optional
745
+ Display width used by some clients
746
+ nullable : bool, optional
747
+ Can the value be NULL?
748
+ default : int, optional
749
+ Default value
750
+ unsigned : bool, optional
751
+ Is the int unsigned?
752
+
753
+ Returns
754
+ -------
755
+ str
756
+
757
+ """
758
+ out = f'BIGINT({display_width})' if display_width else 'BIGINT'
759
+ return out + _modifiers(nullable=nullable, default=default, unsigned=unsigned)
760
+
761
+
762
+ def BIGINT_UNSIGNED(
763
+ display_width: Optional[int] = None,
764
+ *,
765
+ nullable: bool = True,
766
+ default: Optional[int] = None,
767
+ ) -> str:
768
+ """
769
+ BIGINT UNSIGNED type specification.
770
+
771
+ Parameters
772
+ ----------
773
+ display_width : int, optional
774
+ Display width used by some clients
775
+ nullable : bool, optional
776
+ Can the value be NULL?
777
+ default : int, optional
778
+ Default value
779
+
780
+ Returns
781
+ -------
782
+ str
783
+
784
+ """
785
+ out = f'BIGINT({int(display_width)})' if display_width else 'BIGINT'
786
+ return out + _modifiers(nullable=nullable, default=default, unsigned=True)
787
+
788
+
789
+ def FLOAT(
790
+ display_decimals: Optional[int] = None,
791
+ *,
792
+ nullable: bool = True,
793
+ default: Optional[float] = None,
794
+ ) -> str:
795
+ """
796
+ FLOAT type specification.
797
+
798
+ Parameters
799
+ ----------
800
+ display_decimals : int, optional
801
+ Number of decimal places to display
802
+ nullable : bool, optional
803
+ Can the value be NULL?
804
+ default : float, optional
805
+ Default value
806
+
807
+ Returns
808
+ -------
809
+ str
810
+
811
+ """
812
+ out = f'FLOAT({int(display_decimals)})' if display_decimals else 'FLOAT'
813
+ return out + _modifiers(nullable=nullable, default=default)
814
+
815
+
816
+ def DOUBLE(
817
+ display_decimals: Optional[int] = None,
818
+ *,
819
+ nullable: bool = True,
820
+ default: Optional[float] = None,
821
+ ) -> str:
822
+ """
823
+ DOUBLE type specification.
824
+
825
+ Parameters
826
+ ----------
827
+ display_decimals : int, optional
828
+ Number of decimal places to display
829
+ nullable : bool, optional
830
+ Can the value be NULL?
831
+ default : float, optional
832
+ Default value
833
+
834
+ Returns
835
+ -------
836
+ str
837
+
838
+ """
839
+ out = f'DOUBLE({int(display_decimals)})' if display_decimals else 'DOUBLE'
840
+ return out + _modifiers(nullable=nullable, default=default)
841
+
842
+
843
+ def REAL(
844
+ display_decimals: Optional[int] = None,
845
+ *,
846
+ nullable: bool = True,
847
+ default: Optional[float] = None,
848
+ ) -> str:
849
+ """
850
+ REAL type specification.
851
+
852
+ Parameters
853
+ ----------
854
+ display_decimals : int, optional
855
+ Number of decimal places to display
856
+ nullable : bool, optional
857
+ Can the value be NULL?
858
+ default : float, optional
859
+ Default value
860
+
861
+ Returns
862
+ -------
863
+ str
864
+
865
+ """
866
+ out = f'REAL({int(display_decimals)})' if display_decimals else 'REAL'
867
+ return out + _modifiers(nullable=nullable, default=default)
868
+
869
+
870
+ def DECIMAL(
871
+ precision: int,
872
+ scale: int,
873
+ *,
874
+ nullable: bool = True,
875
+ default: Optional[Union[str, decimal.Decimal]] = None,
876
+ ) -> str:
877
+ """
878
+ DECIMAL type specification.
879
+
880
+ Parameters
881
+ ----------
882
+ precision : int
883
+ Decimal precision
884
+ scale : int
885
+ Decimal scale
886
+ nullable : bool, optional
887
+ Can the value be NULL?
888
+ default : str or decimal.Decimal, optional
889
+ Default value
890
+
891
+ Returns
892
+ -------
893
+ str
894
+
895
+ """
896
+ return f'DECIMAL({int(precision)}, {int(scale)})' + \
897
+ _modifiers(nullable=nullable, default=default)
898
+
899
+
900
+ def DEC(
901
+ precision: int,
902
+ scale: int,
903
+ *,
904
+ nullable: bool = True,
905
+ default: Optional[Union[str, decimal.Decimal]] = None,
906
+ ) -> str:
907
+ """
908
+ DEC type specification.
909
+
910
+ Parameters
911
+ ----------
912
+ precision : int
913
+ Decimal precision
914
+ scale : int
915
+ Decimal scale
916
+ nullable : bool, optional
917
+ Can the value be NULL?
918
+ default : str or decimal.Decimal, optional
919
+ Default value
920
+
921
+ Returns
922
+ -------
923
+ str
924
+
925
+ """
926
+ return f'DEC({int(precision)}, {int(scale)})' + \
927
+ _modifiers(nullable=nullable, default=default)
928
+
929
+
930
+ def FIXED(
931
+ precision: int,
932
+ scale: int,
933
+ *,
934
+ nullable: bool = True,
935
+ default: Optional[Union[str, decimal.Decimal]] = None,
936
+ ) -> str:
937
+ """
938
+ FIXED type specification.
939
+
940
+ Parameters
941
+ ----------
942
+ precision : int
943
+ Decimal precision
944
+ scale : int
945
+ Decimal scale
946
+ nullable : bool, optional
947
+ Can the value be NULL?
948
+ default : str or decimal.Decimal, optional
949
+ Default value
950
+
951
+ Returns
952
+ -------
953
+ str
954
+
955
+ """
956
+ return f'FIXED({int(precision)}, {int(scale)})' + \
957
+ _modifiers(nullable=nullable, default=default)
958
+
959
+
960
+ def NUMERIC(
961
+ precision: int,
962
+ scale: int,
963
+ *,
964
+ nullable: bool = True,
965
+ default: Optional[Union[str, decimal.Decimal]] = None,
966
+ ) -> str:
967
+ """
968
+ NUMERIC type specification.
969
+
970
+ Parameters
971
+ ----------
972
+ precision : int
973
+ Decimal precision
974
+ scale : int
975
+ Decimal scale
976
+ nullable : bool, optional
977
+ Can the value be NULL?
978
+ default : str or decimal.Decimal, optional
979
+ Default value
980
+
981
+ Returns
982
+ -------
983
+ str
984
+
985
+ """
986
+ return f'NUMERIC({int(precision)}, {int(scale)})' + \
987
+ _modifiers(nullable=nullable, default=default)
988
+
989
+
990
+ def DATE(
991
+ *,
992
+ nullable: bool = True,
993
+ default: Optional[Union[str, datetime.date]] = None,
994
+ ) -> str:
995
+ """
996
+ DATE type specification.
997
+
998
+ Parameters
999
+ ----------
1000
+ nullable : bool, optional
1001
+ Can the value be NULL?
1002
+ default : str or datetime.date, optional
1003
+ Default value
1004
+
1005
+ Returns
1006
+ -------
1007
+ str
1008
+
1009
+ """
1010
+ return 'DATE' + _modifiers(nullable=nullable, default=default)
1011
+
1012
+
1013
+ def TIME(
1014
+ precision: Optional[int] = None,
1015
+ *,
1016
+ nullable: bool = True,
1017
+ default: Optional[Union[str, datetime.timedelta]] = None,
1018
+ ) -> str:
1019
+ """
1020
+ TIME type specification.
1021
+
1022
+ Parameters
1023
+ ----------
1024
+ precision : int, optional
1025
+ Sub-second precision
1026
+ nullable : bool, optional
1027
+ Can the value be NULL?
1028
+ default : str or datetime.timedelta, optional
1029
+ Default value
1030
+
1031
+ Returns
1032
+ -------
1033
+ str
1034
+
1035
+ """
1036
+ out = f'TIME({int(precision)})' if precision else 'TIME'
1037
+ return out + _modifiers(nullable=nullable, default=default)
1038
+
1039
+
1040
+ def DATETIME(
1041
+ precision: Optional[int] = None,
1042
+ *,
1043
+ nullable: bool = True,
1044
+ default: Optional[Union[str, datetime.datetime]] = None,
1045
+ ) -> str:
1046
+ """
1047
+ DATETIME type specification.
1048
+
1049
+ Parameters
1050
+ ----------
1051
+ precision : int, optional
1052
+ Sub-second precision
1053
+ nullable : bool, optional
1054
+ Can the value be NULL?
1055
+ default : str or datetime.datetime, optional
1056
+ Default value
1057
+
1058
+ Returns
1059
+ -------
1060
+ str
1061
+
1062
+ """
1063
+ out = f'DATETIME({int(precision)})' if precision else 'DATETIME'
1064
+ return out + _modifiers(nullable=nullable, default=default)
1065
+
1066
+
1067
+ def TIMESTAMP(
1068
+ precision: Optional[int] = None,
1069
+ *,
1070
+ nullable: bool = True,
1071
+ default: Optional[Union[str, datetime.datetime]] = None,
1072
+ ) -> str:
1073
+ """
1074
+ TIMESTAMP type specification.
1075
+
1076
+ Parameters
1077
+ ----------
1078
+ precision : int, optional
1079
+ Sub-second precision
1080
+ nullable : bool, optional
1081
+ Can the value be NULL?
1082
+ default : str or datetime.datetime, optional
1083
+ Default value
1084
+
1085
+ Returns
1086
+ -------
1087
+ str
1088
+
1089
+ """
1090
+ out = f'TIMESTAMP({int(precision)})' if precision else 'TIMESTAMP'
1091
+ return out + _modifiers(nullable=nullable, default=default)
1092
+
1093
+
1094
+ def YEAR(*, nullable: bool = True, default: Optional[int] = None) -> str:
1095
+ """
1096
+ YEAR type specification.
1097
+
1098
+ Parameters
1099
+ ----------
1100
+ nullable : bool, optional
1101
+ Can the value be NULL?
1102
+ default : int, optional
1103
+ Default value
1104
+
1105
+ Returns
1106
+ -------
1107
+ str
1108
+
1109
+ """
1110
+ return 'YEAR' + _modifiers(nullable=nullable, default=default)
1111
+
1112
+
1113
+ def CHAR(
1114
+ length: Optional[int] = None,
1115
+ *,
1116
+ nullable: bool = True,
1117
+ default: Optional[str] = None,
1118
+ collate: Optional[str] = None,
1119
+ charset: Optional[str] = None,
1120
+ ) -> str:
1121
+ """
1122
+ CHAR type specification.
1123
+
1124
+ Parameters
1125
+ ----------
1126
+ length : int, optional
1127
+ Maximum string length
1128
+ nullable : bool, optional
1129
+ Can the value be NULL?
1130
+ default : str, optional
1131
+ Default value
1132
+ collate : str, optional
1133
+ Collation
1134
+ charset : str, optional
1135
+ Character set
1136
+
1137
+ Returns
1138
+ -------
1139
+ str
1140
+
1141
+ """
1142
+ out = f'CHAR({int(length)})' if length else 'CHAR'
1143
+ return out + _modifiers(
1144
+ nullable=nullable, default=default,
1145
+ collate=collate, charset=charset,
1146
+ )
1147
+
1148
+
1149
+ def VARCHAR(
1150
+ length: Optional[int] = None,
1151
+ *,
1152
+ nullable: bool = True,
1153
+ default: Optional[str] = None,
1154
+ collate: Optional[str] = None,
1155
+ charset: Optional[str] = None,
1156
+ ) -> str:
1157
+ """
1158
+ VARCHAR type specification.
1159
+
1160
+ Parameters
1161
+ ----------
1162
+ length : int, optional
1163
+ Maximum string length
1164
+ nullable : bool, optional
1165
+ Can the value be NULL?
1166
+ default : str, optional
1167
+ Default value
1168
+ collate : str, optional
1169
+ Collation
1170
+ charset : str, optional
1171
+ Character set
1172
+
1173
+ Returns
1174
+ -------
1175
+ str
1176
+
1177
+ """
1178
+ out = f'VARCHAR({int(length)})' if length else 'VARCHAR'
1179
+ return out + _modifiers(
1180
+ nullable=nullable, default=default,
1181
+ collate=collate, charset=charset,
1182
+ )
1183
+
1184
+
1185
+ def LONGTEXT(
1186
+ length: Optional[int] = None,
1187
+ *,
1188
+ nullable: bool = True,
1189
+ default: Optional[str] = None,
1190
+ collate: Optional[str] = None,
1191
+ charset: Optional[str] = None,
1192
+ ) -> str:
1193
+ """
1194
+ LONGTEXT type specification.
1195
+
1196
+ Parameters
1197
+ ----------
1198
+ length : int, optional
1199
+ Maximum string length
1200
+ nullable : bool, optional
1201
+ Can the value be NULL?
1202
+ default : str, optional
1203
+ Default value
1204
+ collate : str, optional
1205
+ Collation
1206
+ charset : str, optional
1207
+ Character set
1208
+
1209
+ Returns
1210
+ -------
1211
+ str
1212
+
1213
+ """
1214
+ out = f'LONGTEXT({int(length)})' if length else 'LONGTEXT'
1215
+ return out + _modifiers(
1216
+ nullable=nullable, default=default,
1217
+ collate=collate, charset=charset,
1218
+ )
1219
+
1220
+
1221
+ def MEDIUMTEXT(
1222
+ length: Optional[int] = None,
1223
+ *,
1224
+ nullable: bool = True,
1225
+ default: Optional[str] = None,
1226
+ collate: Optional[str] = None,
1227
+ charset: Optional[str] = None,
1228
+ ) -> str:
1229
+ """
1230
+ MEDIUMTEXT type specification.
1231
+
1232
+ Parameters
1233
+ ----------
1234
+ length : int, optional
1235
+ Maximum string length
1236
+ nullable : bool, optional
1237
+ Can the value be NULL?
1238
+ default : str, optional
1239
+ Default value
1240
+ collate : str, optional
1241
+ Collation
1242
+ charset : str, optional
1243
+ Character set
1244
+
1245
+ Returns
1246
+ -------
1247
+ str
1248
+
1249
+ """
1250
+ out = f'MEDIUMTEXT({int(length)})' if length else 'MEDIUMTEXT'
1251
+ return out + _modifiers(
1252
+ nullable=nullable, default=default,
1253
+ collate=collate, charset=charset,
1254
+ )
1255
+
1256
+
1257
+ def TEXT(
1258
+ length: Optional[int] = None,
1259
+ *,
1260
+ nullable: bool = True,
1261
+ default: Optional[str] = None,
1262
+ collate: Optional[str] = None,
1263
+ charset: Optional[str] = None,
1264
+ ) -> str:
1265
+ """
1266
+ TEXT type specification.
1267
+
1268
+ Parameters
1269
+ ----------
1270
+ length : int, optional
1271
+ Maximum string length
1272
+ nullable : bool, optional
1273
+ Can the value be NULL?
1274
+ default : str, optional
1275
+ Default value
1276
+ collate : str, optional
1277
+ Collation
1278
+ charset : str, optional
1279
+ Character set
1280
+
1281
+ Returns
1282
+ -------
1283
+ str
1284
+
1285
+ """
1286
+ out = f'TEXT({int(length)})' if length else 'TEXT'
1287
+ return out + _modifiers(
1288
+ nullable=nullable, default=default,
1289
+ collate=collate, charset=charset,
1290
+ )
1291
+
1292
+
1293
+ def TINYTEXT(
1294
+ length: Optional[int] = None,
1295
+ *,
1296
+ nullable: bool = True,
1297
+ default: Optional[str] = None,
1298
+ collate: Optional[str] = None,
1299
+ charset: Optional[str] = None,
1300
+ ) -> str:
1301
+ """
1302
+ TINYTEXT type specification.
1303
+
1304
+ Parameters
1305
+ ----------
1306
+ length : int, optional
1307
+ Maximum string length
1308
+ nullable : bool, optional
1309
+ Can the value be NULL?
1310
+ default : str, optional
1311
+ Default value
1312
+ collate : str, optional
1313
+ Collation
1314
+ charset : str, optional
1315
+ Character set
1316
+
1317
+ Returns
1318
+ -------
1319
+ str
1320
+
1321
+ """
1322
+ out = f'TINYTEXT({int(length)})' if length else 'TINYTEXT'
1323
+ return out + _modifiers(
1324
+ nullable=nullable, default=default,
1325
+ collate=collate, charset=charset,
1326
+ )
1327
+
1328
+
1329
+ def BINARY(
1330
+ length: Optional[int] = None,
1331
+ *,
1332
+ nullable: bool = True,
1333
+ default: Optional[bytes] = None,
1334
+ collate: Optional[str] = None,
1335
+ ) -> str:
1336
+ """
1337
+ BINARY type specification.
1338
+
1339
+ Parameters
1340
+ ----------
1341
+ length : int, optional
1342
+ Maximum string length
1343
+ nullable : bool, optional
1344
+ Can the value be NULL?
1345
+ default : str, optional
1346
+ Default value
1347
+ collate : str, optional
1348
+ Collation
1349
+
1350
+ Returns
1351
+ -------
1352
+ str
1353
+
1354
+ """
1355
+ out = f'BINARY({int(length)})' if length else 'BINARY'
1356
+ return out + _modifiers(
1357
+ nullable=nullable, default=default, collate=collate,
1358
+ )
1359
+
1360
+
1361
+ def VARBINARY(
1362
+ length: Optional[int] = None,
1363
+ *,
1364
+ nullable: bool = True,
1365
+ default: Optional[bytes] = None,
1366
+ collate: Optional[str] = None,
1367
+ ) -> str:
1368
+ """
1369
+ VARBINARY type specification.
1370
+
1371
+ Parameters
1372
+ ----------
1373
+ length : int, optional
1374
+ Maximum string length
1375
+ nullable : bool, optional
1376
+ Can the value be NULL?
1377
+ default : str, optional
1378
+ Default value
1379
+ collate : str, optional
1380
+ Collation
1381
+
1382
+ Returns
1383
+ -------
1384
+ str
1385
+
1386
+ """
1387
+ out = f'VARBINARY({int(length)})' if length else 'VARBINARY'
1388
+ return out + _modifiers(
1389
+ nullable=nullable, default=default, collate=collate,
1390
+ )
1391
+
1392
+
1393
+ def LONGBLOB(
1394
+ length: Optional[int] = None,
1395
+ *,
1396
+ nullable: bool = True,
1397
+ default: Optional[bytes] = None,
1398
+ collate: Optional[str] = None,
1399
+ ) -> str:
1400
+ """
1401
+ LONGBLOB type specification.
1402
+
1403
+ Parameters
1404
+ ----------
1405
+ length : int, optional
1406
+ Maximum string length
1407
+ nullable : bool, optional
1408
+ Can the value be NULL?
1409
+ default : str, optional
1410
+ Default value
1411
+ collate : str, optional
1412
+ Collation
1413
+
1414
+ Returns
1415
+ -------
1416
+ str
1417
+
1418
+ """
1419
+ out = f'LONGBLOB({int(length)})' if length else 'LONGBLOB'
1420
+ return out + _modifiers(
1421
+ nullable=nullable, default=default, collate=collate,
1422
+ )
1423
+
1424
+
1425
+ def MEDIUMBLOB(
1426
+ length: Optional[int] = None,
1427
+ *,
1428
+ nullable: bool = True,
1429
+ default: Optional[bytes] = None,
1430
+ collate: Optional[str] = None,
1431
+ ) -> str:
1432
+ """
1433
+ MEDIUMBLOB type specification.
1434
+
1435
+ Parameters
1436
+ ----------
1437
+ length : int, optional
1438
+ Maximum string length
1439
+ nullable : bool, optional
1440
+ Can the value be NULL?
1441
+ default : str, optional
1442
+ Default value
1443
+ collate : str, optional
1444
+ Collation
1445
+
1446
+ Returns
1447
+ -------
1448
+ str
1449
+
1450
+ """
1451
+ out = f'MEDIUMBLOB({int(length)})' if length else 'MEDIUMBLOB'
1452
+ return out + _modifiers(
1453
+ nullable=nullable, default=default, collate=collate,
1454
+ )
1455
+
1456
+
1457
+ def BLOB(
1458
+ length: Optional[int] = None,
1459
+ *,
1460
+ nullable: bool = True,
1461
+ default: Optional[bytes] = None,
1462
+ collate: Optional[str] = None,
1463
+ ) -> str:
1464
+ """
1465
+ BLOB type specification.
1466
+
1467
+ Parameters
1468
+ ----------
1469
+ length : int, optional
1470
+ Maximum string length
1471
+ nullable : bool, optional
1472
+ Can the value be NULL?
1473
+ default : str, optional
1474
+ Default value
1475
+ collate : str, optional
1476
+ Collation
1477
+
1478
+ Returns
1479
+ -------
1480
+ str
1481
+
1482
+ """
1483
+ out = f'BLOB({int(length)})' if length else 'BLOB'
1484
+ return out + _modifiers(
1485
+ nullable=nullable, default=default, collate=collate,
1486
+ )
1487
+
1488
+
1489
+ def TINYBLOB(
1490
+ length: Optional[int] = None,
1491
+ *,
1492
+ nullable: bool = True,
1493
+ default: Optional[bytes] = None,
1494
+ collate: Optional[str] = None,
1495
+ ) -> str:
1496
+ """
1497
+ TINYBLOB type specification.
1498
+
1499
+ Parameters
1500
+ ----------
1501
+ length : int, optional
1502
+ Maximum string length
1503
+ nullable : bool, optional
1504
+ Can the value be NULL?
1505
+ default : str, optional
1506
+ Default value
1507
+ collate : str, optional
1508
+ Collation
1509
+
1510
+ Returns
1511
+ -------
1512
+ str
1513
+
1514
+ """
1515
+ out = f'TINYBLOB({int(length)})' if length else 'TINYBLOB'
1516
+ return out + _modifiers(
1517
+ nullable=nullable, default=default, collate=collate,
1518
+ )
1519
+
1520
+
1521
+ def JSON(
1522
+ length: Optional[int] = None,
1523
+ *,
1524
+ nullable: bool = True,
1525
+ default: Optional[str] = None,
1526
+ collate: Optional[str] = None,
1527
+ charset: Optional[str] = None,
1528
+ ) -> str:
1529
+ """
1530
+ JSON type specification.
1531
+
1532
+ Parameters
1533
+ ----------
1534
+ length : int, optional
1535
+ Maximum string length
1536
+ nullable : bool, optional
1537
+ Can the value be NULL?
1538
+ default : str, optional
1539
+ Default value
1540
+ collate : str, optional
1541
+ Collation
1542
+ charset : str, optional
1543
+ Character set
1544
+
1545
+ Returns
1546
+ -------
1547
+ str
1548
+
1549
+ """
1550
+ out = f'JSON({int(length)})' if length else 'JSON'
1551
+ return out + _modifiers(
1552
+ nullable=nullable, default=default,
1553
+ collate=collate, charset=charset,
1554
+ )
1555
+
1556
+
1557
+ def GEOGRAPHYPOINT(*, nullable: bool = True, default: Optional[str] = None) -> str:
1558
+ """
1559
+ GEOGRAPHYPOINT type specification.
1560
+
1561
+ Parameters
1562
+ ----------
1563
+ nullable : bool, optional
1564
+ Can the value be NULL?
1565
+ default : str, optional
1566
+ Default value
1567
+
1568
+ Returns
1569
+ -------
1570
+ str
1571
+
1572
+ """
1573
+ return 'GEOGRAPHYPOINT' + _modifiers(nullable=nullable, default=default)
1574
+
1575
+
1576
+ def GEOGRAPHY(*, nullable: bool = True, default: Optional[str] = None) -> str:
1577
+ """
1578
+ GEOGRAPHYPOINT type specification.
1579
+
1580
+ Parameters
1581
+ ----------
1582
+ nullable : bool, optional
1583
+ Can the value be NULL?
1584
+ default : str, optional
1585
+ Default value
1586
+
1587
+ Returns
1588
+ -------
1589
+ str
1590
+
1591
+ """
1592
+ return 'GEOGRAPHY' + _modifiers(nullable=nullable, default=default)
1593
+
1594
+
1595
+ def RECORD(*args: Tuple[str, DataType], nullable: bool = True) -> str:
1596
+ """
1597
+ RECORD type specification.
1598
+
1599
+ Parameters
1600
+ ----------
1601
+ *args : Tuple[str, DataType]
1602
+ Field specifications
1603
+ nullable : bool, optional
1604
+ Can the value be NULL?
1605
+
1606
+ Returns
1607
+ -------
1608
+ str
1609
+
1610
+ """
1611
+ assert len(args) > 0
1612
+ fields = []
1613
+ for name, value in args:
1614
+ if callable(value):
1615
+ fields.append(f'{escape_name(name)} {value()}')
1616
+ else:
1617
+ fields.append(f'{escape_name(name)} {value}')
1618
+ return f'RECORD({", ".join(fields)})' + _modifiers(nullable=nullable)
1619
+
1620
+
1621
+ def ARRAY(dtype: DataType, nullable: bool = True) -> str:
1622
+ """
1623
+ ARRAY type specification.
1624
+
1625
+ Parameters
1626
+ ----------
1627
+ dtype : DataType
1628
+ The data type of the array elements
1629
+ nullable : bool, optional
1630
+ Can the value be NULL?
1631
+
1632
+ Returns
1633
+ -------
1634
+ str
1635
+
1636
+ """
1637
+ if callable(dtype):
1638
+ dtype = dtype()
1639
+ return f'ARRAY({dtype})' + _modifiers(nullable=nullable)