Wrong variable names for column valued/table valued function parameters on Oracle
See original GitHub issueDescribe the bug
When using table-valued or column-valued functions in Oracle specifically, if the same function is used more than once, there is a collision in the parameter names being used. In the example below, :ODCIVARCHAR2LIST_1, :ODCIVARCHAR2LIST_2, :ODCIVARCHAR2LIST_3
is rendered for both calls, even though the parameters are different. All 6 parameters are correctly passed with unique names, but the query fails because it cannot bind the leftover ones.
To Reproduce
foobar_col = func.SYS.ODCIVARCHAR2LIST("foo", "bar", "baz").column_valued("foobar")
snap_col = func.SYS.ODCIVARCHAR2LIST("snap", "crackle", "pop").column_valued("snap")
numbers_col = func.SYS.ODCINUMBERLIST(1, 2, 3).column_valued("numbers")
my_query = select(foobar_col, snap_col)
print(my_query) # Parameter names are unique
print(my_query.compile(dialect=oracle.dialect())) # Parameter names are repeated!!
with oci_engine.begin() as conn:
res = conn.execute(my_query)
print(res.fetchall())
Error
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-01036: illegal variable name/number
[SQL: SELECT COLUMN_VALUE foobar, COLUMN_VALUE snap
FROM TABLE (SYS.ODCIVARCHAR2LIST(:ODCIVARCHAR2LIST_1, :ODCIVARCHAR2LIST_2, :ODCIVARCHAR2LIST_3)) foobar, TABLE (SYS.ODCIVARCHAR2LIST(:ODCIVARCHAR2LIST_1, :ODCIVARCHAR2LIST_2, :ODCIVARCHAR2LIST_3)) snap]
[parameters: {'ODCIVARCHAR2LIST_1': 'foo', 'ODCIVARCHAR2LIST_2': 'bar', 'ODCIVARCHAR2LIST_3': 'baz', 'ODCIVARCHAR2LIST_4': 'snap', 'ODCIVARCHAR2LIST_5': 'crackle', 'ODCIVARCHAR2LIST_6': 'pop'}]
(Background on this error at: https://sqlalche.me/e/14/4xp6)
Versions
- OS: Windows 10
- Python: 3.10.7
- SQLAlchemy: 1.4.44
- Database: Oracle 19c
- DBAPI : cx_oracle 8.3
Additional context
Aditionnally, COLUMN_VALUE
is always unqualified, meaning the above test query would fail even if the parameter numbering was correct. Below, the same example using two differently-named table-valued functions.
>>> my_query2 = select(foobar_col, numbers_col)
>>> print(my_query2.compile(dialect=oracle.dialect()))
SELECT COLUMN_VALUE foobar, COLUMN_VALUE numbers
FROM TABLE (SYS.ODCIVARCHAR2LIST(:ODCIVARCHAR2LIST_1, :ODCIVARCHAR2LIST_2, :ODCIVARCHAR2LIST_3)) foobar, TABLE (SYS.ODCINUMBERLIST(:ODCINUMBERLIST_1, :ODCINUMBERLIST_2, :ODCINUMBERLIST_3)) numbers
>>> with oci_engine.begin() as conn:
... res = conn.execute(my_query2)
... print(res.fetchall())
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-00918: column ambiguously defined
[SQL: SELECT COLUMN_VALUE foobar, COLUMN_VALUE numbers
FROM TABLE (SYS.ODCIVARCHAR2LIST(:ODCIVARCHAR2LIST_1, :ODCIVARCHAR2LIST_2, :ODCIVARCHAR2LIST_3)) foobar, TABLE (SYS.ODCINUMBERLIST(:ODCINUMBERLIST_1, :ODCINUMBERLIST_2, :ODCINUMBERLIST_3)) numbers]
[parameters: {'ODCIVARCHAR2LIST_1': 'foo', 'ODCIVARCHAR2LIST_2': 'bar', 'ODCIVARCHAR2LIST_3': 'baz', 'ODCINUMBERLIST_1': 1, 'ODCINUMBERLIST_2': 2, 'ODCINUMBERLIST_3': 3}]
(Background on this error at: https://sqlalche.me/e/14/4xp6)
Issue Analytics
- State:
- Created 9 months ago
- Comments:13 (9 by maintainers)
Top Results From Across the Web
B PL/SQL Name Resolution
Name Resolution. In ambiguous SQL statements, the names of columns take precedence over the names of local variables and formal parameters. For example,...
Read more >column_value syntax for Oracle is wrong · Issue #8945 - GitHub
the word "COLUMN_VALUE" is an implicit column name from the column-valued table, not a keyword on its own. ensure the fix for #8827...
Read more >SQL Server multi-statement table-valued functions - SQLShack
Multi-statement table-valued function returns a table as output and ... and updated in the function body according to the parameter value.
Read more >PL/SQL : Can we have same name for variable and column
The tutorial is slightly wrong. It is possible to have variables with the same name in SQL and PL/SQL but it is almost...
Read more >Use Table-Valued Parameters (Database Engine) - SQL Server
Similarly, a variable of table type has scope like any other local variable that is created by using a DECLARE statement. You can...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
every db is strange in its own way 😃
I’m guessing that some ancient oracle version did not like that, like the join or except that were added later on with standard syntax
well this is two issues, so this one is a dupe, the second part is an issue which is at #8945.