Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughInstalls 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
src/backend/catalog/Makefilesrc/backend/catalog/oracle_compat_views.sql
| 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 |
There was a problem hiding this comment.
🧩 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" -C8Repository: 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 -60Repository: 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).
|
Thanks for contribution to IvorySQL! |
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
src/bin/initdb/initdb.c
| setup_run_file(cmdfd, "oracle_compat_views.sql"); | ||
|
|
There was a problem hiding this comment.
🧩 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.cRepository: 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:
-
Declare a static variable (around line 189, after
system_views_file):static char *oracle_compat_views_file;
-
In
setup_data_file_paths()at line 2950, add aftersystem_views_file:set_input(&oracle_compat_views_file, "oracle_compat_views.sql");
-
In
setup_data_file_paths()at line 2982, add aftersystem_views_file:check_input(oracle_compat_views_file);
-
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.
|
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, |
| @@ -0,0 +1,56 @@ | |||
| /*------------------------------------------------------------------------- | |||
There was a problem hiding this comment.
- 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.
- 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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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;
|
issue #1010 |
There was a problem hiding this comment.
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
📒 Files selected for processing (13)
contrib/ivorysql_ora/ivorysql_ora--1.0.sqllogfileorafcesrc/bin/initdb/postgressrc/bin/psql/ora_psqlscanslash.csrc/bin/psql/psqlplusparse.csrc/bin/psql/psqlplusparse.hsrc/bin/psql/psqlplusscan.csrc/fe_utils/ora_keywords.csrc/fe_utils/ora_kwlist_d.hsrc/include/catalog/postgres_oracle.bkisrc/oracle_fe_utils/ora_psqlscan.csrc/test/regress/ora_pg_regress
✅ Files skipped from review due to trivial changes (2)
- src/fe_utils/ora_keywords.c
- logfile
|
Hi, please clean up the unnecessary files. |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
contrib/ivorysql_ora/expected/ora_sysview.outcontrib/ivorysql_ora/sql/ora_sysview.sqlcontrib/ivorysql_ora/src/sysview/sysview--1.0.sql
✅ Files skipped from review due to trivial changes (1)
- contrib/ivorysql_ora/expected/ora_sysview.out
| -- 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 |
There was a problem hiding this comment.
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.
| -- 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).
| 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 |
There was a problem hiding this comment.
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.
| 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.
| 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 |
There was a problem hiding this comment.
🧩 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 -10Repository: 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.sqlRepository: 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 -20Repository: 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.
| 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.
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
contrib/ivorysql_ora/src/sysview/sysview--1.0.sql
| /* 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 |
There was a problem hiding this comment.
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.
| /* 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; |
There was a problem hiding this comment.
Why did you delete these two lines?
Uh oh!
There was an error while loading. Please reload this page.