Skip to content

Commit 182d320

Browse files
committed
fix: traverse and deparse structured table partitions
1 parent c9645d7 commit 182d320

7 files changed

Lines changed: 250 additions & 18 deletions

File tree

src/main/java/net/sf/jsqlparser/statement/alter/AlterExpressionPartition.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.util.Collections;
1515
import java.util.List;
1616
import java.util.Optional;
17+
import java.util.function.Consumer;
18+
import net.sf.jsqlparser.expression.Expression;
1719
import net.sf.jsqlparser.schema.Table;
1820
import net.sf.jsqlparser.statement.create.table.PartitionBound;
1921
import net.sf.jsqlparser.statement.create.table.PartitionDefinition;
@@ -292,6 +294,15 @@ public AlterExpressionPartition addPartitionDefinitions(
292294

293295
@Override
294296
protected void appendBody(StringBuilder b) {
297+
appendBody(b, b::append);
298+
}
299+
300+
public void appendTo(StringBuilder b, Consumer<Expression> expressionPrinter) {
301+
appendBody(b, expressionPrinter);
302+
appendCommonTail(b);
303+
}
304+
305+
private void appendBody(StringBuilder b, Consumer<Expression> expressionPrinter) {
295306
switch (getOperation()) {
296307
case ADD_PARTITION:
297308
b.append("ADD PARTITION ")
@@ -302,8 +313,12 @@ protected void appendBody(StringBuilder b) {
302313
.append(PlainSelect.getStringList(getPartitionNames()));
303314
break;
304315
case ATTACH_PARTITION:
305-
b.append("ATTACH PARTITION ").append(partitionTable).append(" ")
306-
.append(partitionBound);
316+
b.append("ATTACH PARTITION ").append(partitionTable).append(' ');
317+
if (partitionBound == null) {
318+
b.append("null");
319+
} else {
320+
partitionBound.appendTo(b, expressionPrinter);
321+
}
307322
break;
308323
case DETACH_PARTITION:
309324
b.append("DETACH PARTITION ").append(partitionTable);
@@ -313,7 +328,7 @@ protected void appendBody(StringBuilder b) {
313328
break;
314329
case PARTITION_BY:
315330
if (partitioning != null) {
316-
b.append(partitioning);
331+
partitioning.appendTo(b, expressionPrinter);
317332
} else {
318333
toStringPartition(b);
319334
}

src/main/java/net/sf/jsqlparser/statement/create/table/PartitionBound.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package net.sf.jsqlparser.statement.create.table;
1111

1212
import java.io.Serializable;
13+
import java.util.function.Consumer;
1314
import net.sf.jsqlparser.expression.Expression;
1415
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
1516

@@ -113,17 +114,37 @@ public PartitionBound withRemainder(Expression remainder) {
113114

114115
@Override
115116
public String toString() {
117+
StringBuilder sql = new StringBuilder();
118+
appendTo(sql, sql::append);
119+
return sql.toString();
120+
}
121+
122+
public void appendTo(StringBuilder sql, Consumer<Expression> expressionPrinter) {
116123
switch (type) {
117124
case RANGE:
118-
return "FOR VALUES FROM (" + fromExpressions + ") TO (" + toExpressions + ")";
125+
sql.append("FOR VALUES FROM (");
126+
expressionPrinter.accept(fromExpressions);
127+
sql.append(") TO (");
128+
expressionPrinter.accept(toExpressions);
129+
sql.append(')');
130+
break;
119131
case LIST:
120-
return "FOR VALUES IN (" + inExpressions + ")";
132+
sql.append("FOR VALUES IN (");
133+
expressionPrinter.accept(inExpressions);
134+
sql.append(')');
135+
break;
121136
case HASH:
122-
return "FOR VALUES WITH (MODULUS " + modulus + ", REMAINDER " + remainder + ")";
137+
sql.append("FOR VALUES WITH (MODULUS ");
138+
expressionPrinter.accept(modulus);
139+
sql.append(", REMAINDER ");
140+
expressionPrinter.accept(remainder);
141+
sql.append(')');
142+
break;
123143
case DEFAULT:
124-
return "DEFAULT";
144+
sql.append("DEFAULT");
145+
break;
125146
default:
126-
return "";
147+
break;
127148
}
128149
}
129150
}

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.Collections;
1616
import java.util.List;
1717
import java.util.Optional;
18+
import java.util.function.Consumer;
1819
import net.sf.jsqlparser.expression.Expression;
1920
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
2021
import net.sf.jsqlparser.schema.Column;
@@ -256,14 +257,20 @@ public TablePartitioning addPartitionOptions(Collection<String> partitionOptions
256257

257258
@Override
258259
public String toString() {
259-
StringBuilder builder = new StringBuilder("PARTITION BY ");
260-
appendMethod(builder);
260+
StringBuilder builder = new StringBuilder();
261+
appendTo(builder, builder::append);
262+
return builder.toString();
263+
}
264+
265+
public void appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
266+
builder.append("PARTITION BY ");
267+
appendMethod(builder, expressionPrinter);
261268
if (partitions != null) {
262269
builder.append(" PARTITIONS ").append(partitions);
263270
}
264271
if (subPartitioning != null) {
265272
builder.append(" SUBPARTITION BY ");
266-
subPartitioning.appendMethod(builder);
273+
subPartitioning.appendMethod(builder, expressionPrinter);
267274
if (subPartitioning.getPartitions() != null) {
268275
builder.append(" SUBPARTITIONS ").append(subPartitioning.getPartitions());
269276
}
@@ -275,10 +282,9 @@ public String toString() {
275282
if (partitionOptions != null && !partitionOptions.isEmpty()) {
276283
builder.append(" ").append(PlainSelect.getStringList(partitionOptions, false, false));
277284
}
278-
return builder.toString();
279285
}
280286

281-
private void appendMethod(StringBuilder builder) {
287+
private void appendMethod(StringBuilder builder, Consumer<Expression> expressionPrinter) {
282288
if (linear) {
283289
builder.append("LINEAR ");
284290
}
@@ -291,11 +297,17 @@ private void appendMethod(StringBuilder builder) {
291297
builder.append(" COLUMNS");
292298
}
293299
if (expression != null) {
294-
builder.append(" (").append(expression).append(")");
300+
builder.append(" (");
301+
expressionPrinter.accept(expression);
302+
builder.append(')');
295303
} else if (expressionList != null) {
296-
builder.append(" (").append(expressionList).append(")");
304+
builder.append(" (");
305+
expressionPrinter.accept(expressionList);
306+
builder.append(')');
297307
} else if (columns != null) {
298-
builder.append(" ").append(PlainSelect.getStringList(columns, true, true));
308+
builder.append(" (");
309+
expressionPrinter.accept(columns);
310+
builder.append(')');
299311
}
300312
}
301313
}

src/main/java/net/sf/jsqlparser/util/TableDefinitionTraversal.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import net.sf.jsqlparser.schema.Table;
1616
import net.sf.jsqlparser.statement.LikeClause;
1717
import net.sf.jsqlparser.statement.alter.AlterExpression;
18+
import net.sf.jsqlparser.statement.alter.AlterExpressionPartition;
1819
import net.sf.jsqlparser.statement.alter.AlterExpressionPrimaryKey;
1920
import net.sf.jsqlparser.statement.create.index.CreateIndex;
2021
import net.sf.jsqlparser.statement.create.table.CheckConstraint;
@@ -26,6 +27,8 @@
2627
import net.sf.jsqlparser.statement.create.table.ForeignKeyIndex;
2728
import net.sf.jsqlparser.statement.create.table.Index;
2829
import net.sf.jsqlparser.statement.create.table.TableElement;
30+
import net.sf.jsqlparser.statement.create.table.TablePartitioning;
31+
import net.sf.jsqlparser.statement.create.table.PartitionBound;
2932

3033
/** Traverses structured table definitions without interpreting legacy raw column options. */
3134
public final class TableDefinitionTraversal {
@@ -50,6 +53,26 @@ public static void visit(AlterExpression action, Consumer<Expression> expression
5053
if (action.getIndex() != null) {
5154
visit(action.getIndex(), expressions, tables);
5255
}
56+
if (action instanceof AlterExpressionPartition) {
57+
AlterExpressionPartition partition = (AlterExpressionPartition) action;
58+
switch (partition.getOperation()) {
59+
case ATTACH_PARTITION:
60+
accept(partition.getPartitionTable(), tables);
61+
visit(partition.getPartitionBound(), expressions);
62+
break;
63+
case DETACH_PARTITION:
64+
accept(partition.getPartitionTable(), tables);
65+
break;
66+
case EXCHANGE_PARTITION:
67+
accept(partition.getExchangeTable(), tables);
68+
break;
69+
case PARTITION_BY:
70+
visit(partition.getPartitioning(), expressions);
71+
break;
72+
default:
73+
break;
74+
}
75+
}
5376
if (action instanceof AlterExpressionPrimaryKey) {
5477
AlterExpressionPrimaryKey primaryKey = (AlterExpressionPrimaryKey) action;
5578
if (primaryKey.isUsingHash()) {
@@ -72,6 +95,45 @@ public static void visit(CreateTable table, Consumer<Expression> expressions,
7295
}
7396
accept(table.getTrailingLikeTable(), tables);
7497
accept(table.getPartitionOf(), tables);
98+
visit(table.getPartitioning(), expressions);
99+
visit(table.getPartitionBound(), expressions);
100+
}
101+
102+
/** Visits the active partition key and any subpartition key. Raw bounds remain opaque. */
103+
public static void visit(TablePartitioning partitioning, Consumer<Expression> expressions) {
104+
if (partitioning == null) {
105+
return;
106+
}
107+
if (partitioning.getExpression() != null) {
108+
accept(partitioning.getExpression(), expressions);
109+
} else if (partitioning.getExpressionList() != null) {
110+
accept(partitioning.getExpressionList(), expressions);
111+
} else {
112+
accept(partitioning.getColumns(), expressions);
113+
}
114+
visit(partitioning.getSubPartitioning(), expressions);
115+
}
116+
117+
/** Visits expressions belonging to the selected PostgreSQL bound type. */
118+
public static void visit(PartitionBound bound, Consumer<Expression> expressions) {
119+
if (bound == null || bound.getType() == null) {
120+
return;
121+
}
122+
switch (bound.getType()) {
123+
case RANGE:
124+
accept(bound.getFromExpressions(), expressions);
125+
accept(bound.getToExpressions(), expressions);
126+
break;
127+
case LIST:
128+
accept(bound.getInExpressions(), expressions);
129+
break;
130+
case HASH:
131+
accept(bound.getModulus(), expressions);
132+
accept(bound.getRemainder(), expressions);
133+
break;
134+
default:
135+
break;
136+
}
75137
}
76138

77139
public static void visit(TableElement element, Consumer<Expression> expressions,

src/main/java/net/sf/jsqlparser/util/deparser/AlterDeParser.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.sf.jsqlparser.statement.alter.Alter;
1313
import net.sf.jsqlparser.expression.ExpressionVisitor;
1414
import net.sf.jsqlparser.statement.alter.AlterExpression;
15+
import net.sf.jsqlparser.statement.alter.AlterExpressionPartition;
1516
import net.sf.jsqlparser.statement.alter.AlterExpressionPrimaryKey;
1617
import net.sf.jsqlparser.statement.create.table.DefaultConstraint;
1718
import net.sf.jsqlparser.statement.select.PlainSelect;
@@ -49,6 +50,11 @@ public void deParse(Alter alter) {
4950
}
5051

5152
private void deParseAction(AlterExpression action) {
53+
if (action instanceof AlterExpressionPartition) {
54+
((AlterExpressionPartition) action).appendTo(builder,
55+
expression -> expression.accept(expressionVisitor, null));
56+
return;
57+
}
5258
if (action instanceof AlterExpressionPrimaryKey) {
5359
((AlterExpressionPrimaryKey) action).appendTo(builder,
5460
expression -> expression.accept(expressionVisitor, null));

src/main/java/net/sf/jsqlparser/util/deparser/CreateTableDeParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,21 @@ public void deParse(CreateTable createTable) {
105105
}
106106

107107
if (createTable.getPartitionBound() != null) {
108-
builder.append(' ').append(createTable.getPartitionBound());
108+
builder.append(' ');
109+
createTable.getPartitionBound().appendTo(builder,
110+
expression -> expression.accept(statementDeParser.getExpressionDeParser(),
111+
null));
109112
}
110113

111114
params = PlainSelect.getStringList(createTable.getTableOptionsStrings(), false, false);
112115
if (!"".equals(params)) {
113116
builder.append(' ').append(params);
114117
}
115118
if (createTable.getPartitioning() != null) {
116-
builder.append(' ').append(createTable.getPartitioning());
119+
builder.append(' ');
120+
createTable.getPartitioning().appendTo(builder,
121+
expression -> expression.accept(statementDeParser.getExpressionDeParser(),
122+
null));
117123
}
118124

119125
if (createTable.getRowMovement() != null) {

0 commit comments

Comments
 (0)