Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class TableOption implements Serializable {

public enum Kind {
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
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
}

private Kind kind = Kind.OTHER;
Expand Down
74 changes: 72 additions & 2 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1560,9 +1560,15 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
return isKeywordAhead("ENGINE_ATTRIBUTE") || isKeywordAhead("SECONDARY_ENGINE_ATTRIBUTE");
}

private boolean isMySqlAdditionalTableOptionAhead() {
String name = getToken(1).image.toUpperCase(Locale.ROOT);
return Arrays.asList("SECONDARY_ENGINE", "AUTOEXTEND_SIZE", "INSERT_METHOD", "PACK_KEYS",
"DELAY_KEY_WRITE", "CHECKSUM", "CONNECTION", "COMPRESSION").contains(name);
}

private boolean isMySqlScalarTableOptionAhead() {
int kind = getToken(1).kind;
return isMySqlEngineAttributeAhead() || kind == K_ENCRYPTION || kind == K_PASSWORD || kind == K_AUTO_INCREMENT
return isMySqlAdditionalTableOptionAhead() || isMySqlEngineAttributeAhead() || kind == K_ENCRYPTION || kind == K_PASSWORD || kind == K_AUTO_INCREMENT
|| (kind == K_DATA || kind == K_INDEX) && getToken(2).kind == K_DIRECTORY;
}

Expand Down Expand Up @@ -15534,17 +15540,22 @@ TableOption MySqlTableOption(): {
}
}

/** Common CREATE/ALTER options with a quoted string or unsigned integer value. */
/** Shared CREATE/ALTER table options with option-specific value syntax. */
TableOption MySqlScalarTableOption():
{
Token token;
String name;
String value;
TableOption.Kind kind;
boolean useEquals = false;
TableOption additional;
}
{
(
LOOKAHEAD({ isMySqlAdditionalTableOptionAhead() }) additional=MySqlAdditionalTableOption()
{ name = additional.getName(); kind = additional.getKind();
value = additional.getValue(); useEquals = additional.isUseEquals(); }
|
<K_AUTO_INCREMENT> { name = "AUTO_INCREMENT"; kind = TableOption.Kind.AUTO_INCREMENT; }
[ "=" { useEquals = true; } ] token=<S_LONG> { value = token.image; }
|
Expand All @@ -15563,6 +15574,65 @@ TableOption MySqlScalarTableOption():
{ return new TableOption(kind, name, value, useEquals); }
}

TableOption MySqlAdditionalTableOption():
{
Token token;
String name;
String value;
boolean useEquals = false;
}
{
(
LOOKAHEAD({ isKeywordAhead("SECONDARY_ENGINE") })
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
( token=<K_NULL> { value = token.image; } | token=<S_CHAR_LITERAL> { value = token.image; } | value=RelObjectName() )
|
LOOKAHEAD({ isKeywordAhead("INSERT_METHOD") })
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
( token=<K_NO> | token=<K_FIRST> | token=<K_LAST> ) { value = token.image; }
|
LOOKAHEAD({ isKeywordAhead("PACK_KEYS") })
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
( token=<K_DEFAULT> | token=<S_LONG> ) {
value = token.image;
if (token.kind == S_LONG && !"0".equals(value) && !"1".equals(value)) {
throw new ParseException("PACK_KEYS requires 0, 1 or DEFAULT");
}
}
|
LOOKAHEAD({ isKeywordAhead("AUTOEXTEND_SIZE") })
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
value=MySqlSizeNumber()
|
LOOKAHEAD({ isKeywordAhead("CHECKSUM") || isKeywordAhead("DELAY_KEY_WRITE") })
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
token=<S_LONG> { value = token.image; }
|
token=<S_IDENTIFIER> { name = token.image.toUpperCase(Locale.ROOT); }
[ "=" { useEquals = true; } ]
token=<S_CHAR_LITERAL> { value = token.image; }
)
{ if (true) { return new TableOption(TableOption.Kind.valueOf(name), name, value, useEquals); } }
}

String MySqlSizeNumber():
{
Token number;
}
{
( number=<S_LONG> | number=<S_IDENTIFIER> )
{
requireDdlSyntax(number.kind == S_LONG || number.image.matches("[0-9]+[kKmMgG]"),
"Expected an unsigned size with an optional K, M or G suffix");
return number.image;
}
}

/** Statistics and row format share CREATE's validation and option nodes. */
AlterExpressionTableOption AlterSharedTableOption():
{ TableOption option; AlterExpressionTableOption action = new AlterExpressionTableOption(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@

class MySqlSharedTableOptionTest {
@ParameterizedTest
@CsvSource(value = {"ENCRYPTION|'N'|ENCRYPTION", "PASSWORD|'ignored'|PASSWORD",
@CsvSource(value = {"SECONDARY_ENGINE|NULL|SECONDARY_ENGINE",
"SECONDARY_ENGINE|'engine'|SECONDARY_ENGINE",
"SECONDARY_ENGINE|engine_name|SECONDARY_ENGINE", "AUTOEXTEND_SIZE|4M|AUTOEXTEND_SIZE",
"AUTOEXTEND_SIZE|0|AUTOEXTEND_SIZE", "INSERT_METHOD|NO|INSERT_METHOD",
"INSERT_METHOD|FIRST|INSERT_METHOD", "INSERT_METHOD|LAST|INSERT_METHOD",
"PACK_KEYS|DEFAULT|PACK_KEYS", "PACK_KEYS|1|PACK_KEYS", "PACK_KEYS|0|PACK_KEYS",
"DELAY_KEY_WRITE|2|DELAY_KEY_WRITE", "CHECKSUM|0|CHECKSUM",
"CONNECTION|'mysql://server/db/t'|CONNECTION", "COMPRESSION|'zlib'|COMPRESSION",
"ENCRYPTION|'N'|ENCRYPTION", "PASSWORD|'ignored'|PASSWORD",
"DATA DIRECTORY|'/tmp/data dir'|DATA_DIRECTORY",
"INDEX DIRECTORY|'/tmp/index dir'|INDEX_DIRECTORY",
"AUTO_INCREMENT|18446744073709551614|AUTO_INCREMENT"}, delimiter = '|',
Expand Down Expand Up @@ -77,7 +85,8 @@ void commasAndQuerySourceStayOutsideOptions() throws JSQLParserException {

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