diff --git a/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java b/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java index dfec6e930..3fc4fcbf1 100644 --- a/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java +++ b/src/main/java/net/sf/jsqlparser/statement/create/index/CreateIndex.java @@ -9,18 +9,27 @@ */ package net.sf.jsqlparser.statement.create.index; +import static java.util.stream.Collectors.joining; + +import java.util.*; import net.sf.jsqlparser.schema.*; import net.sf.jsqlparser.statement.*; import net.sf.jsqlparser.statement.create.table.*; -import java.util.*; -import static java.util.stream.Collectors.joining; - public class CreateIndex implements Statement { private Table table; private Index index; private List tailParameters; + private boolean indexTypeBeforeOn = false; + + public boolean isIndexTypeBeforeOn() { + return indexTypeBeforeOn; + } + + public void setIndexTypeBeforeOn(boolean indexTypeBeforeOn) { + this.indexTypeBeforeOn = indexTypeBeforeOn; + } public boolean isUsingIfNotExists() { return usingIfNotExists; @@ -78,10 +87,16 @@ public String toString() { buffer.append("IF NOT EXISTS "); } buffer.append(index.getName()); + + if (index.getUsing() != null && isIndexTypeBeforeOn()) { + buffer.append(" USING "); + buffer.append(index.getUsing()); + } + buffer.append(" ON "); buffer.append(table.getFullyQualifiedName()); - if (index.getUsing() != null) { + if (index.getUsing() != null && !isIndexTypeBeforeOn()) { buffer.append(" USING "); buffer.append(index.getUsing()); } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java index 5a292b283..a82f478d7 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/CreateIndexDeParser.java @@ -9,11 +9,11 @@ */ package net.sf.jsqlparser.util.deparser; +import static java.util.stream.Collectors.joining; + import net.sf.jsqlparser.statement.create.index.CreateIndex; import net.sf.jsqlparser.statement.create.table.Index; -import static java.util.stream.Collectors.joining; - public class CreateIndexDeParser extends AbstractDeParser { public CreateIndexDeParser(StringBuilder buffer) { @@ -36,11 +36,17 @@ public void deParse(CreateIndex createIndex) { buffer.append("IF NOT EXISTS "); } buffer.append(index.getName()); + + String using = index.getUsing(); + if (using != null && createIndex.isIndexTypeBeforeOn()) { + buffer.append(" USING "); + buffer.append(using); + } + buffer.append(" ON "); buffer.append(createIndex.getTable().getFullyQualifiedName()); - String using = index.getUsing(); - if (using != null) { + if (using != null && !createIndex.isIndexTypeBeforeOn()) { buffer.append(" USING "); buffer.append(using); } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index f9dafcb4f..824f6d6ce 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -5302,9 +5302,21 @@ CreateIndex CreateIndex(): [ LOOKAHEAD(2) { createIndex.setUsingIfNotExists(true);} ] index = Index() { index.setType(parameter.isEmpty() ? null : parameter.get(0)); } - - table=Table() - [ using= {index.setUsing(using.image);} ] + ( + LOOKAHEAD(3)( + table=Table() + [ using= { index.setUsing(using.image); } ] + ) + | + ( + [ using= { + index.setUsing(using.image); + createIndex.setIndexTypeBeforeOn(true); + } + ] + table=Table() + ) + ) colNames = ColumnNamesWithParamsList() ( parameter=CreateParameter() { tailParameters.addAll(parameter); } )* { diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java index 9901a8488..23b1d581a 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java @@ -9,18 +9,17 @@ */ package net.sf.jsqlparser.statement.create; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.io.StringReader; +import java.util.List; import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.statement.create.index.CreateIndex; import org.junit.jupiter.api.Test; -import java.io.StringReader; -import java.util.List; - -import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - public class CreateIndexTest { private final CCJSqlParserManager parserManager = new CCJSqlParserManager(); @@ -142,4 +141,11 @@ void testIfNotExistsIssue1861() throws JSQLParserException { "CREATE INDEX IF NOT EXISTS test_test_idx ON test.test USING btree (\"time\")"; assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + + @Test + void testCreateIndexIssue1814() throws JSQLParserException { + String sqlStr = + "CREATE INDEX idx_operationlog_operatetime_regioncode USING BTREE ON operation_log (operate_time,region_biz_code)"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } }