Skip to content

USER_CONS_COLUMNS#1270

Closed
3296442201 wants to merge 0 commit intoIvorySQL:masterfrom
3296442201:master
Closed

USER_CONS_COLUMNS#1270
3296442201 wants to merge 0 commit intoIvorySQL:masterfrom
3296442201:master

Conversation

@3296442201
Copy link
Copy Markdown

@3296442201 3296442201 commented Mar 20, 2026

## Add Oracle-compatible USER_CONS_COLUMNS view

This PR implements an Oracle-style `USER_CONS_COLUMNS` view for IvorySQL:
- Creates `public.user_cons_columns` to show user-level constraint columns
- Maps PostgreSQL constraint types to Oracle codes (P/U/F/C)
- Maps PostgreSQL data types to Oracle-friendly names (NUMBER/VARCHAR2/DATE etc.)
- Installs via `Makefile` and works without `pg_catalog` permissions

Tested with:
```sql
CREATE TABLE test (id NUMERIC PRIMARY KEY, name VARCHAR(50) UNIQUE);
SELECT * FROM user_cons_columns;

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Oracle compatibility views now install automatically during database initialization.
  * Oracle-style client command support added to the interactive client (parsing and scanning).
  * New system view exposing constraint-to-column mappings for user tables (SYS.USER_CONS_COLUMNS).

* **Chores**
  * Updated Oracle compatibility support modules and added related test cases.

* **Bug Fixes**
  * Installer/uninstaller now include the Oracle compatibility view scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 20, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Installs and runs an Oracle-compat catalog SQL at init, updates an orafce submodule ref, and adds Oracle-compatible psql lexer/parser, keyword data, sysview definitions, and related test updates and logfile.

Changes

Cohort / File(s) Summary
Catalog install & init
src/backend/catalog/Makefile, src/bin/initdb/initdb.c
Install oracle_compat_views.sql into data directory and execute it during post-bootstrap schema setup.
psql Oracle parser & lexer
src/bin/psql/psqlplusparse.c, src/bin/psql/psqlplusparse.h, src/bin/psql/psqlplusscan.c
Add Bison-generated parser, header, and Flex-generated scanner for psqlplus commands; new parser entrypoint, lexer wrapper and lifecycle functions.
Keyword lookup
src/fe_utils/ora_keywords.c, src/fe_utils/ora_kwlist_d.h
Add Oracle keyword reference and generated keyword lookup table (OraScanKeywords) with hash function and data.
Contrib sysview & tests
contrib/ivorysql_ora/src/sysview/sysview--1.0.sql, contrib/ivorysql_ora/sql/ora_sysview.sql, contrib/ivorysql_ora/expected/ora_sysview.out
Add/modify SYS.USER_CONS_COLUMNS view and add a test exercising constraint-to-column mappings; update expected output.
Submodule & logs
orafce, logfile
Update orafce git submodule ref and add runtime logfile capturing startup, errors, and shutdown sequence.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(220,240,255,0.5)
    participant User
    end
    rect rgba(200,255,200,0.5)
    participant psql as psql (frontend)
    participant Scanner as psqlplus_scanner
    participant Parser as psqlplus_yyparse
    end
    rect rgba(255,230,230,0.5)
    participant Backend as Postgres Server
    end

    User->>psql: enter SQLplus-style command
    psql->>Scanner: psqlplus_scanner_init / tokenize input
    Scanner-->>Parser: tokens (yylex)
    Parser->>psql: AST / parse status
    psql->>Backend: execute SQL or pass-through EXEC block
    Backend-->>psql: results
    psql->>User: display output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • bigplaice
  • yuanyl630
  • jiaoshuntian

Poem

🐇 I nibble tokens, hop and parse,
New views planted in init's sparse,
Lexer hums, the parser sings,
Constraints and keywords sprout their wings,
Hooray — the database learns a new dance! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'USER_CONS_COLUMNS' refers to the main feature being added (an Oracle-compatible view), but it is vague and lacks context about the action or change being made. Consider using a more descriptive title like 'Add USER_CONS_COLUMNS Oracle-compatible view' or 'Implement SYS.USER_CONS_COLUMNS for constraint column mappings' to clearly convey the primary change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/backend/catalog/Makefile`:
- Line 60: The install copies oracle_compat_views.sql but initdb never executes
it; update src/bin/initdb/initdb.c to call setup_run_file() for
"oracle_compat_views.sql" just like the existing calls for "system_views.sql"
and "information_schema.sql" so the CREATE OR REPLACE VIEW in
oracle_compat_views.sql is run during database initialization; locate the initdb
function that invokes setup_run_file() for other catalog SQL scripts and add a
matching setup_run_file(...) invocation for oracle_compat_views.sql (same
pattern and error handling as the existing calls).

In `@src/backend/catalog/oracle_compat_views.sql`:
- Around line 39-45: The inner join to information_schema.key_column_usage
(alias kcu) is dropping CHECK constraints; change that JOIN to a LEFT JOIN, add
a second LEFT JOIN to information_schema.constraint_column_usage (alias ccu) to
surface columns for CHECK constraints, and update the column selection (where
the column name is chosen) to use COALESCE(kcu.column_name, ccu.column_name) so
CHECK constraints are preserved while keeping existing PK/FK/UNIQUE behavior
(refer to aliases tc, kcu, ccu and the column selection that currently picks
kcu.column_name).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7e991046-d06a-440d-a707-e2ce203e28a1

📥 Commits

Reviewing files that changed from the base of the PR and between 479acbd and 842c27a.

📒 Files selected for processing (2)
  • src/backend/catalog/Makefile
  • src/backend/catalog/oracle_compat_views.sql

Comment thread src/backend/catalog/Makefile Outdated
Comment on lines +39 to +45
JOIN
information_schema.key_column_usage kcu
ON
tc.constraint_name = kcu.constraint_name
AND tc.table_name = kcu.table_name
AND tc.table_schema = kcu.table_schema
LEFT JOIN
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

f="$(fd information_schema.sql | head -n1)"
echo "Inspecting: $f"

rg -n "CREATE VIEW key_column_usage|contype|CHECK|PRIMARY KEY|FOREIGN KEY|UNIQUE" "$f" -C4
rg -n "CREATE VIEW constraint_column_usage" "$f" -C8

Repository: IvorySQL/IvorySQL

Length of output: 9032


🏁 Script executed:

#!/bin/bash
# Find and inspect oracle_compat_views.sql
fd oracle_compat_views.sql -x wc -l {}
fd oracle_compat_views.sql -x cat -n {} | head -60

Repository: IvorySQL/IvorySQL

Length of output: 2404


CHECK constraints are silently dropped by the inner join to key_column_usage.

Line 19 advertises support for CHECK constraint mapping (constraint_type 'C'), but lines 39–44 use an inner join to information_schema.key_column_usage, which only includes PRIMARY KEY, UNIQUE, and FOREIGN KEY constraints. CHECK constraints in table_constraints have no match in key_column_usage and are eliminated from the result set, breaking the advertised mapping.

To fix: change the join on line 39 from JOIN to LEFT JOIN, add a second LEFT JOIN to information_schema.constraint_column_usage (which does include CHECK constraints), and use COALESCE(kcu.column_name, ccu.column_name) on line 14 to select the appropriate column source.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/backend/catalog/oracle_compat_views.sql` around lines 39 - 45, The inner
join to information_schema.key_column_usage (alias kcu) is dropping CHECK
constraints; change that JOIN to a LEFT JOIN, add a second LEFT JOIN to
information_schema.constraint_column_usage (alias ccu) to surface columns for
CHECK constraints, and update the column selection (where the column name is
chosen) to use COALESCE(kcu.column_name, ccu.column_name) so CHECK constraints
are preserved while keeping existing PK/FK/UNIQUE behavior (refer to aliases tc,
kcu, ccu and the column selection that currently picks kcu.column_name).

@bigplaice
Copy link
Copy Markdown
Collaborator

Thanks for contribution to IvorySQL!
We'll look into it soon.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/bin/initdb/initdb.c`:
- Around line 2067-2068: The call to setup_run_file uses a bare filename
"oracle_compat_views.sql" which fails because readfile() expects a full path;
declare a static char *oracle_compat_views_file (near system_views_file), call
set_input(&oracle_compat_views_file, "oracle_compat_views.sql") in
setup_data_file_paths(), add check_input(oracle_compat_views_file) alongside
other checks, and change the setup_run_file call to setup_run_file(cmdfd,
oracle_compat_views_file); also consider wrapping the load of
oracle_compat_views_file in a conditional based on database_mode == DB_ORACLE to
match other Oracle-specific files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 405dca93-61c8-45db-b980-c8be79cccb7e

📥 Commits

Reviewing files that changed from the base of the PR and between 842c27a and 91e0b82.

📒 Files selected for processing (1)
  • src/bin/initdb/initdb.c

Comment thread src/bin/initdb/initdb.c Outdated
Comment on lines +2067 to +2068
setup_run_file(cmdfd, "oracle_compat_views.sql");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify the pattern used for setting up SQL files in initdb.c

echo "=== Static file variable declarations ==="
rg -n 'static char \*.*_file;' src/bin/initdb/initdb.c

echo ""
echo "=== set_input calls for SQL files ==="
rg -n 'set_input\(&.*file.*\.sql' src/bin/initdb/initdb.c

echo ""
echo "=== check_input calls ==="
rg -n 'check_input\(.*file\)' src/bin/initdb/initdb.c

echo ""
echo "=== setup_run_file calls ==="
rg -n 'setup_run_file\(cmdfd' src/bin/initdb/initdb.c

Repository: IvorySQL/IvorySQL

Length of output: 1607


Critical: Missing file path setup will cause initdb to fail.

The call at line 2067 passes a bare filename "oracle_compat_views.sql" to setup_run_file(), but readfile() expects a full path. All other SQL files in this codebase are set up via set_input() which prepends share_path. Without this, readfile() will fail since it won't find the file.

Add the missing setup:

  1. Declare a static variable (around line 189, after system_views_file):

    static char *oracle_compat_views_file;
  2. In setup_data_file_paths() at line 2950, add after system_views_file:

    set_input(&oracle_compat_views_file, "oracle_compat_views.sql");
  3. In setup_data_file_paths() at line 2982, add after system_views_file:

    check_input(oracle_compat_views_file);
  4. Update line 2067 to use the variable:

    setup_run_file(cmdfd, oracle_compat_views_file);

Additionally, consider whether this Oracle compatibility view should only be loaded when database_mode == DB_ORACLE, consistent with other Oracle-specific files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/bin/initdb/initdb.c` around lines 2067 - 2068, The call to setup_run_file
uses a bare filename "oracle_compat_views.sql" which fails because readfile()
expects a full path; declare a static char *oracle_compat_views_file (near
system_views_file), call set_input(&oracle_compat_views_file,
"oracle_compat_views.sql") in setup_data_file_paths(), add
check_input(oracle_compat_views_file) alongside other checks, and change the
setup_run_file call to setup_run_file(cmdfd, oracle_compat_views_file); also
consider wrapping the load of oracle_compat_views_file in a conditional based on
database_mode == DB_ORACLE to match other Oracle-specific files.

@bigplaice
Copy link
Copy Markdown
Collaborator

Hi,

I don't think src/backend/catalog is a good place to hold the code of system built-in view for Oracle compatibility. Please take a look in the src/contrib/ivorysql_ora/src/sysview directory. You will find all existing views.

I have given similar comment to xiaoyu509(https://github.com/xiaoyu509) in his/her PR #1201

Thanks,
Steven

@@ -0,0 +1,56 @@
/*-------------------------------------------------------------------------
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Since 'user_cons_columns' is Oracle-compatible view, it would be better to implement in contrib/ivorysql_ora/src/sysview/sysview--1.0.sql, following the placement of existing views such as USER_PROCEDURES.
  2. Following the example of views like USER_PROCEDURES, it is recommended to place this view under the sys schema.


CREATE OR REPLACE VIEW public.user_cons_columns AS
SELECT
current_user::varchar(128) AS owner,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle query results are uppercase by default, whereas IvorySQL uses lowercase by default. To maintain consistency with Oracle, IvorySQL provides the case-conversion function ORA_CASE_TRANS. It is recommended to use this function for automatic case conversion to match Oracle's behavior.


CREATE OR REPLACE VIEW public.user_cons_columns AS
SELECT
current_user::varchar(128) AS owner,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the owner column: in IvorySQL, current_user is not necessarily the owner of the constraint. The pg_constraint system catalog does not store a consowner field. However, the owner can be derived from the table that owns the constraint—specifically, from the table's relowner. For example:
SELECT pg_get_userbyid(c.relowner) AS owner FROM pg_constraint pc JOIN pg_class c ON pc.conrelid = c.oid;

@gaoxueyu
Copy link
Copy Markdown
Collaborator

gaoxueyu commented Apr 6, 2026

issue #1010

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/bin/psql/psqlplusparse.c`:
- Around line 2018-2038: get_guc_settings can return NULL on any failure and
callers pass its return to pg_strcasecmp, causing a NULL deref; change
get_guc_settings to always return an allocated string (never NULL) by setting
val = pg_strdup("") on any non-success path and only pg_strdup the real value
when the PGresult is valid and non-null; also ensure you check that res is
non-NULL and still call PQclear(res) and destroyPQExpBuffer(query) before
returning so callers (e.g., sites that call pg_strcasecmp) always receive a
valid empty string instead of NULL.
- Around line 1732-1737: The code copies the EXEC statement body from the wrong
place by using strlen(state->scanbuf), which points to the end of the outer
buffer; instead capture the remainder of the current line via state->scanline.
In the block that creates psqlplus_cmd_execute (make_exec_node / psqlpluscmd),
replace the offset/substring logic that uses strlen(state->scanbuf) with a
direct copy of the rest of the current line (use pg_strdup(state->scanline) or
otherwise copy from state->scanline) so exec->plisqlstmts contains the text
after EXEC/EXECUTE.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9b7ecadf-418f-476d-8dd8-cb2453f90b34

