Skip to content

Commit 149ba4f

Browse files
authored
feat: share additional MySQL CREATE and ALTER table options (#2713)
Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent 3e8324b commit 149ba4f

3 files changed

Lines changed: 84 additions & 5 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
public class TableOption implements Serializable {
2222

2323
public enum Kind {
24-
ENGINE, CHARACTER_SET, COLLATE, COMMENT, AUTO_INCREMENT, STATS_AUTO_RECALC, STATS_PERSISTENT, STATS_SAMPLE_PAGES, UNION, ENCRYPTION, PASSWORD, DATA_DIRECTORY, INDEX_DIRECTORY, STORAGE_PARAMETERS, WITHOUT_OIDS, ENGINE_ATTRIBUTE, SECONDARY_ENGINE_ATTRIBUTE, ROW_FORMAT, OTHER
24+
ENGINE, CHARACTER_SET, COLLATE, COMMENT, AUTO_INCREMENT, STATS_AUTO_RECALC, STATS_PERSISTENT, STATS_SAMPLE_PAGES, UNION, ENCRYPTION, PASSWORD, DATA_DIRECTORY, INDEX_DIRECTORY, SECONDARY_ENGINE, AUTOEXTEND_SIZE, INSERT_METHOD, PACK_KEYS, DELAY_KEY_WRITE, CHECKSUM, CONNECTION, COMPRESSION, STORAGE_PARAMETERS, WITHOUT_OIDS, ENGINE_ATTRIBUTE, SECONDARY_ENGINE_ATTRIBUTE, ROW_FORMAT, OTHER
2525
}
2626

2727
private Kind kind = Kind.OTHER;

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

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,9 +1561,15 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
15611561
return isKeywordAhead("ENGINE_ATTRIBUTE") || isKeywordAhead("SECONDARY_ENGINE_ATTRIBUTE");
15621562
}
15631563

1564+
private boolean isMySqlAdditionalTableOptionAhead() {
1565+
String name = getToken(1).image.toUpperCase(Locale.ROOT);
1566+
return Arrays.asList("SECONDARY_ENGINE", "AUTOEXTEND_SIZE", "INSERT_METHOD", "PACK_KEYS",
1567+
"DELAY_KEY_WRITE", "CHECKSUM", "CONNECTION", "COMPRESSION").contains(name);
1568+
}
1569+
15641570
private boolean isMySqlScalarTableOptionAhead() {
15651571
int kind = getToken(1).kind;
1566-
return isMySqlEngineAttributeAhead() || kind == K_ENCRYPTION || kind == K_PASSWORD || kind == K_AUTO_INCREMENT
1572+
return isMySqlAdditionalTableOptionAhead() || isMySqlEngineAttributeAhead() || kind == K_ENCRYPTION || kind == K_PASSWORD || kind == K_AUTO_INCREMENT
15671573
|| (kind == K_DATA || kind == K_INDEX) && getToken(2).kind == K_DIRECTORY;
15681574
}
15691575

@@ -15535,17 +15541,22 @@ TableOption MySqlTableOption(): {
1553515541
}
1553615542
}
1553715543

