adutra commented on code in PR #4945:
URL: https://github.com/apache/polaris/pull/4945#discussion_r3588920881


##########
persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/DatasourceOperations.java:
##########
@@ -461,8 +492,45 @@ public boolean isRelationDoesNotExist(SQLException e) {
             && databaseType == DatabaseType.H2);
   }
 
+  /**
+   * Borrows a connection from the datasource and selects the configured 
schema as the session
+   * schema, so that the unqualified table names in generated SQL resolve 
against it. Pooled
+   * connections may be reused across borrowers, so the schema is 
(re-)selected on every borrow.
+   */
   private Connection borrowConnection() throws SQLException {
-    return datasource.getConnection();
+    Connection connection = datasource.getConnection();
+    try (Statement statement = connection.createStatement()) {

Review Comment:
   TBH I am not sure this is the right place to do this.
   
   IMHO the more idiomatic option is to let users define the schema through a 
JDBC configuration property.
   
   Both PostgreSQL and H2 support specifying the schema as a connection 
property/URL param: `currentSchema` for Postgres/CockroachDB, and `SCHEMA` for 
H2 (iirc). 
   
   Users can set this in two ways:
   
   - via `quarkus.datasource.jdbc.url` (by appending the property to the URL)
   - via `quarkus.datasource.jdbc.additional-jdbc-properties.*` (separate 
property)
   
   Besides, the driver would apply it when the _physical_ connection is 
created, so it's set once per physical connection, not re-executed on every 
logical borrow.
   
   The more it goes the more I think that `DatasourceOperations` and related 
classes should become completely agnostic of the schema name.



##########
persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/DatasourceOperations.java:
##########
@@ -461,8 +492,45 @@ public boolean isRelationDoesNotExist(SQLException e) {
             && databaseType == DatabaseType.H2);
   }
 
+  /**
+   * Borrows a connection from the datasource and selects the configured 
schema as the session
+   * schema, so that the unqualified table names in generated SQL resolve 
against it. Pooled
+   * connections may be reused across borrowers, so the schema is 
(re-)selected on every borrow.
+   */
   private Connection borrowConnection() throws SQLException {
-    return datasource.getConnection();
+    Connection connection = datasource.getConnection();
+    try (Statement statement = connection.createStatement()) {
+      // schemaName is validated as a plain SQL identifier in 
resolveSchemaName; identifiers cannot
+      // be bind parameters.
+      statement.execute(selectSessionSchemaStatement());
+      return connection;
+    } catch (SQLException | RuntimeException e) {
+      try {
+        connection.close();
+      } catch (SQLException closeException) {
+        e.addSuppressed(closeException);
+      }
+      throw e;
+    }
+  }
+
+  private String selectSessionSchemaStatement() {
+    return switch (databaseType) {
+      case H2 -> "SET SCHEMA " + schemaName;
+      case POSTGRES, COCKROACHDB -> "SET search_path TO " + schemaName;
+    };
+  }
+
+  /**
+   * Creates the configured schema if it does not exist yet. Uses a raw 
connection instead of {@link
+   * #borrowConnection()}: on some databases (H2) selecting a non-existent 
session schema fails, so
+   * the schema must exist before connections can be borrowed.
+   */
+  private void ensureSchemaExists() throws SQLException {
+    try (Connection connection = datasource.getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE SCHEMA IF NOT EXISTS " + schemaName);

Review Comment:
   Do we absolutely need this feature? I am not convinced that it's the 
application responsibility to create the schema it should be using. This 
statement requires a lot more privileges than the ones the application should 
be normally granted.



##########
persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/RelationalJdbcConfiguration.java:
##########
@@ -35,4 +40,22 @@ public interface RelationalJdbcConfiguration {
    * the JDBC connection metadata. Supported values: "postgresql", 
"cockroachdb", "h2"
    */
   Optional<String> databaseType();
+
+  /**
+   * The database schema (namespace) that holds the Polaris tables. If not 
specified, it defaults to
+   * {@code POLARIS_SCHEMA}. The schema is created during bootstrap if it does 
not already exist,

Review Comment:
   In this case why don't we make this method return `DEFAULT_SCHEMA_NAME`?
   
   For example, you could have here:
   
   ```java
     default String schemaName() {
       return DEFAULT_SCHEMA_NAME;
     }
   ```
   
   And in `QuarkusRelationalJdbcConfiguration`:
   
   ```java
     @Pattern(
         regexp = "[A-Za-z_][A-Za-z0-9_]*",
         message =
             "must start with a letter or underscore and contain only letters, 
digits, and underscores")
     @WithDefault(RelationalJdbcConfiguration.DEFAULT_SCHEMA_NAME)
     @Override
     String schemaName();
   ```
   
   Note: I'm moving the `@Pattern` annotation to 
`QuarkusRelationalJdbcConfiguration` since you mentioned that it won't be 
effective outside of a Quarkus-enabled context.



##########
persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/QueryGenerator.java:
##########
@@ -422,8 +438,7 @@ public static PreparedQuery generateOverlapQuery(
     return new PreparedQuery(query.sql(), where.parameters());
   }
 
-  static String getFullyQualifiedTableName(String tableName) {
-    // TODO: make schema name configurable.
-    return "POLARIS_SCHEMA." + tableName;
+  String getFullyQualifiedTableName(String tableName) {
+    return schemaName + "." + tableName;

Review Comment:
   I think that's reasonable for now, thanks!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to