Commit Graph

1748 Commits

Author SHA1 Message Date
mike bayer c99c93fd64 Merge "don't cache TypeDecorator by default" 2021-05-06 21:12:48 +00:00
Mike Bayer 6967b45020 don't cache TypeDecorator by default
The :class:`.TypeDecorator` class will now emit a warning when used in SQL
compilation with caching unless the ``.cache_ok`` flag is set to ``True``
or ``False``. ``.cache_ok`` indicates that all the parameters passed to the
object are safe to be used as a cache key, ``False`` means they are not.

Fixes: #6436
Change-Id: Ib1bb7dc4b124e38521d615c2e2e691e4915594fb
2021-05-06 13:57:43 -04:00
mike bayer 03d922d4ee Merge "Parenthesize for empty not in" 2021-05-05 16:36:08 +00:00
Mike Bayer 5af854606b Parenthesize for empty not in
Fixed regression caused by the "empty in" change just made in
🎫`6397` 1.4.12 where the expression needs to be parenthesized for
the "not in" use case, otherwise the condition will interfere with the
other filtering criteria.

also amends StrSQLCompiler to use the newer "empty IN" style for
its compilation process.

Fixes: #6428
Change-Id: I182a552fc0d3065a9e38c0f4ece2deb143735c36
2021-05-05 09:54:46 -04:00
Mike Bayer d6ec248fa7 Establish deprecation path for CursorResult.keys()
Established a deprecation path for calling upon the
:meth:`_cursor.CursorResult.keys` method for a statement that returns no
rows to provide support for legacy patterns used by the "records" package
as well as any other non-migrated applications. Previously, this would
raise :class:`.ResourceClosedException` unconditionally in the same way as
it does when attempting to fetch rows. While this is the correct behavior
going forward, the :class:`_cursor.LegacyCursorResult` object will now in
this case return an empty list for ``.keys()`` as it did in 1.3, while also
emitting a 2.0 deprecation warning. The :class:`_cursor.CursorResult`, used
when using a 2.0-style "future" engine, will continue to raise as it does
now.

Fixes: #6427
Change-Id: I4148f28c88039e4141deeab28b1a5994e6d6e098
2021-05-04 13:49:43 -04:00
Mike Bayer 5cde12d816 Support filter_by() from columns, functions, Core SQL
Fixed regression where :meth:`_orm.Query.filter_by` would not work if the
lead entity were a SQL function or other expression derived from the
primary entity in question, rather than a simple entity or column of that
entity. Additionally, improved the behavior of
:meth:`_sql.Select.filter_by` overall to work with column expressions even
in a non-ORM context.

Fixes: #6414
Change-Id: I316b5bf98293bec1ede08787f6181dd14be85419
2021-05-01 11:54:21 -04:00
Mike Bayer a47c158a9a track_on needs to be a fixed size, support sub-tuples
Fixed regression in ``selectinload`` loader strategy that would cause it to
cache its internal state incorrectly when handling relationships that join
across more than one column, such as when using a composite foreign key.
The invalid caching would then cause other loader operations to fail.

Fixes: #6410
Change-Id: I9f95ccca3553e7fd5794c619be4cf85c02b04626
2021-04-30 12:35:28 -04:00
mike bayer d264cb8529 Merge "Ensure iterable passed to Select is not a mapped class" 2021-04-29 21:28:32 +00:00
mike bayer 8716e54b5b Merge "Fix ForeignKeyConstraint.copy() error" 2021-04-29 21:28:19 +00:00
Mike Bayer 7002b2b0b1 Ensure iterable passed to Select is not a mapped class
Fixed regression caused by 🎫`5395` where tuning back the check for
sequences in :func:`_sql.select` now caused failures when doing 2.0-style
querying with a mapped class that also happens to have an ``__iter__()``
method. Tuned the check some more to accommodate this as well as some other
interesting ``__iter__()`` scenarios.

