sqlspec 0.25.0__py3-none-any.whl → 0.27.0__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 sqlspec might be problematic. Click here for more details.
- sqlspec/__init__.py +7 -15
- sqlspec/_serialization.py +256 -24
- sqlspec/_typing.py +71 -52
- sqlspec/adapters/adbc/_types.py +1 -1
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +870 -0
- sqlspec/adapters/adbc/config.py +69 -12
- sqlspec/adapters/adbc/data_dictionary.py +340 -0
- sqlspec/adapters/adbc/driver.py +266 -58
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +504 -0
- sqlspec/adapters/adbc/type_converter.py +153 -0
- sqlspec/adapters/aiosqlite/_types.py +1 -1
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +527 -0
- sqlspec/adapters/aiosqlite/config.py +88 -15
- sqlspec/adapters/aiosqlite/data_dictionary.py +149 -0
- sqlspec/adapters/aiosqlite/driver.py +143 -40
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
- sqlspec/adapters/aiosqlite/pool.py +7 -7
- sqlspec/adapters/asyncmy/__init__.py +7 -1
- sqlspec/adapters/asyncmy/_types.py +2 -2
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +493 -0
- sqlspec/adapters/asyncmy/config.py +68 -23
- sqlspec/adapters/asyncmy/data_dictionary.py +161 -0
- sqlspec/adapters/asyncmy/driver.py +313 -58
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +2 -1
- sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
- sqlspec/adapters/asyncpg/_types.py +11 -7
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +450 -0
- sqlspec/adapters/asyncpg/config.py +59 -35
- sqlspec/adapters/asyncpg/data_dictionary.py +173 -0
- sqlspec/adapters/asyncpg/driver.py +170 -25
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +253 -0
- sqlspec/adapters/bigquery/_types.py +1 -1
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +576 -0
- sqlspec/adapters/bigquery/config.py +27 -10
- sqlspec/adapters/bigquery/data_dictionary.py +149 -0
- sqlspec/adapters/bigquery/driver.py +368 -142
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +327 -0
- sqlspec/adapters/bigquery/type_converter.py +125 -0
- sqlspec/adapters/duckdb/_types.py +1 -1
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +553 -0
- sqlspec/adapters/duckdb/config.py +80 -20
- sqlspec/adapters/duckdb/data_dictionary.py +163 -0
- sqlspec/adapters/duckdb/driver.py +167 -45
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +332 -0
- sqlspec/adapters/duckdb/pool.py +4 -4
- sqlspec/adapters/duckdb/type_converter.py +133 -0
- sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
- sqlspec/adapters/oracledb/_types.py +20 -2
- sqlspec/adapters/oracledb/adk/__init__.py +5 -0
- sqlspec/adapters/oracledb/adk/store.py +1745 -0
- sqlspec/adapters/oracledb/config.py +122 -32
- sqlspec/adapters/oracledb/data_dictionary.py +509 -0
- sqlspec/adapters/oracledb/driver.py +353 -91
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +767 -0
- sqlspec/adapters/oracledb/migrations.py +348 -73
- sqlspec/adapters/oracledb/type_converter.py +207 -0
- sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
- sqlspec/adapters/psqlpy/_types.py +2 -1
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +482 -0
- sqlspec/adapters/psqlpy/config.py +46 -17
- sqlspec/adapters/psqlpy/data_dictionary.py +172 -0
- sqlspec/adapters/psqlpy/driver.py +123 -209
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +272 -0
- sqlspec/adapters/psqlpy/type_converter.py +102 -0
- sqlspec/adapters/psycopg/_type_handlers.py +80 -0
- sqlspec/adapters/psycopg/_types.py +2 -1
- sqlspec/adapters/psycopg/adk/__init__.py +5 -0
- sqlspec/adapters/psycopg/adk/store.py +944 -0
- sqlspec/adapters/psycopg/config.py +69 -35
- sqlspec/adapters/psycopg/data_dictionary.py +331 -0
- sqlspec/adapters/psycopg/driver.py +238 -81
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/sqlite/__init__.py +2 -1
- sqlspec/adapters/sqlite/_type_handlers.py +86 -0
- sqlspec/adapters/sqlite/_types.py +1 -1
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +572 -0
- sqlspec/adapters/sqlite/config.py +87 -15
- sqlspec/adapters/sqlite/data_dictionary.py +149 -0
- sqlspec/adapters/sqlite/driver.py +137 -54
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +318 -0
- sqlspec/adapters/sqlite/pool.py +18 -9
- sqlspec/base.py +45 -26
- sqlspec/builder/__init__.py +73 -4
- sqlspec/builder/_base.py +162 -89
- sqlspec/builder/_column.py +62 -29
- sqlspec/builder/_ddl.py +180 -121
- sqlspec/builder/_delete.py +5 -4
- sqlspec/builder/_dml.py +388 -0
- sqlspec/{_sql.py → builder/_factory.py} +53 -94
- sqlspec/builder/_insert.py +32 -131
- sqlspec/builder/_join.py +375 -0
- sqlspec/builder/_merge.py +446 -11
- sqlspec/builder/_parsing_utils.py +111 -17
- sqlspec/builder/_select.py +1457 -24
- sqlspec/builder/_update.py +11 -42
- sqlspec/cli.py +307 -194
- sqlspec/config.py +252 -67
- sqlspec/core/__init__.py +5 -4
- sqlspec/core/cache.py +17 -17
- sqlspec/core/compiler.py +62 -9
- sqlspec/core/filters.py +37 -37
- sqlspec/core/hashing.py +9 -9
- sqlspec/core/parameters.py +83 -48
- sqlspec/core/result.py +102 -46
- sqlspec/core/splitter.py +16 -17
- sqlspec/core/statement.py +36 -30
- sqlspec/core/type_conversion.py +235 -0
- sqlspec/driver/__init__.py +7 -6
- sqlspec/driver/_async.py +188 -151
- sqlspec/driver/_common.py +285 -80
- sqlspec/driver/_sync.py +188 -152
- sqlspec/driver/mixins/_result_tools.py +20 -236
- sqlspec/driver/mixins/_sql_translator.py +4 -4
- sqlspec/exceptions.py +75 -7
- sqlspec/extensions/adk/__init__.py +53 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +181 -0
- sqlspec/extensions/adk/store.py +536 -0
- sqlspec/extensions/aiosql/adapter.py +73 -53
- sqlspec/extensions/litestar/__init__.py +21 -4
- sqlspec/extensions/litestar/cli.py +54 -10
- sqlspec/extensions/litestar/config.py +59 -266
- sqlspec/extensions/litestar/handlers.py +46 -17
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +324 -223
- sqlspec/extensions/litestar/providers.py +25 -25
- sqlspec/extensions/litestar/store.py +265 -0
- sqlspec/loader.py +30 -49
- sqlspec/migrations/__init__.py +4 -3
- sqlspec/migrations/base.py +302 -39
- sqlspec/migrations/commands.py +611 -144
- sqlspec/migrations/context.py +142 -0
- sqlspec/migrations/fix.py +199 -0
- sqlspec/migrations/loaders.py +68 -23
- sqlspec/migrations/runner.py +543 -107
- sqlspec/migrations/tracker.py +237 -21
- sqlspec/migrations/utils.py +51 -3
- sqlspec/migrations/validation.py +177 -0
- sqlspec/protocols.py +66 -36
- sqlspec/storage/_utils.py +98 -0
- sqlspec/storage/backends/fsspec.py +134 -106
- sqlspec/storage/backends/local.py +78 -51
- sqlspec/storage/backends/obstore.py +278 -162
- sqlspec/storage/registry.py +75 -39
- sqlspec/typing.py +16 -84
- sqlspec/utils/config_resolver.py +153 -0
- sqlspec/utils/correlation.py +4 -5
- sqlspec/utils/data_transformation.py +3 -2
- sqlspec/utils/deprecation.py +9 -8
- sqlspec/utils/fixtures.py +4 -4
- sqlspec/utils/logging.py +46 -6
- sqlspec/utils/module_loader.py +2 -2
- sqlspec/utils/schema.py +288 -0
- sqlspec/utils/serializers.py +50 -2
- sqlspec/utils/sync_tools.py +21 -17
- sqlspec/utils/text.py +1 -2
- sqlspec/utils/type_guards.py +111 -20
- sqlspec/utils/version.py +433 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
- sqlspec-0.27.0.dist-info/RECORD +207 -0
- sqlspec/builder/mixins/__init__.py +0 -55
- sqlspec/builder/mixins/_cte_and_set_ops.py +0 -254
- sqlspec/builder/mixins/_delete_operations.py +0 -50
- sqlspec/builder/mixins/_insert_operations.py +0 -282
- sqlspec/builder/mixins/_join_operations.py +0 -389
- sqlspec/builder/mixins/_merge_operations.py +0 -592
- sqlspec/builder/mixins/_order_limit_operations.py +0 -152
- sqlspec/builder/mixins/_pivot_operations.py +0 -157
- sqlspec/builder/mixins/_select_operations.py +0 -936
- sqlspec/builder/mixins/_update_operations.py +0 -218
- sqlspec/builder/mixins/_where_clause.py +0 -1304
- sqlspec-0.25.0.dist-info/RECORD +0 -139
- sqlspec-0.25.0.dist-info/licenses/NOTICE +0 -29
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
sqlspec/builder/_ddl.py
CHANGED
|
@@ -4,19 +4,21 @@ Provides builders for DDL operations including CREATE, DROP, ALTER,
|
|
|
4
4
|
TRUNCATE, and other schema manipulation statements.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from typing import TYPE_CHECKING, Any,
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Union
|
|
8
8
|
|
|
9
9
|
from sqlglot import exp
|
|
10
10
|
from sqlglot.dialects.dialect import DialectType
|
|
11
11
|
from typing_extensions import Self
|
|
12
12
|
|
|
13
13
|
from sqlspec.builder._base import QueryBuilder, SafeQuery
|
|
14
|
+
from sqlspec.builder._select import Select
|
|
14
15
|
from sqlspec.core.result import SQLResult
|
|
16
|
+
from sqlspec.core.statement import SQL
|
|
15
17
|
from sqlspec.utils.type_guards import has_sqlglot_expression, has_with_method
|
|
16
18
|
|
|
17
19
|
if TYPE_CHECKING:
|
|
18
20
|
from sqlspec.builder._column import ColumnExpression
|
|
19
|
-
from sqlspec.core.statement import
|
|
21
|
+
from sqlspec.core.statement import StatementConfig
|
|
20
22
|
|
|
21
23
|
__all__ = (
|
|
22
24
|
"AlterOperation",
|
|
@@ -39,6 +41,37 @@ __all__ = (
|
|
|
39
41
|
"Truncate",
|
|
40
42
|
)
|
|
41
43
|
|
|
44
|
+
CONSTRAINT_TYPE_PRIMARY_KEY = "PRIMARY KEY"
|
|
45
|
+
CONSTRAINT_TYPE_FOREIGN_KEY = "FOREIGN KEY"
|
|
46
|
+
CONSTRAINT_TYPE_UNIQUE = "UNIQUE"
|
|
47
|
+
CONSTRAINT_TYPE_CHECK = "CHECK"
|
|
48
|
+
|
|
49
|
+
FOREIGN_KEY_ACTION_CASCADE = "CASCADE"
|
|
50
|
+
FOREIGN_KEY_ACTION_SET_NULL = "SET NULL"
|
|
51
|
+
FOREIGN_KEY_ACTION_SET_DEFAULT = "SET DEFAULT"
|
|
52
|
+
FOREIGN_KEY_ACTION_RESTRICT = "RESTRICT"
|
|
53
|
+
FOREIGN_KEY_ACTION_NO_ACTION = "NO ACTION"
|
|
54
|
+
|
|
55
|
+
VALID_FOREIGN_KEY_ACTIONS = {
|
|
56
|
+
FOREIGN_KEY_ACTION_CASCADE,
|
|
57
|
+
FOREIGN_KEY_ACTION_SET_NULL,
|
|
58
|
+
FOREIGN_KEY_ACTION_SET_DEFAULT,
|
|
59
|
+
FOREIGN_KEY_ACTION_RESTRICT,
|
|
60
|
+
FOREIGN_KEY_ACTION_NO_ACTION,
|
|
61
|
+
None,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
VALID_CONSTRAINT_TYPES = {
|
|
65
|
+
CONSTRAINT_TYPE_PRIMARY_KEY,
|
|
66
|
+
CONSTRAINT_TYPE_FOREIGN_KEY,
|
|
67
|
+
CONSTRAINT_TYPE_UNIQUE,
|
|
68
|
+
CONSTRAINT_TYPE_CHECK,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
CURRENT_TIMESTAMP_KEYWORD = "CURRENT_TIMESTAMP"
|
|
72
|
+
CURRENT_DATE_KEYWORD = "CURRENT_DATE"
|
|
73
|
+
CURRENT_TIME_KEYWORD = "CURRENT_TIME"
|
|
74
|
+
|
|
42
75
|
|
|
43
76
|
def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
|
|
44
77
|
"""Build SQLGlot expression for a column definition."""
|
|
@@ -56,14 +89,14 @@ def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
|
|
|
56
89
|
constraints.append(exp.ColumnConstraint(kind=exp.UniqueColumnConstraint()))
|
|
57
90
|
|
|
58
91
|
if col.default is not None:
|
|
59
|
-
default_expr:
|
|
92
|
+
default_expr: exp.Expression | None = None
|
|
60
93
|
if isinstance(col.default, str):
|
|
61
94
|
default_upper = col.default.upper()
|
|
62
|
-
if default_upper ==
|
|
95
|
+
if default_upper == CURRENT_TIMESTAMP_KEYWORD:
|
|
63
96
|
default_expr = exp.CurrentTimestamp()
|
|
64
|
-
elif default_upper ==
|
|
97
|
+
elif default_upper == CURRENT_DATE_KEYWORD:
|
|
65
98
|
default_expr = exp.CurrentDate()
|
|
66
|
-
elif default_upper ==
|
|
99
|
+
elif default_upper == CURRENT_TIME_KEYWORD:
|
|
67
100
|
default_expr = exp.CurrentTime()
|
|
68
101
|
elif "(" in col.default:
|
|
69
102
|
default_expr = exp.maybe_parse(col.default)
|
|
@@ -94,16 +127,16 @@ def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
|
|
|
94
127
|
return col_def
|
|
95
128
|
|
|
96
129
|
|
|
97
|
-
def build_constraint_expression(constraint: "ConstraintDefinition") -> "
|
|
130
|
+
def build_constraint_expression(constraint: "ConstraintDefinition") -> "exp.Expression | None":
|
|
98
131
|
"""Build SQLGlot expression for a table constraint."""
|
|
99
|
-
if constraint.constraint_type ==
|
|
132
|
+
if constraint.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY:
|
|
100
133
|
pk_constraint = exp.PrimaryKey(expressions=[exp.to_identifier(col) for col in constraint.columns])
|
|
101
134
|
|
|
102
135
|
if constraint.name:
|
|
103
136
|
return exp.Constraint(this=exp.to_identifier(constraint.name), expression=pk_constraint)
|
|
104
137
|
return pk_constraint
|
|
105
138
|
|
|
106
|
-
if constraint.constraint_type ==
|
|
139
|
+
if constraint.constraint_type == CONSTRAINT_TYPE_FOREIGN_KEY:
|
|
107
140
|
fk_constraint = exp.ForeignKey(
|
|
108
141
|
expressions=[exp.to_identifier(col) for col in constraint.columns],
|
|
109
142
|
reference=exp.Reference(
|
|
@@ -118,14 +151,14 @@ def build_constraint_expression(constraint: "ConstraintDefinition") -> "Optional
|
|
|
118
151
|
return exp.Constraint(this=exp.to_identifier(constraint.name), expression=fk_constraint)
|
|
119
152
|
return fk_constraint
|
|
120
153
|
|
|
121
|
-
if constraint.constraint_type ==
|
|
154
|
+
if constraint.constraint_type == CONSTRAINT_TYPE_UNIQUE:
|
|
122
155
|
unique_constraint = exp.UniqueKeyProperty(expressions=[exp.to_identifier(col) for col in constraint.columns])
|
|
123
156
|
|
|
124
157
|
if constraint.name:
|
|
125
158
|
return exp.Constraint(this=exp.to_identifier(constraint.name), expression=unique_constraint)
|
|
126
159
|
return unique_constraint
|
|
127
160
|
|
|
128
|
-
if constraint.constraint_type ==
|
|
161
|
+
if constraint.constraint_type == CONSTRAINT_TYPE_CHECK:
|
|
129
162
|
check_expr = exp.Check(this=exp.maybe_parse(constraint.condition) if constraint.condition else None)
|
|
130
163
|
|
|
131
164
|
if constraint.name:
|
|
@@ -142,7 +175,7 @@ class DDLBuilder(QueryBuilder):
|
|
|
142
175
|
|
|
143
176
|
def __init__(self, dialect: DialectType = None) -> None:
|
|
144
177
|
super().__init__(dialect=dialect)
|
|
145
|
-
self._expression:
|
|
178
|
+
self._expression: exp.Expression | None = None
|
|
146
179
|
|
|
147
180
|
def _create_base_expression(self) -> exp.Expression:
|
|
148
181
|
msg = "Subclasses must implement _create_base_expression."
|
|
@@ -157,7 +190,7 @@ class DDLBuilder(QueryBuilder):
|
|
|
157
190
|
self._expression = self._create_base_expression()
|
|
158
191
|
return super().build()
|
|
159
192
|
|
|
160
|
-
def to_statement(self, config: "
|
|
193
|
+
def to_statement(self, config: "StatementConfig | None" = None) -> "SQL":
|
|
161
194
|
return super().to_statement(config=config)
|
|
162
195
|
|
|
163
196
|
|
|
@@ -182,15 +215,15 @@ class ColumnDefinition:
|
|
|
182
215
|
self,
|
|
183
216
|
name: str,
|
|
184
217
|
dtype: str,
|
|
185
|
-
default: "
|
|
218
|
+
default: "Any | None" = None,
|
|
186
219
|
not_null: bool = False,
|
|
187
220
|
primary_key: bool = False,
|
|
188
221
|
unique: bool = False,
|
|
189
222
|
auto_increment: bool = False,
|
|
190
|
-
comment: "
|
|
191
|
-
check: "
|
|
192
|
-
generated: "
|
|
193
|
-
collate: "
|
|
223
|
+
comment: "str | None" = None,
|
|
224
|
+
check: "str | None" = None,
|
|
225
|
+
generated: "str | None" = None,
|
|
226
|
+
collate: "str | None" = None,
|
|
194
227
|
) -> None:
|
|
195
228
|
self.name = name
|
|
196
229
|
self.dtype = dtype
|
|
@@ -224,13 +257,13 @@ class ConstraintDefinition:
|
|
|
224
257
|
def __init__(
|
|
225
258
|
self,
|
|
226
259
|
constraint_type: str,
|
|
227
|
-
name: "
|
|
228
|
-
columns: "
|
|
229
|
-
references_table: "
|
|
230
|
-
references_columns: "
|
|
231
|
-
condition: "
|
|
232
|
-
on_delete: "
|
|
233
|
-
on_update: "
|
|
260
|
+
name: "str | None" = None,
|
|
261
|
+
columns: "list[str] | None" = None,
|
|
262
|
+
references_table: "str | None" = None,
|
|
263
|
+
references_columns: "list[str] | None" = None,
|
|
264
|
+
condition: "str | None" = None,
|
|
265
|
+
on_delete: "str | None" = None,
|
|
266
|
+
on_update: "str | None" = None,
|
|
234
267
|
deferrable: bool = False,
|
|
235
268
|
initially_deferred: bool = False,
|
|
236
269
|
) -> None:
|
|
@@ -281,10 +314,10 @@ class CreateTable(DDLBuilder):
|
|
|
281
314
|
self._columns: list[ColumnDefinition] = []
|
|
282
315
|
self._constraints: list[ConstraintDefinition] = []
|
|
283
316
|
self._table_options: dict[str, Any] = {}
|
|
284
|
-
self._schema:
|
|
285
|
-
self._tablespace:
|
|
286
|
-
self._like_table:
|
|
287
|
-
self._partition_by:
|
|
317
|
+
self._schema: str | None = None
|
|
318
|
+
self._tablespace: str | None = None
|
|
319
|
+
self._like_table: str | None = None
|
|
320
|
+
self._partition_by: str | None = None
|
|
288
321
|
|
|
289
322
|
def in_schema(self, schema_name: str) -> "Self":
|
|
290
323
|
"""Set the schema for the table."""
|
|
@@ -316,19 +349,28 @@ class CreateTable(DDLBuilder):
|
|
|
316
349
|
self._partition_by = partition_spec
|
|
317
350
|
return self
|
|
318
351
|
|
|
352
|
+
@property
|
|
353
|
+
def columns(self) -> "list[ColumnDefinition]":
|
|
354
|
+
"""Get the list of column definitions for this table.
|
|
355
|
+
|
|
356
|
+
Returns:
|
|
357
|
+
List of ColumnDefinition objects.
|
|
358
|
+
"""
|
|
359
|
+
return self._columns
|
|
360
|
+
|
|
319
361
|
def column(
|
|
320
362
|
self,
|
|
321
363
|
name: str,
|
|
322
364
|
dtype: str,
|
|
323
|
-
default: "
|
|
365
|
+
default: "Any | None" = None,
|
|
324
366
|
not_null: bool = False,
|
|
325
367
|
primary_key: bool = False,
|
|
326
368
|
unique: bool = False,
|
|
327
369
|
auto_increment: bool = False,
|
|
328
|
-
comment: "
|
|
329
|
-
check: "
|
|
330
|
-
generated: "
|
|
331
|
-
collate: "
|
|
370
|
+
comment: "str | None" = None,
|
|
371
|
+
check: "str | None" = None,
|
|
372
|
+
generated: "str | None" = None,
|
|
373
|
+
collate: "str | None" = None,
|
|
332
374
|
) -> "Self":
|
|
333
375
|
"""Add a column definition to the table."""
|
|
334
376
|
if not name:
|
|
@@ -356,37 +398,37 @@ class CreateTable(DDLBuilder):
|
|
|
356
398
|
|
|
357
399
|
self._columns.append(column_def)
|
|
358
400
|
|
|
359
|
-
if primary_key and not
|
|
401
|
+
if primary_key and not self._has_primary_key_constraint():
|
|
360
402
|
self.primary_key_constraint([name])
|
|
361
403
|
|
|
362
404
|
return self
|
|
363
405
|
|
|
364
|
-
def primary_key_constraint(self, columns: "
|
|
406
|
+
def primary_key_constraint(self, columns: "str | list[str]", name: "str | None" = None) -> "Self":
|
|
365
407
|
"""Add a primary key constraint."""
|
|
366
408
|
col_list = [columns] if isinstance(columns, str) else list(columns)
|
|
367
409
|
|
|
368
410
|
if not col_list:
|
|
369
411
|
self._raise_sql_builder_error("Primary key must include at least one column")
|
|
370
412
|
|
|
371
|
-
existing_pk =
|
|
413
|
+
existing_pk = self._find_primary_key_constraint()
|
|
372
414
|
if existing_pk:
|
|
373
415
|
for col in col_list:
|
|
374
416
|
if col not in existing_pk.columns:
|
|
375
417
|
existing_pk.columns.append(col)
|
|
376
418
|
else:
|
|
377
|
-
constraint = ConstraintDefinition(constraint_type=
|
|
419
|
+
constraint = ConstraintDefinition(constraint_type=CONSTRAINT_TYPE_PRIMARY_KEY, name=name, columns=col_list)
|
|
378
420
|
self._constraints.append(constraint)
|
|
379
421
|
|
|
380
422
|
return self
|
|
381
423
|
|
|
382
424
|
def foreign_key_constraint(
|
|
383
425
|
self,
|
|
384
|
-
columns: "
|
|
426
|
+
columns: "str | list[str]",
|
|
385
427
|
references_table: str,
|
|
386
|
-
references_columns: "
|
|
387
|
-
name: "
|
|
388
|
-
on_delete: "
|
|
389
|
-
on_update: "
|
|
428
|
+
references_columns: "str | list[str]",
|
|
429
|
+
name: "str | None" = None,
|
|
430
|
+
on_delete: "str | None" = None,
|
|
431
|
+
on_update: "str | None" = None,
|
|
390
432
|
deferrable: bool = False,
|
|
391
433
|
initially_deferred: bool = False,
|
|
392
434
|
) -> "Self":
|
|
@@ -398,14 +440,11 @@ class CreateTable(DDLBuilder):
|
|
|
398
440
|
if len(col_list) != len(ref_col_list):
|
|
399
441
|
self._raise_sql_builder_error("Foreign key columns and referenced columns must have same length")
|
|
400
442
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
self._raise_sql_builder_error(f"Invalid ON DELETE action: {on_delete}")
|
|
404
|
-
if on_update and on_update.upper() not in valid_actions:
|
|
405
|
-
self._raise_sql_builder_error(f"Invalid ON UPDATE action: {on_update}")
|
|
443
|
+
self._validate_foreign_key_action(on_delete, "ON DELETE")
|
|
444
|
+
self._validate_foreign_key_action(on_update, "ON UPDATE")
|
|
406
445
|
|
|
407
446
|
constraint = ConstraintDefinition(
|
|
408
|
-
constraint_type=
|
|
447
|
+
constraint_type=CONSTRAINT_TYPE_FOREIGN_KEY,
|
|
409
448
|
name=name,
|
|
410
449
|
columns=col_list,
|
|
411
450
|
references_table=references_table,
|
|
@@ -419,19 +458,19 @@ class CreateTable(DDLBuilder):
|
|
|
419
458
|
self._constraints.append(constraint)
|
|
420
459
|
return self
|
|
421
460
|
|
|
422
|
-
def unique_constraint(self, columns: "
|
|
461
|
+
def unique_constraint(self, columns: "str | list[str]", name: "str | None" = None) -> "Self":
|
|
423
462
|
"""Add a unique constraint."""
|
|
424
463
|
col_list = [columns] if isinstance(columns, str) else list(columns)
|
|
425
464
|
|
|
426
465
|
if not col_list:
|
|
427
466
|
self._raise_sql_builder_error("Unique constraint must include at least one column")
|
|
428
467
|
|
|
429
|
-
constraint = ConstraintDefinition(constraint_type=
|
|
468
|
+
constraint = ConstraintDefinition(constraint_type=CONSTRAINT_TYPE_UNIQUE, name=name, columns=col_list)
|
|
430
469
|
|
|
431
470
|
self._constraints.append(constraint)
|
|
432
471
|
return self
|
|
433
472
|
|
|
434
|
-
def check_constraint(self, condition: Union[str, "ColumnExpression"], name: "
|
|
473
|
+
def check_constraint(self, condition: Union[str, "ColumnExpression"], name: "str | None" = None) -> "Self":
|
|
435
474
|
"""Add a check constraint."""
|
|
436
475
|
if not condition:
|
|
437
476
|
self._raise_sql_builder_error("Check constraint must have a condition")
|
|
@@ -443,7 +482,7 @@ class CreateTable(DDLBuilder):
|
|
|
443
482
|
else:
|
|
444
483
|
condition_str = str(condition)
|
|
445
484
|
|
|
446
|
-
constraint = ConstraintDefinition(constraint_type=
|
|
485
|
+
constraint = ConstraintDefinition(constraint_type=CONSTRAINT_TYPE_CHECK, name=name, condition=condition_str)
|
|
447
486
|
|
|
448
487
|
self._constraints.append(constraint)
|
|
449
488
|
return self
|
|
@@ -484,10 +523,8 @@ class CreateTable(DDLBuilder):
|
|
|
484
523
|
column_defs.append(col_expr)
|
|
485
524
|
|
|
486
525
|
for constraint in self._constraints:
|
|
487
|
-
if
|
|
488
|
-
|
|
489
|
-
if any(c.name == col_name and c.primary_key for c in self._columns):
|
|
490
|
-
continue
|
|
526
|
+
if self._is_redundant_single_column_primary_key(constraint):
|
|
527
|
+
continue
|
|
491
528
|
|
|
492
529
|
constraint_expr = build_constraint_expression(constraint)
|
|
493
530
|
if constraint_expr:
|
|
@@ -531,6 +568,27 @@ class CreateTable(DDLBuilder):
|
|
|
531
568
|
like=like_expr,
|
|
532
569
|
)
|
|
533
570
|
|
|
571
|
+
def _has_primary_key_constraint(self) -> bool:
|
|
572
|
+
"""Check if table already has a primary key constraint."""
|
|
573
|
+
return any(c.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY for c in self._constraints)
|
|
574
|
+
|
|
575
|
+
def _find_primary_key_constraint(self) -> "ConstraintDefinition | None":
|
|
576
|
+
"""Find existing primary key constraint."""
|
|
577
|
+
return next((c for c in self._constraints if c.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY), None)
|
|
578
|
+
|
|
579
|
+
def _validate_foreign_key_action(self, action: "str | None", action_type: str) -> None:
|
|
580
|
+
"""Validate foreign key action (ON DELETE or ON UPDATE)."""
|
|
581
|
+
if action and action.upper() not in VALID_FOREIGN_KEY_ACTIONS:
|
|
582
|
+
self._raise_sql_builder_error(f"Invalid {action_type} action: {action}")
|
|
583
|
+
|
|
584
|
+
def _is_redundant_single_column_primary_key(self, constraint: "ConstraintDefinition") -> bool:
|
|
585
|
+
"""Check if constraint is a redundant single-column primary key."""
|
|
586
|
+
if constraint.constraint_type != CONSTRAINT_TYPE_PRIMARY_KEY or len(constraint.columns) != 1:
|
|
587
|
+
return False
|
|
588
|
+
|
|
589
|
+
col_name = constraint.columns[0]
|
|
590
|
+
return any(c.name == col_name and c.primary_key for c in self._columns)
|
|
591
|
+
|
|
534
592
|
|
|
535
593
|
class DropTable(DDLBuilder):
|
|
536
594
|
"""Builder for DROP TABLE [IF EXISTS] ... [CASCADE|RESTRICT]."""
|
|
@@ -547,7 +605,7 @@ class DropTable(DDLBuilder):
|
|
|
547
605
|
super().__init__(dialect=dialect)
|
|
548
606
|
self._table_name = table_name
|
|
549
607
|
self._if_exists = False
|
|
550
|
-
self._cascade:
|
|
608
|
+
self._cascade: bool | None = None
|
|
551
609
|
|
|
552
610
|
def table(self, name: str) -> Self:
|
|
553
611
|
self._table_name = name
|
|
@@ -587,9 +645,9 @@ class DropIndex(DDLBuilder):
|
|
|
587
645
|
"""
|
|
588
646
|
super().__init__(dialect=dialect)
|
|
589
647
|
self._index_name = index_name
|
|
590
|
-
self._table_name:
|
|
648
|
+
self._table_name: str | None = None
|
|
591
649
|
self._if_exists = False
|
|
592
|
-
self._cascade:
|
|
650
|
+
self._cascade: bool | None = None
|
|
593
651
|
|
|
594
652
|
def name(self, index_name: str) -> Self:
|
|
595
653
|
self._index_name = index_name
|
|
@@ -638,7 +696,7 @@ class DropView(DDLBuilder):
|
|
|
638
696
|
super().__init__(dialect=dialect)
|
|
639
697
|
self._view_name = view_name
|
|
640
698
|
self._if_exists = False
|
|
641
|
-
self._cascade:
|
|
699
|
+
self._cascade: bool | None = None
|
|
642
700
|
|
|
643
701
|
def name(self, view_name: str) -> Self:
|
|
644
702
|
self._view_name = view_name
|
|
@@ -679,7 +737,7 @@ class DropSchema(DDLBuilder):
|
|
|
679
737
|
super().__init__(dialect=dialect)
|
|
680
738
|
self._schema_name = schema_name
|
|
681
739
|
self._if_exists = False
|
|
682
|
-
self._cascade:
|
|
740
|
+
self._cascade: bool | None = None
|
|
683
741
|
|
|
684
742
|
def name(self, schema_name: str) -> Self:
|
|
685
743
|
self._schema_name = schema_name
|
|
@@ -719,12 +777,12 @@ class CreateIndex(DDLBuilder):
|
|
|
719
777
|
"""
|
|
720
778
|
super().__init__(dialect=dialect)
|
|
721
779
|
self._index_name = index_name
|
|
722
|
-
self._table_name:
|
|
723
|
-
self._columns: list[
|
|
780
|
+
self._table_name: str | None = None
|
|
781
|
+
self._columns: list[str | exp.Ordered | exp.Expression] = []
|
|
724
782
|
self._unique = False
|
|
725
783
|
self._if_not_exists = False
|
|
726
|
-
self._using:
|
|
727
|
-
self._where:
|
|
784
|
+
self._using: str | None = None
|
|
785
|
+
self._where: str | exp.Expression | None = None
|
|
728
786
|
|
|
729
787
|
def name(self, index_name: str) -> Self:
|
|
730
788
|
self._index_name = index_name
|
|
@@ -734,11 +792,11 @@ class CreateIndex(DDLBuilder):
|
|
|
734
792
|
self._table_name = table_name
|
|
735
793
|
return self
|
|
736
794
|
|
|
737
|
-
def columns(self, *cols:
|
|
795
|
+
def columns(self, *cols: str | exp.Ordered | exp.Expression) -> Self:
|
|
738
796
|
self._columns.extend(cols)
|
|
739
797
|
return self
|
|
740
798
|
|
|
741
|
-
def expressions(self, *exprs:
|
|
799
|
+
def expressions(self, *exprs: str | exp.Expression) -> Self:
|
|
742
800
|
self._columns.extend(exprs)
|
|
743
801
|
return self
|
|
744
802
|
|
|
@@ -754,7 +812,7 @@ class CreateIndex(DDLBuilder):
|
|
|
754
812
|
self._using = method
|
|
755
813
|
return self
|
|
756
814
|
|
|
757
|
-
def where(self, condition:
|
|
815
|
+
def where(self, condition: str | exp.Expression) -> Self:
|
|
758
816
|
self._where = condition
|
|
759
817
|
return self
|
|
760
818
|
|
|
@@ -796,8 +854,8 @@ class Truncate(DDLBuilder):
|
|
|
796
854
|
"""
|
|
797
855
|
super().__init__(dialect=dialect)
|
|
798
856
|
self._table_name = table_name
|
|
799
|
-
self._cascade:
|
|
800
|
-
self._identity:
|
|
857
|
+
self._cascade: bool | None = None
|
|
858
|
+
self._identity: str | None = None
|
|
801
859
|
|
|
802
860
|
def table(self, name: str) -> Self:
|
|
803
861
|
self._table_name = name
|
|
@@ -845,15 +903,15 @@ class AlterOperation:
|
|
|
845
903
|
def __init__(
|
|
846
904
|
self,
|
|
847
905
|
operation_type: str,
|
|
848
|
-
column_name: "
|
|
849
|
-
column_definition: "
|
|
850
|
-
constraint_name: "
|
|
851
|
-
constraint_definition: "
|
|
852
|
-
new_type: "
|
|
853
|
-
new_name: "
|
|
854
|
-
after_column: "
|
|
906
|
+
column_name: "str | None" = None,
|
|
907
|
+
column_definition: "ColumnDefinition | None" = None,
|
|
908
|
+
constraint_name: "str | None" = None,
|
|
909
|
+
constraint_definition: "ConstraintDefinition | None" = None,
|
|
910
|
+
new_type: "str | None" = None,
|
|
911
|
+
new_name: "str | None" = None,
|
|
912
|
+
after_column: "str | None" = None,
|
|
855
913
|
first: bool = False,
|
|
856
|
-
using_expression: "
|
|
914
|
+
using_expression: "str | None" = None,
|
|
857
915
|
) -> None:
|
|
858
916
|
self.operation_type = operation_type
|
|
859
917
|
self.column_name = column_name
|
|
@@ -882,7 +940,7 @@ class CreateSchema(DDLBuilder):
|
|
|
882
940
|
super().__init__(dialect=dialect)
|
|
883
941
|
self._schema_name = schema_name
|
|
884
942
|
self._if_not_exists = False
|
|
885
|
-
self._authorization:
|
|
943
|
+
self._authorization: str | None = None
|
|
886
944
|
|
|
887
945
|
def name(self, schema_name: str) -> Self:
|
|
888
946
|
self._schema_name = schema_name
|
|
@@ -937,10 +995,10 @@ class CreateTableAsSelect(DDLBuilder):
|
|
|
937
995
|
|
|
938
996
|
def __init__(self, dialect: DialectType = None) -> None:
|
|
939
997
|
super().__init__(dialect=dialect)
|
|
940
|
-
self._table_name:
|
|
998
|
+
self._table_name: str | None = None
|
|
941
999
|
self._if_not_exists = False
|
|
942
1000
|
self._columns: list[str] = []
|
|
943
|
-
self._select_query:
|
|
1001
|
+
self._select_query: object | None = None
|
|
944
1002
|
|
|
945
1003
|
def name(self, table_name: str) -> Self:
|
|
946
1004
|
self._table_name = table_name
|
|
@@ -954,7 +1012,7 @@ class CreateTableAsSelect(DDLBuilder):
|
|
|
954
1012
|
self._columns = list(cols)
|
|
955
1013
|
return self
|
|
956
1014
|
|
|
957
|
-
def as_select(self, select_query: "
|
|
1015
|
+
def as_select(self, select_query: "str | exp.Expression") -> Self:
|
|
958
1016
|
self._select_query = select_query
|
|
959
1017
|
return self
|
|
960
1018
|
|
|
@@ -966,8 +1024,6 @@ class CreateTableAsSelect(DDLBuilder):
|
|
|
966
1024
|
|
|
967
1025
|
select_expr = None
|
|
968
1026
|
select_parameters = None
|
|
969
|
-
from sqlspec.builder._select import Select
|
|
970
|
-
from sqlspec.core.statement import SQL
|
|
971
1027
|
|
|
972
1028
|
if isinstance(self._select_query, SQL):
|
|
973
1029
|
select_expr = self._select_query.expression
|
|
@@ -1033,12 +1089,12 @@ class CreateMaterializedView(DDLBuilder):
|
|
|
1033
1089
|
self._view_name = view_name
|
|
1034
1090
|
self._if_not_exists = False
|
|
1035
1091
|
self._columns: list[str] = []
|
|
1036
|
-
self._select_query:
|
|
1037
|
-
self._with_data:
|
|
1038
|
-
self._refresh_mode:
|
|
1092
|
+
self._select_query: str | exp.Expression | None = None
|
|
1093
|
+
self._with_data: bool | None = None
|
|
1094
|
+
self._refresh_mode: str | None = None
|
|
1039
1095
|
self._storage_parameters: dict[str, Any] = {}
|
|
1040
|
-
self._tablespace:
|
|
1041
|
-
self._using_index:
|
|
1096
|
+
self._tablespace: str | None = None
|
|
1097
|
+
self._using_index: str | None = None
|
|
1042
1098
|
self._hints: list[str] = []
|
|
1043
1099
|
|
|
1044
1100
|
def name(self, view_name: str) -> Self:
|
|
@@ -1053,7 +1109,7 @@ class CreateMaterializedView(DDLBuilder):
|
|
|
1053
1109
|
self._columns = list(cols)
|
|
1054
1110
|
return self
|
|
1055
1111
|
|
|
1056
|
-
def as_select(self, select_query: "
|
|
1112
|
+
def as_select(self, select_query: "str | exp.Expression") -> Self:
|
|
1057
1113
|
self._select_query = select_query
|
|
1058
1114
|
return self
|
|
1059
1115
|
|
|
@@ -1093,8 +1149,6 @@ class CreateMaterializedView(DDLBuilder):
|
|
|
1093
1149
|
|
|
1094
1150
|
select_expr = None
|
|
1095
1151
|
select_parameters = None
|
|
1096
|
-
from sqlspec.builder._select import Select
|
|
1097
|
-
from sqlspec.core.statement import SQL
|
|
1098
1152
|
|
|
1099
1153
|
if isinstance(self._select_query, SQL):
|
|
1100
1154
|
select_expr = self._select_query.expression
|
|
@@ -1160,7 +1214,7 @@ class CreateView(DDLBuilder):
|
|
|
1160
1214
|
self._view_name = view_name
|
|
1161
1215
|
self._if_not_exists = False
|
|
1162
1216
|
self._columns: list[str] = []
|
|
1163
|
-
self._select_query:
|
|
1217
|
+
self._select_query: str | exp.Expression | None = None
|
|
1164
1218
|
self._hints: list[str] = []
|
|
1165
1219
|
|
|
1166
1220
|
def name(self, view_name: str) -> Self:
|
|
@@ -1175,7 +1229,7 @@ class CreateView(DDLBuilder):
|
|
|
1175
1229
|
self._columns = list(cols)
|
|
1176
1230
|
return self
|
|
1177
1231
|
|
|
1178
|
-
def as_select(self, select_query: "
|
|
1232
|
+
def as_select(self, select_query: "str | exp.Expression") -> Self:
|
|
1179
1233
|
self._select_query = select_query
|
|
1180
1234
|
return self
|
|
1181
1235
|
|
|
@@ -1191,8 +1245,6 @@ class CreateView(DDLBuilder):
|
|
|
1191
1245
|
|
|
1192
1246
|
select_expr = None
|
|
1193
1247
|
select_parameters = None
|
|
1194
|
-
from sqlspec.builder._select import Select
|
|
1195
|
-
from sqlspec.core.statement import SQL
|
|
1196
1248
|
|
|
1197
1249
|
if isinstance(self._select_query, SQL):
|
|
1198
1250
|
select_expr = self._select_query.expression
|
|
@@ -1249,7 +1301,7 @@ class AlterTable(DDLBuilder):
|
|
|
1249
1301
|
super().__init__(dialect=dialect)
|
|
1250
1302
|
self._table_name = table_name
|
|
1251
1303
|
self._operations: list[AlterOperation] = []
|
|
1252
|
-
self._schema:
|
|
1304
|
+
self._schema: str | None = None
|
|
1253
1305
|
self._if_exists = False
|
|
1254
1306
|
|
|
1255
1307
|
def if_exists(self) -> "Self":
|
|
@@ -1261,11 +1313,11 @@ class AlterTable(DDLBuilder):
|
|
|
1261
1313
|
self,
|
|
1262
1314
|
name: str,
|
|
1263
1315
|
dtype: str,
|
|
1264
|
-
default: "
|
|
1316
|
+
default: "Any | None" = None,
|
|
1265
1317
|
not_null: bool = False,
|
|
1266
1318
|
unique: bool = False,
|
|
1267
|
-
comment: "
|
|
1268
|
-
after: "
|
|
1319
|
+
comment: "str | None" = None,
|
|
1320
|
+
after: "str | None" = None,
|
|
1269
1321
|
first: bool = False,
|
|
1270
1322
|
) -> "Self":
|
|
1271
1323
|
"""Add a new column to the table."""
|
|
@@ -1296,7 +1348,7 @@ class AlterTable(DDLBuilder):
|
|
|
1296
1348
|
self._operations.append(operation)
|
|
1297
1349
|
return self
|
|
1298
1350
|
|
|
1299
|
-
def alter_column_type(self, name: str, new_type: str, using: "
|
|
1351
|
+
def alter_column_type(self, name: str, new_type: str, using: "str | None" = None) -> "Self":
|
|
1300
1352
|
"""Change the type of an existing column."""
|
|
1301
1353
|
if not name:
|
|
1302
1354
|
self._raise_sql_builder_error("Column name must be a non-empty string")
|
|
@@ -1327,13 +1379,13 @@ class AlterTable(DDLBuilder):
|
|
|
1327
1379
|
def add_constraint(
|
|
1328
1380
|
self,
|
|
1329
1381
|
constraint_type: str,
|
|
1330
|
-
columns: "
|
|
1331
|
-
name: "
|
|
1332
|
-
references_table: "
|
|
1333
|
-
references_columns: "
|
|
1334
|
-
condition: "
|
|
1335
|
-
on_delete: "
|
|
1336
|
-
on_update: "
|
|
1382
|
+
columns: "str | list[str] | None" = None,
|
|
1383
|
+
name: "str | None" = None,
|
|
1384
|
+
references_table: "str | None" = None,
|
|
1385
|
+
references_columns: "str | list[str] | None" = None,
|
|
1386
|
+
condition: "str | ColumnExpression | None" = None,
|
|
1387
|
+
on_delete: "str | None" = None,
|
|
1388
|
+
on_update: "str | None" = None,
|
|
1337
1389
|
) -> "Self":
|
|
1338
1390
|
"""Add a constraint to the table.
|
|
1339
1391
|
|
|
@@ -1347,8 +1399,7 @@ class AlterTable(DDLBuilder):
|
|
|
1347
1399
|
on_delete: Foreign key ON DELETE action
|
|
1348
1400
|
on_update: Foreign key ON UPDATE action
|
|
1349
1401
|
"""
|
|
1350
|
-
|
|
1351
|
-
if constraint_type.upper() not in valid_types:
|
|
1402
|
+
if constraint_type.upper() not in VALID_CONSTRAINT_TYPES:
|
|
1352
1403
|
self._raise_sql_builder_error(f"Invalid constraint type: {constraint_type}")
|
|
1353
1404
|
|
|
1354
1405
|
col_list = None
|
|
@@ -1359,10 +1410,10 @@ class AlterTable(DDLBuilder):
|
|
|
1359
1410
|
if references_columns is not None:
|
|
1360
1411
|
ref_col_list = [references_columns] if isinstance(references_columns, str) else list(references_columns)
|
|
1361
1412
|
|
|
1362
|
-
condition_str:
|
|
1413
|
+
condition_str: str | None = None
|
|
1363
1414
|
if condition is not None:
|
|
1364
|
-
if
|
|
1365
|
-
sqlglot_expr =
|
|
1415
|
+
if has_sqlglot_expression(condition):
|
|
1416
|
+
sqlglot_expr = condition.sqlglot_expression
|
|
1366
1417
|
condition_str = sqlglot_expr.sql(dialect=self.dialect) if sqlglot_expr else str(condition)
|
|
1367
1418
|
else:
|
|
1368
1419
|
condition_str = str(condition)
|
|
@@ -1472,9 +1523,9 @@ class AlterTable(DDLBuilder):
|
|
|
1472
1523
|
if not op.column_definition or op.column_definition.default is None:
|
|
1473
1524
|
self._raise_sql_builder_error("Default value required for SET DEFAULT")
|
|
1474
1525
|
default_val = op.column_definition.default
|
|
1475
|
-
default_expr:
|
|
1526
|
+
default_expr: exp.Expression | None
|
|
1476
1527
|
if isinstance(default_val, str):
|
|
1477
|
-
if
|
|
1528
|
+
if self._is_sql_function_default(default_val):
|
|
1478
1529
|
default_expr = exp.maybe_parse(default_val)
|
|
1479
1530
|
else:
|
|
1480
1531
|
default_expr = exp.convert(default_val)
|
|
@@ -1494,6 +1545,14 @@ class AlterTable(DDLBuilder):
|
|
|
1494
1545
|
self._raise_sql_builder_error(f"Unknown operation type: {op.operation_type}")
|
|
1495
1546
|
raise AssertionError
|
|
1496
1547
|
|
|
1548
|
+
def _is_sql_function_default(self, default_val: str) -> bool:
|
|
1549
|
+
"""Check if default value is a SQL function or expression."""
|
|
1550
|
+
default_upper = default_val.upper()
|
|
1551
|
+
return (
|
|
1552
|
+
default_upper in {CURRENT_TIMESTAMP_KEYWORD, CURRENT_DATE_KEYWORD, CURRENT_TIME_KEYWORD}
|
|
1553
|
+
or "(" in default_val
|
|
1554
|
+
)
|
|
1555
|
+
|
|
1497
1556
|
|
|
1498
1557
|
class CommentOn(DDLBuilder):
|
|
1499
1558
|
"""Builder for COMMENT ON ... IS ... statements."""
|
|
@@ -1507,10 +1566,10 @@ class CommentOn(DDLBuilder):
|
|
|
1507
1566
|
dialect: SQL dialect to use
|
|
1508
1567
|
"""
|
|
1509
1568
|
super().__init__(dialect=dialect)
|
|
1510
|
-
self._target_type:
|
|
1511
|
-
self._table:
|
|
1512
|
-
self._column:
|
|
1513
|
-
self._comment:
|
|
1569
|
+
self._target_type: str | None = None
|
|
1570
|
+
self._table: str | None = None
|
|
1571
|
+
self._column: str | None = None
|
|
1572
|
+
self._comment: str | None = None
|
|
1514
1573
|
|
|
1515
1574
|
def on_table(self, table: str) -> Self:
|
|
1516
1575
|
self._target_type = "TABLE"
|
|
@@ -1555,7 +1614,7 @@ class RenameTable(DDLBuilder):
|
|
|
1555
1614
|
"""
|
|
1556
1615
|
super().__init__(dialect=dialect)
|
|
1557
1616
|
self._old_name = old_name
|
|
1558
|
-
self._new_name:
|
|
1617
|
+
self._new_name: str | None = None
|
|
1559
1618
|
|
|
1560
1619
|
def table(self, old_name: str) -> Self:
|
|
1561
1620
|
self._old_name = old_name
|