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
22 changes: 21 additions & 1 deletion src/main/java/net/sf/jsqlparser/statement/drop/Drop.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ public enum ObjectType {
private Map<String, List<String>> typeToParameters = new HashMap<>();
private boolean ifExists = false;
private boolean materialized = false;
private boolean concurrently;

/** PostgreSQL DROP INDEX CONCURRENTLY, preceding IF EXISTS and the index name. */
public boolean isConcurrently() {
return concurrently;
}

public void setConcurrently(boolean concurrently) {
this.concurrently = concurrently;
}

public Drop withConcurrently(boolean concurrently) {
setConcurrently(concurrently);
return this;
}


private boolean isUsingTemporary;

Expand Down Expand Up @@ -201,7 +217,11 @@ public StringBuilder appendTo(StringBuilder builder, Consumer<Table> tablePrinte
if (materialized) {
builder.append("MATERIALIZED ");
}
builder.append(type).append(ifExists ? " IF EXISTS " : " ");
builder.append(type);
if (concurrently) {
builder.append(" CONCURRENTLY");
}
builder.append(ifExists ? " IF EXISTS " : " ");
appendNames(builder, tablePrinter);
if ("FUNCTION".equals(type)) {
builder.append(formatFuncParams(getParamsByType("FUNCTION")));
Expand Down
3 changes: 3 additions & 0 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -16334,6 +16334,9 @@ Drop Drop():
tk=<K_FUNCTION>
)
{ drop.setType(tk.image); }
[ LOOKAHEAD({ drop.getObjectType() == Drop.ObjectType.INDEX
&& getToken(1).kind == K_CONCURRENTLY })
<K_CONCURRENTLY> { drop.setConcurrently(true); } ]

[ LOOKAHEAD(2) <K_IF> <K_EXISTS> {drop.setIfExists(true);} ]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2026 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.statement.drop;

import static org.junit.jupiter.api.Assertions.*;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.AbstractJSqlParser.Dialect;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.util.deparser.StatementDeParser;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class PostgreSqlDropIndexTest {
@ParameterizedTest
@ValueSource(strings = {"DROP INDEX CONCURRENTLY ix",
"DROP INDEX CONCURRENTLY IF EXISTS ix",
"DROP INDEX CONCURRENTLY IF EXISTS public.ix RESTRICT"})
void concurrencyIsIndependentOfTarget(String sql) throws JSQLParserException {
Drop drop = (Drop) CCJSqlParserUtil.parse(sql, p -> p.withDialect(Dialect.POSTGRESQL));
assertTrue(drop.isConcurrently());
assertEquals(sql.contains("IF EXISTS"), drop.isIfExists());
assertEquals("ix", drop.getName().getName());
assertEquals(sql, drop.toString());
drop.setName(new Table("new_ix"));
String expected = sql.replace("public.ix", "ix").replace("ix", "new_ix");
assertEquals(expected, drop.toString());
StringBuilder buffer = new StringBuilder();
drop.accept(new StatementDeParser(buffer), null);
assertEquals(expected, buffer.toString());
Drop reparsed = (Drop) CCJSqlParserUtil.parse(expected);
assertEquals("new_ix", reparsed.getName().getName());
assertTrue(reparsed.isConcurrently());
assertEquals(2, CCJSqlParserUtil.parseStatements(expected + "; SELECT 1").size());
drop.setConcurrently(false);
assertEquals(expected.replace("CONCURRENTLY ", ""), drop.toString());
}

@Test
void ordinaryAndQuotedConcurrentNamesArePreserved() throws JSQLParserException {
for (String sql : new String[] {"DROP TABLE concurrently", "DROP INDEX \"concurrently\"",
"DROP INDEX ix1, ix2 CASCADE", "DROP INDEX ix ON t ALGORITHM = INPLACE"}) {
Drop drop = (Drop) CCJSqlParserUtil.parse(sql);
assertFalse(drop.isConcurrently());
assertEquals(sql, drop.toString());
}
}
}
Loading