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
27 changes: 27 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 @@ -647,6 +647,33 @@ public enum Feature {
/** Additional structured catalog targets of COMMENT ON. */
commentOnIndex, commentOnSchema, commentOnSequence, commentOnDomain, commentOnType, commentOnMaterializedView, commentOnFunction, commentOnConstraint,

/** COMMENT ON TRIGGER, POLICY or RULE within a table. */
commentOnTrigger, commentOnPolicy, commentOnRule,

/** COMMENT ON PROCEDURE, ROUTINE, AGGREGATE or CAST. */
commentOnProcedure, commentOnRoutine, commentOnAggregate, commentOnCast,

/** COMMENT ON COLLATION, FOREIGN TABLE or STATISTICS. */
commentOnCollation, commentOnForeignTable, commentOnStatistics,

/** COMMENT ON DATABASE, ROLE or TABLESPACE. */
commentOnDatabase, commentOnRole, commentOnTablespace,

/** COMMENT ON ACCESS METHOD, EXTENSION, FOREIGN DATA WRAPPER, LANGUAGE or SERVER. */
commentOnAccessMethod, commentOnExtension, commentOnForeignDataWrapper, commentOnLanguage, commentOnServer,

/** COMMENT ON EVENT TRIGGER, PUBLICATION or SUBSCRIPTION. */
commentOnEventTrigger, commentOnPublication, commentOnSubscription,

/** COMMENT ON OPERATOR, OPERATOR CLASS or OPERATOR FAMILY. */
commentOnOperator, commentOnOperatorClass, commentOnOperatorFamily,

/** COMMENT ON CONVERSION, LARGE OBJECT or TRANSFORM. */
commentOnConversion, commentOnLargeObject, commentOnTransform,

/** COMMENT ON TEXT SEARCH CONFIGURATION, DICTIONARY, PARSER or TEMPLATE. */
commentOnTextSearchConfiguration, commentOnTextSearchDictionary, commentOnTextSearchParser, commentOnTextSearchTemplate,

/**
* SQL "DESCRIBE" statement is allowed
*
Expand Down
190 changes: 181 additions & 9 deletions src/main/java/net/sf/jsqlparser/statement/comment/CommentTarget.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,63 @@
import java.util.function.Consumer;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.RoutineReference;
import net.sf.jsqlparser.statement.create.table.ColDataType;
import net.sf.jsqlparser.statement.create.table.ExclusionOperator;

/** A catalog object addressed by COMMENT, rather than a function invocation or a query. */
public class CommentTarget implements Serializable {
public enum Kind {
INDEX, SCHEMA, SEQUENCE, DOMAIN, TYPE, MATERIALIZED_VIEW, FUNCTION, CONSTRAINT
INDEX, SCHEMA, SEQUENCE, DOMAIN, TYPE, MATERIALIZED_VIEW, FUNCTION, CONSTRAINT,

TRIGGER, POLICY, RULE, PROCEDURE, ROUTINE, AGGREGATE, CAST,

COLLATION, FOREIGN_TABLE, STATISTICS, DATABASE, ROLE, TABLESPACE, ACCESS_METHOD, EXTENSION,

FOREIGN_DATA_WRAPPER, LANGUAGE, SERVER, EVENT_TRIGGER, PUBLICATION, SUBSCRIPTION,

OPERATOR, OPERATOR_CLASS, OPERATOR_FAMILY, LARGE_OBJECT, CONVERSION, TRANSFORM,

TEXT_SEARCH_CONFIGURATION, TEXT_SEARCH_DICTIONARY, TEXT_SEARCH_PARSER, TEXT_SEARCH_TEMPLATE;

/**
* Whether the target is a routine signature, exposed by {@link CommentTarget#getRoutine()}.
*/
public boolean isRoutine() {
return this == FUNCTION || this == PROCEDURE || this == ROUTINE || this == AGGREGATE;
}

/**
* Whether the target is named within the table or domain of
* {@link CommentTarget#getRelation()}.
*/
public boolean isOwnedByRelation() {
return this == CONSTRAINT || this == TRIGGER || this == POLICY || this == RULE;
}

/**
* Whether the target is named within the index access method of
* {@link CommentTarget#getAccessMethod()}.
*/
public boolean isOwnedByAccessMethod() {
return this == OPERATOR_CLASS || this == OPERATOR_FAMILY;
}
}

private Kind kind;
private Table name;
private RoutineReference routine;
private Table relation;
private boolean onDomain;
private boolean procedural;
private ColDataType sourceType;
private ColDataType targetType;
private ExclusionOperator operator;
private ColDataType leftOperandType;
private ColDataType rightOperandType;
private String accessMethod;
private Long largeObjectOid;
private ColDataType transformType;
private String language;

public Kind getKind() {
return kind;
Expand All @@ -34,7 +79,10 @@ public void setKind(Kind kind) {
this.kind = kind;
}

/** The object's identifier; using Table preserves the individual name components. */
/**
* The object's identifier; using Table preserves the individual name components. Routine, cast,
* operator, large object and transform targets have no name.
*/
public Table getName() {
return name;
}
Expand All @@ -51,7 +99,10 @@ public void setRoutine(RoutineReference routine) {
this.routine = routine;
}

/** The table or domain owning a constraint, distinguished by {@link #isOnDomain()}. */
/**
* The table owning a constraint, trigger, policy or rule, or the domain owning a constraint,
* distinguished by {@link #isOnDomain()}.
*/
public Table getRelation() {
return relation;
}
Expand All @@ -68,34 +119,155 @@ public void setOnDomain(boolean onDomain) {
this.onDomain = onDomain;
}

/** Returns only an explicitly named table/view, never an index, type, function or domain. */
/** Whether a {@link Kind#LANGUAGE} target was written as PROCEDURAL LANGUAGE. */
public boolean isProcedural() {
return procedural;
}

public void setProcedural(boolean procedural) {
this.procedural = procedural;
}

/** The source type of a {@link Kind#CAST} target. */
public ColDataType getSourceType() {
return sourceType;
}

public void setSourceType(ColDataType sourceType) {
this.sourceType = sourceType;
}

/** The target type of a {@link Kind#CAST} target. */
public ColDataType getTargetType() {
return targetType;
}

public void setTargetType(ColDataType targetType) {
this.targetType = targetType;
}

/**
* The possibly schema-qualified operator of an {@link Kind#OPERATOR} target, read by the
* operator reference shared with exclusion constraints and ALTER EXTENSION.
*/
public ExclusionOperator getOperator() {
return operator;
}

public void setOperator(ExclusionOperator operator) {
this.operator = operator;
}

/** The left operand type of an {@link Kind#OPERATOR} target; null stands for NONE. */
public ColDataType getLeftOperandType() {
return leftOperandType;
}

public void setLeftOperandType(ColDataType leftOperandType) {
this.leftOperandType = leftOperandType;
}

/** The right operand type of an {@link Kind#OPERATOR} target; null stands for NONE. */
public ColDataType getRightOperandType() {
return rightOperandType;
}

public void setRightOperandType(ColDataType rightOperandType) {
this.rightOperandType = rightOperandType;
}

/**
* The index access method of an {@link Kind#OPERATOR_CLASS} or {@link Kind#OPERATOR_FAMILY}
* target.
*/
public String getAccessMethod() {
return accessMethod;
}

public void setAccessMethod(String accessMethod) {
this.accessMethod = accessMethod;
}

/** The OID of a {@link Kind#LARGE_OBJECT} target. */
public Long getLargeObjectOid() {
return largeObjectOid;
}

public void setLargeObjectOid(Long largeObjectOid) {
this.largeObjectOid = largeObjectOid;
}

/** The data type of a {@link Kind#TRANSFORM} target. */
public ColDataType getTransformType() {
return transformType;
}

public void setTransformType(ColDataType transformType) {
this.transformType = transformType;
}

/** The procedural language of a {@link Kind#TRANSFORM} target. */
public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

/**
* Returns only an explicitly named table, foreign table or view, never an index, type,
* function, statistics object or domain.
*/
public Table getReferencedRelation() {
if (kind == Kind.MATERIALIZED_VIEW) {
if (namesRelation()) {
return name;
}
return kind == Kind.CONSTRAINT && !onDomain ? relation : null;
return kind != null && kind.isOwnedByRelation() && !onDomain ? relation : null;
}

private boolean namesRelation() {
return kind == Kind.MATERIALIZED_VIEW || kind == Kind.FOREIGN_TABLE;
}

public StringBuilder appendTo(StringBuilder builder, Consumer<Table> relationWriter) {
if (kind == Kind.LANGUAGE && procedural) {
builder.append("PROCEDURAL ");
}
builder.append(kind.name().replace('_', ' ')).append(' ');
if (kind == Kind.FUNCTION) {
if (kind.isRoutine()) {
builder.append(routine);
} else if (kind == Kind.MATERIALIZED_VIEW) {
} else if (kind == Kind.CAST) {
builder.append('(').append(sourceType).append(" AS ").append(targetType).append(')');
} else if (kind == Kind.OPERATOR) {
builder.append(operator).append(" (").append(operandType(leftOperandType))
.append(", ").append(operandType(rightOperandType)).append(')');
} else if (kind == Kind.LARGE_OBJECT) {
builder.append(largeObjectOid);
} else if (kind == Kind.TRANSFORM) {
builder.append("FOR ").append(transformType).append(" LANGUAGE ").append(language);
} else if (namesRelation()) {
relationWriter.accept(name);
} else {
builder.append(name);
if (kind == Kind.CONSTRAINT) {
if (kind.isOwnedByRelation()) {
builder.append(" ON ");
if (onDomain) {
builder.append("DOMAIN ").append(relation);
} else {
relationWriter.accept(relation);
}
} else if (kind.isOwnedByAccessMethod()) {
builder.append(" USING ").append(accessMethod);
}
}
return builder;
}

private static Object operandType(ColDataType type) {
return type == null ? "NONE" : type;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@

import java.io.Serializable;

/** An exclusion operator, optionally qualified and enclosed in PostgreSQL OPERATOR(...). */
/**
* An exclusion operator, optionally qualified and enclosed in PostgreSQL OPERATOR(...). COMMENT ON
* OPERATOR uses the same reference without the OPERATOR keyword.
*/
public class ExclusionOperator implements Serializable {
private String schemaName;
private String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,22 @@ public enum PostgresqlVersion implements Version {
Feature.commentOnDomain, Feature.commentOnType,
Feature.commentOnMaterializedView,
Feature.commentOnFunction, Feature.commentOnConstraint,
Feature.commentOnTrigger, Feature.commentOnPolicy, Feature.commentOnRule,
Feature.commentOnProcedure, Feature.commentOnRoutine,
Feature.commentOnAggregate, Feature.commentOnCast,
Feature.commentOnCollation, Feature.commentOnForeignTable,
Feature.commentOnStatistics, Feature.commentOnDatabase, Feature.commentOnRole,
Feature.commentOnTablespace, Feature.commentOnAccessMethod,
Feature.commentOnExtension, Feature.commentOnForeignDataWrapper,
Feature.commentOnLanguage, Feature.commentOnServer,
Feature.commentOnEventTrigger, Feature.commentOnPublication,
Feature.commentOnSubscription,
Feature.commentOnOperator, Feature.commentOnOperatorClass,
Feature.commentOnOperatorFamily, Feature.commentOnConversion,
Feature.commentOnLargeObject, Feature.commentOnTransform,
Feature.commentOnTextSearchConfiguration,
Feature.commentOnTextSearchDictionary, Feature.commentOnTextSearchParser,
Feature.commentOnTextSearchTemplate,

// https://www.postgresql.org/docs/current/sql-createsequence.html
Feature.createSequence,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,68 @@ private static Feature targetFeature(CommentTarget.Kind kind) {
return Feature.commentOnFunction;
case CONSTRAINT:
return Feature.commentOnConstraint;
case TRIGGER:
return Feature.commentOnTrigger;
case POLICY:
return Feature.commentOnPolicy;
case RULE:
return Feature.commentOnRule;
case PROCEDURE:
return Feature.commentOnProcedure;
case ROUTINE:
return Feature.commentOnRoutine;
case AGGREGATE:
return Feature.commentOnAggregate;
case CAST:
return Feature.commentOnCast;
case COLLATION:
return Feature.commentOnCollation;
case FOREIGN_TABLE:
return Feature.commentOnForeignTable;
case STATISTICS:
return Feature.commentOnStatistics;
case DATABASE:
return Feature.commentOnDatabase;
case ROLE:
return Feature.commentOnRole;
case TABLESPACE:
return Feature.commentOnTablespace;
case ACCESS_METHOD:
return Feature.commentOnAccessMethod;
case EXTENSION:
return Feature.commentOnExtension;
case FOREIGN_DATA_WRAPPER:
return Feature.commentOnForeignDataWrapper;
case LANGUAGE:
return Feature.commentOnLanguage;
case SERVER:
return Feature.commentOnServer;
case EVENT_TRIGGER:
return Feature.commentOnEventTrigger;
case PUBLICATION:
return Feature.commentOnPublication;
case SUBSCRIPTION:
return Feature.commentOnSubscription;
case OPERATOR:
return Feature.commentOnOperator;
case OPERATOR_CLASS:
return Feature.commentOnOperatorClass;
case OPERATOR_FAMILY:
return Feature.commentOnOperatorFamily;
case CONVERSION:
return Feature.commentOnConversion;
case LARGE_OBJECT:
return Feature.commentOnLargeObject;
case TRANSFORM:
return Feature.commentOnTransform;
case TEXT_SEARCH_CONFIGURATION:
return Feature.commentOnTextSearchConfiguration;
case TEXT_SEARCH_DICTIONARY:
return Feature.commentOnTextSearchDictionary;
case TEXT_SEARCH_PARSER:
return Feature.commentOnTextSearchParser;
case TEXT_SEARCH_TEMPLATE:
return Feature.commentOnTextSearchTemplate;
default:
throw new IllegalArgumentException("Unknown COMMENT target: " + kind);
}
Expand Down
Loading
Loading