YangGuanQun commented on issue #37997:
URL: 
https://github.com/apache/shardingsphere/issues/37997#issuecomment-3889125066

   Thank you for your comment. @terrymanu 
   
   I have upgraded to the latest release version 5.5.2, and I tried to remove 
schema names from logicTable and actualDataNodes, like this:
   
   ```java
   ShardingTableRuleConfiguration tableRuleConfiguration = new 
ShardingTableRuleConfiguration("t_order", 
"sharding1.t_order,sharding2.t_order");
   ```
   
   When I used the following SQL statement:
   ```SQL
   INSERT INTO base.t_order (id, data_time) VALUES (?, ?::timestamp)
   ```
   
   I encountered the following error:
   ```
   Please check your sharding conditions 
`ShardingConditions(conditions=[ShardingCondition(values=[], startIndex=0)], 
sqlStatementContext=org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext@bfdcc1a,
 rule=org.apache.shardingsphere.sharding.rule.ShardingRule@4acc5dff, 
subqueryContainsShardingCondition=true)` to avoid the same record in table 
`t_order` routing to multiple data nodes
   ```
   
   It seemed that I also had to remove the schema from the SQL statement, so I 
modified the SQL to:
   ```SQL
   INSERT INTO t_order (id, data_time) VALUES (?, ?::timestamp)
   ```
   
   However, I then got this error:
   ```
   Exception in thread "main" 
org.apache.shardingsphere.infra.exception.kernel.metadata.TableNotFoundException:
 Table or view 't_order' does not exist.
        at 
org.apache.shardingsphere.infra.binder.engine.segment.dml.from.type.SimpleTableSegmentBinder.lambda$checkTableExists$12(SimpleTableSegmentBinder.java:178)
        at 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions.checkState(ShardingSpherePreconditions.java:44)
        at 
org.apache.shardingsphere.infra.binder.engine.segment.dml.from.type.SimpleTableSegmentBinder.checkTableExists(SimpleTableSegmentBinder.java:178)
        at 
org.apache.shardingsphere.infra.binder.engine.segment.dml.from.type.SimpleTableSegmentBinder.bind(SimpleTableSegmentBinder.java:90)
        at 
org.apache.shardingsphere.infra.binder.engine.statement.dml.InsertStatementBinder.lambda$bind$1(InsertStatementBinder.java:49)
        at java.util.Optional.ifPresent(Optional.java:159)
        at 
org.apache.shardingsphere.infra.binder.engine.statement.dml.InsertStatementBinder.bind(InsertStatementBinder.java:49)
        at 
org.apache.shardingsphere.infra.binder.engine.type.DMLStatementBindEngine.bind(DMLStatementBindEngine.java:64)
        at 
org.apache.shardingsphere.infra.binder.engine.SQLBindEngine.bindSQLStatement(SQLBindEngine.java:68)
        at 
org.apache.shardingsphere.infra.binder.engine.SQLBindEngine.bind(SQLBindEngine.java:58)
        at 
org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.<init>(ShardingSpherePreparedStatement.java:143)
        at 
org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.<init>(ShardingSpherePreparedStatement.java:115)
        at 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection.prepareStatement(ShardingSphereConnection.java:108)
        at org.example.ShardingSphereTest.main(ShardingSphereTest.java:44)
   ```
   This makes sense because I did not specify a schema anywhere. I searched for 
this issue online, and some documentation states that I need to set the 
`search_path` for the data source connection. So I tried the following 
configuration:
   ```java
   private static DataSource createDruidDataSource(final String dbName) {
        DruidDataSource druidDs = new DruidDataSource();
        druidDs.setDriverClassName("org.postgresql.Driver");
        
druidDs.setUrl(String.format("jdbc:postgresql://localhost:15432/%s?currentSchema=base&characterEncoding=utf8",
 dbName));
        druidDs.setUsername("postgres");
        druidDs.setPassword("xxxxxx");
        druidDs.setConnectionInitSqls(Arrays.asList("SET search_path TO base"));
        return druidDs;
   }
   ```
   But this did not work, and I still encountered the same "table or view does 
not exist" error.
   
   I tried debugging this error and found code in `SimpleTableSegmentBinder` 
that suggests ShardingSphere only uses the default schema 'public':
   ```java
   private static IdentifierValue getSchemaName(final SimpleTableSegment 
segment, final SQLStatementBinderContext binderContext) {
        if (segment.getOwner().isPresent()) {
                return segment.getOwner().get().getIdentifier();
        }
        // TODO getSchemaName according to search path
        DatabaseType databaseType = 
binderContext.getSqlStatement().getDatabaseType();
        if ((databaseType instanceof PostgreSQLDatabaseType || databaseType 
instanceof OpenGaussDatabaseType)
                        && 
SystemSchemaManager.isSystemTable(databaseType.getType(), PG_CATALOG, 
segment.getTableName().getIdentifier().getValue())) {
                return new IdentifierValue(PG_CATALOG);
        }
        return new IdentifierValue(new 
DatabaseTypeRegistry(databaseType).getDefaultSchemaName(binderContext.getCurrentDatabaseName()));
   }
   ```
   It seems that specifying a schema is not supported in PostgreSQL for 
ShardingSphere, or perhaps there is another way to specify the schema that I am 
unaware of.
   
   Actually, I want to use ShardingSphere in an existing project based on 
PostgreSQL. This project uses multiple schemas under a single data source, and 
each SQL statement explicitly specifies a schema. I hope to implement database 
sharding without modifying existing SQL statements and dynamically identify the 
schema for each SQL statement. Can ShardingSphere achieve this?
   
   Please let me know more details. Thank you.


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