Skip to content

Commit 0d35e65

Browse files
authored
Intercept VtDriver splitTable + setting sequence for each split table. (#135)
1 parent c9e5d17 commit 0d35e65

File tree

4 files changed

+158
-12
lines changed

4 files changed

+158
-12
lines changed

src/main/java/com/jd/jdbc/planbuilder/InsertPlan.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
import com.jd.jdbc.sqltypes.VtPlanValue;
4848
import com.jd.jdbc.tindexes.LogicTable;
4949
import com.jd.jdbc.vindexes.VKeyspace;
50+
import static com.jd.jdbc.vindexes.Vschema.TYPE_PINNED_TABLE;
5051
import io.netty.util.internal.StringUtil;
5152
import java.sql.SQLException;
53+
import java.sql.SQLFeatureNotSupportedException;
5254
import java.util.ArrayList;
5355
import java.util.HashMap;
5456
import java.util.List;
@@ -58,8 +60,6 @@
5860
import lombok.Getter;
5961
import vschema.Vschema;
6062

61-
import static com.jd.jdbc.vindexes.Vschema.TYPE_PINNED_TABLE;
62-
6363
public class InsertPlan {
6464
public static PrimitiveEngine newBuildInsertPlan(MySqlInsertReplaceStatement stmt, VSchemaManager vm, String defaultKeyspace) throws SQLException {
6565
PrimitiveBuilder pb = new PrimitiveBuilder(vm, defaultKeyspace, Jointab.newJointab(SqlParser.getBindVars(stmt)));
@@ -333,7 +333,7 @@ private static PrimitiveEngine buildPartitionTableInsetPlan(MySqlInsertReplaceSt
333333
List<SQLExpr> duplicateKeyUpdateExprList = stmt.getDuplicateKeyUpdate();
334334
if (duplicateKeyUpdateExprList != null && !duplicateKeyUpdateExprList.isEmpty()) {
335335
if (isTindexChangine(duplicateKeyUpdateExprList, insertEngine.getTable())) {
336-
throw new SQLException("unsupported: DML cannot change tindex column");
336+
throw new SQLFeatureNotSupportedException("unsupported: DML cannot change tindex column");
337337
}
338338
insertEngine.setInsertOpcode(Engine.InsertOpcode.InsertShardedIgnore);
339339
}
@@ -343,10 +343,10 @@ private static PrimitiveEngine buildPartitionTableInsetPlan(MySqlInsertReplaceSt
343343

344344
List<SQLInsertStatement.ValuesClause> valuesList = stmt.getValuesList();
345345
if (stmt.getSelectQuery().getSubQuery() != null) {
346-
throw new SQLException("unsupported: insert into select");
346+
throw new SQLFeatureNotSupportedException("unsupported: insert into select");
347347
} else if (valuesList != null && !valuesList.isEmpty()) {
348348
if (valuesHasQuery(valuesList)) {
349-
throw new SQLException("unsupported: subquery in insert values");
349+
throw new SQLFeatureNotSupportedException("unsupported: subquery in insert values");
350350
}
351351
} else {
352352
throw new SQLException("BUG: unexpected construct in insert: " + valuesList);
@@ -392,9 +392,16 @@ private static PrimitiveEngine buildPartitionTableInsetPlan(MySqlInsertReplaceSt
392392
insertEngine.setInsertReplaceStmt(stmt);
393393

394394
MySqlInsertReplaceStatement stmtClone = (MySqlInsertReplaceStatement) stmt.clone();
395-
SwitchTableVisitor visitor = new SwitchTableVisitor(new HashMap<String, String>() {{
396-
put(ltb.getLogicTable(), ltb.getFirstActualTableName());
397-
}});
395+
Map<String, String> map = new HashMap<>();
396+
map.put(ltb.getLogicTable(), ltb.getFirstActualTableName());
397+
SwitchTableVisitor visitor = new SwitchTableVisitor(map);
398+
399+
// check use seq for each table on split table
400+
Vschema.Table table = vm.getTable(defaultKeyspace, ltb.getFirstActualTableName());
401+
if (table != null && table.hasAutoIncrement()) {
402+
throw new SQLFeatureNotSupportedException("Unsupported to use seq for each table on split table");
403+
}
404+
398405
stmtClone.accept(visitor);
399406
InsertEngine innerInsertEigine = (InsertEngine) newBuildInsertPlan(stmtClone, vm, defaultKeyspace);
400407

src/test/java/com/jd/jdbc/table/engine/TableSequenceTest.java

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@
1818

1919
import com.jd.jdbc.table.TableTestUtil;
2020
import java.sql.Connection;
21+
import java.sql.PreparedStatement;
2122
import java.sql.ResultSet;
2223
import java.sql.SQLException;
24+
import java.sql.SQLFeatureNotSupportedException;
2325
import java.sql.Statement;
26+
import java.util.ArrayList;
27+
import java.util.List;
28+
import lombok.AllArgsConstructor;
29+
import lombok.ToString;
2430
import org.junit.After;
2531
import org.junit.Assert;
2632
import org.junit.Before;
@@ -56,8 +62,7 @@ public void close() throws SQLException {
5662
if (stmt2 != null) {
5763
stmt2.close();
5864
}
59-
closeConnection(conn);
60-
closeConnection(conn2);
65+
closeConnection(conn, conn2);
6166
TableTestUtil.setDefaultTableConfig();
6267
}
6368

@@ -75,6 +80,88 @@ public void testSequenceAsTindex() throws SQLException {
7580
testSequence(stmt2);
7681
}
7782

83+
@Ignore
84+
@Test
85+
public void testEachTableSequence() {
86+
List<TestCase> testCaseList = new ArrayList<>();
87+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (null, '11')", null));
88+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (null, ?)", 22));
89+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (101, '11')", null));
90+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (101, ?)", 22));
91+
testCaseList.add(new TestCase("insert into table_seq_test (f_key, f_tinyint) values ('22' , 1)", null));
92+
testCaseList.add(new TestCase("insert into table_seq_test (f_key, f_tinyint) values ('22' , ?)", 55));
93+
94+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (null, '11')", null));
95+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (null, ?)", 22));
96+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (101, '11')", null));
97+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (101, ?)", 22));
98+
testCaseList.add(new TestCase("insert into table_split_seq_test (f_key, f_tinyint) values ('22' , 1)", null));
99+
testCaseList.add(new TestCase("insert into table_split_seq_test (f_key, f_tinyint) values ('22' , ?)", 55));
100+
101+
TableTestUtil.setSplitTableConfig("engine/tableengine/split-table-seq.yml");
102+
for (TestCase testCase : testCaseList) {
103+
try {
104+
if (testCase.var != null) {
105+
PreparedStatement prepareStatement = conn2.prepareStatement(testCase.sql);
106+
prepareStatement.setInt(1, testCase.var);
107+
prepareStatement.execute();
108+
} else {
109+
Statement statement = conn2.createStatement();
110+
statement.execute(testCase.sql);
111+
}
112+
} catch (SQLException e) {
113+
if (e instanceof SQLFeatureNotSupportedException && e.getMessage().equals("Unsupported to use seq for each table on split table")) {
114+
printOk(testCase.toString());
115+
} else {
116+
Assert.fail();
117+
}
118+
}
119+
}
120+
}
121+
122+
@Test
123+
public void testEachTableSequenceAsTindex() {
124+
List<TestCase> testCaseList = new ArrayList<>();
125+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (null, '11')", null));
126+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (null, ?)", 22));
127+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (101, '11')", null));
128+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key) values (101, ?)", 22));
129+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key, f_tinyint) values (null, '22', 1)", null));
130+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key, f_tinyint) values (null, '22', ?)", 55));
131+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key, f_tinyint) values (101, '22', 1)", null));
132+
testCaseList.add(new TestCase("insert into table_seq_test (id, f_key, f_tinyint) values (101, '22', ?)", 55));
133+
134+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (null, '11')", null));
135+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (null, ?)", 22));
136+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (101, '11')", null));
137+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key) values (101, ?)", 22));
138+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key, f_tinyint) values (null, '22', 1)", null));
139+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key, f_tinyint) values (null, '22', ?)", 55));
140+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key, f_tinyint) values (101, '22', 1)", null));
141+
testCaseList.add(new TestCase("insert into table_split_seq_test (id, f_key, f_tinyint) values (101, '22', ?)", 55));
142+
143+
TableTestUtil.setSplitTableConfig("engine/tableengine/split-table-seq-tindex.yml");
144+
for (TestCase testCase : testCaseList) {
145+
try {
146+
if (testCase.var != null) {
147+
PreparedStatement prepareStatement = conn2.prepareStatement(testCase.sql);
148+
prepareStatement.setInt(1, testCase.var);
149+
prepareStatement.execute();
150+
} else {
151+
Statement statement = conn2.createStatement();
152+
statement.execute(testCase.sql);
153+
}
154+
} catch (SQLException e) {
155+
if (e instanceof SQLFeatureNotSupportedException && e.getMessage().equals("Unsupported to use seq for each table on split table")) {
156+
printOk(testCase.toString());
157+
} else {
158+
e.printStackTrace();
159+
Assert.fail();
160+
}
161+
}
162+
}
163+
}
164+
78165
private void testSequence(Statement stmt) throws SQLException {
79166
int num = 120;
80167
stmt.executeUpdate("delete from table_engine_test");
@@ -94,19 +181,27 @@ private void testSequence(Statement stmt) throws SQLException {
94181
checkByCount(stmt, num, "table_engine_test");
95182
}
96183

97-
public void checkByCountDistinct(Statement stmt, final int expected, String tableName, String column) throws SQLException {
184+
private void checkByCountDistinct(Statement stmt, final int expected, String tableName, String column) throws SQLException {
98185
ResultSet resultSet = stmt.executeQuery("select count(distinct(" + column + ")) from " + tableName);
99186
Assert.assertTrue(resultSet.next());
100187
int actual = resultSet.getInt(1);
101188
Assert.assertEquals(printFail("[FAIL]"), expected, actual);
102189
Assert.assertFalse(resultSet.next());
103190
}
104191

105-
public void checkByCount(Statement stmt, final int expected, String tableName) throws SQLException {
192+
private void checkByCount(Statement stmt, final int expected, String tableName) throws SQLException {
106193
ResultSet resultSet = stmt.executeQuery("select count(*) from " + tableName);
107194
Assert.assertTrue(resultSet.next());
108195
int actual = resultSet.getInt(1);
109196
Assert.assertEquals(printFail("[FAIL]"), expected, actual);
110197
Assert.assertFalse(resultSet.next());
111198
}
199+
200+
@AllArgsConstructor
201+
@ToString
202+
class TestCase {
203+
private String sql;
204+
205+
private Integer var;
206+
}
112207
}

src/test/resources/engine/tableengine/split-table-seq-tindex.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ schemas:
88
shardingColumnName: id,
99
shardingColumnType: INT64,
1010
sequenceColumnName: id }
11+
- { actualTableExprs: 'table_seq_test_${1..2}',
12+
logicTable: table_seq_test,
13+
shardingAlgorithms: ShardTableByMurmur,
14+
shardingColumnName: id,
15+
shardingColumnType: INT64 }
16+
- { actualTableExprs: 'table_split_seq_test_${1..2}',
17+
logicTable: table_split_seq_test,
18+
shardingAlgorithms: ShardTableByMurmur,
19+
shardingColumnName: id,
20+
shardingColumnType: INT64,
21+
sequenceColumnName: id }
1122

1223
- schema: customer
1324
logicTables:
@@ -16,4 +27,15 @@ schemas:
1627
shardingAlgorithms: ShardTableByMurmur,
1728
shardingColumnName: id,
1829
shardingColumnType: INT64,
30+
sequenceColumnName: id }
31+
- { actualTableExprs: 'table_seq_test_${1..2}',
32+
logicTable: table_seq_test,
33+
shardingAlgorithms: ShardTableByMurmur,
34+
shardingColumnName: id,
35+
shardingColumnType: INT64 }
36+
- { actualTableExprs: 'table_split_seq_test_${1..2}',
37+
logicTable: table_split_seq_test,
38+
shardingAlgorithms: ShardTableByMurmur,
39+
shardingColumnName: id,
40+
shardingColumnType: INT64,
1941
sequenceColumnName: id }

src/test/resources/engine/tableengine/split-table-seq.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ schemas:
88
shardingColumnName: f_key,
99
shardingColumnType: INT32,
1010
sequenceColumnName: id }
11+
- { actualTableExprs: 'table_seq_test_${1..2}',
12+
logicTable: table_seq_test,
13+
shardingAlgorithms: TableRuleMod,
14+
shardingColumnName: f_key,
15+
shardingColumnType: INT32 }
16+
- { actualTableExprs: 'table_split_seq_test_${1..2}',
17+
logicTable: table_split_seq_test,
18+
shardingAlgorithms: TableRuleMod,
19+
shardingColumnName: f_key,
20+
shardingColumnType: INT32,
21+
sequenceColumnName: id }
1122

1223
- schema: customer
1324
logicTables:
@@ -16,4 +27,15 @@ schemas:
1627
shardingAlgorithms: TableRuleMod,
1728
shardingColumnName: f_key,
1829
shardingColumnType: INT32,
30+
sequenceColumnName: id }
31+
- { actualTableExprs: 'table_seq_test_${1..2}',
32+
logicTable: table_seq_test,
33+
shardingAlgorithms: TableRuleMod,
34+
shardingColumnName: f_key,
35+
shardingColumnType: INT32 }
36+
- { actualTableExprs: 'table_split_seq_test_${1..2}',
37+
logicTable: table_split_seq_test,
38+
shardingAlgorithms: TableRuleMod,
39+
shardingColumnName: f_key,
40+
shardingColumnType: INT32,
1941
sequenceColumnName: id }

0 commit comments

Comments
 (0)