public final class OraclePseudoColumnUtil extends Object
Every caller that either publishes a classification
(TCustomSqlStatement.linkColumnReferenceToTable) or answers a lookup
(TObjectName.isValidColumnName, resolver2.ScopeBuilder) must
go through this class. Keeping two hand-synchronised copies of the list is
what let NEXTVAL and CURRVAL drift apart in Mantis #4675: the
lookup path knew about NEXTVAL and the publish path did not, so the
two answered differently for the same expression.
Oracle documents 18 pseudocolumns, but only some of those names are
reserved words. A name that is not reserved is a perfectly legal
column name, and several are common ones: OBJECT_ID is a real column
of ALL_OBJECTS and DBA_OBJECTS. Classifying such a name as a
pseudocolumn on sight would delete correct lineage for
SELECT OBJECT_ID FROM ALL_OBJECTS while producing no error anywhere -
exactly the silent false negative the project forbids.
So a name is only treated as a pseudocolumn when that is provable from the statement itself:
isReservedPseudoColumn(java.lang.String) - the name is an Oracle reserved word,
so an unquoted occurrence can never be a column. Always safe.isConnectByPseudoColumn(java.lang.String) - only meaningful under a
CONNECT BY; the caller supplies that fact.isSequencePseudoColumn(java.lang.String) - only meaningful when qualified by
something that is not a table or alias in scope.Names that are neither reserved nor context-provable (ORA_ROWSCN,
OBJECT_ID, OBJECT_VALUE, XMLDATA,
COLUMN_VALUE) are deliberately absent. Without catalog metadata there
is no way to tell them from a real column of the same name, and guessing in
either direction is a defect.
| Modifier and Type | Method and Description |
|---|---|
static boolean |
isConnectByPseudoColumn(String nameOnly)
True when
nameOnly is a hierarchical-query pseudocolumn
(CONNECT_BY_ISLEAF, CONNECT_BY_ISCYCLE). |
static boolean |
isDetachedReservedPseudoColumn(String nameOnly)
True for a reserved-word pseudocolumn that belongs to the query rather
than to a table (
ROWNUM, LEVEL). |
static boolean |
isReservedPseudoColumn(String nameOnly)
True when
nameOnly is a pseudocolumn whose name is an Oracle
reserved word, and therefore never a legal unquoted column name. |
static boolean |
isSequencePseudoColumn(String nameOnly)
True when
nameOnly is a sequence pseudocolumn
(NEXTVAL, CURRVAL). |
static boolean |
isTableScopedPseudoColumn(String nameOnly)
True for a reserved-word pseudocolumn that belongs to one specific table
(
ROWID). |
static boolean |
isVersionsPseudoColumn(String nameOnly)
True when
nameOnly is a flashback version query pseudocolumn
(VERSIONS_STARTSCN and friends). |
public static boolean isReservedPseudoColumn(String nameOnly)
nameOnly is a pseudocolumn whose name is an Oracle
reserved word, and therefore never a legal unquoted column name.
The caller is responsible for checking that the identifier was not
quoted: "ROWID" is a distinct, legal, case-sensitive column
name.
nameOnly - the single unqualified name segment, without quotespublic static boolean isDetachedReservedPseudoColumn(String nameOnly)
ROWNUM, LEVEL). These carry no table
attribution at all.nameOnly - the single unqualified name segment, without quotespublic static boolean isTableScopedPseudoColumn(String nameOnly)
ROWID).
These keep getSourceTable() and their entry in the table's
linked columns - a ROWID really did come from that table, and
dropping the attribution would lose information lineage consumers use.
What changes is the reported EDbObjectType:
notAColumn rather than column, so nothing tries to
resolve the name against a catalog that will never contain it.
nameOnly - the single unqualified name segment, without quotespublic static boolean isConnectByPseudoColumn(String nameOnly)
nameOnly is a hierarchical-query pseudocolumn
(CONNECT_BY_ISLEAF, CONNECT_BY_ISCYCLE).
Callers must additionally establish that the enclosing query has a
CONNECT BY clause; without one the same name is an ordinary
identifier and may well be a real column.
nameOnly - the single unqualified name segment, without quotespublic static boolean isSequencePseudoColumn(String nameOnly)
nameOnly is a sequence pseudocolumn
(NEXTVAL, CURRVAL).
Callers must additionally establish that the qualifier is a sequence
rather than a table or alias in scope; x.CURRVAL where x
is a table alias is a reference to a column named CURRVAL.
nameOnly - the single unqualified name segment, without quotespublic static boolean isVersionsPseudoColumn(String nameOnly)
nameOnly is a flashback version query pseudocolumn
(VERSIONS_STARTSCN and friends).
Callers must additionally establish that the FROM clause carries a
VERSIONS BETWEEN clause.
nameOnly - the single unqualified name segment, without quotes