Fixes: #6300
Change-Id: Idf1983fd764b91a7d5fa8117aee8a3def3cfe5ff
2021-04-29 16:41:28 -04:00
Gord Thompson 416fdb1674 Fix ForeignKeyConstraint.copy() error
Fixed an issue with the (deprecated in 1.4)
:meth:`_schema.ForeignKeyConstraint.copy` method that caused an error when
invoked with the ``schema`` argument.

Fixes: #6353
Change-Id: I03330d9ec254d64377f2b2e86af69a4eaff43ac6
2021-04-29 16:24:14 -04:00
mike bayer dc5485b7ec Merge "Use non-subquery form for empty IN" 2021-04-29 19:53:02 +00:00
Mike Bayer aba3088685 Use non-subquery form for empty IN
Revised the "EMPTY IN" expression to no longer rely upon using a subquery,
as this was causing some compatibility and performance problems. The new
approach for selected databases takes advantage of using a NULL-returning
IN expression combined with the usual "1 != 1" or "1 = 1" expression
appended by AND or OR. The expression is now the default for all backends
other than SQLite, which still had some compatibility issues regarding
tuple "IN" for older SQLite versions.

Third party dialects can still override how the "empty set" expression
renders by implementing a new compiler method
``def visit_empty_set_op_expr(self, type_, expand_op)``, which takes
precedence over the existing
``def visit_empty_set_expr(self, element_types)`` which remains in place.

Fixes: #6258
Fixes: #6397
Change-Id: I2df09eb00d2ad3b57039ae48128fdf94641b5e59
2021-04-29 14:43:09 -04:00
mike bayer 93c8f1df8b Merge "Propertly ignore `Identity` in MySQL and MariaDb." 2021-04-29 12:59:42 +00:00
Federico Caselli d3c73ad801 Propertly ignore `Identity` in MySQL and MariaDb.
Ensure that the MySQL and MariaDB dialect ignore the
:class:`_sql.Identity` construct while rendering the
``AUTO_INCREMENT`` keyword in a create table.

The Oracle and PostgreSQL compiler was updated to not render
:class:`_sql.Identity` if the database version does not support it
(Oracle < 12 and PostgreSQL < 10). Previously it was rendered regardless
of the database version.

Fixes: #6338
Change-Id: I2ca0902fdd7b4be4fc1a563cf5585504cbea9360
2021-04-28 20:03:27 -04:00
mike bayer 435f5f40e8 Merge "ensure SelectState.all_selected_columns not memoized as a generator" 2021-04-28 22:51:45 +00:00
Mike Bayer 3dcdc304a6 accommodate for mutiple copies of bind in ckbm
Fixed critical regression where bound parameter tracking as used in the SQL
caching system could fail to track all parameters for the case where the
same SQL expression containing a parameter were used in an ORM-related
query using a feature such as class inheritance, which was then embedded in
an enclosing expression which would make use of that same expression
multiple times, such as a UNION. The ORM would individually copy the
individual SELECT statements as part of compilation with class inheritance,
which then embedded in the enclosing statement would fail to accommodate
for all parameters. The logic that tracks this condition has been adjusted
to work for multiple copies of a parameter.

Fixes: #6391
Change-Id: I6db5dee0d361a3bb58d753a2d27ef2eee2b369c5
2021-04-28 14:17:54 -04:00
Mike Bayer 029c68e636 ensure SelectState.all_selected_columns not memoized as a generator
This regression was found from #6261 before release of 1.4.12

Fixes: #6261
Fixes: #6394
Change-Id: I4c2c5da02dbcf5c2cea26c81d3521de892ef428e
2021-04-28 14:11:20 -04:00
mike bayer a4b2b2b837 Merge "have SchemaType inherit schema from metadata" 2021-04-27 18:20:19 +00:00
Mike Bayer 70c51bbe5e have SchemaType inherit schema from metadata
Fixed very old issue where the :class:`_types.Enum` datatype would not
inherit the :paramref:`_schema.MetaData.schema` parameter of a
:class:`_schema.MetaData` object when that object were passed to the
:class:`_types.Enum` using :paramref:`_types.Enum.metadata`.

