Skip to content

Commit 0f3cf17

Browse files
authored
Support grant statement SQL bind (#36207)
* Support grant statement SQL bind * fix checkstyle * resolve conflict * update release notes * fix: databaseType import in GrantStatementBinderTest
1 parent c6c6193 commit 0f3cf17

File tree

6 files changed

+209
-0
lines changed

6 files changed

+209
-0
lines changed

RELEASE-NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
1. Pipeline: Support multi-columns unique key non-first column nullable - [#37647](https://github.com/apache/shardingsphere/pull/37647)
7575
1. Encrypt: Support handling show create view result decoration in encrypt - [#37299](https://github.com/apache/shardingsphere/pull/37299)
7676
1. JDBC: Enhance ResultSetUtils to support flexible string date/time conversions - [37424](https://github.com/apache/shardingsphere/pull/37424)
77+
1. SQL Binder: Support Grant statement SQL bind - [#36207](https://github.com/apache/shardingsphere/pull/36207)
7778

7879
### Bug Fixes
7980

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shardingsphere.infra.binder.engine.statement.dcl;
19+
20+
import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
21+
import com.google.common.collect.LinkedHashMultimap;
22+
import com.google.common.collect.Multimap;
23+
import org.apache.shardingsphere.infra.binder.engine.segment.dml.from.context.TableSegmentBinderContext;
24+
import org.apache.shardingsphere.infra.binder.engine.segment.dml.from.type.SimpleTableSegmentBinder;
25+
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinder;
26+
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
27+
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementCopyUtils;
28+
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
29+
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.GrantStatement;
30+
31+
import java.util.ArrayList;
32+
import java.util.Collection;
33+
34+
/**
35+
* Grant statement binder.
36+
*/
37+
public final class GrantStatementBinder implements SQLStatementBinder<GrantStatement> {
38+
39+
@Override
40+
public GrantStatement bind(final GrantStatement sqlStatement, final SQLStatementBinderContext binderContext) {
41+
Collection<SimpleTableSegment> tables = sqlStatement.getTables();
42+
if (tables.isEmpty()) {
43+
return sqlStatement;
44+
}
45+
Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts = LinkedHashMultimap.create();
46+
Collection<SimpleTableSegment> boundTables = new ArrayList<>();
47+
for (SimpleTableSegment each : tables) {
48+
boundTables.add(SimpleTableSegmentBinder.bind(each, binderContext, tableBinderContexts));
49+
}
50+
return copyGrantStatement(sqlStatement, boundTables);
51+
}
52+
53+
private GrantStatement copyGrantStatement(final GrantStatement sqlStatement, final Collection<SimpleTableSegment> tables) {
54+
if (tables.equals(sqlStatement.getTables())) {
55+
return sqlStatement;
56+
}
57+
GrantStatement result = new GrantStatement(sqlStatement.getDatabaseType());
58+
result.getTables().addAll(tables);
59+
SQLStatementCopyUtils.copyAttributes(sqlStatement, result);
60+
return result;
61+
}
62+
}

infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/type/DCLStatementBindEngine.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
2121
import org.apache.shardingsphere.infra.binder.engine.statement.dcl.RevokeStatementBinder;
22+
import org.apache.shardingsphere.infra.binder.engine.statement.dcl.GrantStatementBinder;
2223
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.DCLStatement;
2324
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.RevokeStatement;
25+
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.GrantStatement;
2426

2527
/**
2628
* DCL statement bind engine.
@@ -38,6 +40,9 @@ public DCLStatement bind(final DCLStatement statement, final SQLStatementBinderC
3840
if (statement instanceof RevokeStatement) {
3941
return new RevokeStatementBinder().bind((RevokeStatement) statement, binderContext);
4042
}
43+
if (statement instanceof GrantStatement) {
44+
return new GrantStatementBinder().bind((GrantStatement) statement, binderContext);
45+
}
4146
return statement;
4247
}
4348
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.shardingsphere.infra.binder.engine.statement.dcl;
19+
20+
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
21+
import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
22+
import org.apache.shardingsphere.infra.hint.HintValueContext;
23+
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
24+
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
25+
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
26+
import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
27+
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
28+
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
29+
import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
30+
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dcl.GrantStatement;
31+
import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
32+
import org.junit.jupiter.api.Test;
33+
import org.junit.jupiter.api.extension.ExtendWith;
34+
import org.mockito.Mock;
35+
import org.mockito.junit.jupiter.MockitoExtension;
36+
37+
import java.util.Collection;
38+
import java.util.Collections;
39+
40+
import static org.hamcrest.CoreMatchers.is;
41+
import static org.hamcrest.MatcherAssert.assertThat;
42+
import static org.mockito.Mockito.when;
43+
44+
@ExtendWith(MockitoExtension.class)
45+
class GrantStatementBinderTest {
46+
47+
private final DatabaseType databaseType = TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
48+
49+
@Mock
50+
private ShardingSphereMetaData metaData;
51+
52+
@Mock
53+
private ShardingSphereDatabase database;
54+
55+
@Mock
56+
private ShardingSphereSchema schema;
57+
58+
@Mock
59+
private ShardingSphereTable table;
60+
61+
@Test
62+
void assertBind() {
63+
when(metaData.containsDatabase("foo_db")).thenReturn(true);
64+
when(metaData.getDatabase("foo_db")).thenReturn(database);
65+
when(database.containsSchema("foo_db")).thenReturn(true);
66+
when(database.getSchema("foo_db")).thenReturn(schema);
67+
when(schema.containsTable("test_table")).thenReturn(true);
68+
when(schema.getTable("test_table")).thenReturn(table);
69+
when(table.getAllColumns()).thenReturn(Collections.emptyList());
70+
HintValueContext hintValueContext = new HintValueContext();
71+
hintValueContext.setSkipMetadataValidate(true);
72+
SimpleTableSegment tableSegment = new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("test_table")));
73+
GrantStatement original = new GrantStatement(databaseType);
74+
original.getTables().add(tableSegment);
75+
SQLStatementBinderContext binderContext = new SQLStatementBinderContext(metaData, "foo_db", hintValueContext, original);
76+
GrantStatement actual = new GrantStatementBinder().bind(original, binderContext);
77+
Collection<SimpleTableSegment> actualTables = actual.getTables();
78+
assertThat(actualTables.size(), is(1));
79+
assertThat(actualTables.iterator().next().getTableName().getIdentifier().getValue(), is("test_table"));
80+
}
81+
82+
@Test
83+
void assertBindWithEmptyTables() {
84+
GrantStatement original = new GrantStatement(databaseType);
85+
HintValueContext hintValueContext = new HintValueContext();
86+
hintValueContext.setSkipMetadataValidate(true);
87+
SQLStatementBinderContext binderContext = new SQLStatementBinderContext(metaData, "foo_db", hintValueContext, original);
88+
GrantStatement actual = new GrantStatementBinder().bind(original, binderContext);
89+
Collection<SimpleTableSegment> actualTables = actual.getTables();
90+
assertThat(actualTables.size(), is(0));
91+
}
92+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<sql-parser-test-cases>
20+
<grant sql-case-id="grant_select_on_table">
21+
<table name="t_order" start-index="16" stop-index="22">
22+
<table-bound>
23+
<original-database name="foo_db_1" />
24+
<original-schema name="foo_db_1" />
25+
</table-bound>
26+
</table>
27+
</grant>
28+
</sql-parser-test-cases>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<sql-cases>
20+
<sql-case id="grant_select_on_table" value="GRANT SELECT ON t_order TO user1" db-types="MySQL"/>
21+
</sql-cases>

0 commit comments

Comments
 (0)