Skip to content

Commit 12548b9

Browse files
authored
fix: parse PostgreSQL DROP CAST, DROP OPERATOR and DROP TRANSFORM (#2896)
DROP CAST (source AS target), DROP OPERATOR op (left, right) and DROP TRANSFORM FOR type LANGUAGE lang failed in every dialect. pg_dump --clean writes them for every cast, operator and transform, so such a dump could not be parsed as a script. Drop.ObjectType gains CAST, OPERATOR and TRANSFORM, and their targets are typed: getCast() is a CastSignature, getOperators() holds an OperatorSignature per operator, with the operator reference COMMENT ON OPERATOR uses and null as the NONE marker of a missing operand, and getTransform() is a TransformSignature. toString() and the deparser render them through the same appendTo(), and they carry AST nodes spanning their source. Oracle's DROP OPERATOR name keeps a plain name. With the PostgreSQL dialect DROP OPERATOR and DROP TRANSFORM require their signatures, and a signature is followed only by CASCADE or RESTRICT. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent ddb4090 commit 12548b9

10 files changed

Lines changed: 780 additions & 15 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
import net.sf.jsqlparser.statement.create.table.ColDataType;
14+
15+
/**
16+
* A PostgreSQL cast, named by the types it converts between: {@code (source_type AS target_type)},
17+
* as in {@code DROP CAST (text AS integer)}.
18+
*/
19+
public class CastSignature extends ASTNodeAccessImpl {
20+
21+
private ColDataType sourceType;
22+
private ColDataType targetType;
23+
24+
public CastSignature() {
25+
// the types are set by the parser or the setters
26+
}
27+
28+
public CastSignature(ColDataType sourceType, ColDataType targetType) {
29+
this.sourceType = sourceType;
30+
this.targetType = targetType;
31+
}
32+
33+
public ColDataType getSourceType() {
34+
return sourceType;
35+
}
36+
37+
public void setSourceType(ColDataType sourceType) {
38+
this.sourceType = sourceType;
39+
}
40+
41+
public CastSignature withSourceType(ColDataType sourceType) {
42+
setSourceType(sourceType);
43+
return this;
44+
}
45+
46+
public ColDataType getTargetType() {
47+
return targetType;
48+
}
49+
50+
public void setTargetType(ColDataType targetType) {
51+
this.targetType = targetType;
52+
}
53+
54+
public CastSignature withTargetType(ColDataType targetType) {
55+
setTargetType(targetType);
56+
return this;
57+
}
58+
59+
@Override
60+
public StringBuilder appendTo(StringBuilder builder) {
61+
return builder.append('(').append(sourceType).append(" AS ").append(targetType)
62+
.append(')');
63+
}
64+
65+
@Override
66+
public String toString() {
67+
return appendTo(new StringBuilder()).toString();
68+
}
69+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
import net.sf.jsqlparser.statement.create.table.ColDataType;
14+
import net.sf.jsqlparser.statement.create.table.ExclusionOperator;
15+
16+
/**
17+
* A PostgreSQL operator, named by its possibly schema-qualified symbol and its operand types:
18+
* {@code [schema.]op ({left_type | NONE}, {right_type | NONE})}, as in
19+
* {@code DROP OPERATOR ~ (NONE, bigint)}. A null operand type is the NONE marker of a missing
20+
* operand, and is rendered as {@code NONE}.
21+
*/
22+
public class OperatorSignature extends ASTNodeAccessImpl {
23+
24+
private ExclusionOperator operator;
25+
private ColDataType leftType;
26+
private ColDataType rightType;
27+
28+
public OperatorSignature() {
29+
// the operator and its operand types are set by the parser or the setters
30+
}
31+
32+
public OperatorSignature(ExclusionOperator operator, ColDataType leftType,
33+
ColDataType rightType) {
34+
this.operator = operator;
35+
this.leftType = leftType;
36+
this.rightType = rightType;
37+
}
38+
39+
/** The operator symbol and its schema, read by the reference COMMENT ON OPERATOR uses. */
40+
public ExclusionOperator getOperator() {
41+
return operator;
42+
}
43+
44+
public void setOperator(ExclusionOperator operator) {
45+
this.operator = operator;
46+
}
47+
48+
public OperatorSignature withOperator(ExclusionOperator operator) {
49+
setOperator(operator);
50+
return this;
51+
}
52+
53+
/** The left operand type, or null for NONE, the missing left operand of a prefix operator. */
54+
public ColDataType getLeftType() {
55+
return leftType;
56+
}
57+
58+
public void setLeftType(ColDataType leftType) {
59+
this.leftType = leftType;
60+
}
61+
62+
public OperatorSignature withLeftType(ColDataType leftType) {
63+
setLeftType(leftType);
64+
return this;
65+
}
66+
67+
/** The right operand type, or null for NONE. */
68+
public ColDataType getRightType() {
69+
return rightType;
70+
}
71+
72+
public void setRightType(ColDataType rightType) {
73+
this.rightType = rightType;
74+
}
75+
76+
public OperatorSignature withRightType(ColDataType rightType) {
77+
setRightType(rightType);
78+
return this;
79+
}
80+
81+
@Override
82+
public StringBuilder appendTo(StringBuilder builder) {
83+
return builder.append(operator).append(" (").append(operand(leftType)).append(", ")
84+
.append(operand(rightType)).append(')');
85+
}
86+
87+
private static Object operand(ColDataType type) {
88+
return type == null ? "NONE" : type;
89+
}
90+
91+
@Override
92+
public String toString() {
93+
return appendTo(new StringBuilder()).toString();
94+
}
95+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
import net.sf.jsqlparser.statement.create.table.ColDataType;
14+
15+
/**
16+
* A PostgreSQL transform, named by the data type and the procedural language it connects:
17+
* {@code FOR type_name LANGUAGE lang_name}, as in
18+
* {@code DROP TRANSFORM FOR hstore LANGUAGE plpython3u}.
19+
*/
20+
public class TransformSignature extends ASTNodeAccessImpl {
21+
22+
private ColDataType dataType;
23+
private String language;
24+
25+
public TransformSignature() {
26+
// the type and language are set by the parser or the setters
27+
}
28+
29+
public TransformSignature(ColDataType dataType, String language) {
30+
this.dataType = dataType;
31+
this.language = language;
32+
}
33+
34+
public ColDataType getDataType() {
35+
return dataType;
36+
}
37+
38+
public void setDataType(ColDataType dataType) {
39+
this.dataType = dataType;
40+
}
41+
42+
public TransformSignature withDataType(ColDataType dataType) {
43+
setDataType(dataType);
44+
return this;
45+
}
46+
47+
public String getLanguage() {
48+
return language;
49+
}
50+
51+
public void setLanguage(String language) {
52+
this.language = language;
53+
}
54+
55+
public TransformSignature withLanguage(String language) {
56+
setLanguage(language);
57+
return this;
58+
}
59+
60+
@Override
61+
public StringBuilder appendTo(StringBuilder builder) {
62+
return builder.append("FOR ").append(dataType).append(" LANGUAGE ").append(language);
63+
}
64+
65+
@Override
66+
public String toString() {
67+
return appendTo(new StringBuilder()).toString();
68+
}
69+
}

‎src/main/java/net/sf/jsqlparser/statement/create/table/ExclusionOperator.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
/**
1515
* An exclusion operator, optionally qualified and enclosed in PostgreSQL OPERATOR(...). COMMENT ON
16-
* OPERATOR uses the same reference without the OPERATOR keyword.
16+
* OPERATOR and DROP OPERATOR use the same reference without the OPERATOR keyword.
1717
*/
1818
public class ExclusionOperator implements Serializable {
1919
private String schemaName;

0 commit comments

Comments
 (0)