summaryrefslogtreecommitdiff
path: root/test/dialect/oracle/test_compiler.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/dialect/oracle/test_compiler.py')
-rw-r--r--test/dialect/oracle/test_compiler.py243
1 files changed, 214 insertions, 29 deletions
diff --git a/test/dialect/oracle/test_compiler.py b/test/dialect/oracle/test_compiler.py
index ecf43a2cf..45a83ed77 100644
--- a/test/dialect/oracle/test_compiler.py
+++ b/test/dialect/oracle/test_compiler.py
@@ -47,6 +47,12 @@ from sqlalchemy.testing.schema import Table
class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
__dialect__ = "oracle"
+ @testing.fixture
+ def legacy_oracle_limitoffset(self):
+ self.__dialect__ = oracle.OracleDialect(enable_offset_fetch=False)
+ yield
+ del self.__dialect__
+
def test_true_false(self):
self.assert_compile(sql.false(), "0")
self.assert_compile(sql.true(), "1")
@@ -159,7 +165,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"GROUP BY included_parts.sub_part",
)
- def test_limit_one(self):
+ def test_limit_one_legacy(self, legacy_oracle_limitoffset):
t = table("sometable", column("col1"), column("col2"))
s = select(t)
c = s.compile(dialect=oracle.OracleDialect())
@@ -182,6 +188,24 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
eq_(len(c._result_columns), 2)
assert t.c.col1 in set(c._create_result_map()["col1"][1])
+ def test_limit_one(self):
+ t = table("sometable", column("col1"), column("col2"))
+ s = select(t)
+ c = s.compile(dialect=oracle.OracleDialect())
+ assert t.c.col1 in set(c._create_result_map()["col1"][1])
+ s = select(t).limit(10).offset(20)
+ self.assert_compile(
+ s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "OFFSET __[POSTCOMPILE_param_1] ROWS "
+ "FETCH FIRST __[POSTCOMPILE_param_2] ROWS ONLY",
+ checkparams={"param_1": 20, "param_2": 10},
+ )
+
+ c = s.compile(dialect=oracle.OracleDialect())
+ eq_(len(c._result_columns), 2)
+ assert t.c.col1 in set(c._create_result_map()["col1"][1])
+
def test_limit_one_literal_binds(self):
"""test for #6863.
@@ -197,6 +221,25 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
eq_ignore_whitespace(
str(c),
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "OFFSET 20 ROWS FETCH FIRST 10 ROWS ONLY",
+ )
+
+ def test_limit_one_literal_binds_legacy(self, legacy_oracle_limitoffset):
+ """test for #6863.
+
+ the bug does not appear to have affected Oracle's case.
+
+ """
+ t = table("sometable", column("col1"), column("col2"))
+ s = select(t).limit(10).offset(20)
+ c = s.compile(
+ dialect=oracle.OracleDialect(enable_offset_fetch=False),
+ compile_kwargs={"literal_binds": True},
+ )
+
+ eq_ignore_whitespace(
+ str(c),
"SELECT anon_1.col1, anon_1.col2 FROM "
"(SELECT anon_2.col1 AS col1, anon_2.col2 AS col2, "
"ROWNUM AS ora_rn FROM (SELECT sometable.col1 AS col1, "
@@ -204,7 +247,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"WHERE ROWNUM <= 10 + 20) anon_1 WHERE ora_rn > 20",
)
- def test_limit_one_firstrows(self):
+ def test_limit_one_firstrows_legacy(self):
t = table("sometable", column("col1"), column("col2"))
s = select(t)
s = select(t).limit(10).offset(20)
@@ -220,7 +263,34 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"WHERE ora_rn > "
"__[POSTCOMPILE_param_2]",
checkparams={"param_1": 10, "param_2": 20},
- dialect=oracle.OracleDialect(optimize_limits=True),
+ dialect=oracle.OracleDialect(
+ optimize_limits=True, enable_offset_fetch=False
+ ),
+ )
+
+ def test_simple_fetch(self):
+ # as of #8221, all FETCH / ROWS ONLY is using postcompile params;
+ # this is in the spirit of the ROWNUM approach where users reported
+ # that bound parameters caused performance degradation
+ t = table("sometable", column("col1"), column("col2"))
+ s = select(t)
+ s = select(t).fetch(10)
+ self.assert_compile(
+ s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "FETCH FIRST __[POSTCOMPILE_param_1] ROWS ONLY",
+ checkparams={"param_1": 10},
+ )
+
+ def test_simple_fetch_offset(self):
+ t = table("sometable", column("col1"), column("col2"))
+ s = select(t).fetch(10).offset(20)
+ self.assert_compile(
+ s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "OFFSET __[POSTCOMPILE_param_1] ROWS "
+ "FETCH FIRST __[POSTCOMPILE_param_2] ROWS ONLY",
+ checkparams={"param_1": 20, "param_2": 10},
)
def test_limit_two(self):
@@ -230,6 +300,33 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
s2 = select(s.c.col1, s.c.col2)
self.assert_compile(
s2,
+ "SELECT anon_1.col1, anon_1.col2 FROM (SELECT sometable.col1 AS "
+ "col1, sometable.col2 AS col2 FROM sometable OFFSET "
+ "__[POSTCOMPILE_param_1] ROWS FETCH FIRST "
+ "__[POSTCOMPILE_param_2] ROWS ONLY) anon_1",
+ checkparams={"param_1": 20, "param_2": 10},
+ )
+
+ self.assert_compile(
+ s2,
+ "SELECT anon_1.col1, anon_1.col2 FROM (SELECT sometable.col1 AS "
+ "col1, sometable.col2 AS col2 FROM sometable OFFSET 20 "
+ "ROWS FETCH FIRST 10 ROWS ONLY) anon_1",
+ render_postcompile=True,
+ )
+ c = s2.compile(dialect=oracle.OracleDialect())
+ eq_(len(c._result_columns), 2)
+ assert s.c.col1 in set(c._create_result_map()["col1"][1])
+
+ def test_limit_two_legacy(self):
+ t = table("sometable", column("col1"), column("col2"))
+ s = select(t).limit(10).offset(20).subquery()
+
+ s2 = select(s.c.col1, s.c.col2)
+
+ dialect = oracle.OracleDialect(enable_offset_fetch=False)
+ self.assert_compile(
+ s2,
"SELECT anon_1.col1, anon_1.col2 FROM "
"(SELECT anon_2.col1 AS col1, "
"anon_2.col2 AS col2 "
@@ -242,6 +339,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"anon_2 "
"WHERE ora_rn > __[POSTCOMPILE_param_2]) anon_1",
checkparams={"param_1": 10, "param_2": 20},
+ dialect=dialect,
)
self.assert_compile(
@@ -257,8 +355,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"__[POSTCOMPILE_param_2]) "
"anon_2 "
"WHERE ora_rn > __[POSTCOMPILE_param_2]) anon_1",
+ dialect=dialect,
)
- c = s2.compile(dialect=oracle.OracleDialect())
+ c = s2.compile(dialect=dialect)
eq_(len(c._result_columns), 2)
assert s.c.col1 in set(c._create_result_map()["col1"][1])
@@ -268,6 +367,22 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
s = select(t).limit(10).offset(20).order_by(t.c.col2)
self.assert_compile(
s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "ORDER BY sometable.col2 OFFSET __[POSTCOMPILE_param_1] "
+ "ROWS FETCH FIRST __[POSTCOMPILE_param_2] ROWS ONLY",
+ checkparams={"param_1": 20, "param_2": 10},
+ )
+ c = s.compile(dialect=oracle.OracleDialect())
+ eq_(len(c._result_columns), 2)
+ assert t.c.col1 in set(c._create_result_map()["col1"][1])
+
+ def test_limit_three_legacy(self):
+ t = table("sometable", column("col1"), column("col2"))
+
+ s = select(t).limit(10).offset(20).order_by(t.c.col2)
+ dialect = oracle.OracleDialect(enable_offset_fetch=False)
+ self.assert_compile(
+ s,
"SELECT anon_1.col1, anon_1.col2 FROM "
"(SELECT anon_2.col1 AS col1, "
"anon_2.col2 AS col2, ROWNUM AS ora_rn FROM (SELECT "
@@ -277,12 +392,13 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"__[POSTCOMPILE_param_1] + __[POSTCOMPILE_param_2]) anon_1 "
"WHERE ora_rn > __[POSTCOMPILE_param_2]",
checkparams={"param_1": 10, "param_2": 20},
+ dialect=dialect,
)
- c = s.compile(dialect=oracle.OracleDialect())
+ c = s.compile(dialect=dialect)
eq_(len(c._result_columns), 2)
assert t.c.col1 in set(c._create_result_map()["col1"][1])
- def test_limit_four(self):
+ def test_limit_four_legacy(self, legacy_oracle_limitoffset):
t = table("sometable", column("col1"), column("col2"))
s = select(t).with_for_update().limit(10).order_by(t.c.col2)
@@ -296,7 +412,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10},
)
- def test_limit_four_firstrows(self):
+ def test_limit_four_firstrows_legacy(self):
t = table("sometable", column("col1"), column("col2"))
s = select(t).with_for_update().limit(10).order_by(t.c.col2)
@@ -309,7 +425,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"sometable.col2) anon_1 WHERE ROWNUM <= __[POSTCOMPILE_param_1] "
"FOR UPDATE",
checkparams={"param_1": 10},
- dialect=oracle.OracleDialect(optimize_limits=True),
+ dialect=oracle.OracleDialect(
+ optimize_limits=True, enable_offset_fetch=False
+ ),
)
def test_limit_five(self):
@@ -318,6 +436,18 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
s = select(t).with_for_update().limit(10).offset(20).order_by(t.c.col2)
self.assert_compile(
s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "ORDER BY sometable.col2 OFFSET __[POSTCOMPILE_param_1] ROWS "
+ "FETCH FIRST __[POSTCOMPILE_param_2] ROWS ONLY FOR UPDATE",
+ checkparams={"param_1": 20, "param_2": 10},
+ )
+
+ def test_limit_five_legacy(self, legacy_oracle_limitoffset):
+ t = table("sometable", column("col1"), column("col2"))
+
+ s = select(t).with_for_update().limit(10).offset(20).order_by(t.c.col2)
+ self.assert_compile(
+ s,
"SELECT anon_1.col1, anon_1.col2 FROM "
"(SELECT anon_2.col1 AS col1, "
"anon_2.col2 AS col2, ROWNUM AS ora_rn FROM (SELECT "
@@ -341,6 +471,23 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
)
self.assert_compile(
s,
+ "SELECT sometable.col1, sometable.col2 FROM sometable "
+ "ORDER BY sometable.col2 OFFSET :param_1 + :param_2 "
+ "ROWS FETCH FIRST __[POSTCOMPILE_param_3] ROWS ONLY",
+ checkparams={"param_1": 10, "param_2": 20, "param_3": 10},
+ )
+
+ def test_limit_six_legacy(self, legacy_oracle_limitoffset):
+ t = table("sometable", column("col1"), column("col2"))
+
+ s = (
+ select(t)
+ .limit(10)
+ .offset(literal(10) + literal(20))
+ .order_by(t.c.col2)
+ )
+ self.assert_compile(
+ s,
"SELECT anon_1.col1, anon_1.col2 FROM (SELECT anon_2.col1 AS "
"col1, anon_2.col2 AS col2, ROWNUM AS ora_rn FROM "
"(SELECT sometable.col1 AS col1, sometable.col2 AS col2 "
@@ -350,7 +497,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10, "param_2": 10, "param_3": 20},
)
- def test_limit_special_quoting(self):
+ def test_limit_special_quoting_legacy(self, legacy_oracle_limitoffset):
"""Oracle-specific test for #4730.
Even though this issue is generic, test the originally reported Oracle
@@ -510,7 +657,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"FROM mytable WHERE mytable.myid = :myid_1 FOR UPDATE OF table1",
)
- def test_for_update_of_w_limit_adaption_col_present(self):
+ def test_for_update_of_w_limit_col_present_legacy(
+ self, legacy_oracle_limitoffset
+ ):
table1 = table("mytable", column("myid"), column("name"))
self.assert_compile(
@@ -526,7 +675,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10, "myid_1": 7},
)
- def test_for_update_of_w_limit_adaption_col_unpresent(self):
+ def test_for_update_of_w_limit_col_unpresent_legacy(
+ self, legacy_oracle_limitoffset
+ ):
table1 = table("mytable", column("myid"), column("name"))
self.assert_compile(
@@ -541,7 +692,25 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"FOR UPDATE OF anon_1.name NOWAIT",
)
- def test_for_update_of_w_limit_offset_adaption_col_present(self):
+ def test_for_update_of_w_limit_offset_col_present(self):
+ table1 = table("mytable", column("myid"), column("name"))
+
+ self.assert_compile(
+ select(table1.c.myid, table1.c.name)
+ .where(table1.c.myid == 7)
+ .with_for_update(nowait=True, of=table1.c.name)
+ .limit(10)
+ .offset(50),
+ "SELECT mytable.myid, mytable.name FROM mytable "
+ "WHERE mytable.myid = :myid_1 OFFSET __[POSTCOMPILE_param_1] "
+ "ROWS FETCH FIRST __[POSTCOMPILE_param_2] ROWS ONLY "
+ "FOR UPDATE OF mytable.name NOWAIT",
+ checkparams={"param_1": 50, "param_2": 10, "myid_1": 7},
+ )
+
+ def test_for_update_of_w_limit_offset_col_present_legacy(
+ self, legacy_oracle_limitoffset
+ ):
table1 = table("mytable", column("myid"), column("name"))
self.assert_compile(
@@ -563,7 +732,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10, "param_2": 50, "myid_1": 7},
)
- def test_for_update_of_w_limit_offset_adaption_col_unpresent(self):
+ def test_for_update_of_w_limit_offset_col_unpresent_legacy(
+ self, legacy_oracle_limitoffset
+ ):
table1 = table("mytable", column("myid"), column("name"))
self.assert_compile(
@@ -584,7 +755,9 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10, "param_2": 50, "myid_1": 7},
)
- def test_for_update_of_w_limit_offset_adaption_partial_col_unpresent(self):
+ def test_for_update_of_w_limit_offset_partial_col_unpresent_legacy(
+ self, legacy_oracle_limitoffset
+ ):
table1 = table("mytable", column("myid"), column("foo"), column("bar"))
self.assert_compile(
@@ -607,23 +780,25 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
checkparams={"param_1": 10, "param_2": 50, "myid_1": 7},
)
- def test_limit_preserves_typing_information(self):
+ def test_limit_preserves_typing_information_legacy(self):
class MyType(TypeDecorator):
impl = Integer
cache_ok = True
stmt = select(type_coerce(column("x"), MyType).label("foo")).limit(1)
- dialect = oracle.dialect()
+ dialect = oracle.dialect(enable_offset_fetch=False)
compiled = stmt.compile(dialect=dialect)
assert isinstance(compiled._create_result_map()["foo"][-2], MyType)
- def test_use_binds_for_limits_disabled_one(self):
+ def test_use_binds_for_limits_disabled_one_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=False)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=False, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).limit(10),
@@ -634,13 +809,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
dialect=dialect,
)
- def test_use_binds_for_limits_disabled_two(self):
+ def test_use_binds_for_limits_disabled_two_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=False)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=False, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).offset(10),
@@ -652,13 +829,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
dialect=dialect,
)
- def test_use_binds_for_limits_disabled_three(self):
+ def test_use_binds_for_limits_disabled_three_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=False)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=False, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).limit(10).offset(10),
@@ -672,13 +851,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
dialect=dialect,
)
- def test_use_binds_for_limits_enabled_one(self):
+ def test_use_binds_for_limits_enabled_one_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=True)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=True, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).limit(10),
@@ -689,13 +870,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
dialect=dialect,
)
- def test_use_binds_for_limits_enabled_two(self):
+ def test_use_binds_for_limits_enabled_two_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=True)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=True, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).offset(10),
@@ -708,13 +891,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
dialect=dialect,
)
- def test_use_binds_for_limits_enabled_three(self):
+ def test_use_binds_for_limits_enabled_three_legacy(self):
t = table("sometable", column("col1"), column("col2"))
with testing.expect_deprecated(
"The ``use_binds_for_limits`` Oracle dialect parameter is "
"deprecated."
):
- dialect = oracle.OracleDialect(use_binds_for_limits=True)
+ dialect = oracle.OracleDialect(
+ use_binds_for_limits=True, enable_offset_fetch=False
+ )
self.assert_compile(
select(t).limit(10).offset(10),
@@ -932,7 +1117,7 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"anon_1 "
"WHERE ora_rn > __[POSTCOMPILE_param_2]",
checkparams={"param_1": 10, "param_2": 5},
- dialect=oracle.dialect(use_ansi=False),
+ dialect=oracle.dialect(use_ansi=False, enable_offset_fetch=False),
)
def test_outer_join_six(self):