📥 Commits

Reviewing files that changed from the base of the PR and between 91e0b82 and 6f51beb.

📒 Files selected for processing (13)
  • contrib/ivorysql_ora/ivorysql_ora--1.0.sql
  • logfile
  • orafce
  • src/bin/initdb/postgres
  • src/bin/psql/ora_psqlscanslash.c
  • src/bin/psql/psqlplusparse.c
  • src/bin/psql/psqlplusparse.h
  • src/bin/psql/psqlplusscan.c
  • src/fe_utils/ora_keywords.c
  • src/fe_utils/ora_kwlist_d.h
  • src/include/catalog/postgres_oracle.bki
  • src/oracle_fe_utils/ora_psqlscan.c
  • src/test/regress/ora_pg_regress
✅ Files skipped from review due to trivial changes (2)
  • src/fe_utils/ora_keywords.c
  • logfile

Comment thread src/bin/psql/psqlplusparse.c Outdated
Comment thread src/bin/psql/psqlplusparse.c Outdated
@bigplaice
Copy link
Copy Markdown
Collaborator

Hi, please clean up the unnecessary files.
Apparently you did a "git add *" operation in your latest commit.
You can see there are a lot of files that you didn't touch them at all.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contrib/ivorysql_ora/sql/ora_sysview.sql`:
- Around line 86-98: Add more cases around TEST_USER_CONS_COLUMNS to exercise
composite and other constraint types: create additional tables (e.g., TEST_REF
for FK) and alter/create TEST_USER_CONS_COLUMNS with multi-column PRIMARY KEY,
UNIQUE constraint, FOREIGN KEY referencing TEST_REF, and a CHECK constraint so
USER_CONS_COLUMNS returns rows for each constraint type; insert sample rows that
exercise column positions for composite constraints and ensure queries select
OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME plus POSITION/ORDINAL_POSITION
(or equivalent) to validate column ordering; adjust the SELECT to ORDER BY
CONSTRAINT_NAME, POSITION (or COLUMN_NAME position field) and add
assertions/expected outputs for each constraint type; finally ensure proper
cleanup by dropping the created tables and constraints (references:
TEST_USER_CONS_COLUMNS, TEST_REF, USER_CONS_COLUMNS, CONSTRAINT_NAME,
POSITION/ORDINAL_POSITION).

In `@contrib/ivorysql_ora/src/sysview/sysview--1.0.sql`:
- Around line 1196-1216: After creating the SYS.USER_CONS_COLUMNS view, add a
GRANT SELECT on that view to PUBLIC so regular users can read it; locate the
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS block and append a GRANT SELECT ...
TO PUBLIC statement immediately after the view definition (consistent with
neighboring SYS views) to ensure the same access semantics as the other SYS.*
views.
- Around line 1196-1215: The SYS.USER_CONS_COLUMNS view is missing the POSITION
column and a GRANT SELECT to PUBLIC, and its ORDER BY should preserve
multi-column constraint order; update the CREATE OR REPLACE VIEW
SYS.USER_CONS_COLUMNS to include a POSITION expression (derived from the array
index of ATT.ATTNUM within CON.CONKEY), add POSITION to the select-list after
COLUMN_NAME (keeping OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME), change
the trailing ORDER BY to ORDER BY TABLE_NAME, CONSTRAINT_NAME, POSITION, and add
a separate GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC statement after the
view definition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9315fcde-8544-4aff-8f87-96b7e05b7511

📥 Commits

Reviewing files that changed from the base of the PR and between 6f51beb and c7aadfa.

📒 Files selected for processing (3)
  • contrib/ivorysql_ora/expected/ora_sysview.out
  • contrib/ivorysql_ora/sql/ora_sysview.sql
  • contrib/ivorysql_ora/src/sysview/sysview--1.0.sql