Fixes: #6373
Change-Id: Ie77d5e8cbc0bd7bfd0039fb60a4a0bde2df58ca9
2021-04-27 13:13:52 -04:00
Mike Bayer 87b551c260 Handle Sequence in _process_multiparam_default_bind
Fixed issue where usage of an explicit :class:`.Sequence` would produce
inconsistent "inline" behavior for an :class:`.Insert` construct that
includes multiple values phrases; the first seq would be inline but
subsequent ones would be "pre-execute", leading to inconsistent sequence
ordering. The sequence expressions are now fully inline.

Fixes: #6361
Change-Id: Ie16794ec0e19979a7e6c8d1bef5716a9fc199889
2021-04-26 14:59:15 -04:00
Mike Bayer 373e960cb4 dont assume ClauseElement in attributes, coercions
Fixed two distinct issues, each of which would come into play under certain
circumstances, most likely however one which is a common mis-configuration
in :class:`_hybrid.hybrid_property`, where the "expression" implementation
would return a non :class:`_sql.ClauseElement` such as a boolean value.
For both issues, 1.3's behavior was to silently ignore the
mis-configuration and ultimately attempt to interpret the value as a
SQL expression, which would lead to an incorrect query.

* Fixed issue regarding interaction of the attribute system with
hybrid_property, where if the ``__clause_element__()`` method of the
attribute returned a non-:class:`_sql.ClauseElement` object, an internal
``AttributeError`` would lead the attribute to return the ``expression``
function on the hybrid_property itself, as the attribute error was
against the name ``.expression`` which would invoke the ``__getattr__()``
method as a fallback. This now raises explicitly. In 1.3 the
non-:class:`_sql.ClauseElement` was returned directly.

* Fixed issue in SQL argument coercions system where passing the wrong
kind of object to methods that expect column expressions would fail if
the object were altogether not a SQLAlchemy object, such as a Python
function, in cases where the object were not just coerced into a bound
value. Again 1.3 did not have a comprehensive argument coercion system
so this case would also pass silently.

Fixes: #6350
Change-Id: I5bba0a6b27f45e5f8ebadfd6d511fa773388ef7c
2021-04-23 10:54:54 -04:00
Mike Bayer 17072f8b04 omit text from selected_columns; clear memoizations
Fixed regression where usage of the :func:`_sql.text` construct inside the
columns clause of a :class:`_sql.Select` construct, which is better handled
by using a :func:`_sql.literal_column` construct, would nonetheless prevent
constructs like :func:`_sql.union` from working correctly. Other use cases,
such as constructing subuqeries, continue to work the same as in prior
versions where the :func:`_sql.text` construct is silently omitted from the
collection of exported columns. Also repairs similar use within the
ORM.

This adds a new internal method _all_selected_columns.  The existing
"selected_columns" collection can't store a TextClause and this never
worked, so they are omitted.  The TextClause is also not "exported",
i.e. available for SELECT from a subquery, as was already the case
in 1.3, so the "exported_columns" and "exported_columns_iterator"
accessors are where we now omit TextClause.

Fixed regression involving legacy methods such as
:meth:`_sql.Select.append_column` where internal assertions would fail.

Fixes: #6343
Fixes: #6261
Change-Id: I7c2e5b9ae5d94131c77599a020f4310dcf812bcf
2021-04-22 15:09:27 -04:00
Mike Bayer 3a0a6e1db4 Propagate compiler kw for visit_values to parameters
Fixed issue in SQL compiler where the bound parameters set up for a
:class:`.Values` construct wouldn't be positionally tracked correctly if
inside of a :class:`_sql.CTE`, affecting database drivers that support
VALUES + ctes and use positional parameters such as SQL Server in
particular as well as asyncpg.   The fix also repairs support for
compiler flags such as ``literal_binds``.

Fixes: #6327
Change-Id: I2d549228691d0bfc10dadd0955b1549d7584db51
2021-04-20 15:28:45 -04:00
mike bayer 3580e6ed33 Merge "Derive next_value.type from Sequence.data_type if available" 2021-04-20 17:04:57 +00:00
Bryan Forbes adc9509450 Derive next_value.type from Sequence.data_type if available
Fixes #6287

