question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrong variable names for column valued/table valued function parameters on Oracle

See original GitHub issue

Describe 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:closed
  • Created 9 months ago
  • Comments:13 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
CaselITcommented, Dec 7, 2022

…and then Oracle doesn’t mind if it’s there or not for column names but throws an error if it’s used for table aliases. Gotta love vendor uniformity!

every db is strange in its own way 😃

Still, though, it’s interesting that SQLA uses AS for column labels in Postgres but leaves it out for Oracle.

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

1reaction
zzzeekcommented, Dec 7, 2022

well this is two issues, so this one is a dupe, the second part is an issue which is at #8945.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found