xionghao-hw opened a new issue #9024: URL: https://github.com/apache/shardingsphere/issues/9024
## Bug Report **For English only**, other languages will not accept. Before report a bug, make sure you have: - Searched open and closed [GitHub issues](https://github.com/apache/shardingsphere/issues). - Read documentation: [ShardingSphere Doc](https://shardingsphere.apache.org/document/current/en/overview). Please pay attention on issues you submitted, because we maybe need more details. If no response anymore and we cannot reproduce it on current information, we will **close it**. Please answer these questions before submitting your issue. Thanks! ### Which version of ShardingSphere did you use? 5.0.0-alpha ### Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy? ShardingSphere-Proxy ### Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc. Use the vertical sharding solution,different table on defferent database instance, config-sharding.yaml like this: ``` dataSources: ds_0: url: jdbc:postgresql://*****:5432/**** username: **** password: **** connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 minPoolSize: 1 maintenanceIntervalMilliseconds: 30000 #rules: # !SHARDING # tables: ``` not config any sharding rules, expected the proxy can scan all table infomation. And then ,i send a sql like this: ```sql SELECT sub_ports.id AS id, sub_ports.name AS name, sub_ports.admin_state_up AS admin_state_up, sub_ports.status AS status, sub_ports.network_id AS network_id, sub_ports.tenant_id AS tenant_id, sub_ports.tenant_id AS project_id, sub_ports.device_id AS device_id, sub_ports.mac_address AS mac_address, sub_ports.device_owner AS device_owner, qos_port_policy_bindings.policy_id AS qos_policy_id, sub_ports.description AS description, sub_ports.created_at AS created_at, sub_ports.updated_at AS updated_at, ml2_port_bindings.vnic_type AS binding_vnic_type, ml2_port_bindings.vif_details AS binding_vif_details, ml2_port_bindings.profile AS binding_profile, sub_ports.instance_id AS instance_id, sub_ports.instance_type AS instance_type, sub_ports.ecs_flavor AS ecs_flavor FROM ( SELECT ports.id AS id, ports.name AS name, ports.admin_state_up AS admin_state_up, ports.status AS status, ports.network_id AS network_id, ports.tenant_id AS tenant_id, ports.device_id AS device_id, ports.mac_address AS mac_address, ports.device_owner AS device_owner, ports.description AS description, ports.created_at AS created_at, ports.updated_at AS updated_at, ports.instance_id AS instance_id, ports.instance_type AS instance_type, ports.ecs_flavor AS ecs_flavor FROM ports WHERE ports.tenant_id IN('xxxxxxxxxxxxxxxxxx') ORDER BY ports.id ASC LIMIT 2000 ) AS sub_ports LEFT JOIN ml2_port_bindings ON ml2_port_bindings.port_id = sub_ports.id LEFT JOIN qos_port_policy_bindings ON qos_port_policy_bindings.port_id = sub_ports.id LEFT JOIN portsecuritybindings ON portsecuritybindings.port_id = sub_ports.id ORDER BY sub_ports.id ASC ``` Table ports、ml2_port_bindings、qos_port_policy_bindings、portsecuritybindings all in ds_0 I expect this sql can router to ds_0, but not. ### Actual behavior The sharding proxy threw an exception . ``` [ERROR] 15:28:28.331 [pool-4-thread-1] o.a.s.p.f.c.CommandExecutorTask - Exception occur: java.lang.IllegalStateException: Can not find owner from table. at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.find(ProjectionsContextEngine.java:198) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.findShorthandProjection(ProjectionsContextEngine.java:139) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.containsItemWithOwnerInShorthandProjections(ProjectionsContextEngine.java:135) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.containsItemInShorthandProjection(ProjectionsContextEngine.java:121) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.containsProjection(ProjectionsContextEngine.java:105) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.getDerivedOrderColumns(ProjectionsContextEngine.java:96) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.getDerivedOrderByColumns(ProjectionsContextEngine.java:88) at org.apache.shardingsphere.infra.binder.segment.select.projection.engine.ProjectionsContextEngine.createProjectionsContext(ProjectionsContextEngine.java:71) at org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext.<init>(SelectStatementContext.java:89) at org.apache.shardingsphere.infra.binder.SQLStatementContextFactory.getDMLStatementContext(SQLStatementContextFactory.java:113) at org.apache.shardingsphere.infra.binder.SQLStatementContextFactory.newInstance(SQLStatementContextFactory.java:97) at org.apache.shardingsphere.proxy.backend.communication.DatabaseCommunicationEngineFactory.createLogicSQL(DatabaseCommunicationEngineFactory.java:88) at org.apache.shardingsphere.proxy.backend.communication.DatabaseCommunicationEngineFactory.newBinaryProtocolInstance(DatabaseCommunicationEngineFactory.java:80) at org.apache.shardingsphere.proxy.frontend.postgresql.command.query.binary.bind.PostgreSQLComBindExecutor.<init>(PostgreSQLComBindExecutor.java:78) at org.apache.shardingsphere.proxy.frontend.postgresql.command.PostgreSQLCommandExecutorFactory.newInstance(PostgreSQLCommandExecutorFactory.java:62) at org.apache.shardingsphere.proxy.frontend.postgresql.command.PostgreSQLCommandExecuteEngine.getCommandExecutor(PostgreSQLCommandExecuteEngine.java:61) at org.apache.shardingsphere.proxy.frontend.command.CommandExecutorTask.executeCommand(CommandExecutorTask.java:99) at org.apache.shardingsphere.proxy.frontend.command.CommandExecutorTask.run(CommandExecutorTask.java:76) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) ``` ### Reason analyze (If you can) I debuged the code, I found that the alias of the subquery is not processed in ProjectionsContentEngine. The alias of subquery is processed as a normal table name. ```java // tableNameOrAlias = "sub_ports" is not is not included in tables, and then throw Exception private SimpleTableSegment find(final String tableNameOrAlias, final Collection<SimpleTableSegment> tables) { for (SimpleTableSegment each : tables) { if (tableNameOrAlias.equalsIgnoreCase(each.getTableName().getIdentifier().getValue()) || tableNameOrAlias.equals(each.getAlias().orElse(null))) { return each; } } throw new IllegalStateException("Can not find owner from table."); } ``` So I try to modify sql like this: ```sql SELECT * FROM ( SELECT ports.id AS id, ports.name AS name, ports.admin_state_up AS admin_state_up, ports.status AS status, ports.network_id AS network_id, ports.tenant_id AS tenant_id, ports.device_id AS device_id, ports.mac_address AS mac_address, ports.device_owner AS device_owner, ports.description AS description, ports.created_at AS created_at, ports.updated_at AS updated_at, ports.instance_id AS instance_id, ports.instance_type AS instance_type, ports.ecs_flavor AS ecs_flavor FROM ports WHERE ports.tenant_id IN('acea140a0ad54e6f98a8befdc2dab472') ORDER BY ports.id ASC LIMIT 2000 ) AS sub_ports LEFT JOIN ml2_port_bindings ON ml2_port_bindings.port_id = sub_ports.id LEFT JOIN qos_port_policy_bindings ON qos_port_policy_bindings.port_id = sub_ports.id LEFT JOIN portsecuritybindings ON portsecuritybindings.port_id = sub_ports.id ORDER BY sub_ports.id ASC ``` Although it can work, it is not applicable to business scenarios. So i think maybe we can get the subquery alias before this handle projections. ```java public SelectStatementContext(final PhysicalSchemaMetaData schemaMetaData, final List<Object> parameters, final SelectStatement sqlStatement) { super(sqlStatement); tablesContext = new TablesContext(getSimpleTableSegments()); groupByContext = new GroupByContextEngine().createGroupByContext(sqlStatement); orderByContext = new OrderByContextEngine().createOrderBy(sqlStatement, groupByContext); // Get the subquery alias before this handle projections projectionsContext = new ProjectionsContextEngine(schemaMetaData).createProjectionsContext(getSimpleTableSegments(), getSqlStatement().getProjections(), groupByContext, orderByContext); paginationContext = new PaginationContextEngine().createPaginationContext(sqlStatement, projectionsContext, parameters); containsSubquery = containsSubquery(); } ``` ### Example codes for reproduce this issue (such as a github link). None. ---------------------------------------------------------------- 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. For queries about this service, please contact Infrastructure at: [email protected]
