Function names in SQL can contain pretty much anything, e.g.:
=# create function "A Bug?"(integer) returns integer as $$ select $1; $$
language sql;
CREATE FUNCTION
But when attempting to use the function from SQLAlchemy:
from sqlalchemy.sql.expression import func
bug = getattr(func, "A Bug?")(1)
session.query(bug).all()
ProgrammingError: (ProgrammingError) syntax error at or near "?"
LINE 1: SELECT A Bug?(1) AS "A Bug?_1"
'SELECT A Bug?(%(A Bug?_2)s) AS "A Bug?_1"' {'A Bug?_2': 1}
-Ryan P. Kelly
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index dd2a6e0..ada56c6 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -603,7 +603,10 @@ class SQLCompiler(engine.Compiled):
if disp:
return disp(func, **kwargs)
else:
- name = FUNCTIONS.get(func.__class__, func.name + "%(expr)s")
+ name = FUNCTIONS.get(
+ func.__class__,
+ self.preparer.quote(func.name, None) + "%(expr)s"
+ )
return ".".join(list(func.packagenames) + [name]) % \
{'expr': self.function_argspec(func, **kwargs)}
diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py
index 473a422..6ea4d2a 100644
--- a/test/sql/test_compiler.py
+++ b/test/sql/test_compiler.py
@@ -2481,6 +2481,49 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
and_, ("a",), ("b",)
)
+ def test_func(self):
+ f1 = func.somefunc(1)
+ self.assert_compile(
+ select([f1]),
+ "SELECT somefunc(:somefunc_2) AS somefunc_1",
+ )
+ self.assert_compile(
+ select([f1.label("f1")]),
+ "SELECT somefunc(:somefunc_1) AS f1",
+ )
+
+ f2 = func.somefunc(table1.c.name)
+ self.assert_compile(
+ select([f2]),
+ "SELECT somefunc(mytable.name) AS somefunc_1 FROM mytable",
+ )
+ self.assert_compile(
+ select([f2.label("f2")]),
+ "SELECT somefunc(mytable.name) AS f2 FROM mytable",
+ )
+
+ f3 = getattr(func, "Needs Quotes?")(table1.c.myid)
+ self.assert_compile(
+ select([f3]),
+ 'SELECT "Needs Quotes?"(mytable.myid) AS "Needs Quotes?_1" FROM '
+ 'mytable'
+ )
+ self.assert_compile(
+ select([f3.label("f3")]),
+ 'SELECT "Needs Quotes?"(mytable.myid) AS f3 FROM mytable',
+ )
+
+ f4 = getattr(func, "query from pg_stat_activity; --")()
+ self.assert_compile(
+ select([f4]),
+ 'SELECT "query from pg_stat_activity; --"() AS "query from '
+ 'pg_stat_activity; --_1"',
+ )
+ self.assert_compile(
+ select([f4.label("f4")]),
+ 'SELECT "query from pg_stat_activity; --"(mytable.myid) AS f4'
+ )
+
class KwargPropagationTest(fixtures.TestBase):