✅ Files skipped from review due to trivial changes (1)
  • contrib/ivorysql_ora/expected/ora_sysview.out

Comment on lines +86 to +98
-- USER_CONS_COLUMNS
CREATE TABLE TEST_USER_CONS_COLUMNS (
ID INT PRIMARY KEY,
NAME VARCHAR2(30) NOT NULL
);

SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
FROM SYS.USER_CONS_COLUMNS
WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
ORDER BY CONSTRAINT_NAME, COLUMN_NAME;

-- Clean
DROP TABLE TEST_USER_CONS_COLUMNS; No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Expand USER_CONS_COLUMNS tests for full feature coverage.

This test only exercises single-column PK and NOT NULL. It does not validate composite constraint ordering/position behavior or UNIQUE/FK/CHECK scenarios, so regressions can slip through.

Suggested test expansion
 -- USER_CONS_COLUMNS
 CREATE TABLE TEST_USER_CONS_COLUMNS (
     ID INT PRIMARY KEY,
-    NAME VARCHAR2(30) NOT NULL
+    NAME VARCHAR2(30) NOT NULL,
+    CODE INT,
+    CODE2 INT,
+    CONSTRAINT UQ_TEST_USER_CONS_COLUMNS UNIQUE (CODE, CODE2)
 );
+
+CREATE TABLE TEST_USER_CONS_COLUMNS_REF (
+    RID INT PRIMARY KEY
+);
+
+ALTER TABLE TEST_USER_CONS_COLUMNS
+  ADD CONSTRAINT FK_TEST_USER_CONS_COLUMNS
+  FOREIGN KEY (CODE) REFERENCES TEST_USER_CONS_COLUMNS_REF(RID);
 
 SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
 FROM SYS.USER_CONS_COLUMNS
 WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
 ORDER BY CONSTRAINT_NAME, COLUMN_NAME;
+
+-- Optional if POSITION is added in the view:
+-- SELECT CONSTRAINT_NAME, COLUMN_NAME, POSITION
+-- FROM SYS.USER_CONS_COLUMNS
+-- WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
+-- ORDER BY CONSTRAINT_NAME, POSITION;
 
 -- Clean
 DROP TABLE TEST_USER_CONS_COLUMNS;
+DROP TABLE TEST_USER_CONS_COLUMNS_REF;

