in core/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlCreateTableParser.java [91:563]
public MySqlCreateTableStatement parseCreateTable() {
MySqlCreateTableStatement stmt = new MySqlCreateTableStatement();
if (lexer.hasComment() && lexer.isKeepComments()) {
stmt.addBeforeComment(lexer.readAndResetComments());
}
accept(Token.CREATE);
if (lexer.nextIfIdentifier("TEMPORARY")) {
stmt.config(SQLCreateTableStatement.Feature.Temporary);
} else if (lexer.nextIfIdentifier("SHADOW")) {
stmt.config(SQLCreateTableStatement.Feature.Shadow);
}
if (lexer.identifierEquals(FnvHash.Constants.DIMENSION)) {
lexer.nextToken();
stmt.setDimension(true);
}
if (lexer.token() == Token.HINT) {
this.exprParser.parseHints(stmt.getHints());
}
if (lexer.identifierEquals(FnvHash.Constants.EXTERNAL)) {
lexer.nextToken();
stmt.setExternal(true);
}
accept(Token.TABLE);
if (lexer.token() == Token.IF || lexer.identifierEquals("IF")) {
lexer.nextToken();
accept(Token.NOT);
accept(Token.EXISTS);
stmt.setIfNotExists(true);
}
stmt.setName(this.exprParser.name());
if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLName name = this.exprParser.name();
stmt.setLike(name);
}
if (lexer.token() == Token.WITH) {
SQLSelect query = new MySqlSelectParser(this.exprParser).select();
stmt.setSelect(query);
} else if (lexer.token() == (Token.LPAREN)) {
lexer.nextToken();
if (lexer.token() == Token.SELECT) {
SQLSelect query = new MySqlSelectParser(this.exprParser).select();
stmt.setSelect(query);
} else {
for (; ; ) {
SQLColumnDefinition column = null;
boolean global = false;
if (lexer.identifierEquals(FnvHash.Constants.GLOBAL)) {
final Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.INDEX || lexer.token() == Token.UNIQUE) {
global = true;
} else {
lexer.reset(mark);
}
}
boolean local = false;
if (lexer.identifierEquals(FnvHash.Constants.LOCAL)) {
final Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.INDEX || lexer.token() == Token.KEY
|| lexer.token() == Token.UNIQUE) {
local = true;
} else if (lexer.token() == Token.FULLTEXT) {
lexer.nextToken();
if (lexer.token() == Token.KEY) {
MySqlKey fulltextKey = new MySqlKey();
this.exprParser.parseIndex(fulltextKey.getIndexDefinition());
fulltextKey.setIndexType("FULLTEXT");
fulltextKey.setParent(stmt);
stmt.getTableElementList().add(fulltextKey);
while (lexer.token() == Token.HINT) {
lexer.nextToken();
}
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.INDEX) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("FULLTEXT");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.IDENTIFIER && MySqlUtils.isBuiltinDataType(
lexer.stringVal())) {
lexer.reset(mark);
} else {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("FULLTEXT");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
}
} else if (lexer.identifierEquals(FnvHash.Constants.SPATIAL)) {
lexer.nextToken();
if (lexer.token() == Token.INDEX || lexer.token() == Token.KEY ||
lexer.token() != Token.IDENTIFIER || !MySqlUtils.isBuiltinDataType(lexer.stringVal())) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("SPATIAL");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else {
lexer.reset(mark);
}
} else {
lexer.reset(mark);
}
}
if (lexer.token() == Token.FULLTEXT) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.KEY) {
MySqlKey fulltextKey = new MySqlKey();
this.exprParser.parseIndex(fulltextKey.getIndexDefinition());
fulltextKey.setIndexType("FULLTEXT");
fulltextKey.setParent(stmt);
stmt.getTableElementList().add(fulltextKey);
while (lexer.token() == Token.HINT) {
lexer.nextToken();
}
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.INDEX) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("FULLTEXT");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.IDENTIFIER && MySqlUtils.isBuiltinDataType(lexer.stringVal())) {
lexer.reset(mark);
} else {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("FULLTEXT");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
}
} else if (lexer.identifierEquals(FnvHash.Constants.SPATIAL)) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.INDEX || lexer.token() == Token.KEY ||
lexer.token() != Token.IDENTIFIER || !MySqlUtils.isBuiltinDataType(lexer.stringVal())) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("SPATIAL");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else {
lexer.reset(mark);
}
}
if (lexer.identifierEquals(FnvHash.Constants.ANN)) {
Lexer.SavePoint mark = lexer.mark();
lexer.nextToken();
if (lexer.token() == Token.INDEX || lexer.token() == Token.KEY) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("ANN");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else {
lexer.reset(mark);
}
}
if (lexer.identifierEquals(FnvHash.Constants.CLUSTERED)) {
lexer.nextToken();
if (lexer.token() == Token.KEY) {
MySqlKey clsKey = new MySqlKey();
this.exprParser.parseIndex(clsKey.getIndexDefinition());
clsKey.setIndexType("CLUSTERED");
clsKey.setParent(stmt);
stmt.getTableElementList().add(clsKey);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.INDEX) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("CLUSTERED");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
}
} else if (lexer.identifierEquals(FnvHash.Constants.CLUSTERING)) {
lexer.nextToken();
if (lexer.token() == Token.KEY) {
MySqlKey clsKey = new MySqlKey();
this.exprParser.parseIndex(clsKey.getIndexDefinition());
clsKey.setIndexType("CLUSTERING");
clsKey.setParent(stmt);
stmt.getTableElementList().add(clsKey);
if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
} else if (lexer.token() == Token.INDEX) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
idx.setIndexType("CLUSTERING");
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
if (lexer.token() == Token.RPAREN) {
break;
} else if (lexer.token() == Token.COMMA) {
lexer.nextToken();
continue;
}
}
} else if (lexer.token() == Token.IDENTIFIER //
|| lexer.token() == Token.LITERAL_CHARS) {
column = this.exprParser.parseColumn();
column.setParent(stmt);
stmt.getTableElementList().add(column);
if (lexer.isKeepComments() && lexer.hasComment()) {
column.addAfterComment(lexer.readAndResetComments());
}
} else if (lexer.token() == Token.CONSTRAINT //
|| lexer.token() == Token.PRIMARY //
|| lexer.token() == Token.UNIQUE) {
SQLTableConstraint constraint = this.parseConstraint();
constraint.setParent(stmt);
if (constraint instanceof MySqlUnique) {
MySqlUnique unique = (MySqlUnique) constraint;
if (global) {
unique.setGlobal(true);
}
if (local) {
unique.setLocal(true);
}
}
stmt.getTableElementList().add(constraint);
} else if (lexer.token() == (Token.INDEX)) {
MySqlTableIndex idx = new MySqlTableIndex();
this.exprParser.parseIndex(idx.getIndexDefinition());
if (global) {
idx.getIndexDefinition().setGlobal(true);
}
if (local) {
idx.getIndexDefinition().setLocal(true);
}
idx.setParent(stmt);
stmt.getTableElementList().add(idx);
} else if (lexer.token() == (Token.KEY)) {
Lexer.SavePoint savePoint = lexer.mark();
lexer.nextToken();
boolean isColumn = false;
if (lexer.identifierEquals(FnvHash.Constants.VARCHAR)) {
isColumn = true;
}
lexer.reset(savePoint);
if (isColumn) {
column = this.exprParser.parseColumn();
stmt.getTableElementList().add(column);
} else {
stmt.getTableElementList().add(parseConstraint());
}
} else if (lexer.token() == (Token.PRIMARY)) {
SQLTableConstraint pk = parseConstraint();
pk.setParent(stmt);
stmt.getTableElementList().add(pk);
} else if (lexer.token() == (Token.FOREIGN)) {
SQLForeignKeyConstraint fk = this.getExprParser().parseForeignKey();
fk.setParent(stmt);
stmt.getTableElementList().add(fk);
} else if (lexer.token() == Token.CHECK) {
SQLCheck check = this.exprParser.parseCheck();
stmt.getTableElementList().add(check);
} else if (lexer.token() == Token.LIKE) {
lexer.nextToken();
SQLTableLike tableLike = new SQLTableLike();
tableLike.setTable(new SQLExprTableSource(this.exprParser.name()));
tableLike.setParent(stmt);
stmt.getTableElementList().add(tableLike);
if (lexer.identifierEquals(FnvHash.Constants.INCLUDING)) {
lexer.nextToken();
acceptIdentifier("PROPERTIES");
tableLike.setIncludeProperties(true);
} else if (lexer.identifierEquals(FnvHash.Constants.EXCLUDING)) {
lexer.nextToken();
acceptIdentifier("PROPERTIES");
tableLike.setExcludeProperties(true);
}
} else {
column = this.exprParser.parseColumn();
stmt.getTableElementList().add(column);
}
if (lexer.token() == Token.HINT) {
lexer.nextToken();
}
if (lexer.token() != Token.COMMA) {
break;
} else {
lexer.nextToken();
if (lexer.isKeepComments() && lexer.hasComment() && column != null) {
column.addAfterComment(lexer.readAndResetComments());
}
}
}
}
if (lexer.token() == Token.HINT) {
lexer.nextToken();
}
accept(Token.RPAREN);
if (lexer.token() == Token.HINT && lexer.stringVal().charAt(0) == '!') {
lexer.nextToken();
}
}
parseOptions(stmt);
if (lexer.token() == (Token.ON)) {
throw new ParserException("TODO. " + lexer.info());
}
if (lexer.token() == Token.REPLACE) {
lexer.nextToken();
stmt.setReplace(true);
} else if (lexer.identifierEquals("IGNORE")) {
lexer.nextToken();
stmt.setIgnore(true);
} else if (lexer.identifierEquals("SINGLE")) { // for polardb-x
lexer.nextToken();
stmt.setSingle(true);
}
if (lexer.token() == (Token.AS)) {
lexer.nextToken();
if (lexer.token() == Token.LPAREN) {
lexer.nextToken();
SQLSelect query = new MySqlSelectParser(this.exprParser).select();
stmt.setSelect(query);
accept(Token.RPAREN);
}
if (lexer.token() == Token.WITH) {
stmt.setWithSelect(this.parseWith());
}
}
SQLCommentHint hint = null;
if (lexer.token() == Token.HINT) {
hint = this.exprParser.parseHint();
}
if (lexer.token() == (Token.SELECT)) {
SQLSelect query = new MySqlSelectParser(this.exprParser).select();
if (hint != null) {
query.setHeadHint(hint);
}
stmt.setSelect(query);
if (lexer.token() == Token.WITH) {
lexer.nextToken();
if (lexer.identifierEquals(FnvHash.Constants.NO)) {
lexer.nextToken();
acceptIdentifier("DATA");
stmt.setWithData(false);
} else {
acceptIdentifier("DATA");
stmt.setWithData(true);
}
}
}
while (lexer.token() == (Token.HINT)) {
this.exprParser.parseHints(stmt.getOptionHints());
}
return stmt;
}