Skip to content

Commit 94a1c52

Browse files
committed
Support DEFAULT VALUES and VALUES(DEFAULT) individually
Fixed regression where the introduction of the INSERT syntax "INSERT... VALUES (DEFAULT)" was not supported on some backends that do however support "INSERT..DEFAULT VALUES", including SQLite. The two syntaxes are now each individually supported or non-supported for each dialect, for example MySQL supports "VALUES (DEFAULT)" but not "DEFAULT VALUES". Support for Oracle is still not enabled as there are unresolved issues in using RETURNING at the same time. Fixes: #6254 Change-Id: I47959bc826e3d9d2396ccfa290eb084841b02e77
1 parent de7f141 commit 94a1c52

17 files changed

Lines changed: 98 additions & 27 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. change::
2+
:tags: bug, regression, sql, sqlite
3+
:tickets: 6254
4+
5+
Fixed regression where the introduction of the INSERT syntax "INSERT...
6+
VALUES (DEFAULT)" was not supported on some backends that do however
7+
support "INSERT..DEFAULT VALUES", including SQLite. The two syntaxes are
8+
now each individually supported or non-supported for each dialect, for
9+
example MySQL supports "VALUES (DEFAULT)" but not "DEFAULT VALUES".
10+
Support for Oracle has also been enabled.

lib/sqlalchemy/dialects/mysql/base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,6 +2534,11 @@ class MySQLDialect(default.DefaultDialect):
25342534
supports_for_update_of = False # default for MySQL ...
25352535
# ... may be updated to True for MySQL 8+ in initialize()
25362536

2537+
# MySQL doesn't support "DEFAULT VALUES" but *does* support
2538+
# "VALUES (DEFAULT)"
2539+
supports_default_values = False
2540+
supports_default_metavalue = True
2541+
25372542
supports_sane_rowcount = True
25382543
supports_sane_multi_rowcount = False
25392544
supports_multivalues_insert = True

lib/sqlalchemy/dialects/oracle/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,11 @@ class OracleDialect(default.DefaultDialect):
14531453
requires_name_normalize = True
14541454

14551455
supports_comments = True
1456+
1457+
# Oracle supports these syntaxes but I'm not able to get them
1458+
# to work with RETURNING which we usually need
14561459
supports_default_values = False
1460+
supports_default_metavalue = True
14571461
supports_empty_insert = False
14581462

14591463
statement_compiler = OracleCompiler

lib/sqlalchemy/dialects/postgresql/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,9 @@ class PGDialect(default.DefaultDialect):
30793079

30803080
supports_comments = True
30813081
supports_default_values = True
3082+
3083+
supports_default_metavalue = True
3084+
30823085
supports_empty_insert = False
30833086
supports_multivalues_insert = True
30843087
default_paramstyle = "pyformat"

lib/sqlalchemy/dialects/sqlite/base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,12 @@ class SQLiteDialect(default.DefaultDialect):
17911791
supports_alter = False
17921792
supports_unicode_statements = True
17931793
supports_unicode_binds = True
1794+
1795+
# SQlite supports "DEFAULT VALUES" but *does not* support
1796+
# "VALUES (DEFAULT)"
17941797
supports_default_values = True
1798+
supports_default_metavalue = False
1799+
17951800
supports_empty_insert = False
17961801
supports_cast = True
17971802
supports_multivalues_insert = True

lib/sqlalchemy/engine/default.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,18 @@ class DefaultDialect(interfaces.Dialect):
140140
supports_sane_multi_rowcount = True
141141
colspecs = {}
142142
default_paramstyle = "named"
143+
143144
supports_default_values = False
145+
"""dialect supports INSERT... DEFAULT VALUES syntax"""
146+
147+
supports_default_metavalue = False
148+
"""dialect supports INSERT... VALUES (DEFAULT) syntax"""
149+
150+
# not sure if this is a real thing but the compiler will deliver it
151+
# if this is the only flag enabled.
144152
supports_empty_insert = True
153+
"""dialect supports INSERT () VALUES ()"""
154+
145155
supports_multivalues_insert = False
146156

147157
supports_is_distinct_from = True

lib/sqlalchemy/sql/compiler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3480,6 +3480,7 @@ def visit_insert(self, insert_stmt, **kw):
34803480
if (
34813481
not crud_params
34823482
and not self.dialect.supports_default_values
3483+
and not self.dialect.supports_default_metavalue
34833484
and not self.dialect.supports_empty_insert
34843485
):
34853486
raise exc.CompileError(

lib/sqlalchemy/sql/crud.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,11 @@ def _get_crud_params(compiler, stmt, compile_state, **kw):
174174
values = _extend_values_for_multiparams(
175175
compiler, stmt, compile_state, values, kw
176176
)
177-
elif not values and compiler.for_executemany:
177+
elif (
178+
not values
179+
and compiler.for_executemany
180+
and compiler.dialect.supports_default_metavalue
181+
):
178182
# convert an "INSERT DEFAULT VALUES"
179183
# into INSERT (firstcol) VALUES (DEFAULT) which can be turned
180184
# into an in-place multi values. This supports

lib/sqlalchemy/testing/assertions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ def assert_compile(
400400
use_default_dialect=False,
401401
allow_dialect_select=False,
402402
supports_default_values=True,
403+
supports_default_metavalue=True,
403404
literal_binds=False,
404405
render_postcompile=False,
405406
schema_translate_map=None,
@@ -410,6 +411,7 @@ def assert_compile(
410411
if use_default_dialect:
411412
dialect = default.DefaultDialect()
412413
dialect.supports_default_values = supports_default_values
414+
dialect.supports_default_metavalue = supports_default_metavalue
413415
elif allow_dialect_select:
414416
dialect = None
415417
else:
@@ -421,6 +423,7 @@ def assert_compile(
421423
elif dialect == "default":
422424
dialect = default.DefaultDialect()
423425
dialect.supports_default_values = supports_default_values
426+
dialect.supports_default_metavalue = supports_default_metavalue
424427
elif dialect == "default_enhanced":
425428
dialect = default.StrCompileDialect()
426429
elif isinstance(dialect, util.string_types):

lib/sqlalchemy/testing/assertsql.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ def _compare_sql(self, execute_observed, received_statement):
7676

7777
def _compile_dialect(self, execute_observed):
7878
if self.dialect == "default":
79-
return DefaultDialect()
79+
dialect = DefaultDialect()
80+
# this is currently what tests are expecting
81+
# dialect.supports_default_values = True
82+
dialect.supports_default_metavalue = True
83+
return dialect
8084
else:
8185
# ugh
8286
if self.dialect == "postgresql":

0 commit comments

Comments
 (0)