Skip to content

Add Configurable Schema support for PostreSQL DB.#4566

Merged
sadilchamishka merged 1 commit intowso2:4.12.xfrom
ImalshaD:add_postgre_schema_support_for_shared_db
Apr 3, 2026
Merged

Add Configurable Schema support for PostreSQL DB.#4566
sadilchamishka merged 1 commit intowso2:4.12.xfrom
ImalshaD:add_postgre_schema_support_for_shared_db

Conversation

@ImalshaD
Copy link
Copy Markdown

@ImalshaD ImalshaD commented Apr 3, 2026

Related Issues

In order to configure a non default schema for postgreSQL following config should be added to db configs.

[database.shared_db]
type = "postgresql"
url = <url>
username = <db_user_username>
password = <db_user_password>
driver = <driver>
db_props.postgresSchema = <custom_schema>

See the following example

type = "postgresql"
url = "jdbc:postgresql://localhost:5432/is_db_72_patch"
username = "IS_DB_72_PATCH"
password = "123"
driver = "org.postgresql.Driver"
db_props.postgresSchema = "IS_DB_72_PATCH"

This pull request enhances the HybridRoleManager to better support PostgreSQL databases, particularly when tables are located in a non-default schema. The main changes ensure that the correct schema is used when checking for table existence, improving compatibility in environments with custom PostgreSQL schemas.

PostgreSQL schema support improvements:

  • Added logic in isTableExists to detect when the database is PostgreSQL and override the schema name with a configured value if present, ensuring accurate table existence checks in custom schemas.
  • Introduced the getPostgresSchema method to retrieve the postgresSchema property from the data source configuration, used to determine the correct schema for PostgreSQL.
  • Defined new constants POSTGRE_SQL and POSTGRES_SCHEMA for improved code clarity and maintainability.

Dependency and import updates:

  • Added imports for DataSourceProxy and Properties to support the new schema detection logic. [1] [2]

Copilot AI review requested due to automatic review settings April 3, 2026 08:44
Copy link
Copy Markdown

@wso2-engineering wso2-engineering bot left a comment

Choose a reason for hiding this comment

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

AI Agent Log Improvement Checklist

⚠️ Warning: AI-Generated Review Comments

  • The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
  • Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.

✅ Before merging this pull request:

  • Review all AI-generated comments for accuracy and relevance.
  • Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture it.
Comment Accepted (Y/N) Reason
#### Log Improvement Suggestion No: 1
#### Log Improvement Suggestion No: 2

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Summary by CodeRabbit

Bug Fixes

  • PostgreSQL schema handling: Fixed schema resolution for PostgreSQL databases to ensure proper table detection when using custom schema configurations.

Walkthrough

The change adds PostgreSQL-specific schema handling to the HybridRoleManager. When checking if tables exist, the code now detects PostgreSQL databases and applies a configured postgresSchema value to override the default schema before querying table metadata.

Changes

Cohort / File(s) Summary
PostgreSQL Schema Resolution
core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java
Adds PostgreSQL-specific schema detection and resolution in isTableExists() method. Introduces private getPostgresSchema() method to extract schema configuration from Tomcat DataSourceProxy, along with new constants for PostgreSQL product name identification and property key lookup.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding configurable schema support for PostgreSQL databases, which directly matches the code modifications and PR objectives.
Description check ✅ Passed The description includes purpose (related issue and configuration), goals, approach with code details, and testing context; however, it omits several template sections like automation tests, security checks, documentation, and migrations.

✏️ 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

@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.

🧹 Nitpick comments (3)
core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java (3)

1535-1548: Avoid redundant getDatabaseProductName() calls.

The getDatabaseProductName() is called twice: once at line 1535 (for DB2 check) and again at line 1543 (for PostgreSQL check). Consider caching the result in a local variable to avoid redundant metadata queries.

♻️ Proposed refactor to cache database product name
             if (metaData.storesLowerCaseIdentifiers()) {
                 tableName = tableName.toLowerCase();
             }
