summaryrefslogtreecommitdiff
path: root/test/sql
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/sql
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/sql')
-rw-r--r--test/sql/test_quote.py44
-rw-r--r--test/sql/test_returning.py110
-rw-r--r--test/sql/test_selectable.py18
3 files changed, 172 insertions, 0 deletions
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(