Skip to content

Commit 8d6208d

Browse files
committed
feat: parse PostgreSQL CREATE CAST, CREATE TRANSFORM, CREATE CONVERSION and ALTER CONVERSION
CREATE CAST (source AS target) WITH FUNCTION f(args) | WITHOUT FUNCTION | WITH INOUT [AS ASSIGNMENT | AS IMPLICIT], CREATE [OR REPLACE] TRANSFORM FOR type LANGUAGE lang (FROM SQL WITH FUNCTION f, TO SQL WITH FUNCTION g), CREATE [DEFAULT] CONVERSION name FOR 'enc' TO 'enc' FROM function and ALTER CONVERSION name RENAME TO | OWNER TO | SET SCHEMA were unsupported statements. They parse to CreateCast, CreateTransform, CreateConversion and AlterConversion. A cast and a transform are named by the CastSignature and TransformSignature of DROP CAST and DROP TRANSFORM, and functions are RoutineReference objects, read by the existing productions. The statements are wired into the deparser, visitors, table finder, validation (createCast, createTransform, createConversion and alterConversion, enabled for PostgreSQL) and feature analysis. With the PostgreSQL dialect these words start only these statements, so forms the server reports as syntax errors are parse errors. In another dialect and without one, a statement is read this way when it has PostgreSQL's form, and statements of other products that start with the same words, such as CREATE CAST (a AS b) WITH SPECIFIC FUNCTION f, stay unsupported statements. Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent cf057dd commit 8d6208d

21 files changed

Lines changed: 1557 additions & 3 deletions

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
162162
| **MySQL utility statements** | `EXPLAIN`/`DESCRIBE [ANALYZE] FORMAT = …` · `EXPLAIN FOR CONNECTION` · `DESCRIBE t col` · `PREPARE … FROM` · `EXECUTE … USING` · `DROP PREPARE` · `DO` |
163163
| **PostgreSQL administration** | `CREATE`/`ALTER EVENT TRIGGER` · `REINDEX` · `SECURITY LABEL` |
164164
| **PostgreSQL types and rules** | `CREATE TYPE` (shell, composite, enum, range and base types) · `ALTER TYPE` · `CREATE RULE` · `ALTER RULE` |
165+
| **PostgreSQL casts, transforms and conversions** | `CREATE CAST` · `DROP CAST` · `CREATE [OR REPLACE] TRANSFORM` · `DROP TRANSFORM` · `CREATE [DEFAULT] CONVERSION` · `ALTER CONVERSION` |
165166
| **Informix constraints** | `ALTER TABLE … ADD CONSTRAINT` with trailing constraint names for primary, unique, foreign and check constraints; enable with `parser.withDialect(Dialect.INFORMIX)` |
166167
| **Salesforce SOQL** | `INCLUDES` · `EXCLUDES` |
167168

‎src/main/java/net/sf/jsqlparser/parser/feature/Feature.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,30 @@ public enum Feature {
10011001
* @see net.sf.jsqlparser.statement.alter.AlterRule
10021002
*/
10031003
alterRule,
1004+
/**
1005+
* PostgreSQL "CREATE CAST" statement is allowed
1006+
*
1007+
* @see net.sf.jsqlparser.statement.create.cast.CreateCast
1008+
*/
1009+
createCast,
1010+
/**
1011+
* PostgreSQL "CREATE TRANSFORM" statement is allowed
1012+
*
1013+
* @see net.sf.jsqlparser.statement.create.transform.CreateTransform
1014+
*/
1015+
createTransform,
1016+
/**
1017+
* PostgreSQL "CREATE CONVERSION" statement is allowed
1018+
*
1019+
* @see net.sf.jsqlparser.statement.create.conversion.CreateConversion
1020+
*/
1021+
createConversion,
1022+
/**
1023+
* PostgreSQL "ALTER CONVERSION" statement is allowed
1024+
*
1025+
* @see net.sf.jsqlparser.statement.alter.AlterConversion
1026+
*/
1027+
alterConversion,
10041028
/**
10051029
* SQL block starting with "BEGIN" and ends with "END" statement is allowed
10061030
*

‎src/main/java/net/sf/jsqlparser/statement/StatementFeatureVisitor.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
import net.sf.jsqlparser.statement.alter.AlterPublication;
3838
import net.sf.jsqlparser.statement.alter.AlterRelation;
3939
import net.sf.jsqlparser.statement.alter.AlterRule;
40+
import net.sf.jsqlparser.statement.create.cast.CreateCast;
41+
import net.sf.jsqlparser.statement.create.transform.CreateTransform;
42+
import net.sf.jsqlparser.statement.create.conversion.CreateConversion;
43+
import net.sf.jsqlparser.statement.alter.AlterConversion;
4044
import net.sf.jsqlparser.statement.alter.AlterServer;
4145
import net.sf.jsqlparser.statement.alter.AlterSession;
4246
import net.sf.jsqlparser.statement.alter.AlterStatistics;
@@ -1557,4 +1561,24 @@ public <S> Void visit(CreateCollation statement, S context) {
15571561
public <S> Void visit(AlterRule statement, S context) {
15581562
return schemaOnly();
15591563
}
1564+
1565+
@Override
1566+
public <S> Void visit(CreateCast statement, S context) {
1567+
return schemaOnly();
1568+
}
1569+
1570+
@Override
1571+
public <S> Void visit(CreateTransform statement, S context) {
1572+
return schemaOnly();
1573+
}
1574+
1575+
@Override
1576+
public <S> Void visit(CreateConversion statement, S context) {
1577+
return schemaOnly();
1578+
}
1579+
1580+
@Override
1581+
public <S> Void visit(AlterConversion statement, S context) {
1582+
return schemaOnly();
1583+
}
15601584
}

‎src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
import net.sf.jsqlparser.statement.create.collation.CreateCollation;
2626
import net.sf.jsqlparser.statement.alter.AlterCollation;
2727
import net.sf.jsqlparser.statement.alter.AlterRule;
28+
import net.sf.jsqlparser.statement.create.cast.CreateCast;
29+
import net.sf.jsqlparser.statement.create.transform.CreateTransform;
30+
import net.sf.jsqlparser.statement.create.conversion.CreateConversion;
31+
import net.sf.jsqlparser.statement.alter.AlterConversion;
2832
import net.sf.jsqlparser.statement.alter.AlterRoutine;
2933
import net.sf.jsqlparser.statement.alter.AlterTrigger;
3034
import net.sf.jsqlparser.statement.alter.AlterPolicy;
@@ -1182,4 +1186,36 @@ default <S> T visit(AlterRule statement, S context) {
11821186
default void visit(AlterRule statement) {
11831187
visit(statement, null);
11841188
}
1189+
1190+
default <S> T visit(CreateCast statement, S context) {
1191+
return null;
1192+
}
1193+
1194+
default void visit(CreateCast statement) {
1195+
visit(statement, null);
1196+
}
1197+
1198+
default <S> T visit(CreateTransform statement, S context) {
1199+
return null;
1200+
}
1201+
1202+
default void visit(CreateTransform statement) {
1203+
visit(statement, null);
1204+
}
1205+
1206+
default <S> T visit(CreateConversion statement, S context) {
1207+
return null;
1208+
}
1209+
1210+
default void visit(CreateConversion statement) {
1211+
visit(statement, null);
1212+
}
1213+
1214+
default <S> T visit(AlterConversion statement, S context) {
1215+
return null;
1216+
}
1217+
1218+
default void visit(AlterConversion statement) {
1219+
visit(statement, null);
1220+
}
11851221
}

‎src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
import net.sf.jsqlparser.statement.alter.AlterRelation;
1313
import net.sf.jsqlparser.statement.alter.AlterRule;
14+
import net.sf.jsqlparser.statement.create.cast.CreateCast;
15+
import net.sf.jsqlparser.statement.create.transform.CreateTransform;
16+
import net.sf.jsqlparser.statement.create.conversion.CreateConversion;
17+
import net.sf.jsqlparser.statement.alter.AlterConversion;
1418
import net.sf.jsqlparser.statement.alter.AlterTablespace;
1519
import net.sf.jsqlparser.statement.alter.AlterPolicy;
1620
import net.sf.jsqlparser.statement.alter.AlterRoutine;
@@ -1241,4 +1245,24 @@ public <S> T visit(AlterRule statement, S context) {
12411245
fromItemVisitor.visitFromItem(statement.getTable(), context);
12421246
return null;
12431247
}
1248+
1249+
@Override
1250+
public <S> T visit(CreateCast statement, S context) {
1251+
return null;
1252+
}
1253+
1254+
@Override
1255+
public <S> T visit(CreateTransform statement, S context) {
1256+
return null;
1257+
}
1258+
1259+
@Override
1260+
public <S> T visit(CreateConversion statement, S context) {
1261+
return null;
1262+
}
1263+
1264+
@Override
1265+
public <S> T visit(AlterConversion statement, S context) {
1266+
return null;
1267+
}
12441268
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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.alter;
11+
12+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
13+
import net.sf.jsqlparser.statement.Statement;
14+
import net.sf.jsqlparser.statement.StatementVisitor;
15+
16+
/**
17+
* PostgreSQL
18+
* {@code ALTER CONVERSION name {RENAME TO new_name | OWNER TO role | SET SCHEMA schema}}. Names
19+
* retain SQL identifier quoting.
20+
*/
21+
public class AlterConversion extends ASTNodeAccessImpl implements Statement {
22+
public enum Action {
23+
RENAME, OWNER, SET_SCHEMA
24+
}
25+
26+
private String name;
27+
private Action action;
28+
private String newName;
29+
private String owner;
30+
private String schemaName;
31+
32+
public String getName() {
33+
return name;
34+
}
35+
36+
public void setName(String name) {
37+
this.name = name;
38+
}
39+
40+
public AlterConversion withName(String name) {
41+
setName(name);
42+
return this;
43+
}
44+
45+
public Action getAction() {
46+
return action;
47+
}
48+
49+
public void setAction(Action action) {
50+
this.action = action;
51+
}
52+
53+
public AlterConversion withAction(Action action) {
54+
setAction(action);
55+
return this;
56+
}
57+
58+
public String getNewName() {
59+
return newName;
60+
}
61+
62+
public void setNewName(String newName) {
63+
this.newName = newName;
64+
}
65+
66+
public AlterConversion withNewName(String newName) {
67+
setNewName(newName);
68+
return this;
69+
}
70+
71+
/**
72+
* The new owner: a role name, {@code CURRENT_ROLE}, {@code CURRENT_USER} or
73+
* {@code SESSION_USER}.
74+
*
75+
* @return the owner of {@code OWNER TO}
76+
*/
77+
public String getOwner() {
78+
return owner;
79+
}
80+
81+
public void setOwner(String owner) {
82+
this.owner = owner;
83+
}
84+
85+
public AlterConversion withOwner(String owner) {
86+
setOwner(owner);
87+
return this;
88+
}
89+
90+
public String getSchemaName() {
91+
return schemaName;
92+
}
93+
94+
public void setSchemaName(String schemaName) {
95+
this.schemaName = schemaName;
96+
}
97+
98+
public AlterConversion withSchemaName(String schemaName) {
99+
setSchemaName(schemaName);
100+
return this;
101+
}
102+
103+
public StringBuilder appendTo(StringBuilder builder) {
104+
builder.append("ALTER CONVERSION ").append(name);
105+
switch (action) {
106+
case RENAME:
107+
builder.append(" RENAME TO ").append(newName);
108+
break;
109+
case OWNER:
110+
builder.append(" OWNER TO ").append(owner);
111+
break;
112+
case SET_SCHEMA:
113+
builder.append(" SET SCHEMA ").append(schemaName);
114+
break;
115+
default:
116+
throw new IllegalStateException("Unknown conversion action: " + action);
117+
}
118+
return builder;
119+
}
120+
121+
@Override
122+
public String toString() {
123+
return appendTo(new StringBuilder()).toString();
124+
}
125+
126+
@Override
127+
public <T, S> T accept(StatementVisitor<T> statementVisitor, S context) {
128+
return statementVisitor.visit(this, context);
129+
}
130+
}

0 commit comments

Comments
 (0)