Skip to content

Commit 42d4670

Browse files
authored
fix: replace partition key representations consistently (#2710)
Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent 01926d1 commit 42d4670

2 files changed

Lines changed: 108 additions & 5 deletions

File tree

‎src/main/java/net/sf/jsqlparser/statement/create/table/TablePartitioning.java‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ public List<Index.ColumnParams> getKeyColumns() {
4343
}
4444

4545
public void setKeyColumns(List<Index.ColumnParams> keyColumns) {
46+
if (keyColumns != null) {
47+
clearKeyRepresentation();
48+
}
4649
this.keyColumns = keyColumns;
47-
expression = null;
48-
expressionList = null;
49-
columns = null;
5050
}
5151

5252
private Type type;
@@ -97,8 +97,10 @@ public Expression getExpression() {
9797
}
9898

9999
public void setExpression(Expression expression) {
100+
if (expression != null) {
101+
clearKeyRepresentation();
102+
}
100103
this.expression = expression;
101-
keyColumns = null;
102104
}
103105

104106
/**
@@ -111,17 +113,29 @@ public ExpressionList<Expression> getExpressionList() {
111113
}
112114

113115
public void setExpressionList(ExpressionList<Expression> expressionList) {
116+
if (expressionList != null) {
117+
clearKeyRepresentation();
118+
}
114119
this.expressionList = expressionList;
115-
keyColumns = null;
116120
}
117121

118122
public ExpressionList<Column> getColumns() {
119123
return columns;
120124
}
121125

122126
public void setColumns(ExpressionList<Column> columns) {
127+
if (columns != null) {
128+
clearKeyRepresentation();
129+
}
123130
this.columns = columns;
131+
}
132+
133+
/** Selecting a key representation must replace the previously rendered key. */
134+
private void clearKeyRepresentation() {
124135
keyColumns = null;
136+
expression = null;
137+
expressionList = null;
138+
columns = null;
125139
}
126140

127141
public Integer getAlgorithm() {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.create;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
import java.util.List;
14+
import net.sf.jsqlparser.JSQLParserException;
15+
import net.sf.jsqlparser.expression.Expression;
16+
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
17+
import net.sf.jsqlparser.parser.AbstractJSqlParser.Dialect;
18+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
19+
import net.sf.jsqlparser.schema.Column;
20+
import net.sf.jsqlparser.statement.create.table.CreateTable;
21+
import net.sf.jsqlparser.statement.create.table.Index;
22+
import net.sf.jsqlparser.statement.create.table.TablePartitioning;
23+
import net.sf.jsqlparser.util.deparser.StatementDeParser;
24+
import org.junit.jupiter.api.Test;
25+
26+
class PartitionKeyMutationTest {
27+
@Test
28+
void replacingSingleKeyWithSeveralKeysChangesBothRenderers() throws JSQLParserException {
29+
CreateTable table = parse("CREATE TABLE t(id INT,other INT) PARTITION BY RANGE(id)",
30+
Dialect.POSTGRESQL);
31+
table.getPartitioning().setExpressionList(
32+
new ExpressionList<Expression>(new Column("other"), new Column("id")));
33+
assertRoundTrip(table,
34+
"CREATE TABLE t (id INT, other INT) PARTITION BY RANGE (other, id)",
35+
Dialect.POSTGRESQL);
36+
assertNull(table.getPartitioning().getExpression());
37+
}
38+
39+
@Test
40+
void switchingHashToKeyUsesNewColumnNames() throws JSQLParserException {
41+
CreateTable table = parse("CREATE TABLE t(id INT,other INT) PARTITION BY HASH(id)",
42+
Dialect.MYSQL);
43+
TablePartitioning partition = table.getPartitioning();
44+
partition.setType(TablePartitioning.Type.KEY);
45+
partition.setColumns(new ExpressionList<>(new Column("other")));
46+
assertRoundTrip(table, "CREATE TABLE t (id INT, other INT) PARTITION BY KEY (other)",
47+
Dialect.MYSQL);
48+
partition.setType(TablePartitioning.Type.HASH);
49+
partition.setExpression(new Column("id"));
50+
assertNull(partition.getColumns());
51+
assertRoundTrip(table, "CREATE TABLE t (id INT, other INT) PARTITION BY HASH (id)",
52+
Dialect.MYSQL);
53+
}
54+
55+
@Test
56+
void attributedKeysReplaceAndAreReplacedByPlainKeys() throws JSQLParserException {
57+
CreateTable table = parse("CREATE TABLE t(id INT,other INT) PARTITION BY RANGE(id,other)",
58+
Dialect.POSTGRESQL);
59+
TablePartitioning partition = table.getPartitioning();
60+
partition.setKeyColumns(
61+
List.of(new Index.ColumnParams("other").withOperatorClass("int4_ops")));
62+
assertNull(partition.getExpressionList());
63+
assertRoundTrip(table,
64+
"CREATE TABLE t (id INT, other INT) PARTITION BY RANGE (other int4_ops)",
65+
Dialect.POSTGRESQL);
66+
partition.setExpression(new Column("id"));
67+
assertNull(partition.getKeyColumns());
68+
assertRoundTrip(table, "CREATE TABLE t (id INT, other INT) PARTITION BY RANGE (id)",
69+
Dialect.POSTGRESQL);
70+
partition.setColumns(null);
71+
partition.setExpressionList(null);
72+
partition.setKeyColumns(null);
73+
assertRoundTrip(table, "CREATE TABLE t (id INT, other INT) PARTITION BY RANGE (id)",
74+
Dialect.POSTGRESQL);
75+
}
76+
77+
private static CreateTable parse(String sql, Dialect dialect) throws JSQLParserException {
78+
return (CreateTable) CCJSqlParserUtil.parse(sql, p -> p.withDialect(dialect));
79+
}
80+
81+
private static void assertRoundTrip(CreateTable table, String expected, Dialect dialect)
82+
throws JSQLParserException {
83+
assertEquals(expected, table.toString());
84+
StringBuilder output = new StringBuilder();
85+
table.accept(new StatementDeParser(output), null);
86+
assertEquals(expected, output.toString());
87+
assertEquals(expected, parse(output.toString(), dialect).toString());
88+
}
89+
}

0 commit comments

Comments
 (0)