Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support information_schema.schemata query #12011

Merged
merged 12 commits into from
Aug 26, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public static TextProtocolBackendHandler newInstance(final DatabaseType database
if (sqlStatement instanceof DistSQLStatement) {
return DistSQLBackendHandlerFactory.newInstance(databaseType, (DistSQLStatement) sqlStatement, backendConnection);
}
Optional<TextProtocolBackendHandler> databaseAdminBackendHandler = DatabaseAdminBackendHandlerFactory.newInstance(databaseType, sqlStatement, backendConnection, sql);
if (databaseAdminBackendHandler.isPresent()) {
return databaseAdminBackendHandler.get();
}
SQLStatementContext<?> sqlStatementContext = SQLStatementContextFactory.newInstance(
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaDataMap(), Collections.emptyList(), sqlStatement, backendConnection.getDefaultSchemaName());
// TODO optimize SQLStatementSchemaHolder
Expand All @@ -101,7 +105,7 @@ public static TextProtocolBackendHandler newInstance(final DatabaseType database
if (sqlStatement instanceof CreateDatabaseStatement || sqlStatement instanceof DropDatabaseStatement) {
return DatabaseOperateBackendHandlerFactory.newInstance(sqlStatement, backendConnection);
}
Optional<TextProtocolBackendHandler> databaseAdminBackendHandler = DatabaseAdminBackendHandlerFactory.newInstance(databaseType, sqlStatement, backendConnection);
databaseAdminBackendHandler = DatabaseAdminBackendHandlerFactory.newInstance(databaseType, sqlStatement, backendConnection);
return databaseAdminBackendHandler.orElseGet(() -> DatabaseBackendHandlerFactory.newInstance(sqlStatementContext, sql, backendConnection));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ public final class DatabaseAdminBackendHandlerFactory {
}

/**
* Create new instance of database admin backend handler.
*
* Create new instance of database admin backend handler,
* and this handler requires a connection containing a schema to be used.
*
* @param databaseType database type
* @param sqlStatement SQL statement
* @param backendConnection backend connection
Expand All @@ -55,7 +56,26 @@ public static Optional<TextProtocolBackendHandler> newInstance(final DatabaseTyp
if (!executorFactory.isPresent()) {
return Optional.empty();
}
Optional<DatabaseAdminExecutor> executor = executorFactory.get().newInstance(backendConnection.getSchemaName(), sqlStatement);
Optional<DatabaseAdminExecutor> executor = executorFactory.get().newInstance(sqlStatement);
return executor.map(optional -> createTextProtocolBackendHandler(sqlStatement, backendConnection, optional));
}

/**
* Create new instance of database admin backend handler.
*
* @param databaseType database type
* @param sqlStatement SQL statement
* @param backendConnection backend connection
* @param sql SQL being executed
* @return new instance of database admin backend handler
*/
public static Optional<TextProtocolBackendHandler> newInstance(final DatabaseType databaseType, final SQLStatement sqlStatement,
final BackendConnection backendConnection, final String sql) {
Optional<DatabaseAdminExecutorFactory> executorFactory = TypedSPIRegistry.findRegisteredService(DatabaseAdminExecutorFactory.class, databaseType.getName(), new Properties());
if (!executorFactory.isPresent()) {
return Optional.empty();
}
Optional<DatabaseAdminExecutor> executor = executorFactory.get().newInstance(sqlStatement, sql);
return executor.map(optional -> createTextProtocolBackendHandler(sqlStatement, backendConnection, optional));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.apache.shardingsphere.proxy.backend.text.admin.executor.DatabaseAdminExecutor;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;

import java.sql.SQLException;

/**
* Database admin update backend handler.
*/
Expand All @@ -38,7 +40,7 @@ public final class DatabaseAdminUpdateBackendHandler implements TextProtocolBack
private final DatabaseAdminExecutor executor;

@Override
public ResponseHeader execute() {
public ResponseHeader execute() throws SQLException {
executor.execute(backendConnection);
return new UpdateResponseHeader(sqlStatement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;

import java.sql.SQLException;

/**
* Database admin executor.
*/
Expand All @@ -28,6 +30,7 @@ public interface DatabaseAdminExecutor {
* Execute.
*
* @param backendConnection backend connection
* @throws SQLException SQLException
*/
void execute(BackendConnection backendConnection);
void execute(BackendConnection backendConnection) throws SQLException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,20 @@
public interface DatabaseAdminExecutorFactory extends TypedSPI {

/**
* New instance of database admin executor.
*
* @param currentSchema current schema
* Create an instance of database admin executor,
* and this executor requires a connection containing a schema to be used.
*
* @param sqlStatement SQL statement
* @return instance of database admin executor
*/
Optional<DatabaseAdminExecutor> newInstance(String currentSchema, SQLStatement sqlStatement);
Optional<DatabaseAdminExecutor> newInstance(SQLStatement sqlStatement);

/**
* Create an executor of database admin executor.
*
* @param sqlStatement SQL statement
* @param sql SQL
* @return instance of database admin executor
*/
Optional<DatabaseAdminExecutor> newInstance(SQLStatement sqlStatement, String sql);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,32 @@ public final class MySQLAdminExecutorFactory implements DatabaseAdminExecutorFac
private static final String PERFORMANCE_SCHEMA = "performance_schema";

@Override
public Optional<DatabaseAdminExecutor> newInstance(final String currentSchema, final SQLStatement sqlStatement) {
public Optional<DatabaseAdminExecutor> newInstance(final SQLStatement sqlStatement) {
if (sqlStatement instanceof MySQLShowTablesStatement) {
return Optional.of(new ShowTablesExecutor((MySQLShowTablesStatement) sqlStatement));
}
return Optional.empty();
}

@Override
public Optional<DatabaseAdminExecutor> newInstance(final SQLStatement sqlStatement, final String sql) {
if (sqlStatement instanceof UseStatement) {
return Optional.of(new UseDatabaseExecutor((UseStatement) sqlStatement));
}
if (sqlStatement instanceof MySQLShowDatabasesStatement) {
return Optional.of(new ShowDatabasesExecutor());
}
if (sqlStatement instanceof MySQLShowTablesStatement) {
return Optional.of(new ShowTablesExecutor((MySQLShowTablesStatement) sqlStatement));
}
if (sqlStatement instanceof MySQLShowProcessListStatement) {
return Optional.of(new ShowProcessListExecutor());
}
if (sqlStatement instanceof SelectStatement) {
if (isShowCurrentDatabaseStatement((SelectStatement) sqlStatement)) {
return Optional.of(new ShowCurrentDatabaseExecutor());
}
if (isQueryInformationSchema(currentSchema, (SelectStatement) sqlStatement)) {
// TODO
return Optional.empty();
}
if (isQueryPerformanceSchema(currentSchema, (SelectStatement) sqlStatement)) {
if (isQueryInformationSchema((SelectStatement) sqlStatement)) {
return Optional.of(MySQLInformationSchemaExecutorFactory.newInstance((SelectStatement) sqlStatement, sql));
}
if (isQueryPerformanceSchema((SelectStatement) sqlStatement)) {
// TODO
return Optional.empty();
}
Expand All @@ -81,22 +85,19 @@ private boolean isShowCurrentDatabaseStatement(final SelectStatement sqlStatemen
return firstProjection instanceof ExpressionProjectionSegment && ShowCurrentDatabaseExecutor.FUNCTION_NAME.equalsIgnoreCase(((ExpressionProjectionSegment) firstProjection).getText());
}

private boolean isQueryInformationSchema(final String currentSchema, final SelectStatement sqlStatement) {
return isQuerySpecialSchema(currentSchema, sqlStatement, INFORMATION_SCHEMA);
private boolean isQueryInformationSchema(final SelectStatement sqlStatement) {
return isQuerySpecialSchema(sqlStatement, INFORMATION_SCHEMA);
}

private boolean isQueryPerformanceSchema(final String currentSchema, final SelectStatement sqlStatement) {
return isQuerySpecialSchema(currentSchema, sqlStatement, PERFORMANCE_SCHEMA);
private boolean isQueryPerformanceSchema(final SelectStatement sqlStatement) {
return isQuerySpecialSchema(sqlStatement, PERFORMANCE_SCHEMA);
}

private boolean isQuerySpecialSchema(final String currentSchema, final SelectStatement sqlStatement, final String specialSchemaName) {
private boolean isQuerySpecialSchema(final SelectStatement sqlStatement, final String specialSchemaName) {
TableSegment tableSegment = sqlStatement.getFrom();
if (!(tableSegment instanceof SimpleTableSegment)) {
return false;
}
if (specialSchemaName.equalsIgnoreCase(currentSchema) && !((SimpleTableSegment) tableSegment).getOwner().isPresent()) {
return true;
}
return ((SimpleTableSegment) tableSegment).getOwner().isPresent() && specialSchemaName.equalsIgnoreCase(((SimpleTableSegment) tableSegment).getOwner().get().getIdentifier().getValue());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.proxy.backend.text.admin.mysql;

import org.apache.shardingsphere.proxy.backend.text.admin.executor.DatabaseAdminQueryExecutor;
import org.apache.shardingsphere.proxy.backend.text.admin.mysql.executor.information.SelectSchemataExecutor;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;

/**
* Construct the information schema executor's factory.
*/
public final class MySQLInformationSchemaExecutorFactory {

public static final String SCHEMATA = "schemata";

/**
* Create executor.
*
* @param sqlStatement SQL statement
* @param sql SQL being executed
* @return executor
*/
public static DatabaseAdminQueryExecutor newInstance(final SelectStatement sqlStatement, final String sql) {
String tableName = ((SimpleTableSegment) sqlStatement.getFrom()).getTableName().getIdentifier().getValue();
if (SCHEMATA.equalsIgnoreCase(tableName)) {
return new SelectSchemataExecutor(sqlStatement, sql);
}
throw new UnsupportedOperationException(String.format("unsupported table : `%s`", tableName));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.shardingsphere.proxy.backend.text.admin.mysql.enums;

/**
* Enumeration of the fields in the schemata table of the information schema.
*/
public enum InformationSchemataEnum {

CATALOG_NAME,
lanchengx marked this conversation as resolved.
Show resolved Hide resolved
SCHEMA_NAME,
DEFAULT_CHARACTER_SET_NAME,
DEFAULT_COLLATION_NAME,
SQL_PATH,
DEFAULT_ENCRYPTION;
}
Loading