As per coding guidelines **/sql/*.sql: Test SQL files. Ensure comprehensive coverage of features.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-- USER_CONS_COLUMNS
CREATE TABLE TEST_USER_CONS_COLUMNS (
ID INT PRIMARY KEY,
NAME VARCHAR2(30) NOT NULL
);
SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
FROM SYS.USER_CONS_COLUMNS
WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
ORDER BY CONSTRAINT_NAME, COLUMN_NAME;
-- Clean
DROP TABLE TEST_USER_CONS_COLUMNS;
-- USER_CONS_COLUMNS
CREATE TABLE TEST_USER_CONS_COLUMNS (
ID INT PRIMARY KEY,
NAME VARCHAR2(30) NOT NULL,
CODE INT,
CODE2 INT,
CONSTRAINT UQ_TEST_USER_CONS_COLUMNS UNIQUE (CODE, CODE2)
);
CREATE TABLE TEST_USER_CONS_COLUMNS_REF (
RID INT PRIMARY KEY
);
ALTER TABLE TEST_USER_CONS_COLUMNS
ADD CONSTRAINT FK_TEST_USER_CONS_COLUMNS
FOREIGN KEY (CODE) REFERENCES TEST_USER_CONS_COLUMNS_REF(RID);
SELECT OWNER, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
FROM SYS.USER_CONS_COLUMNS
WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
ORDER BY CONSTRAINT_NAME, COLUMN_NAME;
-- Optional if POSITION is added in the view:
-- SELECT CONSTRAINT_NAME, COLUMN_NAME, POSITION
-- FROM SYS.USER_CONS_COLUMNS
-- WHERE TABLE_NAME = 'TEST_USER_CONS_COLUMNS'
-- ORDER BY CONSTRAINT_NAME, POSITION;
-- Clean
DROP TABLE TEST_USER_CONS_COLUMNS;
DROP TABLE TEST_USER_CONS_COLUMNS_REF;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contrib/ivorysql_ora/sql/ora_sysview.sql` around lines 86 - 98, Add more
cases around TEST_USER_CONS_COLUMNS to exercise composite and other constraint
types: create additional tables (e.g., TEST_REF for FK) and alter/create
TEST_USER_CONS_COLUMNS with multi-column PRIMARY KEY, UNIQUE constraint, FOREIGN
KEY referencing TEST_REF, and a CHECK constraint so USER_CONS_COLUMNS returns
rows for each constraint type; insert sample rows that exercise column positions
for composite constraints and ensure queries select OWNER, TABLE_NAME,
CONSTRAINT_NAME, COLUMN_NAME plus POSITION/ORDINAL_POSITION (or equivalent) to
validate column ordering; adjust the SELECT to ORDER BY CONSTRAINT_NAME,
POSITION (or COLUMN_NAME position field) and add assertions/expected outputs for
each constraint type; finally ensure proper cleanup by dropping the created
tables and constraints (references: TEST_USER_CONS_COLUMNS, TEST_REF,
USER_CONS_COLUMNS, CONSTRAINT_NAME, POSITION/ORDINAL_POSITION).

Comment on lines +1196 to +1216
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = ANY(CON.CONKEY)
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
; No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Grant read access for the new SYS view.

Unlike neighboring SYS views in this file, SYS.USER_CONS_COLUMNS is not followed by GRANT SELECT ... TO PUBLIC; this can block expected access for regular users.

Proposed fix
 ORDER BY
 	TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
 ;
+
+/* GRANT SELECT PRIVILEGE TO PUBLIC */
+GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = ANY(CON.CONKEY)
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
;
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = ANY(CON.CONKEY)
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
;
/* GRANT SELECT PRIVILEGE TO PUBLIC */
GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contrib/ivorysql_ora/src/sysview/sysview--1.0.sql` around lines 1196 - 1216,
After creating the SYS.USER_CONS_COLUMNS view, add a GRANT SELECT on that view
to PUBLIC so regular users can read it; locate the CREATE OR REPLACE VIEW
SYS.USER_CONS_COLUMNS block and append a GRANT SELECT ... TO PUBLIC statement
immediately after the view definition (consistent with neighboring SYS views) to
ensure the same access semantics as the other SYS.* views.

Comment on lines +1196 to +1215
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = ANY(CON.CONKEY)
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In Oracle Database docs (19c/21c), what are the exact columns exposed by USER_CONS_COLUMNS, and does it include OWNER or POSITION?

💡 Result:

In the Oracle Database 19c and 21c reference docs, USER_CONS_COLUMNS has the same columns as ALL_CONS_COLUMNS. [1], [2]

Columns exposed (19c/21c): [3], [4]

  • OWNER (VARCHAR2(128), NOT NULL)
  • CONSTRAINT_NAME (VARCHAR2(128), NOT NULL)
  • TABLE_NAME (VARCHAR2(128), NOT NULL)
  • COLUMN_NAME (VARCHAR2(4000))
  • POSITION (NUMBER)

So yes, it includes both OWNER and POSITION. [3], [4]

Sources:
[1] https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/USER_CONS_COLUMNS.html
[2] https://docs.oracle.com/en/database/oracle/oracle-database/21/refrn/USER_CONS_COLUMNS.html
[3] https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/ALL_CONS_COLUMNS.html
[4] https://docs.oracle.com/en/database/oracle/oracle-database/21/refrn/ALL_CONS_COLUMNS.html


🏁 Script executed:

# Check the file structure and look for other USER_* views and GRANT patterns
head -100 contrib/ivorysql_ora/src/sysview/sysview--1.0.sql | tail -20
echo "---"
# Find other USER_* views to see if they have GRANT statements
grep -n "CREATE OR REPLACE VIEW SYS.USER_" contrib/ivorysql_ora/src/sysview/sysview--1.0.sql | head -10
echo "---"
# Check if any views have GRANT SELECT statements
grep -n "GRANT SELECT" contrib/ivorysql_ora/src/sysview/sysview--1.0.sql | head -10

Repository: IvorySQL/IvorySQL

Length of output: 1490


🏁 Script executed:

# Look at the context around the USER_CONS_COLUMNS view and nearby views
sed -n '1180,1230p' contrib/ivorysql_ora/src/sysview/sysview--1.0.sql

Repository: IvorySQL/IvorySQL

Length of output: 1383


🏁 Script executed:

# Check for constraints of different types in the repo to understand filtering
grep -n "CON.CONTYPE" contrib/ivorysql_ora/src/sysview/sysview--1.0.sql | head -20

Repository: IvorySQL/IvorySQL

Length of output: 43


Add missing POSITION column and GRANT SELECT statement to SYS.USER_CONS_COLUMNS.

The view is missing the POSITION column (required by Oracle docs for USER_CONS_COLUMNS) and lacks the GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC statement present in other USER_* views. To preserve column order for multi-column constraints, replace ORDER BY COLUMN_NAME with ORDER BY POSITION.

Keep the OWNER column—Oracle Database 19c/21c explicitly includes it in USER_CONS_COLUMNS.

Proposed fix
 CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
 	SELECT
 		SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
 		SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
 		SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
-		SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
+		SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME,
+		K.POSITION::NUMBER AS POSITION
 	FROM
 		PG_CONSTRAINT AS CON
 	JOIN PG_CLASS AS C
 		ON CON.CONRELID = C.OID
+	JOIN LATERAL UNNEST(CON.CONKEY) WITH ORDINALITY AS K(ATTNUM, POSITION)
+		ON TRUE
 	JOIN PG_ATTRIBUTE AS ATT
 		ON ATT.ATTRELID = C.OID
-		AND ATT.ATTNUM = ANY(CON.CONKEY)
+		AND ATT.ATTNUM = K.ATTNUM
 	WHERE
 		C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
 		AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
 		AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
 		AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
 ORDER BY
-	TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
+	TABLE_NAME, CONSTRAINT_NAME, POSITION
 ;
+GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = ANY(CON.CONKEY)
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
SYS.ORA_CASE_TRANS(PG_GET_USERBYID(C.RELOWNER)::VARCHAR2)::VARCHAR2(128) AS OWNER,
SYS.ORA_CASE_TRANS(C.RELNAME::VARCHAR2)::VARCHAR2(128) AS TABLE_NAME,
SYS.ORA_CASE_TRANS(CON.CONNAME::VARCHAR2)::VARCHAR2(128) AS CONSTRAINT_NAME,
SYS.ORA_CASE_TRANS(ATT.ATTNAME::VARCHAR2)::VARCHAR2(128) AS COLUMN_NAME,
K.POSITION::NUMBER AS POSITION
FROM
PG_CONSTRAINT AS CON
JOIN PG_CLASS AS C
ON CON.CONRELID = C.OID
JOIN LATERAL UNNEST(CON.CONKEY) WITH ORDINALITY AS K(ATTNUM, POSITION)
ON TRUE
JOIN PG_ATTRIBUTE AS ATT
ON ATT.ATTRELID = C.OID
AND ATT.ATTNUM = K.ATTNUM
WHERE
C.RELOWNER::REGROLE = CURRENT_USER::REGROLE
AND C.RELNAMESPACE != 'PG_CATALOG'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'PG_TOAST'::REGNAMESPACE::OID
AND C.RELNAMESPACE != 'INFORMATION_SCHEMA'::REGNAMESPACE::OID
ORDER BY
TABLE_NAME, CONSTRAINT_NAME, POSITION
;
GRANT SELECT ON SYS.USER_CONS_COLUMNS TO PUBLIC;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contrib/ivorysql_ora/src/sysview/sysview--1.0.sql` around lines 1196 - 1215,
The SYS.USER_CONS_COLUMNS view is missing the POSITION column and a GRANT SELECT
to PUBLIC, and its ORDER BY should preserve multi-column constraint order;
update the CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS to include a POSITION
expression (derived from the array index of ATT.ATTNUM within CON.CONKEY), add
POSITION to the select-list after COLUMN_NAME (keeping OWNER, TABLE_NAME,
CONSTRAINT_NAME, COLUMN_NAME), change the trailing ORDER BY to ORDER BY
TABLE_NAME, CONSTRAINT_NAME, POSITION, and add a separate GRANT SELECT ON
SYS.USER_CONS_COLUMNS TO PUBLIC statement after the view definition.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contrib/ivorysql_ora/src/sysview/sysview--1.0.sql`:
- Around line 1218-1241: The file mistakenly redefines the constraint metadata
view SYS.USER_CONS_COLUMNS with a table-column metadata query; revert this by
removing or renaming the CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS block so
the original constraint-oriented view (with OWNER, CONSTRAINT_NAME and full
CONSTRAINT_TYPE mapping P/U/F/C derived from constraints, not just pg_index) is
preserved; if the table-column query belongs as a separate catalog object, give
it a distinct view name (not SYS.USER_CONS_COLUMNS) and ensure it does not
shadow OWNER/CONSTRAINT_NAME or overwrite the constraint-type logic that the
real USER_CONS_COLUMNS must provide.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 73359d16-34c4-4e2e-831c-2aebf7e1c5ed

📥 Commits

Reviewing files that changed from the base of the PR and between c7aadfa and c2209bb.

📒 Files selected for processing (1)
  • contrib/ivorysql_ora/src/sysview/sysview--1.0.sql

Comment on lines +1218 to +1241
/* USER_CONS_COLUMNS */
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
c.relname AS TABLE_NAME,
a.attname AS COLUMN_NAME,
a.attnum AS COLUMN_ID,
t.typname AS DATA_TYPE,
a.atttypmod AS DATA_LENGTH,
a.attnotnull AS NULLABLE,
CASE WHEN i.indisprimary THEN 'P' ELSE NULL END AS CONSTRAINT_TYPE,
d.description AS COMMENTS
FROM
pg_class c
JOIN pg_attribute a ON c.oid = a.attrelid
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = i.indkey[0]
LEFT JOIN pg_description d ON c.oid = d.objoid AND a.attnum = d.objsubid
WHERE
c.relowner = (SELECT usesysid FROM pg_user WHERE usename = current_user)
AND c.relkind IN ('r', 'v')
AND a.attnum > 0
AND NOT a.attisdropped
ORDER BY
c.relname, a.attnum; No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove the accidental second USER_CONS_COLUMNS definition.

This block replaces the constraint-column view defined just above with a table-column metadata view. After install, SYS.USER_CONS_COLUMNS no longer exposes OWNER/CONSTRAINT_NAME and only ever derives 'P' from pg_index, so the PR's P/U/F/C mapping and Oracle-compatible shape are lost. If this query belongs to another catalog view, give it a different name; otherwise delete this redefinition.

🧹 Proposed fix
-/* USER_CONS_COLUMNS */
-CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
-SELECT
-    c.relname AS TABLE_NAME,
-    a.attname AS COLUMN_NAME,
-    a.attnum AS COLUMN_ID,
-    t.typname AS DATA_TYPE,
-    a.atttypmod AS DATA_LENGTH,
-    a.attnotnull AS NULLABLE,
-    CASE WHEN i.indisprimary THEN 'P' ELSE NULL END AS CONSTRAINT_TYPE,
-    d.description AS COMMENTS
-FROM
-    pg_class c
-    JOIN pg_attribute a ON c.oid = a.attrelid
-    JOIN pg_type t ON a.atttypid = t.oid
-    LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = i.indkey[0]
-    LEFT JOIN pg_description d ON c.oid = d.objoid AND a.attnum = d.objsubid
-WHERE
-    c.relowner = (SELECT usesysid FROM pg_user WHERE usename = current_user)
-    AND c.relkind IN ('r', 'v')
-    AND a.attnum > 0
-    AND NOT a.attisdropped
-ORDER BY
-    c.relname, a.attnum;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* USER_CONS_COLUMNS */
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS AS
SELECT
c.relname AS TABLE_NAME,
a.attname AS COLUMN_NAME,
a.attnum AS COLUMN_ID,
t.typname AS DATA_TYPE,
a.atttypmod AS DATA_LENGTH,
a.attnotnull AS NULLABLE,
CASE WHEN i.indisprimary THEN 'P' ELSE NULL END AS CONSTRAINT_TYPE,
d.description AS COMMENTS
FROM
pg_class c
JOIN pg_attribute a ON c.oid = a.attrelid
JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_index i ON c.oid = i.indrelid AND a.attnum = i.indkey[0]
LEFT JOIN pg_description d ON c.oid = d.objoid AND a.attnum = d.objsubid
WHERE
c.relowner = (SELECT usesysid FROM pg_user WHERE usename = current_user)
AND c.relkind IN ('r', 'v')
AND a.attnum > 0
AND NOT a.attisdropped
ORDER BY
c.relname, a.attnum;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contrib/ivorysql_ora/src/sysview/sysview--1.0.sql` around lines 1218 - 1241,
The file mistakenly redefines the constraint metadata view SYS.USER_CONS_COLUMNS
with a table-column metadata query; revert this by removing or renaming the
CREATE OR REPLACE VIEW SYS.USER_CONS_COLUMNS block so the original
constraint-oriented view (with OWNER, CONSTRAINT_NAME and full CONSTRAINT_TYPE
mapping P/U/F/C derived from constraints, not just pg_index) is preserved; if
the table-column query belongs as a separate catalog object, give it a distinct
view name (not SYS.USER_CONS_COLUMNS) and ensure it does not shadow
OWNER/CONSTRAINT_NAME or overwrite the constraint-type logic that the real
USER_CONS_COLUMNS must provide.

(5 rows)

-- clean data
DROP FUNCTION IF EXISTS FUNC_WITH_DEFAULT;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you delete these two lines?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants