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 @@ -145,6 +145,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
| **DDL** | `CREATE …` · `ALTER …` · `DROP …` |
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `OPTIMIZE` · `REPAIR TABLE` |
| **PostgreSQL RLS** | `CREATE POLICY` · `ALTER TABLE … ENABLE`/`DISABLE`/`FORCE`/`NO FORCE ROW LEVEL SECURITY` |
| **Routine changes** | `ALTER FUNCTION` · `ALTER PROCEDURE` · `ALTER ROUTINE` · PostgreSQL `ALTER TRIGGER` |
| **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
10 changes: 10 additions & 0 deletions src/main/java/net/sf/jsqlparser/parser/RoutineBodyBoundary.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ private enum Block {
private boolean handlerAction;
private boolean statementStart = true;

/**
* Tracks a compound statement without a routine header, such as a MySQL trigger body. Its
* tokens belong to the body from the start, as after a routine's parameter list.
*/
static RoutineBodyBoundary forCompoundStatement() {
RoutineBodyBoundary boundary = new RoutineBodyBoundary();
boundary.hasParameters = true;
return boundary;
}

boolean endsAt(Token token) throws ParseException {
if (token.kind == EOF) {
if (!blocks.isEmpty()) {
Expand Down
18 changes: 18 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 @@ -509,6 +509,12 @@ public enum Feature {
* @see CreateDatabase
*/
createDatabase,
/**
* SQL "ALTER DATABASE" statement is allowed
*
* @see net.sf.jsqlparser.statement.alter.database.AlterDatabase
*/
alterDatabase,
/**
* SQL "CREATE SCHEMA" statement is allowed
*
Expand Down Expand Up @@ -711,6 +717,18 @@ public enum Feature {
functionalStatement,

alterFunction, alterProcedure, createOrAlterRoutine,
/**
* PostgreSQL "ALTER ROUTINE" statement is allowed
*
* @see net.sf.jsqlparser.statement.alter.AlterRoutine
*/
alterRoutine,
/**
* PostgreSQL "ALTER TRIGGER" statement is allowed
*
* @see net.sf.jsqlparser.statement.alter.AlterTrigger
*/
alterTrigger,
/**
* SQL block starting with "BEGIN" and ends with "END" statement is allowed
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*-
* #%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;

import java.io.Serializable;
import java.util.function.Consumer;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;

/**
* A PostgreSQL {@code SET} or {@code RESET} of a configuration parameter, shared by statements that
* store parameter defaults: {@code ALTER ROLE}, {@code ALTER DATABASE} and the routine
* characteristics of {@code ALTER FUNCTION}, {@code ALTER PROCEDURE} and {@code ALTER ROUTINE}:
*
* <pre>
* SET parameter { TO | = } { value [, ...] | DEFAULT }
* SET parameter FROM CURRENT
* RESET { parameter | ALL }
* </pre>
*
* Parameter names keep their SQL spelling, including qualifiers and identifier quotes.
* {@code RESET ALL} uses the parameter name {@code ALL}.
*/
public class ConfigurationParameterChange implements Serializable {

public enum Action {
SET, RESET
}

/** What a {@code SET} assigns. Only the selected kind is rendered. */
public enum ValueKind {
/** The explicit values of {@link #getValues()}. */
VALUES,
/** {@code TO DEFAULT} or {@code = DEFAULT}. */
DEFAULT,
/** {@code FROM CURRENT}. */
FROM_CURRENT
}

private Action action = Action.SET;
private String parameter;
private ValueKind valueKind = ValueKind.VALUES;
private boolean useEquals;
private ExpressionList<Expression> values;

public ConfigurationParameterChange() {}

public ConfigurationParameterChange(Action action, String parameter) {
this.action = action;
this.parameter = parameter;
}

public Action getAction() {
return action;
}

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

public String getParameter() {
return parameter;
}

public void setParameter(String parameter) {
this.parameter = parameter;
}

public ValueKind getValueKind() {
return valueKind;
}

/**
* Selects what a {@code SET} assigns. The values are retained when another kind is selected.
*
* @param valueKind the assigned value kind
*/
public void setValueKind(ValueKind valueKind) {
this.valueKind = valueKind;
}

/**
* Whether {@code =} rather than {@code TO} precedes the value.
*
* @return {@code true} for {@code =}
*/
public boolean isUseEquals() {
return useEquals;
}

public void setUseEquals(boolean useEquals) {
this.useEquals = useEquals;
}

/**
* The values assigned by {@link ValueKind#VALUES}, as a mutable list.
*
* @return the values, or {@code null} if none were set
*/
public ExpressionList<Expression> getValues() {
return values;
}

public void setValues(ExpressionList<Expression> values) {
this.values = values;
}

public ConfigurationParameterChange withAction(Action action) {
setAction(action);
return this;
}

public ConfigurationParameterChange withParameter(String parameter) {
setParameter(parameter);
return this;
}

public ConfigurationParameterChange withValueKind(ValueKind valueKind) {
setValueKind(valueKind);
return this;
}

public ConfigurationParameterChange withUseEquals(boolean useEquals) {
setUseEquals(useEquals);
return this;
}

public ConfigurationParameterChange withValues(ExpressionList<Expression> values) {
setValues(values);
return this;
}

/**
* Appends this clause to a builder.
*
* @param builder the target
* @param valueRenderer appends each value, for example through an expression deparser
* @return the builder
*/
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> valueRenderer) {
if (action == Action.RESET) {
return builder.append("RESET ").append(parameter);
}
builder.append("SET ").append(parameter);
if (valueKind == ValueKind.FROM_CURRENT) {
return builder.append(" FROM CURRENT");
}
builder.append(useEquals ? " = " : " TO ");
if (valueKind == ValueKind.DEFAULT) {
return builder.append("DEFAULT");
}
if (values != null) {
for (int i = 0; i < values.size(); i++) {
if (i > 0) {
builder.append(", ");
}
valueRenderer.accept(values.get(i));
}
}
return builder;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
return appendTo(builder, builder::append).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum Operation {
}

private Operation operation = Operation.CREATE;
private MySqlDefiner definer;
private FunctionReturnType returnType;
private List<String> routineBodyParts;

Expand All @@ -42,6 +43,19 @@ public void setOperation(Operation operation) {
this.operation = operation;
}

/**
* The MySQL {@code DEFINER} account, rendered after {@code CREATE [OR REPLACE]}.
*
* @return the definer, or {@code null}
*/
public MySqlDefiner getDefiner() {
return definer;
}

public void setDefiner(MySqlDefiner definer) {
this.definer = definer;
}

public FunctionReturnType getReturnType() {
return returnType;
}
Expand Down Expand Up @@ -139,6 +153,9 @@ public StringBuilder appendTo(StringBuilder builder, Consumer<TableElement> prin
if (orReplace && operation == Operation.CREATE) {
builder.append("OR REPLACE ");
}
if (definer != null) {
builder.append("DEFINER = ").append(definer).append(' ');
}
builder.append(kind).append(' ');
return appendDeclarationTo(builder, printer);
}
Expand Down
Loading
Loading