Skip to content

Commit 8d57096

Browse files
committed
feat: Capture expression name part delimiters
1 parent b815601 commit 8d57096

File tree

8 files changed

+181
-40
lines changed

8 files changed

+181
-40
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2024 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.parser;
11+
12+
import java.util.List;
13+
14+
public class ObjectNames {
15+
16+
private final List<String> names;
17+
private final List<String> delimiters;
18+
19+
public ObjectNames(List<String> names, List<String> delimiters) {
20+
this.names = names;
21+
this.delimiters = delimiters;
22+
}
23+
24+
public List<String> getNames() {
25+
return names;
26+
}
27+
28+
public List<String> getDelimiters() {
29+
return delimiters;
30+
}
31+
}

src/main/java/net/sf/jsqlparser/schema/Column.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
package net.sf.jsqlparser.schema;
1111

12+
import java.util.ArrayList;
13+
import java.util.Collections;
1214
import java.util.List;
1315
import net.sf.jsqlparser.expression.ArrayConstructor;
1416
import net.sf.jsqlparser.expression.Expression;
@@ -24,6 +26,7 @@ public class Column extends ASTNodeAccessImpl implements Expression, MultiPartNa
2426
private String columnName;
2527
private String commentText;
2628
private ArrayConstructor arrayConstructor;
29+
private String tableDelimiter = ".";
2730

2831
public Column() {}
2932

@@ -33,8 +36,15 @@ public Column(Table table, String columnName) {
3336
}
3437

3538
public Column(List<String> nameParts) {
36-
this(nameParts.size() > 1 ? new Table(nameParts.subList(0, nameParts.size() - 1)) : null,
37-
nameParts.get(nameParts.size() - 1));
39+
this(nameParts, nameParts.size() > 1 ? Collections.nCopies(nameParts.size() - 1, ".") : new ArrayList<>());
40+
}
41+
42+
public Column(List<String> nameParts, List<String> delimiters) {
43+
this(
44+
nameParts.size() > 1 ? new Table(nameParts.subList(0, nameParts.size() - 1), delimiters.subList(0, delimiters.size() - 1)) : null,
45+
nameParts.get(nameParts.size() - 1)
46+
);
47+
setTableDelimiter(delimiters.isEmpty() ? "." : delimiters.get(delimiters.size() - 1));
3848
}
3949

4050
public Column(String columnName) {
@@ -92,6 +102,14 @@ public void setColumnName(String string) {
92102
columnName = string;
93103
}
94104

105+
public String getTableDelimiter() {
106+
return tableDelimiter;
107+
}
108+
109+
public void setTableDelimiter(String tableDelimiter) {
110+
this.tableDelimiter = tableDelimiter;
111+
}
112+
95113
@Override
96114
public String getFullyQualifiedName() {
97115
return getFullyQualifiedName(false);
@@ -108,7 +126,7 @@ public String getFullyQualifiedName(boolean aliases) {
108126
}
109127
}
110128
if (fqn.length() > 0) {
111-
fqn.append('.');
129+
fqn.append(tableDelimiter);
112130
}
113131
if (columnName != null) {
114132
fqn.append(columnName);
@@ -157,6 +175,11 @@ public Column withCommentText(String commentText) {
157175
return this;
158176
}
159177

178+
public Column withTableDelimiter(String delimiter) {
179+
this.setTableDelimiter(delimiter);
180+
return this;
181+
}
182+
160183
public void setCommentText(String commentText) {
161184
this.commentText = commentText;
162185
}

src/main/java/net/sf/jsqlparser/schema/Table.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class Table extends ASTNodeAccessImpl implements FromItem, MultiPartName
4141

4242
private List<String> partItems = new ArrayList<>();
4343

44+
private List<String> partDelimiters = new ArrayList<>();
45+
4446
private Alias alias;
4547

4648
private SampleClause sampleClause;
@@ -75,6 +77,16 @@ public Table(List<String> partItems) {
7577
Collections.reverse(this.partItems);
7678
}
7779

80+
public Table(List<String> partItems, List<String> partDelimiters) {
81+
if (partDelimiters.size() != partItems.size() - 1) {
82+
throw new IllegalArgumentException("the length of the delimiters list must be 1 less than nameParts");
83+
}
84+
this.partItems = new ArrayList<>(partItems);
85+
this.partDelimiters = new ArrayList<>(partDelimiters);
86+
Collections.reverse(this.partItems);
87+
Collections.reverse(this.partDelimiters);
88+
}
89+
7890
public Database getDatabase() {
7991
return new Database(getIndex(DATABASE_IDX));
8092
}
@@ -177,7 +189,7 @@ public String getFullyQualifiedName() {
177189
}
178190
fqn.append(part);
179191
if (i != 0) {
180-
fqn.append(".");
192+
fqn.append(partDelimiters.isEmpty() ? "." : partDelimiters.get(i - 1));
181193
}
182194
}
183195

@@ -299,4 +311,8 @@ public Table withSqlServerHints(SQLServerHints sqlServerHints) {
299311
public List<String> getNameParts() {
300312
return partItems;
301313
}
314+
315+
public List<String> getNamePartDelimiters() {
316+
return partDelimiters;
317+
}
302318
}

src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ public void visit(Column tableColumn) {
571571
}
572572
}
573573
if (tableName != null && !tableName.isEmpty()) {
574-
buffer.append(tableName).append(".");
574+
buffer.append(tableName).append(tableColumn.getTableDelimiter());
575575
}
576576

577577
buffer.append(tableColumn.getColumnName());

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

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,33 +1886,38 @@ MergeOperation MergeWhenNotMatched() : {
18861886
{ return mi; }
18871887
}
18881888

1889-
List<String> RelObjectNameList() : {
1889+
ObjectNames RelObjectNames() : {
18901890
String token = null;
1891+
Token delimiter = null;
18911892
List<String> data = new ArrayList<String>();
1893+
List<String> delimiters = new ArrayList<String>();
18921894
} {
18931895
token = RelObjectNameExt() { data.add(token); }
1894-
( LOOKAHEAD (2) ("." | ":") ("." { data.add(null); })* token = RelObjectNameExt2() { data.add(token); } ) *
1896+
(
1897+
LOOKAHEAD (2) ( delimiter = "." | delimiter = ":" ) { delimiters.add(delimiter.image); } ( delimiter = "." { data.add(null); delimiters.add(delimiter.image); })*
1898+
token = RelObjectNameExt2() { data.add(token); }
1899+
) *
18951900

1896-
{ return data; }
1901+
{ return new ObjectNames(data, delimiters); }
18971902
}
18981903

18991904
// See: http://technet.microsoft.com/en-us/library/ms187879%28v=sql.105%29.aspx
19001905

19011906
Column Column() #Column :
19021907
{
1903-
List<String> data = new ArrayList<String>();
1908+
ObjectNames data = null;
19041909
ArrayConstructor arrayConstructor = null;
19051910
Token tk = null;
19061911
}
19071912
{
1908-
data = RelObjectNameList()
1913+
data = RelObjectNames()
19091914
[ LOOKAHEAD(2) <K_COMMENT> tk=<S_CHAR_LITERAL> ]
19101915
// @todo: we better should return a SEQUENCE instead of a COLUMN
1911-
[ "." <K_NEXTVAL> { data.add("nextval"); } ]
1916+
[ "." <K_NEXTVAL> { data.getNames().add("nextval"); } ]
19121917

19131918
[ LOOKAHEAD(2) arrayConstructor = ArrayConstructor(false) ]
19141919
{
1915-
Column col = new Column(data);
1920+
Column col = new Column(data.getNames(), data.getDelimiters());
19161921
if (tk != null) { col.withCommentText(tk.image); }
19171922
if (arrayConstructor!=null) {
19181923
col.setArrayConstructor(arrayConstructor);
@@ -2004,13 +2009,13 @@ String RelObjectNameExt2():
20042009
Table Table() #TableName :
20052010
{
20062011
//String serverName = null, databaseName = null, schemaName = null, tableName = null;
2007-
List<String> data = new ArrayList<String>();
2012+
ObjectNames data = null;
20082013
}
20092014
{
2010-
data = RelObjectNameList()
2015+
data = RelObjectNames()
20112016

20122017
{
2013-
Table table = new Table(data);
2018+
Table table = new Table(data.getNames());
20142019
linkAST(table,jjtThis);
20152020
return table;
20162021
}
@@ -4545,13 +4550,13 @@ ConnectByRootOperator ConnectByRootOperator() #ConnectByRootOperator: {
45454550
}
45464551

45474552
NextValExpression NextValExpression() : {
4548-
List<String> data = new ArrayList<String>();
4553+
ObjectNames data = null;
45494554
Token token;
45504555
}
45514556
{
4552-
token=<K_NEXTVAL> data = RelObjectNameList()
4557+
token=<K_NEXTVAL> data = RelObjectNames()
45534558
{
4554-
return new NextValExpression(data, token.image);
4559+
return new NextValExpression(data.getNames(), token.image);
45554560
}
45564561
}
45574562

@@ -5350,7 +5355,7 @@ EqualsTo VariableExpression(): {
53505355

53515356
Execute Execute(): {
53525357
Token token;
5353-
List<String> funcName;
5358+
ObjectNames funcName;
53545359
ExpressionList expressionList = null;
53555360
Execute execute = new Execute();
53565361
List<Expression> namedExprList;
@@ -5361,7 +5366,7 @@ Execute Execute(): {
53615366
| <K_EXECUTE> { execute.setExecType(Execute.ExecType.EXECUTE); }
53625367
| <K_CALL> { execute.setExecType(Execute.ExecType.CALL); } )
53635368

5364-
funcName=RelObjectNameList() { execute.setName(funcName); }
5369+
funcName=RelObjectNames() { execute.setName(funcName.getNames()); }
53655370

53665371
(
53675372
LOOKAHEAD(2) expressionList=ExpressionList() { execute.setExprList(expressionList); }
@@ -5483,13 +5488,13 @@ Function SpecialStringFunctionWithNamedParameters() :
54835488
Function SimpleFunction():
54845489
{
54855490
Function function = new Function();
5486-
List<String> name;
5491+
ObjectNames name;
54875492
Expression expr=null;
54885493
Expression attributeExpression = null;
54895494
Column attributeColumn = null;
54905495
}
54915496
{
5492-
name = RelObjectNameList()
5497+
name = RelObjectNames()
54935498
"("
54945499
[
54955500
(
@@ -5508,7 +5513,7 @@ Function SimpleFunction():
55085513
]
55095514
")"
55105515
{
5511-
function.setName(name);
5516+
function.setName(name.getNames());
55125517
if (expr!=null) {
55135518
function.setParameters(expr);
55145519
}
@@ -5533,7 +5538,7 @@ Function InternalFunction(boolean escaped):
55335538
{
55345539
Token prefixToken = null;
55355540
Function retval = new Function();
5536-
List<String> funcName;
5541+
ObjectNames funcName;
55375542
ExpressionList expressionList = null;
55385543
KeepExpression keep = null;
55395544
Expression expr = null;
@@ -5544,7 +5549,7 @@ Function InternalFunction(boolean escaped):
55445549
}
55455550
{
55465551
[ LOOKAHEAD(2) prefixToken = <K_APPROXIMATE> ]
5547-
funcName = RelObjectNameList() { if (prefixToken!=null) funcName.add(0, prefixToken.image ); }
5552+
funcName = RelObjectNames() { if (prefixToken!=null) funcName.getNames().add(0, prefixToken.image ); }
55485553

55495554
"("
55505555
[
@@ -5601,7 +5606,7 @@ Function InternalFunction(boolean escaped):
56015606
{
56025607
retval.setEscaped(escaped);
56035608
retval.setParameters(expressionList);
5604-
retval.setName(funcName);
5609+
retval.setName(funcName.getNames());
56055610
retval.setKeep(keep);
56065611
return retval;
56075612
}
@@ -5698,10 +5703,10 @@ List<Index.ColumnParams> ColumnNamesWithParamsList() : {
56985703
}
56995704

57005705
Index Index(): {
5701-
List<String> name;
5706+
ObjectNames name;
57025707
}
57035708
{
5704-
name= RelObjectNameList() { return new Index().withName(name).withType(""); }
5709+
name= RelObjectNames() { return new Index().withName(name.getNames()).withType(""); }
57055710
}
57065711

57075712
CreateIndex CreateIndex():
@@ -7311,7 +7316,7 @@ Grant Grant():
73117316
ArrayList<String> privileges = new ArrayList<String>();
73127317
List<String> users;
73137318
Token tk = null;
7314-
List<String> objName;
7319+
ObjectNames objName;
73157320
}
73167321
{
73177322
<K_GRANT>
@@ -7320,7 +7325,7 @@ Grant Grant():
73207325
[readGrantTypes(privileges) (<K_COMMA> readGrantTypes(privileges))*]
73217326
<K_ON>
73227327
(
7323-
objName=RelObjectNameList() { grant.setObjectName(objName); }
7328+
objName=RelObjectNames() { grant.setObjectName(objName.getNames()); }
73247329
)
73257330
)
73267331
|
@@ -7365,13 +7370,13 @@ void readGrantTypes(ArrayList<String> privileges):
73657370

73667371
Sequence Sequence() #Sequence :
73677372
{
7368-
List<String> data = new ArrayList<String>();
7373+
ObjectNames data = null;
73697374
String serverName = null, databaseName = null, schemaName = null, sequenceName = null;
73707375
}
73717376
{
7372-
data = RelObjectNameList()
7377+
data = RelObjectNames()
73737378
{
7374-
Sequence sequence = new Sequence(data);
7379+
Sequence sequence = new Sequence(data.getNames());
73757380
linkAST(sequence,jjtThis);
73767381
return sequence;
73777382
}
@@ -7575,29 +7580,29 @@ CreateSynonym CreateSynonym(boolean isUsingOrReplace):
75757580
CreateSynonym createSynonym = new CreateSynonym();
75767581
Synonym synonym;
75777582
boolean publicSynonym = false;
7578-
List<String> data = new ArrayList<String>();
7583+
ObjectNames data = null;
75797584
}
75807585
{
75817586
[<K_PUBLIC> { publicSynonym = true; } ]
75827587
<K_SYNONYM> synonym=Synonym() { createSynonym.setSynonym(synonym); }
7583-
<K_FOR> data = RelObjectNameList()
7588+
<K_FOR> data = RelObjectNames()
75847589
{
75857590
createSynonym.setOrReplace(isUsingOrReplace);
75867591
createSynonym.setPublicSynonym(publicSynonym);
7587-
createSynonym.setForList(data);
7592+
createSynonym.setForList(data.getNames());
75887593
return createSynonym;
75897594
}
75907595
}
75917596

75927597
Synonym Synonym() #Synonym :
75937598
{
7594-
List<String> data = new ArrayList<String>();
7599+
ObjectNames data = null;
75957600
String serverName = null, databaseName = null, schemaName = null, sequenceName = null;
75967601
}
75977602
{
7598-
data = RelObjectNameList()
7603+
data = RelObjectNames()
75997604
{
7600-
Synonym synonym = new Synonym(data);
7605+
Synonym synonym = new Synonym(data.getNames());
76017606
linkAST(synonym,jjtThis);
76027607
return synonym;
76037608
}

0 commit comments

Comments
 (0)