-            if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains(DB2)) {
+            String databaseProductName = metaData.getDatabaseProductName();
+            if (databaseProductName != null && databaseProductName.toLowerCase().contains(DB2)) {
                 return connection.getMetaData().getTables(null, null, tableName, new String[]{"TABLE"}).next();
             }
             String schemaName = connection.getSchema();
             String catalogName = connection.getCatalog();

             // For PostgreSQL, use the configured schema if available. This handles cases where tables reside in a
             // non-default schema that differs from the first entry in the database user's search path.
-            if (POSTGRE_SQL.equalsIgnoreCase(connection.getMetaData().getDatabaseProductName())) {
+            if (POSTGRE_SQL.equalsIgnoreCase(databaseProductName)) {
                 String postgresSchema = getPostgresSchema();
                 if (org.apache.commons.lang.StringUtils.isNotBlank(postgresSchema)) {
                     schemaName = postgresSchema.trim();
                 }
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java`
around lines 1535 - 1548, The code in HybridRoleManager repeatedly calls
connection.getMetaData().getDatabaseProductName(); cache this value in a local
variable (e.g., dbProductName) immediately after obtaining the metadata and use
that variable for the DB2 check (contains(DB2)) and the
POSTGRE_SQL.equalsIgnoreCase check; ensure you apply the same case handling used
currently (toLowerCase() for DB2 check or call toLowerCase() on the cached
value) and retain the existing logic that reads and possibly overrides
schemaName using getPostgresSchema().

25-25: Tight coupling to Tomcat JDBC pool.

The import of DataSourceProxy couples this feature specifically to Tomcat's JDBC connection pool. If a different pool implementation is used (e.g., HikariCP), the PostgreSQL schema configuration will silently be ignored. The graceful fallback (return null) prevents failures, but the feature simply won't work with non-Tomcat pools.

Consider documenting this limitation or adding a warning log when the data source is not a DataSourceProxy.

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

In
`@core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java`
at line 25, The code in HybridRoleManager currently assumes a Tomcat
DataSourceProxy, which silently makes Postgres schema config a no-op for other
pools; update the logic that checks the DataSource instance (in
HybridRoleManager) to detect when the datasource is not an instance of
org.apache.tomcat.jdbc.pool.DataSourceProxy and emit a warning via the class
logger describing that only Tomcat's DataSourceProxy is supported and the
Postgres schema configuration will be ignored; also add a short Javadoc or
comment on HybridRoleManager noting this limitation so callers are aware.

1562-1573: Consider adding debug logging for troubleshooting.

When the data source is not a DataSourceProxy or when the postgresSchema property is not configured, the method silently returns null. Adding debug-level logging would help users troubleshoot when the PostgreSQL schema configuration isn't being applied as expected.

🔍 Proposed enhancement with debug logging
     private String getPostgresSchema() {

+        if (log.isDebugEnabled()) {
+            log.debug("Retrieving PostgreSQL schema configuration.");
+        }
         String customSchema = null;
         if (!(dataSource instanceof DataSourceProxy)) {
+            if (log.isDebugEnabled()) {
+                log.debug("DataSource is not an instance of DataSourceProxy. PostgreSQL schema configuration " +
+                        "is only supported with Tomcat JDBC pool.");
+            }
             return null;
         }
         Properties properties = ((DataSourceProxy) dataSource).getDbProperties();
         if (properties != null) {
             customSchema = properties.getProperty(POSTGRES_SCHEMA);
+            if (log.isDebugEnabled() && customSchema != null) {
+                log.debug("Found PostgreSQL schema configuration: " + customSchema);
+            }
         }
         return customSchema;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java`
around lines 1562 - 1573, getPostgresSchema currently returns null silently when
dataSource is not a DataSourceProxy or when POSTGRES_SCHEMA is missing; add
debug logging to both failure paths to aid troubleshooting. In
getPostgresSchema, use the class logger (or create one if missing) to emit debug
messages: one when !(dataSource instanceof DataSourceProxy) indicating the
actual dataSource class and that POSTGRES_SCHEMA lookup was skipped, and another
when properties != null but properties.getProperty(POSTGRES_SCHEMA) is null
indicating the property is not set; keep return behavior unchanged but ensure
messages reference getPostgresSchema, DataSourceProxy, POSTGRES_SCHEMA and
dataSource for context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java`:
- Around line 1535-1548: The code in HybridRoleManager repeatedly calls
connection.getMetaData().getDatabaseProductName(); cache this value in a local
variable (e.g., dbProductName) immediately after obtaining the metadata and use
that variable for the DB2 check (contains(DB2)) and the
POSTGRE_SQL.equalsIgnoreCase check; ensure you apply the same case handling used
currently (toLowerCase() for DB2 check or call toLowerCase() on the cached
value) and retain the existing logic that reads and possibly overrides
schemaName using getPostgresSchema().
- Line 25: The code in HybridRoleManager currently assumes a Tomcat
DataSourceProxy, which silently makes Postgres schema config a no-op for other
pools; update the logic that checks the DataSource instance (in
HybridRoleManager) to detect when the datasource is not an instance of
org.apache.tomcat.jdbc.pool.DataSourceProxy and emit a warning via the class
logger describing that only Tomcat's DataSourceProxy is supported and the
Postgres schema configuration will be ignored; also add a short Javadoc or
comment on HybridRoleManager noting this limitation so callers are aware.
- Around line 1562-1573: getPostgresSchema currently returns null silently when
dataSource is not a DataSourceProxy or when POSTGRES_SCHEMA is missing; add
debug logging to both failure paths to aid troubleshooting. In
getPostgresSchema, use the class logger (or create one if missing) to emit debug
messages: one when !(dataSource instanceof DataSourceProxy) indicating the
actual dataSource class and that POSTGRES_SCHEMA lookup was skipped, and another
when properties != null but properties.getProperty(POSTGRES_SCHEMA) is null
indicating the property is not set; keep return behavior unchanged but ensure
messages reference getPostgresSchema, DataSourceProxy, POSTGRES_SCHEMA and
dataSource for context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: aedc30c0-5f4a-4410-9064-51d681149111

📥 Commits

Reviewing files that changed from the base of the PR and between ba5f6cc and c9cf395.

📒 Files selected for processing (1)
  • core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/hybrid/HybridRoleManager.java

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for checking table existence in a configured (non-default) PostgreSQL schema so HybridRoleManager works correctly when PostgreSQL tables live outside the default search path.

Changes:

  • Updates isTableExists to prefer a configured PostgreSQL schema when the DB product is PostgreSQL.
  • Introduces getPostgresSchema() to read postgresSchema from datasource DB properties.
  • Adds constants for PostgreSQL product name and the postgresSchema property key.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jenkins-is-staging
Copy link
Copy Markdown

PR builder started
Link: https://github.com/wso2/product-is/actions/runs/23940509067

@jenkins-is-staging
Copy link
Copy Markdown

PR builder completed
Link: https://github.com/wso2/product-is/actions/runs/23940509067
Status: success

Copy link
Copy Markdown

@jenkins-is-staging jenkins-is-staging left a comment

Choose a reason for hiding this comment

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

Approving the pull request based on the successful pr build https://github.com/wso2/product-is/actions/runs/23940509067

@sadilchamishka sadilchamishka merged commit f73c2d1 into wso2:4.12.x Apr 3, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants