Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Capture expression name part delimiters #2001

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/main/java/net/sf/jsqlparser/schema/Column.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
*/
package net.sf.jsqlparser.schema;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.jsqlparser.expression.ArrayConstructor;
import net.sf.jsqlparser.expression.Expression;
Expand All @@ -24,6 +26,7 @@ public class Column extends ASTNodeAccessImpl implements Expression, MultiPartNa
private String columnName;
private String commentText;
private ArrayConstructor arrayConstructor;
private String tableDelimiter = ".";

public Column() {}

Expand All @@ -33,8 +36,16 @@ public Column(Table table, String columnName) {
}

public Column(List<String> nameParts) {
this(nameParts.size() > 1 ? new Table(nameParts.subList(0, nameParts.size() - 1)) : null,
this(nameParts, nameParts.size() > 1 ? Collections.nCopies(nameParts.size() - 1, ".")
: new ArrayList<>());
}

public Column(List<String> nameParts, List<String> delimiters) {
this(
nameParts.size() > 1 ? new Table(nameParts.subList(0, nameParts.size() - 1),
delimiters.subList(0, delimiters.size() - 1)) : null,
nameParts.get(nameParts.size() - 1));
setTableDelimiter(delimiters.isEmpty() ? "." : delimiters.get(delimiters.size() - 1));
}

public Column(String columnName) {
Expand Down Expand Up @@ -92,6 +103,14 @@ public void setColumnName(String string) {
columnName = string;
}

public String getTableDelimiter() {
return tableDelimiter;
}

public void setTableDelimiter(String tableDelimiter) {
this.tableDelimiter = tableDelimiter;
}

@Override
public String getFullyQualifiedName() {
return getFullyQualifiedName(false);
Expand All @@ -108,7 +127,7 @@ public String getFullyQualifiedName(boolean aliases) {
}
}
if (fqn.length() > 0) {
fqn.append('.');
fqn.append(tableDelimiter);
}
if (columnName != null) {
fqn.append(columnName);
Expand Down Expand Up @@ -157,6 +176,11 @@ public Column withCommentText(String commentText) {
return this;
}

public Column withTableDelimiter(String delimiter) {
this.setTableDelimiter(delimiter);
return this;
}

public void setCommentText(String commentText) {
this.commentText = commentText;
}
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/net/sf/jsqlparser/schema/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class Table extends ASTNodeAccessImpl implements FromItem, MultiPartName

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

private List<String> partDelimiters = new ArrayList<>();

private Alias alias;

private SampleClause sampleClause;
Expand Down Expand Up @@ -75,6 +77,17 @@ public Table(List<String> partItems) {
Collections.reverse(this.partItems);
}

public Table(List<String> partItems, List<String> partDelimiters) {
if (partDelimiters.size() != partItems.size() - 1) {
throw new IllegalArgumentException(
"the length of the delimiters list must be 1 less than nameParts");
}
this.partItems = new ArrayList<>(partItems);
this.partDelimiters = new ArrayList<>(partDelimiters);
Collections.reverse(this.partItems);
Collections.reverse(this.partDelimiters);
}

public Database getDatabase() {
return new Database(getIndex(DATABASE_IDX));
}
Expand Down Expand Up @@ -177,7 +190,7 @@ public String getFullyQualifiedName() {
}
fqn.append(part);
if (i != 0) {
fqn.append(".");
fqn.append(partDelimiters.isEmpty() ? "." : partDelimiters.get(i - 1));
}
}

Expand Down Expand Up @@ -299,4 +312,8 @@ public Table withSqlServerHints(SQLServerHints sqlServerHints) {
public List<String> getNameParts() {
return partItems;
}

public List<String> getNamePartDelimiters() {
return partDelimiters;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ public void visit(Column tableColumn) {
}
}
if (tableName != null && !tableName.isEmpty()) {
buffer.append(tableName).append(".");
buffer.append(tableName).append(tableColumn.getTableDelimiter());
}

buffer.append(tableColumn.getColumnName());
Expand Down
92 changes: 58 additions & 34 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,25 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
public Node getASTRoot() {
return jjtree.rootNode();
}

private static class ObjectNames {

private final List<String> names;
private final List<String> delimiters;

public ObjectNames(List<String> names, List<String> delimiters) {
this.names = names;
this.delimiters = delimiters;
}

public List<String> getNames() {
return names;
}

public List<String> getDelimiters() {
return delimiters;
}
}
}

PARSER_END(CCJSqlParser)
Expand Down Expand Up @@ -1886,33 +1905,38 @@ MergeOperation MergeWhenNotMatched() : {
{ return mi; }
}

List<String> RelObjectNameList() : {
ObjectNames RelObjectNames() : {
String token = null;
Token delimiter = null;
List<String> data = new ArrayList<String>();
List<String> delimiters = new ArrayList<String>();
} {
token = RelObjectNameExt() { data.add(token); }
( LOOKAHEAD (2) ("." | ":") ("." { data.add(null); })* token = RelObjectNameExt2() { data.add(token); } ) *
(
LOOKAHEAD (2) ( delimiter = "." | delimiter = ":" ) { delimiters.add(delimiter.image); } (( delimiter = "." | delimiter = ":" ) { data.add(null); delimiters.add(delimiter.image); })*
token = RelObjectNameExt2() { data.add(token); }
) *

{ return data; }
{ return new ObjectNames(data, delimiters); }
}

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

Column Column() #Column :
{
List<String> data = new ArrayList<String>();
ObjectNames data = null;
ArrayConstructor arrayConstructor = null;
Token tk = null;
}
{
data = RelObjectNameList()
data = RelObjectNames()
[ LOOKAHEAD(2) <K_COMMENT> tk=<S_CHAR_LITERAL> ]
// @todo: we better should return a SEQUENCE instead of a COLUMN
[ "." <K_NEXTVAL> { data.add("nextval"); } ]
[ "." <K_NEXTVAL> { data.getNames().add("nextval"); } ]

[ LOOKAHEAD(2) arrayConstructor = ArrayConstructor(false) ]
{
Column col = new Column(data);
Column col = new Column(data.getNames(), data.getDelimiters());
if (tk != null) { col.withCommentText(tk.image); }
if (arrayConstructor!=null) {
col.setArrayConstructor(arrayConstructor);
Expand Down Expand Up @@ -2004,13 +2028,13 @@ String RelObjectNameExt2():
Table Table() #TableName :
{
//String serverName = null, databaseName = null, schemaName = null, tableName = null;
List<String> data = new ArrayList<String>();
ObjectNames data = null;
}
{
data = RelObjectNameList()
data = RelObjectNames()

{
Table table = new Table(data);
Table table = new Table(data.getNames());
linkAST(table,jjtThis);
return table;
}
Expand Down Expand Up @@ -4545,13 +4569,13 @@ ConnectByRootOperator ConnectByRootOperator() #ConnectByRootOperator: {
}

NextValExpression NextValExpression() : {
List<String> data = new ArrayList<String>();
ObjectNames data = null;
Token token;
}
{
token=<K_NEXTVAL> data = RelObjectNameList()
token=<K_NEXTVAL> data = RelObjectNames()
{
return new NextValExpression(data, token.image);
return new NextValExpression(data.getNames(), token.image);
}
}

Expand Down Expand Up @@ -5350,7 +5374,7 @@ EqualsTo VariableExpression(): {

Execute Execute(): {
Token token;
List<String> funcName;
ObjectNames funcName;
ExpressionList expressionList = null;
Execute execute = new Execute();
List<Expression> namedExprList;
Expand All @@ -5361,7 +5385,7 @@ Execute Execute(): {
| <K_EXECUTE> { execute.setExecType(Execute.ExecType.EXECUTE); }
| <K_CALL> { execute.setExecType(Execute.ExecType.CALL); } )

funcName=RelObjectNameList() { execute.setName(funcName); }
funcName=RelObjectNames() { execute.setName(funcName.getNames()); }

(
LOOKAHEAD(2) expressionList=ExpressionList() { execute.setExprList(expressionList); }
Expand Down Expand Up @@ -5483,13 +5507,13 @@ Function SpecialStringFunctionWithNamedParameters() :
Function SimpleFunction():
{
Function function = new Function();
List<String> name;
ObjectNames name;
Expression expr=null;
Expression attributeExpression = null;
Column attributeColumn = null;
}
{
name = RelObjectNameList()
name = RelObjectNames()
"("
[
(
Expand All @@ -5508,7 +5532,7 @@ Function SimpleFunction():
]
")"
{
function.setName(name);
function.setName(name.getNames());
if (expr!=null) {
function.setParameters(expr);
}
Expand All @@ -5533,7 +5557,7 @@ Function InternalFunction(boolean escaped):
{
Token prefixToken = null;
Function retval = new Function();
List<String> funcName;
ObjectNames funcName;
ExpressionList expressionList = null;
KeepExpression keep = null;
Expression expr = null;
Expand All @@ -5544,7 +5568,7 @@ Function InternalFunction(boolean escaped):
}
{
[ LOOKAHEAD(2) prefixToken = <K_APPROXIMATE> ]
funcName = RelObjectNameList() { if (prefixToken!=null) funcName.add(0, prefixToken.image ); }
funcName = RelObjectNames() { if (prefixToken!=null) funcName.getNames().add(0, prefixToken.image ); }

"("
[
Expand Down Expand Up @@ -5601,7 +5625,7 @@ Function InternalFunction(boolean escaped):
{
retval.setEscaped(escaped);
retval.setParameters(expressionList);
retval.setName(funcName);
retval.setName(funcName.getNames());
retval.setKeep(keep);
return retval;
}
Expand Down Expand Up @@ -5698,10 +5722,10 @@ List<Index.ColumnParams> ColumnNamesWithParamsList() : {
}

Index Index(): {
List<String> name;
ObjectNames name;
}
{
name= RelObjectNameList() { return new Index().withName(name).withType(""); }
name= RelObjectNames() { return new Index().withName(name.getNames()).withType(""); }
}

CreateIndex CreateIndex():
Expand Down Expand Up @@ -7311,7 +7335,7 @@ Grant Grant():
ArrayList<String> privileges = new ArrayList<String>();
List<String> users;
Token tk = null;
List<String> objName;
ObjectNames objName;
}
{
<K_GRANT>
Expand All @@ -7320,7 +7344,7 @@ Grant Grant():
[readGrantTypes(privileges) (<K_COMMA> readGrantTypes(privileges))*]
<K_ON>
(
objName=RelObjectNameList() { grant.setObjectName(objName); }
objName=RelObjectNames() { grant.setObjectName(objName.getNames()); }
)
)
|
Expand Down Expand Up @@ -7365,13 +7389,13 @@ void readGrantTypes(ArrayList<String> privileges):

Sequence Sequence() #Sequence :
{
List<String> data = new ArrayList<String>();
ObjectNames data = null;
String serverName = null, databaseName = null, schemaName = null, sequenceName = null;
}
{
data = RelObjectNameList()
data = RelObjectNames()
{
Sequence sequence = new Sequence(data);
Sequence sequence = new Sequence(data.getNames());
linkAST(sequence,jjtThis);
return sequence;
}
Expand Down Expand Up @@ -7575,29 +7599,29 @@ CreateSynonym CreateSynonym(boolean isUsingOrReplace):
CreateSynonym createSynonym = new CreateSynonym();
Synonym synonym;
boolean publicSynonym = false;
List<String> data = new ArrayList<String>();
ObjectNames data = null;
}
{
[<K_PUBLIC> { publicSynonym = true; } ]
<K_SYNONYM> synonym=Synonym() { createSynonym.setSynonym(synonym); }
<K_FOR> data = RelObjectNameList()
<K_FOR> data = RelObjectNames()
{
createSynonym.setOrReplace(isUsingOrReplace);
createSynonym.setPublicSynonym(publicSynonym);
createSynonym.setForList(data);
createSynonym.setForList(data.getNames());
return createSynonym;
}
}

Synonym Synonym() #Synonym :
{
List<String> data = new ArrayList<String>();
ObjectNames data = null;
String serverName = null, databaseName = null, schemaName = null, sequenceName = null;
}
{
data = RelObjectNameList()
data = RelObjectNames()
{
Synonym synonym = new Synonym(data);
Synonym synonym = new Synonym(data.getNames());
linkAST(synonym,jjtThis);
return synonym;
}
Expand Down