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 @@ -158,6 +158,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
| **Routine changes** | `ALTER FUNCTION` · `ALTER PROCEDURE` · `ALTER ROUTINE` · PostgreSQL `ALTER TRIGGER` |
| **MySQL metadata statements** | `SHOW [FULL] COLUMNS`/`FIELDS` · `SHOW TABLE STATUS` · `SHOW CREATE TABLE`/`VIEW`/`PROCEDURE`/`FUNCTION`/`TRIGGER`/`EVENT`/`DATABASE`/`USER` |
| **PostgreSQL administration** | `CREATE`/`ALTER EVENT TRIGGER` · `REINDEX` · `SECURITY LABEL` |
| **PostgreSQL types and rules** | `CREATE TYPE` (shell, composite, enum, range and base types) · `ALTER TYPE` · `CREATE RULE` · `ALTER RULE` |
| **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
6 changes: 6 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 @@ -945,6 +945,12 @@ public enum Feature {
* @see net.sf.jsqlparser.statement.alter.AlterTrigger
*/
alterTrigger,
/**
* PostgreSQL "ALTER RULE" statement is allowed
*
* @see net.sf.jsqlparser.statement.alter.AlterRule
*/
alterRule,
/**
* SQL block starting with "BEGIN" and ends with "END" statement is allowed
*
Expand Down
179 changes: 179 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/DefinitionArgument.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*-
* #%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.Objects;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.statement.create.table.ColDataType;

/**
* The value of a {@link DefinitionElement}: PostgreSQL's {@code def_arg}. The grammar reads a name,
* such as a function or a storage strategy, as a type name, so it is a {@link Kind#TYPE} argument.
*/
public final class DefinitionArgument implements Serializable {
public enum Kind {
/** A type or a name, see {@link #getDataType()}. */
TYPE,
/** A reserved keyword such as {@code TRUE} or {@code NULL}, see {@link #getKeyword()}. */
KEYWORD,
/** An operator, see {@link #getOperator()}. */
OPERATOR,
/** A number with an optional sign, see {@link #getNumber()}. */
NUMBER,
/** A string constant, see {@link #getString()}. */
STRING,
/** The keyword {@code NONE}. */
NONE
}

private final Kind kind;
private ColDataType dataType;
private boolean setOf;
private boolean typeReference;
private String keyword;
private String operator;
private boolean operatorKeyword;
private Expression number;
private StringValue string;

private DefinitionArgument(Kind kind) {
this.kind = kind;
}

public static DefinitionArgument type(ColDataType dataType) {
return type(dataType, false, false);
}

/**
* A type argument.
*
* @param dataType the type or name
* @param setOf whether {@code SETOF} precedes the type
* @param typeReference whether {@code %TYPE} follows the name of a column
* @return the argument
*/
public static DefinitionArgument type(ColDataType dataType, boolean setOf,
boolean typeReference) {
DefinitionArgument argument = new DefinitionArgument(Kind.TYPE);
argument.dataType = Objects.requireNonNull(dataType);
argument.setOf = setOf;
argument.typeReference = typeReference;
return argument;
}

public static DefinitionArgument keyword(String keyword) {
DefinitionArgument argument = new DefinitionArgument(Kind.KEYWORD);
argument.keyword = Objects.requireNonNull(keyword);
return argument;
}

/**
* An operator argument.
*
* @param operator the operator, with its schema when written as {@code OPERATOR(schema.op)}
* @param operatorKeyword whether the operator is written as {@code OPERATOR(...)}
* @return the argument
*/
public static DefinitionArgument operator(String operator, boolean operatorKeyword) {
DefinitionArgument argument = new DefinitionArgument(Kind.OPERATOR);
argument.operator = Objects.requireNonNull(operator);
argument.operatorKeyword = operatorKeyword;
return argument;
}

public static DefinitionArgument number(Expression number) {
DefinitionArgument argument = new DefinitionArgument(Kind.NUMBER);
argument.number = Objects.requireNonNull(number);
return argument;
}

public static DefinitionArgument string(StringValue string) {
DefinitionArgument argument = new DefinitionArgument(Kind.STRING);
argument.string = Objects.requireNonNull(string);
return argument;
}

public static DefinitionArgument none() {
return new DefinitionArgument(Kind.NONE);
}

public Kind getKind() {
return kind;
}

/**
* The type of a {@link Kind#TYPE} argument. A plain name, such as the function of
* {@code INPUT = box3_in}, is the type's {@link ColDataType#getDataType() name}.
*
* @return the type, or {@code null} for another kind
*/
public ColDataType getDataType() {
return dataType;
}

public boolean isSetOf() {
return setOf;
}

/**
* Whether {@code %TYPE} follows the name, which then names a column.
*
* @return {@code true} for {@code table.column%TYPE}
*/
public boolean isTypeReference() {
return typeReference;
}

public String getKeyword() {
return keyword;
}

public String getOperator() {
return operator;
}

public boolean isOperatorKeyword() {
return operatorKeyword;
}

/**
* The number of a {@link Kind#NUMBER} argument: a long or double value, inside a signed
* expression when a sign is written.
*
* @return the number, or {@code null} for another kind
*/
public Expression getNumber() {
return number;
}

public StringValue getString() {
return string;
}

@Override
public String toString() {
switch (kind) {
case TYPE:
return (setOf ? "SETOF " : "") + dataType + (typeReference ? "%TYPE" : "");
case KEYWORD:
return keyword;
case OPERATOR:
return operatorKeyword ? "OPERATOR(" + operator + ")" : operator;
case NUMBER:
return number.toString();
case STRING:
return string.toString();
default:
return "NONE";
}
}
}
69 changes: 69 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/DefinitionElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*-
* #%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.List;
import java.util.stream.Collectors;

/**
* One element of a PostgreSQL definition list, {@code name [= value]}, as in
* {@code CREATE TYPE name (INPUT = fn, PASSEDBYVALUE)} or
* {@code ALTER TYPE name SET (SEND = NONE)}. The name keeps its spelling and quoting.
*/
public class DefinitionElement implements Serializable {
private String name;
private DefinitionArgument argument;

public DefinitionElement() {
// empty constructor
}

public DefinitionElement(String name, DefinitionArgument argument) {
this.name = name;
this.argument = argument;
}

public String getName() {
return name;
}

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

/**
* The value after the equals sign.
*
* @return the argument, or {@code null} for an element without a value
*/
public DefinitionArgument getArgument() {
return argument;
}

public void setArgument(DefinitionArgument argument) {
this.argument = argument;
}

/**
* Renders a definition list in parentheses.
*
* @param elements the elements
* @return the list, such as {@code (INPUT = fn, PASSEDBYVALUE)}
*/
public static String toString(List<DefinitionElement> elements) {
return elements.stream().map(Object::toString).collect(Collectors.joining(", ", "(", ")"));
}

@Override
public String toString() {
return argument == null ? name : name + " = " + argument;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import net.sf.jsqlparser.statement.alter.AlterPolicy;
import net.sf.jsqlparser.statement.alter.AlterPublication;
import net.sf.jsqlparser.statement.alter.AlterRelation;
import net.sf.jsqlparser.statement.alter.AlterRule;
import net.sf.jsqlparser.statement.alter.AlterServer;
import net.sf.jsqlparser.statement.alter.AlterSession;
import net.sf.jsqlparser.statement.alter.AlterStatistics;
Expand Down Expand Up @@ -1489,4 +1490,9 @@ public <S> Void visit(CreateCollation statement, S context) {
return schemaOnly();
}


@Override
public <S> Void visit(AlterRule statement, S context) {
return schemaOnly();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.sf.jsqlparser.statement.notify.NotifyStatement;
import net.sf.jsqlparser.statement.create.collation.CreateCollation;
import net.sf.jsqlparser.statement.alter.AlterCollation;
import net.sf.jsqlparser.statement.alter.AlterRule;
import net.sf.jsqlparser.statement.alter.AlterRoutine;
import net.sf.jsqlparser.statement.alter.AlterTrigger;
import net.sf.jsqlparser.statement.alter.AlterPolicy;
Expand Down Expand Up @@ -1119,4 +1120,12 @@ default <S> T visit(AlterTrigger statement, S context) {
default void visit(AlterTrigger statement) {
visit(statement, null);
}

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

default void visit(AlterRule statement) {
visit(statement, null);
}
}
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.AlterRule;
import net.sf.jsqlparser.statement.alter.AlterTablespace;
import net.sf.jsqlparser.statement.alter.AlterPolicy;
import net.sf.jsqlparser.statement.alter.AlterRoutine;
Expand Down Expand Up @@ -1193,4 +1194,10 @@ public <S> T visit(AlterTrigger statement, S context) {
return null;
}


@Override
public <S> T visit(AlterRule statement, S context) {
fromItemVisitor.visitFromItem(statement.getTable(), context);
return null;
}
}
Loading
Loading