Skip to content

Commit

Permalink
feat: CREATE INDEX IF NOT EXISTS...
Browse files Browse the repository at this point in the history
- fixes #1861
  • Loading branch information
manticore-projects committed Sep 11, 2023
1 parent 1a6bb7a commit da13d7d
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ public class CreateIndex implements Statement {
private Index index;
private List<String> 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);
Expand Down Expand Up @@ -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());
Expand All @@ -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(")");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CreateIndex> {

public CreateIndexDeParser(StringBuilder buffer) {
Expand All @@ -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());
Expand All @@ -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(")");
}
Expand Down
12 changes: 3 additions & 9 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -5167,29 +5167,23 @@ CreateIndex CreateIndex():
CreateIndex createIndex = new CreateIndex();
Table table = null;
List<Index.ColumnParams> colNames;
//Token columnName;
Token using;
Index index = null;
//String name = null;
List<String> parameter = new ArrayList<String>();
List<String> tailParameters = new ArrayList<String>();
List<String> name;
}
{
[ parameter=CreateParameter() ]

<K_INDEX> index = Index() { index.setType(parameter.isEmpty()?null:parameter.get(0)); }
<K_INDEX>
[ LOOKAHEAD(2) <K_IF> <K_NOT> <K_EXISTS> { createIndex.setUsingIfNotExists(true);} ]
index = Index() { index.setType(parameter.isEmpty() ? null : parameter.get(0)); }

<K_ON> table=Table()

[ <K_USING> using=<S_IDENTIFIER> {index.setUsing(using.image);} ]

colNames = ColumnNamesWithParamsList()

/* [ tailParameter = CreateParameter() {} ] */

( parameter=CreateParameter() { tailParameters.addAll(parameter); } )*

{
index.setColumns(colNames);
createIndex.setIndex(index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@
*/
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 {

private final CCJSqlParserManager parserManager = new CCJSqlParserManager();

@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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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());
Expand All @@ -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"
Expand All @@ -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);
}
}

0 comments on commit da13d7d

Please sign in to comment.