XXX_COLUMNS System Views
1. Purpose
IvorySQL provides the Oracle data dictionary-compatible system views SYS.USER_CONS_COLUMNS, SYS.ALL_CONS_COLUMNS, SYS.DBA_CONS_COLUMNS, and SYS.ALL_TAB_COLUMNS for querying constraint columns and column metadata for objects accessible to a user.
This document describes the purpose, column definitions, visibility rules, usage, and current compatibility boundaries of all four views.
2. Feature Description
2.1. View Overview
All four views reside in the SYS schema, and SELECT privilege on them is granted to PUBLIC.
| View | Purpose | Current visibility |
|---|---|---|
|
Constraint columns of tables owned by the current user |
Shows only objects whose table owner is |
|
Constraint columns of objects accessible to the current user |
Requires |
|
Constraint columns of ordinary tables in the database |
The current implementation does not filter by the current user; a caller can see all metadata included by the view |
|
Column definitions and partial statistics for objects accessible to the current user |
The current user must have at least one of |
Identifiers are converted by SYS.ORA_CASE_TRANS according to IvorySQL identifier case rules. With the default Oracle-compatible configuration, ordinary unquoted object names are generally displayed in uppercase.
2.2. SYS.USER_CONS_COLUMNS
SYS.USER_CONS_COLUMNS returns the constraints and constraint columns of objects owned by the current user. Each constraint column occupies one row. For a composite constraint, POSITION identifies the order of the column within the constraint.
The view contains the following columns:
| Column | Description |
|---|---|
|
Name of the database role that owns the table |
|
Name of the table containing the constraint |
|
Constraint name |
|
Name of a column participating in the constraint |
|
One-based position of the column in a composite constraint key |
The view reads primary keys, unique constraints, foreign keys, check constraints, and the NOT NULL constraints recorded in the constraint catalog by the current version. Objects in the PG_CATALOG, PG_TOAST, and INFORMATION_SCHEMA schemas are excluded.
For example, query the columns in a composite primary key owned by the current user as follows:
SELECT table_name, constraint_name, column_name, position
FROM sys.user_cons_columns
WHERE table_name = 'ORDERS'
AND constraint_name = 'ORDERS_PK'
ORDER BY position;
2.3. SYS.ALL_CONS_COLUMNS
SYS.ALL_CONS_COLUMNS returns constraint columns for which the current user has both schema access and table query privileges. Its column order is:
OWNER, CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME, POSITION
OWNER is derived from the role that owns the table, not from the schema containing the table. Regular constraints include primary keys, unique constraints, foreign keys, and check constraints.
NOT NULL columns are converted into constraint-column rows by an additional branch. The generated constraint name has the following format:
table_name_column_name_NOT_NULL
If a NOT NULL column already belongs to a primary key, the additional branch does not generate another NOT NULL row for that column, thereby avoiding duplication in that branch.
For example, query constraint columns on an accessible table as follows:
SELECT owner, constraint_name, table_name, column_name, position
FROM sys.all_cons_columns
WHERE table_name = 'ORDERS'
ORDER BY constraint_name, position;
The view includes relevant catalog records for ordinary tables, views, materialized views, and partitioned tables. It excludes objects in the PG_CATALOG, INFORMATION_SCHEMA, and PG_TOAST schemas, as well as dropped columns.
2.4. SYS.DBA_CONS_COLUMNS
SYS.DBA_CONS_COLUMNS provides a database-wide view of constraint columns on ordinary tables. Its column order is the same as that of SYS.ALL_CONS_COLUMNS:
OWNER, CONSTRAINT_NAME, TABLE_NAME, COLUMN_NAME, POSITION
Regular constraint rows come from the system constraint catalog, while NOT NULL rows are additionally generated from column NOT NULL flags. POSITION represents the column order in a composite constraint.
Although this view is named DBA_CONS_COLUMNS, query privilege is granted to PUBLIC, and its definition does not check the current user’s object privileges. It should therefore be treated as a database-wide metadata view rather than as a security boundary restricted to database administrators.
Queries should restrict the result by owner, table name, or constraint name:
SELECT owner, constraint_name, table_name, column_name, position
FROM sys.dba_cons_columns
WHERE table_name = 'ORDERS'
AND constraint_name IN ('ORDERS_PK', 'ORDERS_CUSTOMER_FK')
ORDER BY constraint_name, position;
2.5. SYS.ALL_TAB_COLUMNS
SYS.ALL_TAB_COLUMNS returns columns of objects on which the current user has at least one supported table-level privilege. Supported object types include ordinary tables, views, materialized views, partitioned tables, and foreign tables. Partition children, dropped columns, and objects in system schemas are excluded.
The view contains 34 columns, grouped below by purpose.
2.5.1. Object and Type Information
| Column | Description |
|---|---|
|
Name of the schema containing the object |
|
Name of the table or other supported relation object |
|
Column name |
|
One-based display position of the column in the object |
|
Mapped Oracle-style data type name |
|
Data type modifier information; currently always |
|
Owner of a user-defined type; |
|
Data length calculated from the type and type modifier |
|
Numeric precision |
|
Numeric scale |
|
|
|
Column default obtained by deparsing the system default expression |
Common mappings include integer and NUMERIC types to NUMBER, floating-point types to FLOAT, character types to VARCHAR2 or CHAR, text types to CLOB, binary types to BLOB, and date and timestamp types to DATE and TIMESTAMP.
2.5.2. Statistics
| Column | Description |
|---|---|
|
Number of distinct values; currently always |
|
Statistical range boundaries; currently always |
|
Column value density; currently always |
|
Number of NULL values calculated from |
|
Number of histogram buckets; currently always |
|
Time of the most recent |
|
Statistical sample size; currently always |
|
Currently always |
|
Currently always |
|
Average column width from |
|
Histogram type; currently always |
Fields such as NUM_NULLS and AVG_COL_LEN can have values only after ANALYZE has run and a corresponding row can be found in pg_stats.
2.5.3. Character, Default, and Other Attributes
| Column | Description |
|---|---|
|
|
|
Declared length of a character or RAW column |
|
Character length of a character column |
|
|
|
Currently always |
|
Currently always |
|
Byte length of the default expression |
|
Collation; currently always |
|
|
|
Currently always |
A basic query is shown below:
SELECT owner, table_name, column_name, column_id,
data_type, data_length, data_precision, data_scale,
nullable, data_default
FROM sys.all_tab_columns
WHERE owner = SYS.ORA_CASE_TRANS(CURRENT_SCHEMA::VARCHAR2)
AND table_name = 'ORDERS'
ORDER BY column_id;
2.6. Differences in OWNER Semantics
The OWNER column in the three constraint-column views comes from PG_CLASS.RELOWNER and represents the database role that owns the table. SYS.ALL_TAB_COLUMNS.OWNER comes from PG_NAMESPACE.NSPNAME and represents the schema containing the object.
IvorySQL allows a schema name to differ from the role that owns a table. Consequently, the same object can have different OWNER values in a constraint-column view and in ALL_TAB_COLUMNS. When joining these views, do not rely solely on OWNER and TABLE_NAME; account for the current object naming and privilege model.
2.7. Current Implementation Boundaries
-
The four objects are compatibility views built on PostgreSQL system catalogs, not complete replicas of the Oracle data dictionary.
-
SYS.USER_CONS_COLUMNScurrently contains anOWNERcolumn, and its column order differs from that ofSYS.ALL_CONS_COLUMNSandSYS.DBA_CONS_COLUMNS. -
The NOT NULL branch of
SYS.DBA_CONS_COLUMNScurrently does not exclude system columns. It may generate rows forTABLEOID,XMIN,CMIN,XMAX,CMAX, andCTID; the same user column can also appear both as a catalog constraint and as a generated row. Filter by explicit constraint names or exclude these system columns when necessary. -
SYS.DBA_CONS_COLUMNSis restricted to ordinary tables but currently does not exclude thePG_TOASTschema. Its object scope and schema filters differ from those of the other two constraint-column views. -
SYS.ALL_CONS_COLUMNSuses onlySELECTas its table privilege condition, whereasSYS.ALL_TAB_COLUMNSaccepts multiple table-level privileges. Their visible object sets can therefore differ. -
Several Oracle statistics fields in
SYS.ALL_TAB_COLUMNScurrently contain fixed values orNULL;NUM_NULLSis also an estimate based on PostgreSQL statistics.
3. Test Cases
3.1. Preparing Test Objects
SET ivorysql.compatible_mode = oracle;
CREATE TABLE TEST_XXX_COLUMNS
(
ID INT NOT NULL,
NAME VARCHAR2(30) NOT NULL,
EMAIL VARCHAR2(50),
REQUIRED_NOTE VARCHAR2(20) NOT NULL,
AMOUNT NUMBER(8,2) DEFAULT 0,
CONSTRAINT PK_TEST_XXX_COLUMNS PRIMARY KEY (ID, NAME),
CONSTRAINT UQ_TEST_XXX_COLUMNS UNIQUE (EMAIL),
CONSTRAINT CK_TEST_XXX_COLUMNS CHECK (AMOUNT >= 0)
);
ANALYZE TEST_XXX_COLUMNS;
3.2. Querying USER_CONS_COLUMNS
SELECT table_name, constraint_name, column_name, position
FROM sys.user_cons_columns
WHERE table_name = 'TEST_XXX_COLUMNS'
AND constraint_name IN ('PK_TEST_XXX_COLUMNS', 'UQ_TEST_XXX_COLUMNS')
ORDER BY constraint_name, position;
Expected result:
table_name | constraint_name | column_name | position
------------------+------------------------+-------------+----------
TEST_XXX_COLUMNS | PK_TEST_XXX_COLUMNS | ID | 1
TEST_XXX_COLUMNS | PK_TEST_XXX_COLUMNS | NAME | 2
TEST_XXX_COLUMNS | UQ_TEST_XXX_COLUMNS | EMAIL | 1
3.3. Querying ALL_CONS_COLUMNS and DBA_CONS_COLUMNS
SELECT constraint_name, column_name, position
FROM sys.all_cons_columns
WHERE table_name = 'TEST_XXX_COLUMNS'
AND constraint_name IN ('PK_TEST_XXX_COLUMNS',
'UQ_TEST_XXX_COLUMNS',
'CK_TEST_XXX_COLUMNS')
ORDER BY constraint_name, position;
SELECT constraint_name, column_name, position
FROM sys.dba_cons_columns
WHERE table_name = 'TEST_XXX_COLUMNS'
AND constraint_name IN ('PK_TEST_XXX_COLUMNS',
'UQ_TEST_XXX_COLUMNS',
'CK_TEST_XXX_COLUMNS')
ORDER BY constraint_name, position;
For explicit constraints, both queries return the same constraint columns and positions:
constraint_name | column_name | position
------------------------+-------------+----------
CK_TEST_XXX_COLUMNS | AMOUNT | 1
PK_TEST_XXX_COLUMNS | ID | 1
PK_TEST_XXX_COLUMNS | NAME | 2
UQ_TEST_XXX_COLUMNS | EMAIL | 1
ALL_CONS_COLUMNS also generates a NOT NULL row for REQUIRED_NOTE, which is not part of the primary key. Query it as follows:
SELECT constraint_name, column_name, position
FROM sys.all_cons_columns
WHERE table_name = 'TEST_XXX_COLUMNS'
AND column_name = 'REQUIRED_NOTE';
3.4. Querying ALL_TAB_COLUMNS
SELECT table_name, column_name, column_id, data_type,
data_length, data_precision, data_scale,
nullable, data_default
FROM sys.all_tab_columns
WHERE table_name = 'TEST_XXX_COLUMNS'
AND owner = SYS.ORA_CASE_TRANS(CURRENT_SCHEMA::VARCHAR2)
ORDER BY column_id;
In the result, ID is mapped to NUMBER; NAME, EMAIL, and REQUIRED_NOTE are mapped to VARCHAR2; and AMOUNT has precision 8, scale 2, and a default value of 0.
Clean up the test object after testing:
DROP TABLE TEST_XXX_COLUMNS;