From cc29c4afff20dd251dbc045a490da9942f98b1bf Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 11 Oct 2014 18:25:21 -0400 Subject: [PATCH] - Fixed long-standing bug in Oracle dialect where bound parameter names that started with numbers would not be quoted, as Oracle doesn't like numerics in bound parameter names. fixes #2138 --- doc/build/changelog/changelog_09.rst | 9 +++++++++ lib/sqlalchemy/dialects/oracle/base.py | 3 ++- test/dialect/test_oracle.py | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index e2b893d07f..fdc83c7670 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -13,6 +13,15 @@ .. changelog:: :version: 0.9.8 + .. change:: + :tags: bug, oracle + :versions: 1.0.0 + :tickets: 2138 + + Fixed long-standing bug in Oracle dialect where bound parameter + names that started with numbers would not be quoted, as Oracle + doesn't like numerics in bound parameter names. + .. change:: :tags: bug, sql :versions: 1.0.0 diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index 837a498fbb..6df38e57ef 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -813,7 +813,8 @@ class OracleDDLCompiler(compiler.DDLCompiler): class OracleIdentifierPreparer(compiler.IdentifierPreparer): reserved_words = set([x.lower() for x in RESERVED_WORDS]) - illegal_initial_characters = set(range(0, 10)).union(["_", "$"]) + illegal_initial_characters = set( + (str(dig) for dig in range(0, 10))).union(["_", "$"]) def _bindparam_requires_quotes(self, value): """Return True if the given identifier requires quoting.""" diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py index 36eacf8643..a771c5d80a 100644 --- a/test/dialect/test_oracle.py +++ b/test/dialect/test_oracle.py @@ -104,6 +104,28 @@ class QuotedBindRoundTripTest(fixtures.TestBase): (2, 2, 2) ) + def test_numeric_bind_round_trip(self): + eq_( + testing.db.scalar( + select([ + literal_column("2", type_=Integer()) + + bindparam("2_1", value=2)]) + ), + 4 + ) + + @testing.provide_metadata + def test_numeric_bind_in_crud(self): + t = Table( + "asfd", self.metadata, + Column("100K", Integer) + ) + t.create() + + testing.db.execute(t.insert(), {"100K": 10}) + eq_( + testing.db.scalar(t.select()), 10 + ) class CompileTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = "oracle" #oracle.dialect() -- 2.47.2