99 */
1010package net .sf .jsqlparser .statement .alter ;
1111
12+ import java .util .ArrayList ;
13+ import java .util .Collection ;
14+ import java .util .Collections ;
15+ import java .util .List ;
16+ import java .util .Optional ;
1217import net .sf .jsqlparser .schema .Table ;
1318import net .sf .jsqlparser .statement .create .table .PartitionBound ;
19+ import net .sf .jsqlparser .statement .create .table .PartitionDefinition ;
20+ import net .sf .jsqlparser .statement .create .table .TablePartitioning ;
21+ import net .sf .jsqlparser .statement .select .PlainSelect ;
1422
1523/**
16- * Internal subclass for partition maintenance operations within ALTER TABLE. Handles TRUNCATE,
17- * COALESCE, REORGANIZE, EXCHANGE, ANALYZE, CHECK, OPTIMIZE, REBUILD, REPAIR PARTITION, PARTITION
18- * BY, and REMOVE PARTITIONING.
24+ * Structured model for partition operations within {@code ALTER TABLE}.
25+ *
26+ * <p>
27+ * MySQL partition names and definitions remain available through the inherited
28+ * {@link #getPartitions()} and {@link #getPartitionDefinitions()} methods. This subtype adds
29+ * structured access to the complete {@code PARTITION BY} clause, the table used by
30+ * {@code EXCHANGE PARTITION}, and its validation mode. It also models PostgreSQL
31+ * {@code ATTACH/DETACH PARTITION} operations.
1932 */
2033public class AlterExpressionPartition extends AlterExpression {
2134
2235 public enum DetachMode {
2336 CONCURRENTLY , FINALIZE
2437 }
2538
39+ public enum ExchangeValidationMode {
40+ WITH , WITHOUT
41+ }
42+
2643 private Table partitionTable ;
2744 private PartitionBound partitionBound ;
2845 private DetachMode detachMode ;
46+ private TablePartitioning partitioning ;
47+ private Integer coalescePartitionCount ;
48+ private Table exchangeTable ;
49+ private ExchangeValidationMode exchangeValidationMode ;
2950
3051 public Table getPartitionTable () {
3152 return partitionTable ;
@@ -51,6 +72,136 @@ public void setDetachMode(DetachMode detachMode) {
5172 this .detachMode = detachMode ;
5273 }
5374
75+ /**
76+ * Returns the full MySQL partitioning clause for a {@link AlterOperation#PARTITION_BY}
77+ * operation.
78+ */
79+ public TablePartitioning getPartitioning () {
80+ return partitioning ;
81+ }
82+
83+ public void setPartitioning (TablePartitioning partitioning ) {
84+ this .partitioning = partitioning ;
85+ if (partitioning != null ) {
86+ setPartitionType (partitioning .getType () != null
87+ ? partitioning .getType ().toString ()
88+ : null );
89+ setPartitionExpression (partitioning .getExpression () != null
90+ ? partitioning .getExpression ()
91+ : partitioning .getExpressionList ());
92+ if (partitioning .getColumns () != null ) {
93+ List <String > partitionColumns = new ArrayList <>();
94+ partitioning .getColumns ().forEach (
95+ column -> partitionColumns .add (column .getFullyQualifiedName ()));
96+ setPartitionColumns (partitionColumns );
97+ } else {
98+ setPartitionColumns (null );
99+ }
100+ setPartitionDefinitions (partitioning .getPartitionDefinitions ());
101+ }
102+ }
103+
104+ /**
105+ * Convenience alias that names the inherited MySQL partition-name list explicitly.
106+ */
107+ public List <String > getPartitionNames () {
108+ return getPartitions ();
109+ }
110+
111+ public void setPartitionNames (List <String > partitionNames ) {
112+ setPartitions (partitionNames );
113+ }
114+
115+ /**
116+ * Returns whether the operation targets every partition rather than named partitions.
117+ */
118+ public boolean isAllPartitions () {
119+ List <String > partitionNames = getPartitionNames ();
120+ return partitionNames != null && partitionNames .size () == 1
121+ && "ALL" .equalsIgnoreCase (partitionNames .get (0 ));
122+ }
123+
124+ public void setAllPartitions (boolean allPartitions ) {
125+ if (allPartitions ) {
126+ setPartitionNames (Collections .singletonList ("ALL" ));
127+ } else if (isAllPartitions ()) {
128+ setPartitionNames (null );
129+ }
130+ }
131+
132+ /**
133+ * Returns the number of partitions added by a MySQL {@code COALESCE PARTITION} operation.
134+ * Unlike the legacy primitive accessor, this is {@code null} when no count was supplied.
135+ */
136+ public Integer getCoalescePartitionCount () {
137+ return coalescePartitionCount ;
138+ }
139+
140+ public void setCoalescePartitionCount (Integer coalescePartitionCount ) {
141+ this .coalescePartitionCount = coalescePartitionCount ;
142+ if (coalescePartitionCount != null ) {
143+ super .setCoalescePartitionNumber (coalescePartitionCount );
144+ }
145+ }
146+
147+ @ Override
148+ public void setCoalescePartitionNumber (int coalescePartitionNumber ) {
149+ super .setCoalescePartitionNumber (coalescePartitionNumber );
150+ this .coalescePartitionCount = coalescePartitionNumber ;
151+ }
152+
153+ public Table getExchangeTable () {
154+ return exchangeTable ;
155+ }
156+
157+ public void setExchangeTable (Table exchangeTable ) {
158+ this .exchangeTable = exchangeTable ;
159+ super .setExchangePartitionTableName (
160+ exchangeTable != null ? exchangeTable .getFullyQualifiedName () : null );
161+ }
162+
163+ @ Override
164+ public void setExchangePartitionTableName (String exchangePartitionTableName ) {
165+ super .setExchangePartitionTableName (exchangePartitionTableName );
166+ this .exchangeTable = exchangePartitionTableName != null
167+ ? new Table (exchangePartitionTableName )
168+ : null ;
169+ }
170+
171+ public ExchangeValidationMode getExchangeValidationMode () {
172+ return exchangeValidationMode ;
173+ }
174+
175+ public void setExchangeValidationMode (ExchangeValidationMode exchangeValidationMode ) {
176+ this .exchangeValidationMode = exchangeValidationMode ;
177+ super .setExchangePartitionWithValidation (
178+ exchangeValidationMode == ExchangeValidationMode .WITH );
179+ super .setExchangePartitionWithoutValidation (
180+ exchangeValidationMode == ExchangeValidationMode .WITHOUT );
181+ }
182+
183+ @ Override
184+ public void setExchangePartitionWithValidation (boolean exchangePartitionWithValidation ) {
185+ super .setExchangePartitionWithValidation (exchangePartitionWithValidation );
186+ if (exchangePartitionWithValidation ) {
187+ exchangeValidationMode = ExchangeValidationMode .WITH ;
188+ super .setExchangePartitionWithoutValidation (false );
189+ } else if (exchangeValidationMode == ExchangeValidationMode .WITH ) {
190+ exchangeValidationMode = null ;
191+ }
192+ }
193+
194+ @ Override
195+ public void setExchangePartitionWithoutValidation (boolean exchangePartitionWithoutValidation ) {
196+ super .setExchangePartitionWithoutValidation (exchangePartitionWithoutValidation );
197+ if (exchangePartitionWithoutValidation ) {
198+ exchangeValidationMode = ExchangeValidationMode .WITHOUT ;
199+ super .setExchangePartitionWithValidation (false );
200+ } else if (exchangeValidationMode == ExchangeValidationMode .WITHOUT ) {
201+ exchangeValidationMode = null ;
202+ }
203+ }
204+
54205 public AlterExpressionPartition withPartitionTable (Table partitionTable ) {
55206 setPartitionTable (partitionTable );
56207 return this ;
@@ -66,18 +217,121 @@ public AlterExpressionPartition withDetachMode(DetachMode detachMode) {
66217 return this ;
67218 }
68219
220+ @ Override
221+ public AlterExpressionPartition withOperation (AlterOperation operation ) {
222+ setOperation (operation );
223+ return this ;
224+ }
225+
226+ public AlterExpressionPartition withPartitioning (TablePartitioning partitioning ) {
227+ setPartitioning (partitioning );
228+ return this ;
229+ }
230+
231+ public AlterExpressionPartition withPartitionNames (List <String > partitionNames ) {
232+ setPartitionNames (partitionNames );
233+ return this ;
234+ }
235+
236+ public AlterExpressionPartition withAllPartitions (boolean allPartitions ) {
237+ setAllPartitions (allPartitions );
238+ return this ;
239+ }
240+
241+ public AlterExpressionPartition withCoalescePartitionCount (Integer coalescePartitionCount ) {
242+ setCoalescePartitionCount (coalescePartitionCount );
243+ return this ;
244+ }
245+
246+ public AlterExpressionPartition withExchangeTable (Table exchangeTable ) {
247+ setExchangeTable (exchangeTable );
248+ return this ;
249+ }
250+
251+ public AlterExpressionPartition withExchangeValidationMode (
252+ ExchangeValidationMode exchangeValidationMode ) {
253+ setExchangeValidationMode (exchangeValidationMode );
254+ return this ;
255+ }
256+
257+ public AlterExpressionPartition withPartitionDefinitions (
258+ List <PartitionDefinition > partitionDefinitions ) {
259+ setPartitionDefinitions (partitionDefinitions );
260+ return this ;
261+ }
262+
263+ public AlterExpressionPartition addPartitionNames (String ... partitionNames ) {
264+ List <String > collection =
265+ Optional .ofNullable (getPartitionNames ()).orElseGet (ArrayList ::new );
266+ Collections .addAll (collection , partitionNames );
267+ return withPartitionNames (collection );
268+ }
269+
270+ public AlterExpressionPartition addPartitionNames (Collection <String > partitionNames ) {
271+ List <String > collection =
272+ Optional .ofNullable (getPartitionNames ()).orElseGet (ArrayList ::new );
273+ collection .addAll (partitionNames );
274+ return withPartitionNames (collection );
275+ }
276+
277+ public AlterExpressionPartition addPartitionDefinitions (
278+ PartitionDefinition ... partitionDefinitions ) {
279+ List <PartitionDefinition > collection = Optional .ofNullable (getPartitionDefinitions ())
280+ .orElseGet (ArrayList ::new );
281+ Collections .addAll (collection , partitionDefinitions );
282+ return withPartitionDefinitions (collection );
283+ }
284+
285+ public AlterExpressionPartition addPartitionDefinitions (
286+ Collection <? extends PartitionDefinition > partitionDefinitions ) {
287+ List <PartitionDefinition > collection = Optional .ofNullable (getPartitionDefinitions ())
288+ .orElseGet (ArrayList ::new );
289+ collection .addAll (partitionDefinitions );
290+ return withPartitionDefinitions (collection );
291+ }
292+
69293 @ Override
70294 protected void appendBody (StringBuilder b ) {
71- if (getOperation () == AlterOperation .ATTACH_PARTITION ) {
72- b .append ("ATTACH PARTITION " ).append (partitionTable ).append (" " )
73- .append (partitionBound );
74- } else if (getOperation () == AlterOperation .DETACH_PARTITION ) {
75- b .append ("DETACH PARTITION " ).append (partitionTable );
76- if (detachMode != null ) {
77- b .append (" " ).append (detachMode );
78- }
79- } else {
80- toStringPartition (b );
295+ switch (getOperation ()) {
296+ case ADD_PARTITION :
297+ b .append ("ADD PARTITION " )
298+ .append (PlainSelect .getStringList (getPartitionDefinitions (), true , true ));
299+ break ;
300+ case DROP_PARTITION :
301+ b .append ("DROP PARTITION " )
302+ .append (PlainSelect .getStringList (getPartitionNames ()));
303+ break ;
304+ case ATTACH_PARTITION :
305+ b .append ("ATTACH PARTITION " ).append (partitionTable ).append (" " )
306+ .append (partitionBound );
307+ break ;
308+ case DETACH_PARTITION :
309+ b .append ("DETACH PARTITION " ).append (partitionTable );
310+ if (detachMode != null ) {
311+ b .append (" " ).append (detachMode );
312+ }
313+ break ;
314+ case PARTITION_BY :
315+ if (partitioning != null ) {
316+ b .append (partitioning );
317+ } else {
318+ toStringPartition (b );
319+ }
320+ break ;
321+ case EXCHANGE_PARTITION :
322+ if (exchangeTable != null ) {
323+ b .append ("EXCHANGE PARTITION " ).append (getPartitionNames ().get (0 ))
324+ .append (" WITH TABLE " ).append (exchangeTable );
325+ if (exchangeValidationMode != null ) {
326+ b .append (" " ).append (exchangeValidationMode ).append (" VALIDATION" );
327+ }
328+ } else {
329+ toStringPartition (b );
330+ }
331+ break ;
332+ default :
333+ toStringPartition (b );
334+ break ;
81335 }
82336 }
83337}
0 commit comments