15538-
/** Common CREATE/ALTER options with a quoted string or unsigned integer value. */
15544+
/** Shared CREATE/ALTER table options with option-specific value syntax. */
1553915545
TableOption MySqlScalarTableOption():
1554015546
{
1554115547
Token token;
1554215548
String name;
1554315549
String value;
1554415550
TableOption.Kind kind;
1554515551
boolean useEquals = false;
15552+
TableOption additional;
1554615553
}
1554715554
{
1554815555
(
15556+
LOOKAHEAD({ isMySqlAdditionalTableOptionAhead() }) additional=MySqlAdditionalTableOption()
15557+
{ name = additional.getName(); kind = additional.getKind();
15558+
value = additional.getValue(); useEquals = additional.isUseEquals(); }
15559+
|
1554915560
<K_AUTO_INCREMENT> { name = "AUTO_INCREMENT"; kind = TableOption.Kind.AUTO_INCREMENT; }
1555015561
[ "=" { useEquals = true; } ] token=<S_LONG> { value = token.image; }
1555115562
|
@@ -15564,6 +15575,65 @@ TableOption MySqlScalarTableOption():
1556415575
{ return new TableOption(kind, name, value, useEquals); }
1556515576
}
1556615577

15578+
TableOption MySqlAdditionalTableOption():
15579+
{
15580+
Token token;
15581+
String name;
15582+
String value;
15583+
boolean useEquals = false;
15584+
}
15585+
{
15586+
(
15587+
LOOKAHEAD({ isKeywordAhead("SECONDARY_ENGINE") })
15588+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15589+
[ "=" { useEquals = true; } ]
15590+
( token=<K_NULL> { value = token.image; } | token=<S_CHAR_LITERAL> { value = token.image; } | value=RelObjectName() )
15591+
|
15592+
LOOKAHEAD({ isKeywordAhead("INSERT_METHOD") })
15593+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15594+
[ "=" { useEquals = true; } ]
15595+
( token=<K_NO> | token=<K_FIRST> | token=<K_LAST> ) { value = token.image; }
15596+
|
15597+
LOOKAHEAD({ isKeywordAhead("PACK_KEYS") })
15598+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15599+
[ "=" { useEquals = true; } ]
15600+
( token=<K_DEFAULT> | token=<S_LONG> ) {
15601+
value = token.image;
15602+
if (token.kind == S_LONG && !"0".equals(value) && !"1".equals(value)) {
15603+
throw new ParseException("PACK_KEYS requires 0, 1 or DEFAULT");
15604+
}
15605+
}
15606+
|
15607+
LOOKAHEAD({ isKeywordAhead("AUTOEXTEND_SIZE") })
15608+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15609+
[ "=" { useEquals = true; } ]
15610+
value=MySqlSizeNumber()
15611+
|
15612+
LOOKAHEAD({ isKeywordAhead("CHECKSUM") || isKeywordAhead("DELAY_KEY_WRITE") })
15613+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15614+
[ "=" { useEquals = true; } ]
15615+
token=<S_LONG> { value = token.image; }
15616+
|
15617+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15618+
[ "=" { useEquals = true; } ]
15619+
token=<S_CHAR_LITERAL> { value = token.image; }
15620+
)
15621+
{ if (true) { return new TableOption(TableOption.Kind.valueOf(name), name, value, useEquals); } }
15622+
}
15623+
15624+
String MySqlSizeNumber():
15625+
{
15626+
Token number;
15627+
}
15628+
{
15629+
( number=<S_LONG> | number=<S_IDENTIFIER> )
15630+
{
15631+
requireDdlSyntax(number.kind == S_LONG || number.image.matches("[0-9]+[kKmMgG]"),
15632+
"Expected an unsigned size with an optional K, M or G suffix");
15633+
return number.image;
15634+
}
15635+
}
15636+
1556715637
/** Statistics and row format share CREATE's validation and option nodes. */
1556815638
AlterExpressionTableOption AlterSharedTableOption():
1556915639
{ TableOption option; AlterExpressionTableOption action = new AlterExpressionTableOption(); }

‎src/test/java/net/sf/jsqlparser/statement/create/MySqlSharedTableOptionTest.java‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@
2626

2727
class MySqlSharedTableOptionTest {
2828
@ParameterizedTest
29-
@CsvSource(value = {"ENCRYPTION|'N'|ENCRYPTION", "PASSWORD|'ignored'|PASSWORD",
29+
@CsvSource(value = {"SECONDARY_ENGINE|NULL|SECONDARY_ENGINE",
30+
"SECONDARY_ENGINE|'engine'|SECONDARY_ENGINE",
31+
"SECONDARY_ENGINE|engine_name|SECONDARY_ENGINE", "AUTOEXTEND_SIZE|4M|AUTOEXTEND_SIZE",
32+
"AUTOEXTEND_SIZE|0|AUTOEXTEND_SIZE", "INSERT_METHOD|NO|INSERT_METHOD",
33+
"INSERT_METHOD|FIRST|INSERT_METHOD", "INSERT_METHOD|LAST|INSERT_METHOD",
34+
"PACK_KEYS|DEFAULT|PACK_KEYS", "PACK_KEYS|1|PACK_KEYS", "PACK_KEYS|0|PACK_KEYS",
35+
"DELAY_KEY_WRITE|2|DELAY_KEY_WRITE", "CHECKSUM|0|CHECKSUM",
36+
"CONNECTION|'mysql://server/db/t'|CONNECTION", "COMPRESSION|'zlib'|COMPRESSION",
37+
"ENCRYPTION|'N'|ENCRYPTION", "PASSWORD|'ignored'|PASSWORD",
3038
"DATA DIRECTORY|'/tmp/data dir'|DATA_DIRECTORY",
3139
"INDEX DIRECTORY|'/tmp/index dir'|INDEX_DIRECTORY",
3240
"AUTO_INCREMENT|18446744073709551614|AUTO_INCREMENT"}, delimiter = '|',
@@ -77,7 +85,8 @@ void commasAndQuerySourceStayOutsideOptions() throws JSQLParserException {
7785

7886
@ParameterizedTest
7987
@ValueSource(strings = {"ENCRYPTION=", "PASSWORD=1", "DATA DIRECTORY='/tmp' INDEX DIRECTORY=",
80-
"AUTO_INCREMENT=-1", "AUTO_INCREMENT='5'", "ENCRYPTION='N',"})
88+
"PACK_KEYS=2", "AUTOEXTEND_SIZE=-1", "INSERT_METHOD=UNKNOWN", "COMPRESSION=1",
89+
"SECONDARY_ENGINE=", "AUTO_INCREMENT=-1", "AUTO_INCREMENT='5'", "ENCRYPTION='N',"})
8190
void rejectsMissingOrWrongCreateValues(String option) {
8291
assertThrows(JSQLParserException.class,
8392
() -> CCJSqlParserUtil.parse("CREATE TABLE t (id INT) " + option));

0 commit comments

Comments
 (0)