Change-Id: I7d428ed86cd72cd910bfff9058a52c7fcb7c64ac
2021-04-18 13:54:57 -05:00
mike bayer 4d85ec1372 Merge "Don't stringify unnamed column elements when proxying" 2021-04-17 17:25:00 +00:00
mike bayer e42f0abe28 Merge "pass asfrom correctly in compilers" 2021-04-17 05:18:47 +00:00
mike bayer 23a09b117d Merge "Uniquify FROMs when traversing through select" 2021-04-17 04:45:28 +00:00
Mike Bayer 9f758d7fe3 Don't stringify unnamed column elements when proxying
Repaired and solidified issues regarding custom functions and other
arbitrary expression constructs which within SQLAlchemy's column labeling
mechanics would seek to use ``str(obj)`` to get a string representation to
use as an anonymous column name in the ``.c`` collection of a subquery.
This is a very legacy behavior that performs poorly and leads to lots of
issues, so has been revised to no longer perform any compilation by
establishing specific methods on :class:`.FunctionElement` to handle this
case, as SQL functions are the only use case that it came into play. An
effect of this behavior is that an unlabeled column expression with no
derivable name will be given an arbitrary label starting with the prefix
``"_no_label"`` in the ``.c`` collection of a subquery; these were
previously being represented either as the generic stringification of that
expression, or as an internal symbol.

This change seeks to make the concept of "anon name" more private
and renames anon_label and anon_key_label to _anon_name_label
and _anon_key_label.   There's no end-user utility to these accessors
and we need to be able to reorganize these as well.

Fixes: #6256
Change-Id: Ie63c86b20ca45873affea78500388da94cf8bf94
2021-04-17 00:40:52 -04:00
Mike Bayer 901f7a2b53 pass asfrom correctly in compilers
Fixed an argument error in the default and PostgreSQL compilers that
would interfere with an UPDATE..FROM or DELETE..FROM..USING statement
that was then SELECTed from as a CTE.

The incorrect pattern was also fixed in the mysql and sybase dialects.
MySQL supports CTEs but not "returning".

Fixes: #6303
Change-Id: Ic94805611a5ec443749fb6b1fd8a1326b0d83ef7
2021-04-17 00:37:47 -04:00
Mike Bayer 46f34449f3 Uniquify FROMs when traversing through select
Fixed a critical performance issue where the traversal of a
:func:`_sql.select` construct would traverse a repetitive product of the
represented FROM clauses as they were each referred towards by columns in
the columns clause; for a series of nested subqueries with lots of columns
this could cause a large delay and significant memory growth. This
traversal is used by a wide variety of SQL and ORM functions, including by
the ORM :class:`_orm.Session` when it's configured to have
"table-per-bind", which while this is not a common use case, it seems to be
what Flask-SQLAlchemy is hardcoded as using, so the issue impacts
Flask-SQLAlchemy users. The traversal has been repaired to uniqify on FROM
clauses which was effectively what would happen implicitly with the pre-1.4
architecture.

Fixes: #6304
Change-Id: I43497e943db4065deab0bfc830fbb68c17b80a53
2021-04-17 00:10:00 -04:00
Federico Caselli 91562f5618 Fit literal compile of empty in on a tuple
Fixed regression where an empty in statement on a tuple would result
in an error when compiled with the option ``literal_binds=True``.

Fixes: #6290
Change-Id: Ic0dff8f4a874cccdb201b6d9dcd3c2e7b7884cbb
2021-04-16 22:28:16 +02:00
Mike Bayer 60b0a693c9 Fix with_expression() cache leak; don't adapt singletons
Fixed a cache leak involving the :func:`_orm.with_expression` loader
option, where the given SQL expression would not be correctly considered as
part of the cache key.

Additionally, fixed regression involving the corresponding
:func:`_orm.query_expression` feature. While the bug technically exists in
1.3 as well, it was not exposed until 1.4. The "default expr" value of
``null()`` would be rendered when not needed, and additionally was also not
adapted correctly when the ORM rewrites statements such as when using
joined eager loading. The fix ensures "singleton" expressions like ``NULL``
and ``true`` aren't "adapted" to refer to columns in ORM statements, and
additionally ensures that a :func:`_orm.query_expression` with no default
expression doesn't render in the statement if a
:func:`_orm.with_expression` isn't used.

