-
Notifications
You must be signed in to change notification settings - Fork 6.7k
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
MySQL's ResultSet of SELECT *
is wrong when with Masking Feature
#27879
Comments
Hi @zhaojinchao95 , could you help with this issue? |
SELECT *
is wrong when with Masking Feature
Also, the result is also broken too when add both of masking rules.
|
I debugged 6 cases ([
First of all, ShardingSphere needs to predict result columns sequence correctly.
|
Hi @134130, can you try master branch? We made some optimizations for the asterisk expansion. |
@strongduanmu Hi, thanks for your comment. |
Thanks for testing and look forward to your feedback. |
|
package org.apache.shardingsphere.driver;
import com.zaxxer.hikari.HikariDataSource;
import groovy.lang.Tuple2;
import org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory;
import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.mask.api.config.MaskRuleConfiguration;
import org.apache.shardingsphere.mask.api.config.rule.MaskColumnRuleConfiguration;
import org.apache.shardingsphere.mask.api.config.rule.MaskTableRuleConfiguration;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class CooperTests {
private static List<Tuple2<String, Integer>> getSQLs() {
List<Tuple2<String, Integer>> result = new ArrayList<>();
result.add(new Tuple2<>("SELECT * FROM film_actor JOIN actor AS a ON a.actor_id JOIN film AS f ON f.film_id LIMIT 1", 21));
result.add(new Tuple2<>("SELECT a.first_name, f.title FROM film_actor JOIN actor AS a ON a.actor_id JOIN film AS f ON f.film_id LIMIT 1", 2));
return result;
}
@Test
public void no_mask_test() throws SQLException {
MaskRuleConfiguration maskRule = createMaskRule(Collections.emptyList());
DataSource dataSource = createDataSource(Collections.singleton(maskRule));
for (Tuple2<String, Integer> sql : getSQLs()) {
try (Connection connection = dataSource.getConnection()) {
ResultSet resultSet = connection.createStatement().executeQuery(sql.getV1());
assertThat(resultSet.getMetaData().getColumnCount(), is(sql.getV2()));
printResultSet(resultSet);
}
}
}
@Test
public void first_name_mask_test() throws SQLException {
MaskRuleConfiguration maskRule = createMaskRule(Collections.singleton(createMaskTableRule("actor", "first_name")));
DataSource dataSource = createDataSource(Collections.singleton(maskRule));
for (Tuple2<String, Integer> sql : getSQLs()) {
try (Connection connection = dataSource.getConnection()) {
ResultSet resultSet = connection.createStatement().executeQuery(sql.getV1());
assertThat(resultSet.getMetaData().getColumnCount(), is(sql.getV2()));
}
}
}
@Test
public void first_name_and_title_mask_test() throws SQLException {
MaskRuleConfiguration actorMaskRule = createMaskRule(
Collections.singleton(createMaskTableRule("actor", "first_name")));
MaskRuleConfiguration filmMaskRule = createMaskRule(
Collections.singleton(createMaskTableRule("film", "title")));
Collection<RuleConfiguration> maskRules = Arrays.asList(actorMaskRule, filmMaskRule);
DataSource dataSource = createDataSource(maskRules);
for (Tuple2<String, Integer> sql : getSQLs()) {
try (Connection connection = dataSource.getConnection()) {
ResultSet resultSet = connection.createStatement().executeQuery(sql.getV1());
assertThat(resultSet.getMetaData().getColumnCount(), is(sql.getV2()));
}
}
}
private void printResultSet(ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + ", " + resultSet.getString(2));
System.out.println();
}
System.out.println("==============================");
}
private MaskRuleConfiguration createMaskRule(Collection<MaskTableRuleConfiguration> tableRules) {
Properties props = new Properties();
props.setProperty("first-n", "1");
props.setProperty("last-m", "1");
props.setProperty("replace-char", "*");
AlgorithmConfiguration algorithm = new AlgorithmConfiguration("KEEP_FIRST_N_LAST_M", props);
Map<String, AlgorithmConfiguration> algorithms = Collections.singletonMap(
"default_cooper", algorithm);
return new MaskRuleConfiguration(tableRules, algorithms);
}
private MaskTableRuleConfiguration createMaskTableRule(String table, String column) {
MaskColumnRuleConfiguration columnRule = new MaskColumnRuleConfiguration(column, "default_cooper");
return new MaskTableRuleConfiguration(table, Collections.singleton(columnRule));
}
private DataSource createDataSource(Collection<RuleConfiguration> configs) {
try {
return ShardingSphereDataSourceFactory.createDataSource(
createHikariDataSource(),
configs,
new Properties());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
private HikariDataSource createHikariDataSource() {
HikariDataSource result = new HikariDataSource();
result.setDriverClassName("com.mysql.jdbc.Driver");
result.setJdbcUrl("jdbc:mysql://localhost:3306/sakila?useSSL=false");
result.setUsername("root");
result.setPassword("root");
return result;
}
} Here is my test code what I used. Sorry for I am not used to Java tests. |
Thank you for your feedback, I will check this exception again. |
Hi @134130, I have test this case with 5130950, and it can work now. Besides, I do some change for your test case, since from 5.4.0, ShardingSphere will not load single tables by default. private DataSource createDataSource(Collection<RuleConfiguration> configs) {
try {
Collection<RuleConfiguration> allConfigs = new LinkedList<>(configs);
SingleRuleConfiguration singleRuleConfig = new SingleRuleConfiguration();
singleRuleConfig.setTables(Collections.singletonList("*.*"));
allConfigs.add(singleRuleConfig);
return ShardingSphereDataSourceFactory.createDataSource(
createHikariDataSource(),
allConfigs,
new Properties());
} catch (SQLException e) {
throw new RuntimeException(e);
}
} |
Since this bug has been fixed in master branch 5130950, I will close this issue. |
Bug Report
For English only, other languages will not accept.
Before report a bug, make sure you have:
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.4.0
Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?
ShardingSphere-JDBC with SharingSphere-Mask
Expected behavior
Actual behavior
Reason analyze (If you can)
May MaskingContext pollute MetadataContext
Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.
build.gradle.kts
Prepare MySQL
Run these SQLs
Run this Query with ShardingSphere-Masking
Example codes for reproduce this issue (such as a github link).
The text was updated successfully, but these errors were encountered: