Skip to content
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
| **DML** | `INSERT` · `UPDATE` · `UPSERT` · `MERGE` · `DELETE` · `TRUNCATE TABLE` |
| **DDL** | `CREATE …` · `ALTER …` · `DROP …` |
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `OPTIMIZE` · `REPAIR TABLE` |
| **Tablespaces** | MySQL and PostgreSQL `CREATE TABLESPACE` · `ALTER TABLESPACE` |
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/net/sf/jsqlparser/parser/feature/Feature.java
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,19 @@ public enum Feature {
*/
alterIndex,

/**
* MySQL and PostgreSQL "CREATE TABLESPACE" statement is allowed
*
* @see net.sf.jsqlparser.statement.create.tablespace.CreateTablespace
*/
createTablespace,
/**
* MySQL and PostgreSQL "ALTER TABLESPACE" statement is allowed
*
* @see net.sf.jsqlparser.statement.alter.AlterTablespace
*/
alterTablespace,


/**
* SQL "ANALYZE" statement is allowed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import net.sf.jsqlparser.statement.alter.AlterStatistics;
import net.sf.jsqlparser.statement.alter.AlterSubscription;
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
import net.sf.jsqlparser.statement.alter.AlterTablespace;
import net.sf.jsqlparser.statement.alter.AlterTablespaceMove;
import net.sf.jsqlparser.statement.alter.AlterTextSearchConfiguration;
import net.sf.jsqlparser.statement.alter.AlterType;
Expand Down Expand Up @@ -67,6 +68,7 @@
import net.sf.jsqlparser.statement.create.subscription.SubscriptionOption;
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.tablespace.CreateTablespace;
import net.sf.jsqlparser.statement.create.textsearch.CreateTextSearchConfiguration;
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
import net.sf.jsqlparser.statement.create.type.CreateType;
Expand Down Expand Up @@ -1201,6 +1203,16 @@ public <S> Void visit(AlterTablespaceMove statement, S context) {
return schemaOnly();
}

@Override
public <S> Void visit(CreateTablespace statement, S context) {
return schemaOnly();
}

@Override
public <S> Void visit(AlterTablespace statement, S context) {
return schemaOnly();
}

@Override
public <S> Void visit(AlterTextSearchConfiguration statement, S context) {
return schemaOnly();
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.sf.jsqlparser.statement.create.statistics.CreateStatistics;
import net.sf.jsqlparser.statement.alter.AlterStatistics;
import net.sf.jsqlparser.statement.alter.AlterRelation;
import net.sf.jsqlparser.statement.alter.AlterTablespace;
import net.sf.jsqlparser.statement.alter.AlterTablespaceMove;
import net.sf.jsqlparser.statement.alter.database.AlterDatabase;
import net.sf.jsqlparser.statement.alter.schema.AlterSchema;
Expand Down Expand Up @@ -66,6 +67,7 @@
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.tablespace.CreateTablespace;
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
import net.sf.jsqlparser.statement.create.user.CreateUser;
import net.sf.jsqlparser.statement.create.view.AlterView;
Expand Down Expand Up @@ -740,6 +742,22 @@ default void visit(AlterTablespaceMove statement) {
visit(statement, null);
}

default <S> T visit(CreateTablespace statement, S context) {
return null;
}

default void visit(CreateTablespace statement) {
visit(statement, null);
}

default <S> T visit(AlterTablespace statement, S context) {
return null;
}

default void visit(AlterTablespace statement) {
visit(statement, null);
}

default <S> T visit(AlterPolicy statement, S context) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package net.sf.jsqlparser.statement;

import net.sf.jsqlparser.statement.alter.AlterRelation;
import net.sf.jsqlparser.statement.alter.AlterTablespace;
import net.sf.jsqlparser.statement.alter.AlterPolicy;
import net.sf.jsqlparser.statement.drop.DropPolicy;
import net.sf.jsqlparser.statement.create.statistics.CreateStatistics;
Expand Down Expand Up @@ -68,6 +69,7 @@
import net.sf.jsqlparser.statement.create.sequence.CreateSequence;
import net.sf.jsqlparser.statement.create.synonym.CreateSynonym;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.tablespace.CreateTablespace;
import net.sf.jsqlparser.statement.create.trigger.CreateTrigger;
import net.sf.jsqlparser.statement.create.user.CreateUser;
import net.sf.jsqlparser.statement.create.view.AlterView;
Expand Down Expand Up @@ -937,6 +939,18 @@ public <S> T visit(AlterRelation statement, S context) {
return null;
}

@Override
public <S> T visit(CreateTablespace statement, S context) {
statement.visitExpressions(expression -> expression.accept(expressionVisitor, context));
return null;
}

@Override
public <S> T visit(AlterTablespace statement, S context) {
statement.visitExpressions(expression -> expression.accept(expressionVisitor, context));
return null;
}

@Override
public <S> T visit(AlterPolicy statement, S context) {
fromItemVisitor.visitFromItem(statement.getTable(), context);
Expand Down
216 changes: 216 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/alter/AlterTablespace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/*-
* #%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.alter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.create.table.IndexOption;
import net.sf.jsqlparser.statement.create.table.TableOption;
import net.sf.jsqlparser.statement.select.PlainSelect;

/**
* A MySQL {@code ALTER [UNDO] TABLESPACE} or PostgreSQL {@code ALTER TABLESPACE} statement. The
* {@link Action} selects which properties are rendered. Moving all relations of a tablespace with
* {@code ALTER TABLE ALL IN TABLESPACE} remains {@link AlterTablespaceMove}.
*/
public class AlterTablespace implements Statement {

public enum Action {
/** {@code RENAME TO newName}. */
RENAME,
/** PostgreSQL {@code OWNER TO owner}. */
OWNER,
/** PostgreSQL {@code SET (parameter = value, ...)}. */
SET_PARAMETERS,
/** PostgreSQL {@code RESET (parameter, ...)}. */
RESET_PARAMETERS,
/** MySQL undo tablespace {@code SET ACTIVE} or {@code SET INACTIVE}, then any options. */
SET_STATE,
/** MySQL options such as {@code ENGINE} or {@code ENCRYPTION}. */
OPTIONS
}

/** The state of a MySQL undo tablespace. */
public enum State {
ACTIVE, INACTIVE
}

private String name;
private boolean undo;
private Action action;
private String newName;
private String owner;
private List<IndexOption> parameters;
private List<String> resetParameters;
private State state;
private final List<TableOption> options = new ArrayList<>();

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

/** Whether this is a MySQL {@code ALTER UNDO TABLESPACE} statement. */
public boolean isUndo() {
return undo;
}

public void setUndo(boolean undo) {
this.undo = undo;
}

public Action getAction() {
return action;
}

public void setAction(Action action) {
this.action = action;
}

/** Returns the new name of a {@link Action#RENAME}. */
public String getNewName() {
return newName;
}

public void setNewName(String newName) {
this.newName = newName;
}

/** Returns the new owner of an {@link Action#OWNER}. */
public String getOwner() {
return owner;
}

public void setOwner(String owner) {
this.owner = owner;
}

/** Returns the PostgreSQL parameters of a {@link Action#SET_PARAMETERS}. */
public List<IndexOption> getParameters() {
return parameters;
}

public void setParameters(List<IndexOption> parameters) {
this.parameters = parameters;
}

/** Returns the PostgreSQL parameter names of a {@link Action#RESET_PARAMETERS}. */
public List<String> getResetParameters() {
return resetParameters;
}

public void setResetParameters(List<String> resetParameters) {
this.resetParameters = resetParameters;
}

/** Returns the MySQL undo tablespace state of a {@link Action#SET_STATE}. */
public State getState() {
return state;
}

public void setState(State state) {
this.state = state;
}

/**
* Returns the mutable MySQL options of a {@link Action#SET_STATE} or {@link Action#OPTIONS} in
* source order; commas between them are not kept.
*/
public List<TableOption> getOptions() {
return options;
}

public void setOptions(Collection<TableOption> options) {
this.options.clear();
if (options != null) {
this.options.addAll(options);
}
}

public AlterTablespace addOptions(TableOption... options) {
Collections.addAll(this.options, options);
return this;
}

/** Returns the first MySQL option of the given kind. */
public Optional<TableOption> getOption(TableOption.Kind kind) {
return options.stream().filter(option -> option.getKind() == kind).findFirst();
}

public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
if (action == null) {
throw new IllegalStateException("ALTER TABLESPACE requires an action");
}
builder.append(undo ? "ALTER UNDO TABLESPACE " : "ALTER TABLESPACE ").append(name);
switch (action) {
case RENAME:
builder.append(" RENAME TO ").append(newName);
break;
case OWNER:
builder.append(" OWNER TO ").append(owner);
break;
case SET_PARAMETERS:
builder.append(" SET ");
IndexOption.appendListTo(builder, parameters, expressionPrinter);
break;
case RESET_PARAMETERS:
builder.append(" RESET ")
.append(PlainSelect.getStringList(resetParameters, true, true));
break;
case SET_STATE:
builder.append(" SET ").append(state);
appendOptionsTo(builder, expressionPrinter);
break;
case OPTIONS:
appendOptionsTo(builder, expressionPrinter);
break;
default:
throw new IllegalStateException("Unknown tablespace action: " + action);
}
return builder;
}

private void appendOptionsTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
for (TableOption option : options) {
builder.append(' ');
option.appendTo(builder, expressionPrinter);
}
}

/** Visits the values of PostgreSQL {@code SET} parameters. */
public void visitExpressions(Consumer<Expression> visitor) {
if (action == Action.SET_PARAMETERS && parameters != null) {
parameters.stream().map(IndexOption::getValue).filter(Objects::nonNull)
.forEach(visitor);
}
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
return appendTo(builder, builder::append).toString();
}

@Override
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
return statementVisitor.visit(this, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
/**
* A shared CREATE/ALTER TABLE option with either opaque tokens or structured properties. Setting
* non-null tokens discards all structured properties. A structured setter discards the tokens;
* their contents are never parsed or restored by a later setter.
* their contents are never parsed or restored by a later setter. MySQL tablespace statements reuse
* this model for their options; {@link Kind#FILE_BLOCK_SIZE} occurs only there.
*/
public class TableOption implements Serializable {

Expand All @@ -35,7 +36,7 @@ public class TableOption implements Serializable {
private ColumnOption.Storage tablespaceStorage;

public enum Kind {
ENGINE, CHARACTER_SET, COLLATE, COMMENT, AUTO_INCREMENT, STATS_AUTO_RECALC, STATS_PERSISTENT, STATS_SAMPLE_PAGES, UNION, ENCRYPTION, PASSWORD, DATA_DIRECTORY, INDEX_DIRECTORY, SECONDARY_ENGINE, AUTOEXTEND_SIZE, INSERT_METHOD, PACK_KEYS, DELAY_KEY_WRITE, CHECKSUM, CONNECTION, COMPRESSION, STORAGE_PARAMETERS, WITHOUT_OIDS, ENGINE_ATTRIBUTE, SECONDARY_ENGINE_ATTRIBUTE, ROW_FORMAT, AVG_ROW_LENGTH, MAX_ROWS, MIN_ROWS, KEY_BLOCK_SIZE, TABLESPACE, FOREIGN_SERVER, OTHER
ENGINE, CHARACTER_SET, COLLATE, COMMENT, AUTO_INCREMENT, STATS_AUTO_RECALC, STATS_PERSISTENT, STATS_SAMPLE_PAGES, UNION, ENCRYPTION, PASSWORD, DATA_DIRECTORY, INDEX_DIRECTORY, SECONDARY_ENGINE, AUTOEXTEND_SIZE, INSERT_METHOD, PACK_KEYS, DELAY_KEY_WRITE, CHECKSUM, CONNECTION, COMPRESSION, STORAGE_PARAMETERS, WITHOUT_OIDS, ENGINE_ATTRIBUTE, SECONDARY_ENGINE_ATTRIBUTE, ROW_FORMAT, AVG_ROW_LENGTH, MAX_ROWS, MIN_ROWS, KEY_BLOCK_SIZE, TABLESPACE, FOREIGN_SERVER, FILE_BLOCK_SIZE, OTHER
}

public ForeignTableOptions getForeignTableOptions() {
Expand Down
Loading
Loading