summaryrefslogtreecommitdiff
path: root/test/sql/test_query.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/sql/test_query.py')
-rw-r--r--test/sql/test_query.py164
1 files changed, 163 insertions, 1 deletions
diff --git a/test/sql/test_query.py b/test/sql/test_query.py
index f9ec82a6a..6b1e516ec 100644
--- a/test/sql/test_query.py
+++ b/test/sql/test_query.py
@@ -29,6 +29,7 @@ class QueryTest(fixtures.TestBase):
Column('user_name', VARCHAR(20)),
test_needs_acid=True
)
+
metadata.create_all()
@engines.close_first
@@ -264,7 +265,6 @@ class QueryTest(fixtures.TestBase):
)
concat = ("test: " + users.c.user_name).label('thedata')
- print select([concat]).order_by("thedata")
eq_(
select([concat]).order_by("thedata").execute().fetchall(),
[("test: ed",), ("test: fred",), ("test: jack",)]
@@ -1207,6 +1207,168 @@ class PercentSchemaNamesTest(fixtures.TestBase):
]
)
+class KeyTargetingTest(fixtures.TablesTest):
+ run_inserts = 'once'
+ run_deletes = None
+
+ @classmethod
+ def define_tables(cls, metadata):
+ keyed1 = Table('keyed1', metadata,
+ Column("a", CHAR(2), key="b"),
+ Column("c", CHAR(2), key="q")
+ )
+ keyed2 = Table('keyed2', metadata,
+ Column("a", CHAR(2)),
+ Column("b", CHAR(2)),
+ )
+ keyed3 = Table('keyed3', metadata,
+ Column("a", CHAR(2)),
+ Column("d", CHAR(2)),
+ )
+ keyed4 = Table('keyed4', metadata,
+ Column("b", CHAR(2)),
+ Column("q", CHAR(2)),
+ )
+
+ content = Table('content', metadata,
+ Column('t', String(30), key="type"),
+ )
+ bar = Table('bar', metadata,
+ Column('ctype', String(30), key="content_type")
+ )
+
+ @classmethod
+ def insert_data(cls):
+ cls.tables.keyed1.insert().execute(dict(b="a1", q="c1"))
+ cls.tables.keyed2.insert().execute(dict(a="a2", b="b2"))
+ cls.tables.keyed3.insert().execute(dict(a="a3", d="d3"))
+ cls.tables.keyed4.insert().execute(dict(b="b4", q="q4"))
+ cls.tables.content.insert().execute(type="t1")
+
+ def test_keyed_accessor_single(self):
+ keyed1 = self.tables.keyed1
+ row = testing.db.execute(keyed1.select()).first()
+
+ eq_(row.b, "a1")
+ eq_(row.q, "c1")
+ eq_(row.a, "a1")
+ eq_(row.c, "c1")
+
+ def test_keyed_accessor_single_labeled(self):
+ keyed1 = self.tables.keyed1
+ row = testing.db.execute(keyed1.select().apply_labels()).first()
+
+ eq_(row.keyed1_b, "a1")
+ eq_(row.keyed1_q, "c1")
+ eq_(row.keyed1_a, "a1")
+ eq_(row.keyed1_c, "c1")
+
+ def test_keyed_accessor_composite_conflict_2(self):
+ keyed1 = self.tables.keyed1
+ keyed2 = self.tables.keyed2
+
+ row = testing.db.execute(select([keyed1, keyed2])).first()
+ # without #2397, row.b is unambiguous
+ eq_(row.b, "b2")
+ # row.a is ambiguous
+ assert_raises_message(
+ exc.InvalidRequestError,
+ "Ambig",
+ getattr, row, "a"
+ )
+
+ @testing.fails_if(lambda: True, "Possible future behavior")
+ def test_keyed_accessor_composite_conflict_2397(self):
+ keyed1 = self.tables.keyed1
+ keyed2 = self.tables.keyed2
+
+ row = testing.db.execute(select([keyed1, keyed2])).first()
+ # with #2397, row.a is unambiguous
+ eq_(row.a, "a2")
+ # row.b is ambiguous
+ assert_raises_message(
+ exc.InvalidRequestError,
+ "Ambiguous column name 'b'",
+ getattr, row, 'b'
+ )
+
+ def test_keyed_accessor_composite_names_precedent(self):
+ keyed1 = self.tables.keyed1
+ keyed4 = self.tables.keyed4
+
+ row = testing.db.execute(select([keyed1, keyed4])).first()
+ eq_(row.b, "b4")
+ eq_(row.q, "q4")
+ eq_(row.a, "a1")
+ eq_(row.c, "c1")
+
+ def test_keyed_accessor_composite_keys_precedent(self):
+ keyed1 = self.tables.keyed1
+ keyed3 = self.tables.keyed3
+
+ row = testing.db.execute(select([keyed1, keyed3])).first()
+ assert 'b' not in row
+ eq_(row.q, "c1")
+ assert_raises_message(
+ exc.InvalidRequestError,
+ "Ambiguous column name 'a'",
+ getattr, row, "a"
+ )
+ eq_(row.d, "d3")
+
+ @testing.fails_if(lambda: True, "Possible future behavior")
+ def test_keyed_accessor_composite_2397(self):
+ keyed1 = self.tables.keyed1
+ keyed3 = self.tables.keyed3
+
+ row = testing.db.execute(select([keyed1, keyed3])).first()
+ eq_(row.b, "a1")
+ eq_(row.q, "c1")
+ eq_(row.a, "a3")
+ eq_(row.d, "d3")
+
+ def test_keyed_accessor_composite_labeled(self):
+ keyed1 = self.tables.keyed1
+ keyed2 = self.tables.keyed2
+
+ row = testing.db.execute(select([keyed1, keyed2]).apply_labels()).first()
+ eq_(row.keyed1_b, "a1")
+ eq_(row.keyed1_a, "a1")
+ eq_(row.keyed1_q, "c1")
+ eq_(row.keyed1_c, "c1")
+ eq_(row.keyed2_a, "a2")
+ eq_(row.keyed2_b, "b2")
+ assert_raises(KeyError, lambda: row['keyed2_c'])
+ assert_raises(KeyError, lambda: row['keyed2_q'])
+
+ def test_column_label_overlap_fallback(self):
+ content, bar = self.tables.content, self.tables.bar
+ row = testing.db.execute(select([content.c.type.label("content_type")])).first()
+ assert content.c.type in row
+ assert bar.c.content_type not in row
+ assert sql.column('content_type') in row
+
+ row = testing.db.execute(select([func.now().label("content_type")])).first()
+ assert content.c.type not in row
+ assert bar.c.content_type not in row
+ assert sql.column('content_type') in row
+
+ def test_column_label_overlap_fallback_2(self):
+ # this fails with #2397
+ content, bar = self.tables.content, self.tables.bar
+ row = testing.db.execute(content.select(use_labels=True)).first()
+ assert content.c.type in row
+ assert bar.c.content_type not in row
+ assert sql.column('content_type') not in row
+
+ @testing.fails_if(lambda: True, "Possible future behavior")
+ def test_column_label_overlap_fallback_3(self):
+ # this passes with #2397
+ content, bar = self.tables.content, self.tables.bar
+ row = testing.db.execute(content.select(use_labels=True)).first()
+ assert content.c.type in row
+ assert bar.c.content_type not in row
+ assert sql.column('content_type') in row
class LimitTest(fixtures.TestBase):