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 806eda9a6..dfec6e930 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 @@ -22,6 +22,17 @@ public class CreateIndex implements Statement { private Index index; private List tailParameters; + public boolean isUsingIfNotExists() { + return usingIfNotExists; + } + + public CreateIndex setUsingIfNotExists(boolean usingIfNotExists) { + this.usingIfNotExists = usingIfNotExists; + return this; + } + + private boolean usingIfNotExists = false; + @Override public void accept(StatementVisitor statementVisitor) { statementVisitor.visit(this); @@ -63,6 +74,9 @@ public String toString() { } buffer.append("INDEX "); + if (usingIfNotExists) { + buffer.append("IF NOT EXISTS "); + } buffer.append(index.getName()); buffer.append(" ON "); buffer.append(table.getFullyQualifiedName()); @@ -77,8 +91,10 @@ public String toString() { buffer.append( index.getColumns().stream() - .map(cp -> cp.columnName + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) : "")).collect(joining(", ")) - ); + .map(cp -> cp.columnName + (cp.getParams() != null + ? " " + String.join(" ", cp.getParams()) + : "")) + .collect(joining(", "))); buffer.append(")"); 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 0f2aae236..5a292b283 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) { @@ -32,6 +32,9 @@ public void deParse(CreateIndex createIndex) { } buffer.append("INDEX "); + if (createIndex.isUsingIfNotExists()) { + buffer.append("IF NOT EXISTS "); + } buffer.append(index.getName()); buffer.append(" ON "); buffer.append(createIndex.getTable().getFullyQualifiedName()); @@ -45,7 +48,9 @@ public void deParse(CreateIndex createIndex) { if (index.getColumnsNames() != null) { buffer.append(" ("); buffer.append(index.getColumnWithParams().stream() - .map(cp -> cp.columnName + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) : "")) + .map(cp -> cp.columnName + + (cp.getParams() != null ? " " + String.join(" ", cp.getParams()) + : "")) .collect(joining(", "))); buffer.append(")"); } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 93ecfc537..f933ffef9 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -5167,10 +5167,8 @@ CreateIndex CreateIndex(): CreateIndex createIndex = new CreateIndex(); Table table = null; List colNames; - //Token columnName; Token using; Index index = null; - //String name = null; List parameter = new ArrayList(); List tailParameters = new ArrayList(); List name; @@ -5178,18 +5176,14 @@ CreateIndex CreateIndex(): { [ parameter=CreateParameter() ] - index = Index() { index.setType(parameter.isEmpty()?null:parameter.get(0)); } + + [ LOOKAHEAD(2) { createIndex.setUsingIfNotExists(true);} ] + index = Index() { index.setType(parameter.isEmpty() ? null : parameter.get(0)); } table=Table() - [ using= {index.setUsing(using.image);} ] - colNames = ColumnNamesWithParamsList() - - /* [ tailParameter = CreateParameter() {} ] */ - ( parameter=CreateParameter() { tailParameters.addAll(parameter); } )* - { index.setColumns(colNames); createIndex.setIndex(index); 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 a159215b7..9901a8488 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateIndexTest.java @@ -9,15 +9,17 @@ */ package net.sf.jsqlparser.statement.create; -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 static net.sf.jsqlparser.test.TestUtils.*; +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; -import org.junit.jupiter.api.Test; public class CreateIndexTest { @@ -25,8 +27,7 @@ public class CreateIndexTest { @Test public void testCreateIndex() throws JSQLParserException { - String statement - = "CREATE INDEX myindex ON mytab (mycol, mycol2)"; + String statement = "CREATE INDEX myindex ON mytab (mycol, mycol2)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(2, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -38,8 +39,7 @@ public void testCreateIndex() throws JSQLParserException { @Test public void testCreateIndex2() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol, mycol2)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol, mycol2)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(2, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -51,8 +51,7 @@ public void testCreateIndex2() throws JSQLParserException { @Test public void testCreateIndex3() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2, mycol3)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2, mycol3)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -63,8 +62,7 @@ public void testCreateIndex3() throws JSQLParserException { @Test public void testCreateIndex4() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3)"; + String statement = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -75,8 +73,8 @@ public void testCreateIndex4() throws JSQLParserException { @Test public void testCreateIndex5() throws JSQLParserException { - String statement - = "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3) mymodifiers"; + String statement = + "CREATE mytype INDEX myindex ON mytab (mycol ASC, mycol2 (75), mycol3) mymodifiers"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(3, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex", createIndex.getIndex().getName()); @@ -93,8 +91,7 @@ public void testCreateIndex6() throws JSQLParserException { @Test public void testCreateIndex7() throws JSQLParserException { - String statement - = "CREATE INDEX myindex1 ON mytab USING GIST (mycol)"; + String statement = "CREATE INDEX myindex1 ON mytab USING GIST (mycol)"; CreateIndex createIndex = (CreateIndex) parserManager.parse(new StringReader(statement)); assertEquals(1, createIndex.getIndex().getColumnsNames().size()); assertEquals("myindex1", createIndex.getIndex().getName()); @@ -108,23 +105,25 @@ public void testCreateIndex7() throws JSQLParserException { @Test public void testCreateIndexIssue633() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX idx_american_football_action_plays_1 ON american_football_action_plays USING btree (play_type)"); } @Test public void testFullIndexNameIssue936() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\" ASC) TABLESPACE \"TS\""); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\" ASC) TABLESPACE \"TS\""); } @Test public void testFullIndexNameIssue936_2() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\") TABLESPACE \"TS\""); + assertSqlCanBeParsedAndDeparsed( + "CREATE INDEX \"TS\".\"IDX\" ON \"TEST\" (\"ID\") TABLESPACE \"TS\""); } @Test public void testCreateIndexTrailingOptions() throws JSQLParserException { - String statement - = "CREATE UNIQUE INDEX cfe.version_info_idx2\n" + String statement = "CREATE UNIQUE INDEX cfe.version_info_idx2\n" + " ON cfe.version_info ( major_version\n" + " , minor_version\n" + " , patch_level ) parallel compress nologging\n" @@ -136,4 +135,11 @@ public void testCreateIndexTrailingOptions() throws JSQLParserException { assertEquals(tailParameters.get(1), "compress"); assertEquals(tailParameters.get(2), "nologging"); } + + @Test + void testIfNotExistsIssue1861() throws JSQLParserException { + String sqlStr = + "CREATE INDEX IF NOT EXISTS test_test_idx ON test.test USING btree (\"time\")"; + assertSqlCanBeParsedAndDeparsed(sqlStr, true); + } }