Skip to content

Commit 241779b

Browse files
author
jthomas
committed
Enhance AlterExpression grammar:
1. optional "COLUMN" keyword in ADD alter operation 2. new alter operation: MODIFY 3. add column specs to alter table column definitions
1 parent 068a85b commit 241779b

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed

src/main/java/net/sf/jsqlparser/statement/alter/AlterExpression.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import net.sf.jsqlparser.statement.select.PlainSelect;
2828

2929
import java.util.ArrayList;
30+
import java.util.Collections;
3031
import java.util.List;
3132

3233
/**
@@ -106,10 +107,14 @@ public List<ColumnDataType> getColDataTypeList() {
106107
}
107108

108109
public void addColDataType(String columnName, ColDataType colDataType) {
110+
addColDataType(new ColumnDataType(columnName, colDataType, null));
111+
}
112+
113+
public void addColDataType(ColumnDataType columnDataType) {
109114
if (colDataTypeList == null) {
110115
colDataTypeList = new ArrayList<ColumnDataType>();
111116
}
112-
colDataTypeList.add(new ColumnDataType(columnName, colDataType));
117+
colDataTypeList.add(columnDataType);
113118
}
114119

115120
public List<String> getFkSourceColumns() {
@@ -208,14 +213,16 @@ public String toString() {
208213
return b.toString();
209214
}
210215

211-
public class ColumnDataType {
216+
public static class ColumnDataType {
212217

213218
private final String columnName;
214219
private final ColDataType colDataType;
220+
private final List<String> columnSpecs;
215221

216-
public ColumnDataType(String columnName, ColDataType colDataType) {
222+
public ColumnDataType(String columnName, ColDataType colDataType, List<String> columnSpecs) {
217223
this.columnName = columnName;
218224
this.colDataType = colDataType;
225+
this.columnSpecs = columnSpecs;
219226
}
220227

221228
public String getColumnName() {
@@ -226,9 +233,24 @@ public ColDataType getColDataType() {
226233
return colDataType;
227234
}
228235

236+
public List<String> getColumnSpecs() {
237+
if (columnSpecs == null) {
238+
return Collections.emptyList();
239+
}
240+
return Collections.unmodifiableList(columnSpecs);
241+
}
242+
229243
@Override
230244
public String toString() {
231-
return columnName + " " + colDataType;
245+
return columnName + " " + colDataType + parametersToString();
246+
}
247+
248+
private String parametersToString()
249+
{
250+
if (columnSpecs == null || columnSpecs.isEmpty()) {
251+
return "";
252+
}
253+
return " " + PlainSelect.getStringList(columnSpecs, false, false);
232254
}
233255
}
234256

src/main/java/net/sf/jsqlparser/statement/alter/AlterOperation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,5 @@
4444
* @author toben
4545
*/
4646
public enum AlterOperation {
47-
ADD, DROP;
47+
ADD, DROP, MODIFY;
4848
}

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
204204
| <K_SIBLINGS:"SIBLINGS">
205205
| <K_ALTER:"ALTER">
206206
| <K_ADD:"ADD">
207+
| <K_MODIFY: "MODIFY">
207208
| <K_COLUMN:"COLUMN">
208209
| <K_NULLS: "NULLS">
209210
| <K_FIRST: "FIRST">
@@ -3054,6 +3055,24 @@ Truncate Truncate():
30543055
}
30553056
}
30563057

3058+
3059+
AlterExpression.ColumnDataType AlterExpressionColumnDataType():
3060+
{
3061+
String columnName = null;
3062+
ColDataType dataType = null;
3063+
List<String> columnSpecs = null;
3064+
List<String> parameter = null;
3065+
}
3066+
{
3067+
columnName = RelObjectName()
3068+
dataType = ColDataType() { columnSpecs = new ArrayList(); }
3069+
( parameter = CreateParameter() { columnSpecs.addAll(parameter); } )*
3070+
{
3071+
return new AlterExpression.ColumnDataType(columnName, dataType, columnSpecs);
3072+
}
3073+
}
3074+
3075+
30573076
AlterExpression AlterExpression():
30583077
{
30593078
AlterExpression alterExp = new AlterExpression();
@@ -3065,23 +3084,20 @@ AlterExpression AlterExpression():
30653084
ForeignKeyIndex fkIndex = null;
30663085
NamedConstraint index = null;
30673086
Table fkTable = null;
3087+
AlterExpression.ColumnDataType alterExpressionColumnDataType = null;
30683088
}
30693089
{
30703090

30713091
(
3072-
(<K_ADD>
3073-
{
3074-
alterExp.setOperation(AlterOperation.ADD);
3075-
}
3092+
((<K_ADD> { alterExp.setOperation(AlterOperation.ADD); } | <K_MODIFY> { alterExp.setOperation(AlterOperation.MODIFY); })
30763093
(
3077-
( <K_COLUMN>
3078-
sk3 = RelObjectName() dataType=ColDataType()
3079-
{ alterExp.addColDataType(sk3, dataType); }
3094+
( (<K_COLUMN>)*
3095+
alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); }
30803096
)
30813097
|
30823098
(
3083-
"(" sk3 = RelObjectName() dataType = ColDataType() { alterExp.addColDataType(sk3, dataType); }
3084-
("," sk3 = RelObjectName() dataType = ColDataType() { alterExp.addColDataType(sk3, dataType); } )* ")"
3099+
"(" alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); }
3100+
("," alterExpressionColumnDataType = AlterExpressionColumnDataType() { alterExp.addColDataType(alterExpressionColumnDataType); } )* ")"
30853101
)
30863102
|
30873103
( <K_PRIMARY> <K_KEY> columnNames=ColumnsNamesList() { alterExp.setPkColumns(columnNames); } )

src/test/java/net/sf/jsqlparser/test/alter/AlterTest.java

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import net.sf.jsqlparser.statement.alter.AlterExpression;
1111
import net.sf.jsqlparser.statement.alter.AlterExpression.ColumnDataType;
1212
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
13+
import static net.sf.jsqlparser.test.TestUtils.assertStatementCanBeDeparsedAs;
1314

1415
public class AlterTest extends TestCase {
1516

@@ -28,8 +29,20 @@ public void testAlterTableAddColumn() throws JSQLParserException {
2829
assertEquals("mycolumn", colDataTypes.get(0).getColumnName());
2930
assertEquals("varchar (255)", colDataTypes.get(0).getColDataType().toString());
3031
}
31-
32-
public void testAlterTablePrimaryKey() throws JSQLParserException {
32+
33+
public void testAlterTableAddColumn_ColumnKeyWordImplicit() throws JSQLParserException {
34+
Statement stmt = CCJSqlParserUtil.parse("ALTER TABLE mytable ADD mycolumn varchar (255)");
35+
assertTrue(stmt instanceof Alter);
36+
Alter alter = (Alter)stmt;
37+
assertEquals("mytable",alter.getTable().getFullyQualifiedName());
38+
AlterExpression alterExp = alter.getAlterExpressions().get(0);
39+
assertNotNull(alterExp);
40+
List<ColumnDataType> colDataTypes = alterExp.getColDataTypeList();
41+
assertEquals("mycolumn", colDataTypes.get(0).getColumnName());
42+
assertEquals("varchar (255)", colDataTypes.get(0).getColDataType().toString());
43+
}
44+
45+
public void testAlterTablePrimaryKey() throws JSQLParserException {
3346
assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals ADD PRIMARY KEY (id)");
3447
}
3548

@@ -109,6 +122,42 @@ public void testAlterTableAddColumn4() throws JSQLParserException {
109122
assertEquals("integer", col2DataTypes.get(0).getColDataType().toString());
110123
}
111124

125+
public void testAlterTableAddColumn5() throws JSQLParserException {
126+
Statement stmt = CCJSqlParserUtil.parse("ALTER TABLE mytable ADD col1 timestamp (3)");
127+
128+
// COLUMN keyword appears in deparsed statement
129+
assertStatementCanBeDeparsedAs(stmt, "ALTER TABLE mytable ADD COLUMN col1 timestamp (3)");
130+
131+
Alter alter = (Alter) stmt;
132+
List<AlterExpression> alterExps = alter.getAlterExpressions();
133+
AlterExpression col1Exp = alterExps.get(0);
134+
List<ColumnDataType> col1DataTypes = col1Exp.getColDataTypeList();
135+
assertEquals("col1", col1DataTypes.get(0).getColumnName());
136+
assertEquals("timestamp (3)", col1DataTypes.get(0).getColDataType().toString());
137+
}
138+
139+
public void testAlterTableAddColumn6() throws JSQLParserException {
140+
final String sql = "ALTER TABLE mytable ADD COLUMN col1 timestamp (3) not null";
141+
Statement stmt = CCJSqlParserUtil.parse(sql);
142+
assertStatementCanBeDeparsedAs(stmt, sql);
143+
Alter alter = (Alter) stmt;
144+
List<AlterExpression> alterExps = alter.getAlterExpressions();
145+
AlterExpression col1Exp = alterExps.get(0);
146+
assertEquals("not", col1Exp.getColDataTypeList().get(0).getColumnSpecs().get(0));
147+
assertEquals("null", col1Exp.getColDataTypeList().get(0).getColumnSpecs().get(1));
148+
}
149+
150+
public void testAlterTableModifyColumn1() throws JSQLParserException {
151+
assertSqlCanBeParsedAndDeparsed("ALTER TABLE animals MODIFY (col1 integer, col2 number (8, 2))");
152+
}
153+
154+
public void testAlterTableModifyColumn2() throws JSQLParserException {
155+
Statement stmt = CCJSqlParserUtil.parse("ALTER TABLE mytable modify col1 timestamp (6)");
156+
157+
// COLUMN keyword appears in deparsed statement, modify becomes all caps
158+
assertStatementCanBeDeparsedAs(stmt, "ALTER TABLE mytable MODIFY COLUMN col1 timestamp (6)");
159+
}
160+
112161
public void testAlterTableAddColumnWithZone() throws JSQLParserException {
113162
assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 timestamp with time zone");
114163
assertSqlCanBeParsedAndDeparsed("ALTER TABLE mytable ADD COLUMN col1 timestamp without time zone");

0 commit comments

Comments
 (0)