summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-03-25 17:08:48 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-03-30 14:04:52 -0400
commit4e754a8914a1c2c16c97bdf363d2e24bfa823730 (patch)
treedb723242b4e4c0d4c7f15c167857dd79fdfa6ccb /test
parentdba480ebaf89c0b5ea787661583de9da3928920f (diff)
downloadsqlalchemy-4e754a8914a1c2c16c97bdf363d2e24bfa823730.tar.gz
pep-484: the pep-484ening, SQL part three
hitting DML which is causing us to open up the ColumnCollection structure a bit, as we do put anonymous column expressions with None here. However, we still want Table /TableClause to have named column collections that don't return None, so parametrize the "key" in this collection also. * rename some "immutable" elements to "readonly". we change the contents of immutablecolumncollection underneath, so it's not "immutable" Change-Id: I2593995a4e5c6eae874bed5bf76117198be8ae97
Diffstat (limited to 'test')
-rw-r--r--test/base/test_utils.py38
-rw-r--r--test/profiles.txt22
-rw-r--r--test/sql/test_quote.py44
-rw-r--r--test/sql/test_returning.py110
-rw-r--r--test/sql/test_selectable.py18
5 files changed, 202 insertions, 30 deletions
diff --git a/test/base/test_utils.py b/test/base/test_utils.py
index 67fcc8870..fc61e39b6 100644
--- a/test/base/test_utils.py
+++ b/test/base/test_utils.py
@@ -357,8 +357,8 @@ class ImmutableTest(fixtures.TestBase):
with expect_raises_message(TypeError, "object is immutable"):
m()
- def test_immutable_properties(self):
- d = util.ImmutableProperties({3: 4})
+ def test_readonly_properties(self):
+ d = util.ReadOnlyProperties({3: 4})
calls = (
lambda: d.__delitem__(1),
lambda: d.__setitem__(2, 3),
@@ -563,7 +563,7 @@ class ColumnCollectionCommon(testing.AssertsCompiledSQL):
eq_(keys, ["c1", "foo", "c3"])
ne_(id(keys), id(cc.keys()))
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci.keys(), ["c1", "foo", "c3"])
def test_values(self):
@@ -576,7 +576,7 @@ class ColumnCollectionCommon(testing.AssertsCompiledSQL):
eq_(val, [c1, c2, c3])
ne_(id(val), id(cc.values()))
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci.values(), [c1, c2, c3])
def test_items(self):
@@ -589,7 +589,7 @@ class ColumnCollectionCommon(testing.AssertsCompiledSQL):
eq_(items, [("c1", c1), ("foo", c2), ("c3", c3)])
ne_(id(items), id(cc.items()))
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci.items(), [("c1", c1), ("foo", c2), ("c3", c3)])
def test_key_index_error(self):
@@ -732,7 +732,7 @@ class ColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
self._assert_collection_integrity(cc)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci._all_columns, [c1, c2a, c3, c2b])
eq_(list(ci), [c1, c2a, c3, c2b])
eq_(ci.keys(), ["c1", "c2", "c3", "c2"])
@@ -763,7 +763,7 @@ class ColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
self._assert_collection_integrity(cc)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci._all_columns, [c1, c2a, c3, c2b])
eq_(list(ci), [c1, c2a, c3, c2b])
eq_(ci.keys(), ["c1", "c2", "c3", "c2"])
@@ -786,7 +786,7 @@ class ColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
assert cc.contains_column(c2)
self._assert_collection_integrity(cc)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci._all_columns, [c1, c2, c3, c2])
eq_(list(ci), [c1, c2, c3, c2])
@@ -821,7 +821,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
c2.key = "foo"
cc = self._column_collection(columns=[("c1", c1), ("foo", c2)])
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
d = {"cc": cc, "ci": ci}
@@ -922,7 +922,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
assert cc.contains_column(c2)
self._assert_collection_integrity(cc)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci._all_columns, [c1, c2, c3])
eq_(list(ci), [c1, c2, c3])
@@ -944,13 +944,13 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
assert cc.contains_column(c2)
self._assert_collection_integrity(cc)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(ci._all_columns, [c1, c2, c3])
eq_(list(ci), [c1, c2, c3])
def test_replace(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2a, c3, c2b = (
column("c1"),
@@ -979,7 +979,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
def test_replace_key_matches_name_of_another(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2a, c3, c2b = (
column("c1"),
@@ -1009,7 +1009,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
def test_replace_key_matches(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2a, c3, c2b = (
column("c1"),
@@ -1041,7 +1041,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
def test_replace_name_matches(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2a, c3, c2b = (
column("c1"),
@@ -1073,7 +1073,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
def test_replace_no_match(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2, c3, c4 = column("c1"), column("c2"), column("c3"), column("c4")
c4.key = "X"
@@ -1123,7 +1123,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
cc = DedupeColumnCollection(
columns=[("c1", c1), ("c2", c2), ("c3", c3)]
)
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
eq_(cc._all_columns, [c1, c2, c3])
eq_(list(cc), [c1, c2, c3])
@@ -1184,7 +1184,7 @@ class DedupeColumnCollectionTest(ColumnCollectionCommon, fixtures.TestBase):
def test_dupes_extend(self):
cc = DedupeColumnCollection()
- ci = cc.as_immutable()
+ ci = cc.as_readonly()
c1, c2a, c3, c2b = (
column("c1"),
@@ -3044,7 +3044,7 @@ class TestProperties(fixtures.TestBase):
def test_pickle_immuatbleprops(self):
data = {"hello": "bla"}
- props = util.Properties(data).as_immutable()
+ props = util.Properties(data).as_readonly()
for loader, dumper in picklers():
s = dumper(props)
diff --git a/test/profiles.txt b/test/profiles.txt
index 074b649f2..31f72bd16 100644
--- a/test/profiles.txt
+++ b/test/profiles.txt
@@ -69,17 +69,17 @@ test.aaa_profiling.test_compiler.CompileTest.test_update x86_64_linux_cpython_3.
# TEST: test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_mysqldb_dbapiunicode_cextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_mysqldb_dbapiunicode_nocextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_pymysql_dbapiunicode_cextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_pymysql_dbapiunicode_nocextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mssql_pyodbc_dbapiunicode_cextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_oracle_cx_oracle_dbapiunicode_cextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_oracle_cx_oracle_dbapiunicode_nocextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_postgresql_psycopg2_dbapiunicode_cextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_postgresql_psycopg2_dbapiunicode_nocextensions 174
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 170
-test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 173
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_mysqldb_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_mysqldb_dbapiunicode_nocextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_pymysql_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mariadb_pymysql_dbapiunicode_nocextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_mssql_pyodbc_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_oracle_cx_oracle_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_oracle_cx_oracle_dbapiunicode_nocextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_postgresql_psycopg2_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_postgresql_psycopg2_dbapiunicode_nocextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_cextensions 180
+test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause x86_64_linux_cpython_3.10_sqlite_pysqlite_dbapiunicode_nocextensions 180
# TEST: test.aaa_profiling.test_misc.CacheKeyTest.test_statement_key_is_cached
diff --git a/test/sql/test_quote.py b/test/sql/test_quote.py
index 9812f84c1..7d90bc67b 100644
--- a/test/sql/test_quote.py
+++ b/test/sql/test_quote.py
@@ -252,6 +252,50 @@ class QuoteTest(fixtures.TestBase, AssertsCompiledSQL):
eq_(repr(name), repr("姓名"))
+ def test_literal_column_label_embedded_select_samename_explicit_quote(
+ self,
+ ):
+ col = sql.literal_column("NEEDS QUOTES").label(
+ quoted_name("NEEDS QUOTES", True)
+ )
+
+ self.assert_compile(
+ select(col).subquery().select(),
+ 'SELECT anon_1."NEEDS QUOTES" FROM '
+ '(SELECT NEEDS QUOTES AS "NEEDS QUOTES") AS anon_1',
+ )
+
+ def test_literal_column_label_embedded_select_diffname_explicit_quote(
+ self,
+ ):
+ col = sql.literal_column("NEEDS QUOTES").label(
+ quoted_name("NEEDS QUOTES_", True)
+ )
+
+ self.assert_compile(
+ select(col).subquery().select(),
+ 'SELECT anon_1."NEEDS QUOTES_" FROM '
+ '(SELECT NEEDS QUOTES AS "NEEDS QUOTES_") AS anon_1',
+ )
+
+ def test_literal_column_label_embedded_select_diffname(self):
+ col = sql.literal_column("NEEDS QUOTES").label("NEEDS QUOTES_")
+
+ self.assert_compile(
+ select(col).subquery().select(),
+ 'SELECT anon_1."NEEDS QUOTES_" FROM (SELECT NEEDS QUOTES AS '
+ '"NEEDS QUOTES_") AS anon_1',
+ )
+
+ def test_literal_column_label_embedded_select_samename(self):
+ col = sql.literal_column("NEEDS QUOTES").label("NEEDS QUOTES")
+
+ self.assert_compile(
+ select(col).subquery().select(),
+ 'SELECT anon_1."NEEDS QUOTES" FROM (SELECT NEEDS QUOTES AS '
+ '"NEEDS QUOTES") AS anon_1',
+ )
+
def test_lower_case_names(self):
# Create table with quote defaults
metadata = MetaData()
diff --git a/test/sql/test_returning.py b/test/sql/test_returning.py
index 138e7a4c6..ffbab3223 100644
--- a/test/sql/test_returning.py
+++ b/test/sql/test_returning.py
@@ -1,6 +1,7 @@
import itertools
from sqlalchemy import Boolean
+from sqlalchemy import column
from sqlalchemy import delete
from sqlalchemy import exc as sa_exc
from sqlalchemy import func
@@ -10,9 +11,11 @@ from sqlalchemy import MetaData
from sqlalchemy import select
from sqlalchemy import Sequence
from sqlalchemy import String
+from sqlalchemy import table
from sqlalchemy import testing
from sqlalchemy import type_coerce
from sqlalchemy import update
+from sqlalchemy.sql.sqltypes import NullType
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import AssertsCompiledSQL
from sqlalchemy.testing import AssertsExecutionResults
@@ -88,6 +91,113 @@ class ReturnCombinationTests(fixtures.TestBase, AssertsCompiledSQL):
t.c.x,
)
+ def test_named_expressions_selected_columns(self, table_fixture):
+ table = table_fixture
+ stmt = (
+ table.insert()
+ .values(goofy="someOTHERgoofy")
+ .returning(func.lower(table.c.x).label("goof"))
+ )
+ self.assert_compile(
+ select(stmt.exported_columns.goof),
+ "SELECT lower(foo.x) AS goof FROM foo",
+ )
+
+ def test_anon_expressions_selected_columns(self, table_fixture):
+ table = table_fixture
+ stmt = (
+ table.insert()
+ .values(goofy="someOTHERgoofy")
+ .returning(func.lower(table.c.x))
+ )
+ self.assert_compile(
+ select(stmt.exported_columns[0]),
+ "SELECT lower(foo.x) AS lower_1 FROM foo",
+ )
+
+ def test_returning_fromclause(self):
+ t = table("t", column("x"), column("y"), column("z"))
+ stmt = t.update().returning(t)
+
+ self.assert_compile(
+ stmt,
+ "UPDATE t SET x=%(x)s, y=%(y)s, z=%(z)s RETURNING t.x, t.y, t.z",
+ )
+
+ eq_(
+ stmt.returning_column_descriptions,
+ [
+ {
+ "name": "x",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.x,
+ },
+ {
+ "name": "y",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.y,
+ },
+ {
+ "name": "z",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.z,
+ },
+ ],
+ )
+
+ cte = stmt.cte("c")
+
+ stmt = select(cte.c.z)
+ self.assert_compile(
+ stmt,
+ "WITH c AS (UPDATE t SET x=%(x)s, y=%(y)s, z=%(z)s "
+ "RETURNING t.x, t.y, t.z) SELECT c.z FROM c",
+ )
+
+ def test_returning_inspectable(self):
+ t = table("t", column("x"), column("y"), column("z"))
+
+ class HasClauseElement:
+ def __clause_element__(self):
+ return t
+
+ stmt = update(HasClauseElement()).returning(HasClauseElement())
+
+ eq_(
+ stmt.returning_column_descriptions,
+ [
+ {
+ "name": "x",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.x,
+ },
+ {
+ "name": "y",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.y,
+ },
+ {
+ "name": "z",
+ "type": testing.eq_type_affinity(NullType),
+ "expr": t.c.z,
+ },
+ ],
+ )
+
+ self.assert_compile(
+ stmt,
+ "UPDATE t SET x=%(x)s, y=%(y)s, z=%(z)s "
+ "RETURNING t.x, t.y, t.z",
+ )
+ cte = stmt.cte("c")
+
+ stmt = select(cte.c.z)
+ self.assert_compile(
+ stmt,
+ "WITH c AS (UPDATE t SET x=%(x)s, y=%(y)s, z=%(z)s "
+ "RETURNING t.x, t.y, t.z) SELECT c.z FROM c",
+ )
+
class ReturningTest(fixtures.TablesTest, AssertsExecutionResults):
__requires__ = ("returning",)
diff --git a/test/sql/test_selectable.py b/test/sql/test_selectable.py
index 4944f2d57..ca5f43bb6 100644
--- a/test/sql/test_selectable.py
+++ b/test/sql/test_selectable.py
@@ -208,6 +208,24 @@ class SelectableTest(
{"name": "table1", "table": table1},
[],
),
+ (
+ table1.alias("some_alias"),
+ None,
+ {
+ "name": "some_alias",
+ "table": testing.eq_clause_element(table1.alias("some_alias")),
+ },
+ [],
+ ),
+ (
+ table1.join(table2),
+ None,
+ {
+ "name": None,
+ "table": testing.eq_clause_element(table1.join(table2)),
+ },
+ [],
+ ),
argnames="entity, cols, expected_entity, expected_returning",
)
def test_dml_descriptions(