17
votes

I've just come across a strange behaviour in Oracle where I would expect ORA-00918 to be raised, but isn't. Take this query, for example.

SELECT *
FROM USER_TABLES TAB
JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
WHERE STATUS = 'DISABLED'

This query is notionally looking for the details of tables with disabled triggers, but please note that this is not the problem I'm trying to solve. The problem is not unique to this query, the data dictionary, views or tables; as far as I can tell it applies to any set of tables or views (from the two or three I've tried).

Anyway, try to run this query and you get ORA-00918 because both USER_TABLES and USER_TRIGGERS have a column called STATUS so to get the query to run the WHERE clause needs to be changed to TRG.STATUS. Ok, cool, but try instead joining another table.

SELECT *
FROM USER_TABLES TAB
JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
WHERE STATUS = 'DISABLED'

This query, without qualifying which STATUS column you mean, magically works! Never mind the semantics or what the query returns, there is no error. USER_CONSTRAINTS even has a column called STATUS too, so how come it doesn't know what to do when there are two columns to choose from but it's okay with even more ambiguity?

This is all on 10.2.0.3.0 by the way, and in essence ORA-00918 stops being raised if you have more than two tables in your query. If this is an Oracle bug, does anyone know when it was fixed and so which Oracle version is likely to cause cowboy queries to blow up if our database is upgraded?

Update

Thanks to BQ for demonstrating the bug is fixed in 11.2.0.1.0. Bounty for anyone that can show it fixed in an earlier version!

5
very good question indeed, you can select distinct status on the second query, and select distinct tab.status and you get different results.Benoit
I see the same behavior 9.2.0.8.0 and 10.2.0.4.0Conrad Frix
I've been stung by this issue before. Couldn't work why a key column now had nulls after outer joining to another table. Good to see I'm not the only one! And glad to see it's fixed in 11g.Mike Meyers

5 Answers

8
votes

Can't say when it was fixed, but here's my results:

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options

SQL> SELECT *
  2  FROM USER_TABLES TAB
  3  JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
  4  WHERE STATUS = 'DISABLED';
WHERE STATUS = 'DISABLED'
      *
ERROR at line 4:
ORA-00918: column ambiguously defined

SQL> ed
Wrote file afiedt.buf

  1  SELECT *
  2  FROM USER_TABLES TAB
  3  JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
  4  JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
  5* WHERE STATUS = 'DISABLED'
SQL> /
WHERE STATUS = 'DISABLED'
      *
ERROR at line 5:
ORA-00918: column ambiguously defined
13
votes

Searched Oracle Support and found this:

Bug 5368296 - ANSI join SQL may not report ORA-918 for ambiguous column [ID 5368296.8]

Versions confirmed as being affected:

  • 10.2.0.3
  • 10.2.0.4

This issue is fixed in

  • 10.2.0.4 Patch 2 on Windows Platforms
  • 10.2.0.5 (Server Patch Set)
  • 11.1.0.6 (Base Release)

Not posting more than that since you need an Oracle Support account to view the details, but thought the Oracle Bug number/versions affected would be okay to share to point you in the right direction on Oracle Support.

2
votes

You are using ANSI SQL. I'm guessing that it associates the STATUS in the where clause with the driving table.

When you use "oracle" syntax you'll see the expected behaviour.

SELECT *
FROM USER_TABLES TAB, USER_TRIGGERS TRG, USER_CONSTRAINTS CON
WHERE TRG.TABLE_NAME = TAB.TABLE_NAME
AND CON.TABLE_NAME = TAB.TABLE_NAME
AND STATUS = 'DISABLED'
1
votes

More confirmed bug about this here: http://oracledoug.com/serendipity/index.php?/archives/1555-Bug-Hunting.html

Latest update is that it's fixed in 11.2.0.2

0
votes

Well, if I try this on 11.2.0.2.0, I get the same issue. Regardless of the functionality, if you add in some left and right joins, this bug does not seem to be fixed at all!

SELECT *
FROM USER_TABLES TAB
LEFT JOIN USER_TRIGGERS TRG ON TRG.TABLE_NAME = TAB.TABLE_NAME
RIGHT JOIN USER_CONSTRAINTS CON ON CON.TABLE_NAME = TAB.TABLE_NAME
WHERE STATUS = 'DISABLED'