Fixes: #6259
Change-Id: I5a70bc12dadad125bbc4324b64048c8d4a18916c
2021-04-14 19:41:02 -04:00
Mike Bayer 94a1c52398 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
2021-04-14 12:51:58 -04:00
Mike Bayer f0a3349033 Ensure bindparam key escaping applied in all cases
Fixed regression where the :class:`_sql.BindParameter` object would not
properly render for an IN expression (i.e. using the "post compile" feature
in 1.4) if the object were copied from either an internal cloning
operation, or from a pickle operation, and the parameter name contained
spaces or other special characters.

Fixes: #6249
Change-Id: Icd0d4096c8fa4eb1a1d4c20f8a96d8b1ae439f0a
2021-04-12 14:33:50 -04:00
Mike Bayer 41de9a86c0 Return Row for CursorResult.inserted_primary_key
The tuple returned by :attr:`.CursorResult.inserted_primary_key` is now a
:class:`_result.Row` object with a named tuple interface on top of the
existing tuple interface.

Fixes: #3314
Change-Id: I85677ef60d8329648f368bf497f634758f4e087b
2021-04-11 17:15:55 -04:00
mike bayer 5e416bfa91 Merge "Fix LegacyRow/Row index access" 2021-04-08 21:22:47 +00:00
Mike Bayer dca3a43de6 Fix LegacyRow/Row index access
Fixed up the behavior of the :class:`_result.Row` object when dictionary
access is used upon it, meaning converting to a dict via ``dict(row)`` or
accessing members using strings or other objects i.e. ``row["some_key"]``
works as it would with a dictionary, rather than raising ``TypeError`` as
would be the case with a tuple, whether or not the C extensions are in
place. This was originally supposed to emit a 2.0 deprecation warning for
the "non-future" case using :class:`_result.LegacyRow`, and was to raise
``TypeError`` for the "future" :class:`_result.Row` class. However, the C
version of :class:`_result.Row` was failing to raise this ``TypeError``,
and to complicate matters, the :meth:`_orm.Session.execute` method now
returns :class:`_result.Row` in all cases to maintain consistency with the
ORM result case, so users who didn't have C extensions installed would
see different behavior in this one case for existing pre-1.4 style
code.

Therefore, in order to soften the overall upgrade scheme as most users have
not been exposed to the more strict behavior of :class:`_result.Row` up
through 1.4.6, :class:`_result.LegacyRow` and :class:`_result.Row` both
provide for string-key access as well as support for ``dict(row)``, in all
cases emitting the 2.0 deprecation warning when ``SQLALCHEMY_WARN_20`` is
enabled. The :class:`_result.Row` object still uses tuple-like behavior for
``__contains__``, which is probably the only noticeable behavioral change
compared to :class:`_result.LegacyRow`, other than the removal of
dictionary-style methods ``values()`` and ``items()``.

Also remove filters for result set warnings.

callcounts updated for 2.7/ 3.9, am pushing jenkins to use python 3.9
now

Fixes: #6218
Change-Id: Ia69b974f3dbc46943c57423f57ec82323c8ae63b
2021-04-08 16:06:41 -04:00
mike bayer faf980c0bd Merge "Infer types in BindParameter when expanding=True" 2021-04-08 16:04:44 +00:00
Mike Bayer df078a6fb0 Infer types in BindParameter when expanding=True
Enhanced the "expanding" feature used for :meth:`_sql.ColumnOperators.in_`
operations to infer the type of expression from the right hand list of
elements, if the left hand side does not have any explicit type set up.
This allows the expression to support stringification among other things.
In 1.3, "expanding" was not automatically used for
:meth:`_sql.ColumnOperators.in_` expressions, so in that sense this change
fixes a behavioral regression.

