Skip to content

Commit

Permalink
Fix alter sql_parser rule not refresh parser engine and support previ…
Browse files Browse the repository at this point in the history
…ew hint with sqlcommentParseEnabled=false. (apache#26664)

* Fix alter sql_parser rule not refresh parser engine.

* support preview hint with sqlCommentParseEnabled=false
  • Loading branch information
tuichenchuxin authored Jul 3, 2023
1 parent 1a6ab60 commit 437c447
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.shardingsphere.infra.parser.sql;

import com.github.benmanes.caffeine.cache.LoadingCache;
import lombok.Getter;
import org.apache.shardingsphere.infra.parser.cache.SQLStatementCacheBuilder;
import org.apache.shardingsphere.sql.parser.api.CacheOption;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
Expand All @@ -31,9 +32,21 @@ public final class SQLStatementParserEngine {

private final LoadingCache<String, SQLStatement> sqlStatementCache;

@Getter
private final CacheOption sqlStatementCacheOption;

@Getter
private final CacheOption parseTreeCacheOption;

@Getter
private final boolean isParseComment;

public SQLStatementParserEngine(final String databaseType, final CacheOption sqlStatementCacheOption, final CacheOption parseTreeCacheOption, final boolean isParseComment) {
sqlStatementParserExecutor = new SQLStatementParserExecutor(databaseType, parseTreeCacheOption, isParseComment);
sqlStatementCache = SQLStatementCacheBuilder.build(databaseType, sqlStatementCacheOption, parseTreeCacheOption, isParseComment);
this.sqlStatementCacheOption = sqlStatementCacheOption;
this.parseTreeCacheOption = parseTreeCacheOption;
this.isParseComment = isParseComment;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public static SQLStatementParserEngine getSQLStatementParserEngine(final String
SQLStatementParserEngine result = ENGINES.get(databaseType);
if (null == result) {
result = ENGINES.computeIfAbsent(databaseType, key -> new SQLStatementParserEngine(key, sqlStatementCacheOption, parseTreeCacheOption, isParseComment));
} else if (!result.getSqlStatementCacheOption().equals(sqlStatementCacheOption) || !result.getParseTreeCacheOption().equals(parseTreeCacheOption)
|| result.isParseComment() != isParseComment) {
ENGINES.put(databaseType, result = new SQLStatementParserEngine(databaseType, sqlStatementCacheOption, parseTreeCacheOption, isParseComment));
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.infra.parser.sql;

import org.apache.shardingsphere.sql.parser.api.CacheOption;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;

class SQLStatementParserEngineFactoryTest {

@Test
void assertGetSQLStatementParserEngineNotSame() {
SQLStatementParserEngine before = SQLStatementParserEngineFactory.getSQLStatementParserEngine("MySQL", new CacheOption(2000, 65535L), new CacheOption(128, 1024L), false);
SQLStatementParserEngine after = SQLStatementParserEngineFactory.getSQLStatementParserEngine("MySQL", new CacheOption(2000, 65535L), new CacheOption(128, 1024L), true);
assertNotSame(before, after);
}

@Test
void assertGetSQLStatementParserEngineSame() {
SQLStatementParserEngine before = SQLStatementParserEngineFactory.getSQLStatementParserEngine("MySQL", new CacheOption(2000, 65535L), new CacheOption(128, 1024L), false);
SQLStatementParserEngine after = SQLStatementParserEngineFactory.getSQLStatementParserEngine("MySQL", new CacheOption(2000, 65535L), new CacheOption(128, 1024L), false);
assertSame(before, after);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.shardingsphere.sql.parser.api;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

Expand All @@ -25,6 +26,7 @@
*/
@RequiredArgsConstructor
@Getter
@EqualsAndHashCode
public final class CacheOption {

private final int initialCapacity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecutionPrepareEngine;
import org.apache.shardingsphere.infra.executor.sql.prepare.driver.jdbc.JDBCDriverType;
import org.apache.shardingsphere.infra.executor.sql.prepare.driver.jdbc.StatementOption;
import org.apache.shardingsphere.infra.hint.HintValueContext;
import org.apache.shardingsphere.infra.hint.SQLHintUtils;
import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
Expand Down Expand Up @@ -91,9 +93,11 @@ public Collection<LocalDataQueryResultRow> getRows(final ShardingSphereMetaData
String databaseType = DatabaseTypeEngine.getTrunkDatabaseTypeName(metaDataContexts.getMetaData().getDatabase(databaseName).getProtocolType());
ShardingSphereRuleMetaData globalRuleMetaData = metaDataContexts.getMetaData().getGlobalRuleMetaData();
SQLParserRule sqlParserRule = globalRuleMetaData.getSingleRule(SQLParserRule.class);
SQLStatement previewedStatement = sqlParserRule.getSQLParserEngine(databaseType).parse(sqlStatement.getSql(), false);
String sql = sqlParserRule.isSqlCommentParseEnabled() ? sqlStatement.getSql() : SQLHintUtils.removeHint(sqlStatement.getSql());
SQLStatement previewedStatement = sqlParserRule.getSQLParserEngine(databaseType).parse(sql, false);
SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(metaDataContexts.getMetaData(), previewedStatement, databaseName);
QueryContext queryContext = new QueryContext(sqlStatementContext, sqlStatement.getSql(), Collections.emptyList());
HintValueContext hintValueContext = sqlParserRule.isSqlCommentParseEnabled() ? new HintValueContext() : SQLHintUtils.extractHint(sqlStatement.getSql()).orElseGet(HintValueContext::new);
QueryContext queryContext = new QueryContext(sqlStatementContext, sql, Collections.emptyList(), hintValueContext);
connectionSession.setQueryContext(queryContext);
if (sqlStatementContext instanceof CursorAvailable && sqlStatementContext instanceof CursorDefinitionAware) {
setUpCursorDefinition(sqlStatementContext, connectionSession);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
~ 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.
-->

<dataset>
<metadata>
<column name="data_source_name" />
<column name="actual_sql" />
</metadata>
<row values="write_ds_0| SELECT * FROM t_user_item" />
</dataset>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->

<integration-test-cases>
<test-case sql="ALTER SQL_PARSER RULE (SQL_COMMENT_PARSE_ENABLED=false, PARSE_TREE_CACHE(INITIAL_CAPACITY=128, MAXIMUM_SIZE=1024), SQL_STATEMENT_CACHE(INITIAL_CAPACITY=2000, MAXIMUM_SIZE=65535));">
<assertion expected-data-file="preview_sql_hint_comment_parse_enable_false.xml">
<assertion-sql sql="PREVIEW /* SHARDINGSPHERE_HINT: DATA_SOURCE_NAME = write_ds_0, SKIP_SQL_REWRITE = true */ SELECT * FROM t_user_item" />
<destroy-sql sql="ALTER SQL_PARSER RULE (SQL_COMMENT_PARSE_ENABLED=true, PARSE_TREE_CACHE(INITIAL_CAPACITY=128, MAXIMUM_SIZE=1024), SQL_STATEMENT_CACHE(INITIAL_CAPACITY=2000, MAXIMUM_SIZE=65535));" />
</assertion>
</test-case>
</integration-test-cases>

0 comments on commit 437c447

Please sign in to comment.