Skip to content

Commit 0562417

Browse files
committed
fix mysql convert
1 parent 6227b0b commit 0562417

File tree

3 files changed

+113
-35
lines changed

3 files changed

+113
-35
lines changed

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

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public class AlterExpression implements Serializable {
5353
private List<PartitionDefinition> partitionDefinitions;
5454
private List<ConstraintState> constraints;
5555
private List<String> parameters;
56+
57+
private ConvertType convertType;
58+
private boolean hasEqualForCharacterSet;
59+
private boolean hasEqualForCollate;
60+
5661
private String characterSet;
5762
private String collation;
5863
private String lockOption;
@@ -196,7 +201,7 @@ public boolean isOnDeleteCascade() {
196201
/**
197202
* @param onDeleteCascade
198203
* @deprecated use
199-
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
204+
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
200205
*/
201206
@Deprecated
202207
public void setOnDeleteCascade(boolean onDeleteCascade) {
@@ -216,7 +221,7 @@ public boolean isOnDeleteRestrict() {
216221
/**
217222
* @param onDeleteRestrict
218223
* @deprecated use
219-
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
224+
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
220225
*/
221226
@Deprecated
222227
public void setOnDeleteRestrict(boolean onDeleteRestrict) {
@@ -236,7 +241,7 @@ public boolean isOnDeleteSetNull() {
236241
/**
237242
* @param onDeleteSetNull
238243
* @deprecated use
239-
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
244+
* {@link #setReferentialAction(ReferentialAction.Type, ReferentialAction.Action, boolean)}
240245
*/
241246
@Deprecated
242247
public void setOnDeleteSetNull(boolean onDeleteSetNull) {
@@ -401,6 +406,14 @@ public List<String> getParameters() {
401406
return parameters;
402407
}
403408

409+
public ConvertType getConvertType() {
410+
return convertType;
411+
}
412+
413+
public void setConvertType(ConvertType convertType) {
414+
this.convertType = convertType;
415+
}
416+
404417
public String getCharacterSet() {
405418
return characterSet;
406419
}
@@ -486,12 +499,30 @@ public String toString() {
486499

487500
b.append("DROP PRIMARY KEY ");
488501
} else if (operation == AlterOperation.CONVERT) {
489-
b.append("CONVERT TO CHARACTER SET ");
502+
if (convertType == ConvertType.CONVERT_TO) {
503+
b.append("CONVERT TO CHARACTER SET ");
504+
} else if (convertType == ConvertType.DEFAULT_CHARACTER_SET) {
505+
b.append("DEFAULT CHARACTER SET ");
506+
if (hasEqualForCharacterSet) {
507+
b.append("= ");
508+
}
509+
} else if (convertType == ConvertType.CHARACTER_SET) {
510+
b.append("CHARACTER SET ");
511+
if (hasEqualForCharacterSet) {
512+
b.append("= ");
513+
}
514+
}
515+
490516
if (getCharacterSet() != null) {
491517
b.append(getCharacterSet());
492518
}
519+
493520
if (getCollation() != null) {
494-
b.append(" COLLATE ").append(getCollation());
521+
b.append(" COLLATE ");
522+
if (hasEqualForCollate) {
523+
b.append("= ");
524+
}
525+
b.append(getCollation());
495526
}
496527
} else if (operation == AlterOperation.DROP_UNIQUE) {
497528

@@ -805,6 +836,14 @@ public void setPartitionDefinitions(List<PartitionDefinition> partitionDefinitio
805836
this.partitionDefinitions = partitionDefinition;
806837
}
807838

839+
public void setHasEqualForCharacterSet(boolean hasEqualForCharacterSet) {
840+
this.hasEqualForCharacterSet = hasEqualForCharacterSet;
841+
}
842+
843+
public void setHasEqualForCollate(boolean hasEqualForCollate) {
844+
this.hasEqualForCollate = hasEqualForCollate;
845+
}
846+
808847
public static final class ColumnDataType extends ColumnDefinition {
809848

810849
private final boolean withType;
@@ -898,4 +937,8 @@ public String toString() {
898937
return columnName + " DROP DEFAULT";
899938
}
900939
}
940+
941+
public enum ConvertType {
942+
CONVERT_TO, DEFAULT_CHARACTER_SET, CHARACTER_SET
943+
}
901944
}

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7430,11 +7430,31 @@ AlterExpression AlterExpression():
74307430
<K_RENAME> <K_TO> {alterExp.setOperation(AlterOperation.RENAME_TABLE);}
74317431
(tk2=<S_IDENTIFIER> | tk2=<S_QUOTED_IDENTIFIER>) { alterExp.setNewTableName(tk2.image);}
74327432
)
7433-
|
7434-
(<K_CONVERT> { alterExp.setOperation(AlterOperation.CONVERT); }
7433+
| (<K_CONVERT> {
7434+
alterExp.setOperation(AlterOperation.CONVERT);
7435+
alterExp.setConvertType(AlterExpression.ConvertType.CONVERT_TO);
7436+
}
74357437
<K_TO> <K_CHARACTER> <K_SET> tk=<S_IDENTIFIER> { alterExp.setCharacterSet(tk.image); }
74367438
[<K_COLLATE> tk2=<S_IDENTIFIER> { alterExp.setCollation(tk2.image); }]
7437-
)
7439+
)
7440+
| (<K_DEFAULT> {
7441+
alterExp.setOperation(AlterOperation.CONVERT);
7442+
alterExp.setConvertType(AlterExpression.ConvertType.DEFAULT_CHARACTER_SET);
7443+
}
7444+
<K_CHARACTER> <K_SET> [ "=" { alterExp.setHasEqualForCharacterSet(true); } ]
7445+
tk=<S_IDENTIFIER> { alterExp.setCharacterSet(tk.image); }
7446+
[<K_COLLATE> [ "=" { alterExp.setHasEqualForCollate(true); } ]
7447+
tk2=<S_IDENTIFIER> { alterExp.setCollation(tk2.image); }]
7448+
)
7449+
| (<K_CHARACTER> <K_SET> [ "=" { alterExp.setHasEqualForCharacterSet(true); } ]
7450+
tk=<S_IDENTIFIER> {
7451+
alterExp.setOperation(AlterOperation.CONVERT);
7452+
alterExp.setConvertType(AlterExpression.ConvertType.CHARACTER_SET);
7453+
alterExp.setCharacterSet(tk.image);
7454+
}
7455+
[<K_COLLATE> [ "=" { alterExp.setHasEqualForCollate(true); } ]
7456+
tk2=<S_IDENTIFIER> { alterExp.setCollation(tk2.image); }]
7457+
)
74387458
|
74397459
(<K_COMMENT> {alterExp.setOperation(AlterOperation.COMMENT);}
74407460
["=" {alterExp.setOperation(AlterOperation.COMMENT_WITH_EQUAL_SIGN);} ]

src/test/java/net/sf/jsqlparser/statement/alter/AlterTest.java

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@
2424
import net.sf.jsqlparser.statement.create.table.*;
2525
import net.sf.jsqlparser.statement.create.table.Index.ColumnParams;
2626
import org.junit.jupiter.api.Test;
27+
import org.junit.jupiter.params.ParameterizedTest;
28+
import org.junit.jupiter.params.provider.Arguments;
29+
import org.junit.jupiter.params.provider.MethodSource;
2730

2831
import java.util.Arrays;
2932
import java.util.Collections;
3033
import java.util.List;
34+
import java.util.stream.Stream;
3135

3236
import static net.sf.jsqlparser.test.TestUtils.*;
3337
import static org.junit.jupiter.api.Assertions.*;
@@ -834,7 +838,7 @@ public void testAlterTableDefaultValueTrueIssue926() throws JSQLParserException
834838
}
835839

836840
private void assertReferentialActionOnConstraint(Alter parsed, Action onUpdate,
837-
Action onDelete) {
841+
Action onDelete) {
838842
AlterExpression alterExpression = parsed.getAlterExpressions().get(0);
839843
ForeignKeyIndex index = (ForeignKeyIndex) alterExpression.getIndex();
840844

@@ -1092,45 +1096,56 @@ public void testIssue2090LockExclusive() throws JSQLParserException {
10921096
assertEquals("EXCLUSIVE", lockExp.getLockOption());
10931097
}
10941098

1095-
@Test
1096-
public void testIssue2089() throws JSQLParserException {
1097-
String sql = "ALTER TABLE test_table CONVERT TO CHARACTER SET utf8mb4";
1099+
@ParameterizedTest
1100+
@MethodSource("provideMySQLConvertTestCases")
1101+
public void testIssue2089(String sql, String expectedCharacterSet, String expectedCollation)
1102+
throws JSQLParserException {
10981103
Statement stmt = CCJSqlParserUtil.parse(sql);
1099-
assertTrue(stmt instanceof Alter);
1100-
Alter alter = (Alter) stmt;
1101-
assertEquals("test_table", alter.getTable().getFullyQualifiedName());
1102-
1103-
List<AlterExpression> alterExpressions = alter.getAlterExpressions();
1104-
assertNotNull(alterExpressions);
1105-
assertEquals(1, alterExpressions.size());
1106-
1107-
AlterExpression convertExp = alterExpressions.get(0);
1108-
assertEquals(AlterOperation.CONVERT, convertExp.getOperation());
1109-
assertEquals("utf8mb4", convertExp.getCharacterSet());
1110-
assertNull(convertExp.getCollation());
1111-
}
1104+
assertTrue(stmt instanceof Alter,
1105+
"Expected instance of Alter but got: " + stmt.getClass().getSimpleName());
11121106

1113-
@Test
1114-
public void testIssue2089ConvertWithCollation() throws JSQLParserException {
1115-
String sql =
1116-
"ALTER TABLE test_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci";
1117-
Statement stmt = CCJSqlParserUtil.parse(sql);
1118-
assertTrue(stmt instanceof Alter);
11191107
Alter alter = (Alter) stmt;
11201108
assertEquals("test_table", alter.getTable().getFullyQualifiedName());
11211109

11221110
List<AlterExpression> alterExpressions = alter.getAlterExpressions();
1123-
assertNotNull(alterExpressions);
1124-
assertEquals(1, alterExpressions.size());
1111+
assertNotNull(alterExpressions, "Alter expressions should not be null for SQL: " + sql);
1112+
assertEquals(1, alterExpressions.size(), "Expected 1 alter expression for SQL: " + sql);
11251113

11261114
AlterExpression convertExp = alterExpressions.get(0);
11271115
assertEquals(AlterOperation.CONVERT, convertExp.getOperation());
1128-
assertEquals("utf8mb4", convertExp.getCharacterSet());
1129-
assertEquals("utf8mb4_general_ci", convertExp.getCollation());
11301116

1117+
assertEquals(expectedCharacterSet, convertExp.getCharacterSet(),
1118+
"CHARACTER SET mismatch for SQL: " + sql);
1119+
assertEquals(expectedCollation, convertExp.getCollation(),
1120+
"COLLATE mismatch for SQL: " + sql);
11311121
assertSqlCanBeParsedAndDeparsed(sql);
11321122
}
11331123

1124+
private static Stream<Arguments> provideMySQLConvertTestCases() {
1125+
return Stream.of(
1126+
Arguments.of("ALTER TABLE test_table CONVERT TO CHARACTER SET utf8mb4", "utf8mb4",
1127+
null),
1128+
Arguments.of(
1129+
"ALTER TABLE test_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci",
1130+
"utf8mb4", "utf8mb4_general_ci"),
1131+
Arguments.of(
1132+
"ALTER TABLE test_table DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci",
1133+
"utf8mb4", "utf8mb4_general_ci"),
1134+
Arguments.of(
1135+
"ALTER TABLE test_table DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci",
1136+
"utf8mb4", "utf8mb4_general_ci"),
1137+
Arguments.of(
1138+
"ALTER TABLE test_table CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci",
1139+
"utf8mb4", "utf8mb4_general_ci"),
1140+
Arguments.of(
1141+
"ALTER TABLE test_table CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci",
1142+
"utf8mb4", "utf8mb4_general_ci"),
1143+
Arguments.of("ALTER TABLE test_table DEFAULT CHARACTER SET utf8mb4", "utf8mb4",
1144+
null),
1145+
Arguments.of("ALTER TABLE test_table DEFAULT CHARACTER SET = utf8mb4", "utf8mb4",
1146+
null));
1147+
}
1148+
11341149
@Test
11351150
public void testIssue2106AlterTableAddPartition1() throws JSQLParserException {
11361151
String sql = "ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));";

0 commit comments

Comments
 (0)