Fixes: #6222
Change-Id: Icdfda1e2c226a21896cafd6d8f251547794451c2
2021-04-08 10:29:08 -04:00
mike bayer f657705bfc Merge "support multivalues insert on strsqlcompiler" 2021-04-07 22:35:23 +00:00
Mike Bayer 26f1efcb05 support multivalues insert on strsqlcompiler
Fixed the "stringify" compiler to support a basic stringification
of a "multirow" INSERT statement, i.e. one with multiple tuples
following the VALUES keyword.

Change-Id: I1fe38d204d9965275d3a72157d5a72a53bec4b11
2021-04-07 17:52:23 -04:00
Mike Bayer f630692135 Expand reg for schema translate map for most special characters
Fixed regression where usage of a token in the
:paramref:`_engine.Connection.execution_options.schema_translate_map`
dictionary which contained special characters such as braces would fail to
be substituted properly. Use of square bracket characters ``[]`` is now
explicitly disallowed as these are used as a delimiter character in the
current implementation.

Fixes: #6216
Change-Id: I7ccfc2292b17340054cedf485ed1adf3119b96c8
2021-04-07 10:57:36 -04:00
mike bayer 34ed854de8 Merge "Table arguments name and metadata are positional only" 2021-04-06 22:29:39 +00:00
Federico Caselli 3de954bc02 Table arguments name and metadata are positional only
The :class:`_sql.Table` object now raises an informative error message if
it is instantiated without passing at least the :paramref:`_sql.Table.name`
and :paramref:`_sql.Table.metadata` arguments positionally. Previously, if
these were passed as keyword arguments, the object would silently fail to
initialize correctly.

Fixes: #6135
Change-Id: I54d0c89fd549fc504289a87ea0bb37369f982b06
2021-04-06 17:18:44 -04:00
mike bayer d5a2241047 Merge "Disallow AliasedReturnsRows from execution" 2021-04-06 14:29:44 +00:00
Mike Bayer ac2ed15740 Disallow AliasedReturnsRows from execution
Executing a :class:`_sql.Subquery` using :meth:`_engine.Connection.execute`
is deprecated and will emit a deprecation warning; this use case was an
oversight that should have been removed from 1.4. The operation will now
execute the underlying :class:`_sql.Select` object directly for backwards
compatibility. Similarly, the :class:`_sql.CTE` class is also not
appropriate for execution. In 1.3, attempting to execute a CTE would result
in an invalid "blank" SQL statement being executed; since this use case was
not working it now raises :class:`_exc.ObjectNotExecutableError`.
Previously, 1.4 was attempting to execute the CTE as a statement however it
was working only erratically.

The change also breaks out StatementRole from ReturnsRowsRole, as these
roles should not be in the same lineage (some statements don't return
rows, the whole class of ReturnsRows that are from clauses are
not statements).    Consolidate StatementRole and
CoerceTextStatementRole as there's no usage difference between
these.   Simplify some old tests that were trying to make
sure that "execution options" didn't transmit from a cte/subquery
out to a select; as cte/subuqery() aren't executable in any case
the options are removed.

Fixes: #6204
Change-Id: I62613b7ab418afdd22c409eae75659e3f52fb65f
2021-04-05 23:35:53 -04:00
Mike Bayer 279d185058 uniquify when popping literal_execute_params from param dict
Fixed further issues in the same area as that of 🎫`6173` released in
1.4.5, where a "postcompile" parameter, again most typically those used for
LIMIT/OFFSET rendering in Oracle and SQL Server, would fail to be processed
correctly if the same parameter rendered in multiple places in the
statement.

Fixes: #6202
Change-Id: I95c355aa52a7546fe579ad67f9a8402a213cb79d
2021-04-05 19:30:19 -04:00
Mike Bayer a16687b3fc Ensure Grouping._with_binary_element_type() maintains class
Fixed regression where use of the :meth:`.Operators.in_` method with a
:class:`_sql.Select` object against a non-table-bound column would produce
an ``AttributeError``, or more generally using a :class:`_sql.ScalarSelect`
that has no datatype in a binary expression would produce invalid state.

Fixes: #6181
Change-Id: I1ddea433b3603fdab8f489bff571b512a6ffc66b
2021-04-02 11:08:10 -04:00