Skip to content

Commit e50738b

Browse files
committed
feat: share additional MySQL CREATE and ALTER table options
Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent 8ffa565 commit e50738b

3 files changed

Lines changed: 84 additions & 6 deletions

File tree

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +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,
25-
STORAGE_PARAMETERS, WITHOUT_OIDS, ENGINE_ATTRIBUTE, SECONDARY_ENGINE_ATTRIBUTE, 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, OTHER
2625
}
2726

2827
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
@@ -1560,9 +1560,15 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
15601560
return isKeywordAhead("ENGINE_ATTRIBUTE") || isKeywordAhead("SECONDARY_ENGINE_ATTRIBUTE");
15611561
}
15621562

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

@@ -15434,17 +15440,22 @@ TableOption MySqlTableOption(): {
1543415440
}
1543515441
}
1543615442

15437-
/** Common CREATE/ALTER options with a quoted string or unsigned integer value. */
15443+
/** Shared CREATE/ALTER table options with option-specific value syntax. */
1543815444
TableOption MySqlScalarTableOption():
1543915445
{
1544015446
Token token;
1544115447
String name;
1544215448
String value;
1544315449
TableOption.Kind kind;
1544415450
boolean useEquals = false;
15451+
TableOption additional;
1544515452
}
1544615453
{
1544715454
(
15455+
LOOKAHEAD({ isMySqlAdditionalTableOptionAhead() }) additional=MySqlAdditionalTableOption()
15456+
{ name = additional.getName(); kind = additional.getKind();
15457+
value = additional.getValue(); useEquals = additional.isUseEquals(); }
15458+
|
1544815459
<K_AUTO_INCREMENT> { name = "AUTO_INCREMENT"; kind = TableOption.Kind.AUTO_INCREMENT; }
1544915460
[ "=" { useEquals = true; } ] token=<S_LONG> { value = token.image; }
1545015461
|
@@ -15463,6 +15474,65 @@ TableOption MySqlScalarTableOption():
1546315474
{ return new TableOption(kind, name, value, useEquals); }
1546415475
}
1546515476

15477+
TableOption MySqlAdditionalTableOption():
15478+
{
15479+
Token token;
15480+
String name;
15481+
String value;
15482+
boolean useEquals = false;
15483+
}
15484+
{
15485+
(
15486+
LOOKAHEAD({ isKeywordAhead("SECONDARY_ENGINE") })
15487+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15488+
[ "=" { useEquals = true; } ]
15489+
( token=<K_NULL> { value = token.image; } | token=<S_CHAR_LITERAL> { value = token.image; } | value=RelObjectName() )
15490+
|
15491+
LOOKAHEAD({ isKeywordAhead("INSERT_METHOD") })
15492+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15493+
[ "=" { useEquals = true; } ]
15494+
( token=<K_NO> | token=<K_FIRST> | token=<K_LAST> ) { value = token.image; }
15495+
|
15496+
LOOKAHEAD({ isKeywordAhead("PACK_KEYS") })
15497+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15498+
[ "=" { useEquals = true; } ]
15499+
( token=<K_DEFAULT> | token=<S_LONG> ) {
15500+
value = token.image;
15501+
if (token.kind == S_LONG && !"0".equals(value) && !"1".equals(value)) {
15502+
throw new ParseException("PACK_KEYS requires 0, 1 or DEFAULT");
15503+
}
15504+
}
15505+
|
15506+
LOOKAHEAD({ isKeywordAhead("AUTOEXTEND_SIZE") })
15507+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15508+
[ "=" { useEquals = true; } ]
15509+
value=MySqlSizeNumber()
15510+
|
15511+
LOOKAHEAD({ isKeywordAhead("CHECKSUM") || isKeywordAhead("DELAY_KEY_WRITE") })
15512+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15513+
[ "=" { useEquals = true; } ]
15514+
token=<S_LONG> { value = token.image; }
15515+
|
15516+
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
15517+
[ "=" { useEquals = true; } ]
15518+
token=<S_CHAR_LITERAL> { value = token.image; }
15519+
)
15520+
{ if (true) { return new TableOption(TableOption.Kind.valueOf(name), name, value, useEquals); } }
15521+
}
15522+
15523+
String MySqlSizeNumber():
15524+
{
15525+
Token number;
15526+
}
15527+
{
15528+
( number=<S_LONG> | number=<S_IDENTIFIER> )
15529+
{
15530+
requireDdlSyntax(number.kind == S_LONG || number.image.matches("[0-9]+[kKmMgG]"),
15531+
"Expected an unsigned size with an optional K, M or G suffix");
15532+
return number.image;
15533+
}
15534+
}
15535+
1546615536
AlterExpressionTableOption AlterScalarTableOption():
1546715537
{
1546815538
TableOption option;

‎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)