Skip to content

Commit 7a08e3f

Browse files
author
Stefan Steinhauser
committed
Merge branch 'master' into feature/exasol-import-export
2 parents 3b74289 + e17cdef commit 7a08e3f

File tree

14 files changed

+348
-58
lines changed

14 files changed

+348
-58
lines changed

src/main/java/net/sf/jsqlparser/parser/AbstractJSqlParser.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public abstract class AbstractJSqlParser<P> {
2121
protected boolean errorRecovery = false;
2222
protected List<ParseException> parseErrors = new ArrayList<>();
2323

24+
public enum Dialect {
25+
ORACLE, EXASOL
26+
}
27+
2428
public P withSquareBracketQuotation() {
2529
return withFeature(Feature.allowSquareBracketQuotation, true);
2630
}
@@ -57,6 +61,14 @@ public P withTimeOut(long timeOutMillSeconds) {
5761
return withFeature(Feature.timeOut, timeOutMillSeconds);
5862
}
5963

64+
public P withDialect(Dialect dialect) {
65+
return withFeature(Feature.dialect, dialect.name());
66+
}
67+
68+
public P withAllowedNestingDepth(int allowedNestingDepth) {
69+
return withFeature(Feature.allowedNestingDepth, allowedNestingDepth);
70+
}
71+
6072
public P withBackslashEscapeCharacter() {
6173
return withFeature(Feature.allowBackslashEscapeCharacter, true);
6274
}
@@ -83,8 +95,21 @@ public P withFeature(Feature f, long value) {
8395
return me();
8496
}
8597

98+
public P withFeature(Feature f, String value) {
99+
getConfiguration().setValue(f, value);
100+
return me();
101+
}
102+
86103
public abstract FeatureConfiguration getConfiguration();
87104

105+
public FeatureConfiguration setValue(Feature feature, Object value) {
106+
return getConfiguration().setValue(feature, value);
107+
}
108+
109+
public Object getValue(Feature feature) {
110+
return getConfiguration().getValue(feature);
111+
}
112+
88113
public abstract P me();
89114

90115
public boolean getAsBoolean(Feature f) {
@@ -95,6 +120,18 @@ public Long getAsLong(Feature f) {
95120
return getConfiguration().getAsLong(f);
96121
}
97122

123+
public int getAsInt(Feature f) {
124+
return getConfiguration().getAsInt(f);
125+
}
126+
127+
public Integer getAsInteger(Feature f) {
128+
return getConfiguration().getAsInteger(f);
129+
}
130+
131+
public String getAsString(Feature f) {
132+
return getConfiguration().getAsString(f);
133+
}
134+
98135
public void setErrorRecovery(boolean errorRecovery) {
99136
this.errorRecovery = errorRecovery;
100137
}

src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
@SuppressWarnings("PMD.CyclomaticComplexity")
4141
public final class CCJSqlParserUtil {
4242
public final static Logger LOGGER = Logger.getLogger(CCJSqlParserUtil.class.getName());
43-
public final static int ALLOWED_NESTING_DEPTH = 10;
4443

4544
static {
4645
LOGGER.setLevel(Level.OFF);
@@ -50,7 +49,7 @@ private CCJSqlParserUtil() {}
5049

5150
public static Statement parse(Reader statementReader) throws JSQLParserException {
5251
ExecutorService executorService = Executors.newSingleThreadExecutor();
53-
Statement statement = null;
52+
Statement statement;
5453
CCJSqlParser parser = new CCJSqlParser(new StreamProvider(statementReader));
5554
try {
5655
statement = parseStatement(parser, executorService);
@@ -86,7 +85,7 @@ public static Statement parse(String sql, Consumer<CCJSqlParser> consumer)
8685
}
8786

8887
ExecutorService executorService = Executors.newSingleThreadExecutor();
89-
Statement statement = null;
88+
Statement statement;
9089
try {
9190
statement = parse(sql, executorService, consumer);
9291
} finally {
@@ -102,20 +101,22 @@ public static Statement parse(String sql, ExecutorService executorService,
102101
return null;
103102
}
104103

105-
Statement statement = null;
104+
Statement statement;
106105
// first, try to parse fast and simple
107106
CCJSqlParser parser = newParser(sql);
108107
if (consumer != null) {
109108
consumer.accept(parser);
110109
}
111-
boolean allowComplex = parser.getConfiguration().getAsBoolean(Feature.allowComplexParsing);
110+
boolean allowComplex = parser.getAsBoolean(Feature.allowComplexParsing);
111+
int allowedNestingDepth = parser.getAsInt(Feature.allowedNestingDepth);
112112
LOGGER.info("Allowed Complex Parsing: " + allowComplex);
113113
try {
114114
LOGGER.info("Trying SIMPLE parsing " + (allowComplex ? "first" : "only"));
115115
statement = parseStatement(parser.withAllowComplexParsing(false), executorService);
116116
} catch (JSQLParserException ex) {
117117
LOGGER.info("Nesting Depth" + getNestingDepth(sql));
118-
if (allowComplex && getNestingDepth(sql) <= ALLOWED_NESTING_DEPTH) {
118+
if (allowComplex
119+
&& (allowedNestingDepth < 0 || getNestingDepth(sql) <= allowedNestingDepth)) {
119120
LOGGER.info("Trying COMPLEX parsing when SIMPLE parsing failed");
120121
// beware: the parser must not be reused, but needs to be re-initiated
121122
parser = newParser(sql);
@@ -222,23 +223,21 @@ public static Expression parseExpression(String expressionStr, boolean allowPart
222223
} catch (JSQLParserException ex1) {
223224
// when fast simple parsing fails, try complex parsing but only if it has a chance to
224225
// succeed
225-
if (getNestingDepth(expressionStr) <= ALLOWED_NESTING_DEPTH) {
226-
CCJSqlParser parser = newParser(expressionStr).withAllowComplexParsing(true);
227-
if (consumer != null) {
228-
consumer.accept(parser);
229-
}
230-
try {
231-
expression = parser.Expression();
232-
if (!allowPartialParse
233-
&& parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
234-
throw new JSQLParserException(
235-
"could only parse partial expression " + expression.toString());
236-
}
237-
} catch (JSQLParserException ex) {
238-
throw ex;
239-
} catch (ParseException ex) {
240-
throw new JSQLParserException(ex);
226+
CCJSqlParser parser = newParser(expressionStr).withAllowComplexParsing(true);
227+
if (consumer != null) {
228+
consumer.accept(parser);
229+
}
230+
try {
231+
expression = parser.Expression();
232+
if (!allowPartialParse
233+
&& parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
234+
throw new JSQLParserException(
235+
"could only parse partial expression " + expression.toString());
241236
}
237+
} catch (JSQLParserException ex) {
238+
throw ex;
239+
} catch (ParseException ex) {
240+
throw new JSQLParserException(ex);
242241
}
243242
}
244243
return expression;
@@ -301,24 +300,22 @@ public static Expression parseCondExpression(String conditionalExpressionStr,
301300
throw new JSQLParserException(ex);
302301
}
303302
} catch (JSQLParserException ex1) {
304-
if (getNestingDepth(conditionalExpressionStr) <= ALLOWED_NESTING_DEPTH) {
305-
CCJSqlParser parser =
306-
newParser(conditionalExpressionStr).withAllowComplexParsing(true);
307-
if (consumer != null) {
308-
consumer.accept(parser);
309-
}
310-
try {
311-
expression = parser.Expression();
312-
if (!allowPartialParse
313-
&& parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
314-
throw new JSQLParserException(
315-
"could only parse partial expression " + expression.toString());
316-
}
317-
} catch (JSQLParserException ex) {
318-
throw ex;
319-
} catch (ParseException ex) {
320-
throw new JSQLParserException(ex);
303+
CCJSqlParser parser =
304+
newParser(conditionalExpressionStr).withAllowComplexParsing(true);
305+
if (consumer != null) {
306+
consumer.accept(parser);
307+
}
308+
try {
309+
expression = parser.Expression();
310+
if (!allowPartialParse
311+
&& parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
312+
throw new JSQLParserException(
313+
"could only parse partial expression " + expression.toString());
321314
}
315+
} catch (JSQLParserException ex) {
316+
throw ex;
317+
} catch (ParseException ex) {
318+
throw new JSQLParserException(ex);
322319
}
323320
}
324321
return expression;
@@ -334,15 +331,15 @@ public static Expression parseCondExpression(String conditionalExpressionStr,
334331

335332
public static Statement parseStatement(CCJSqlParser parser, ExecutorService executorService)
336333
throws JSQLParserException {
337-
Statement statement = null;
334+
Statement statement;
338335
Future<Statement> future = executorService.submit(new Callable<Statement>() {
339336
@Override
340337
public Statement call() throws ParseException {
341338
return parser.Statement();
342339
}
343340
});
344341
try {
345-
statement = future.get(parser.getConfiguration().getAsLong(Feature.timeOut),
342+
statement = future.get(parser.getAsLong(Feature.timeOut),
346343
TimeUnit.MILLISECONDS);
347344
} catch (TimeoutException ex) {
348345
parser.interrupted = true;
@@ -397,15 +394,17 @@ public static Statements parseStatements(String sqls, ExecutorService executorSe
397394
if (consumer != null) {
398395
consumer.accept(parser);
399396
}
400-
boolean allowComplex = parser.getConfiguration().getAsBoolean(Feature.allowComplexParsing);
397+
boolean allowComplex = parser.getAsBoolean(Feature.allowComplexParsing);
398+
int allowedNestingDepth = parser.getAsInt(Feature.allowedNestingDepth);
401399

402400
// first, try to parse fast and simple
403401
try {
404402
statements = parseStatements(parser.withAllowComplexParsing(false), executorService);
405403
} catch (JSQLParserException ex) {
406404
// when fast simple parsing fails, try complex parsing but only if it has a chance to
407405
// succeed
408-
if (allowComplex && getNestingDepth(sqls) <= ALLOWED_NESTING_DEPTH) {
406+
if (allowComplex
407+
&& (allowedNestingDepth < 0 || getNestingDepth(sqls) <= allowedNestingDepth)) {
409408
// beware: parser must not be re-used but needs to be re-initiated
410409
parser = newParser(sqls);
411410
if (consumer != null) {
@@ -434,7 +433,7 @@ public Statements call() throws ParseException {
434433
}
435434
});
436435
try {
437-
statements = future.get(parser.getConfiguration().getAsLong(Feature.timeOut),
436+
statements = future.get(parser.getAsLong(Feature.timeOut),
438437
TimeUnit.MILLISECONDS);
439438
} catch (TimeoutException ex) {
440439
parser.interrupted = true;
@@ -450,17 +449,14 @@ public static void streamStatements(StatementListener listener, InputStream is,
450449
throws JSQLParserException {
451450
try {
452451
CCJSqlParser parser = newParser(is, encoding);
453-
while (true) {
452+
do {
454453
Statement stmt = parser.SingleStatement();
455454
listener.accept(stmt);
456455
if (parser.getToken(1).kind == CCJSqlParserTokenManager.ST_SEMICOLON) {
457456
parser.getNextToken();
458457
}
459458

460-
if (parser.getToken(1).kind == CCJSqlParserTokenManager.EOF) {
461-
break;
462-
}
463-
}
459+
} while (parser.getToken(1).kind != CCJSqlParserTokenManager.EOF);
464460
} catch (Exception ex) {
465461
throw new JSQLParserException(ex);
466462
}

src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class ParserKeywordsUtils {
6464
{"CURRENT", RESTRICTED_JSQLPARSER},
6565
{"DEFAULT", RESTRICTED_ALIAS},
6666
{"DISTINCT", RESTRICTED_SQL2016},
67+
{"DISTINCTROW", RESTRICTED_SQL2016},
6768
{"DOUBLE", RESTRICTED_ALIAS},
6869
{"ELSE", RESTRICTED_JSQLPARSER},
6970
{"ERRORS", RESTRICTED_JSQLPARSER},

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,13 @@ public enum Feature {
793793
*/
794794
allowUnparenthesizedSubSelects(false),
795795

796+
/**
797+
* maximum nesting depth for trying complex parsing, can bet set to -1 to ignore
798+
*/
799+
allowedNestingDepth(10),
800+
801+
dialect(null),
802+
796803
/**
797804
* "IMPORT"
798805
*/

src/main/java/net/sf/jsqlparser/parser/feature/FeatureConfiguration.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class FeatureConfiguration {
1919

2020
private static final Logger LOG = Logger.getLogger(FeatureConfiguration.class.getName());
2121

22-
private Map<Feature, Object> featureEnabled = new EnumMap<>(Feature.class);
22+
private final Map<Feature, Object> featureEnabled = new EnumMap<>(Feature.class);
2323

2424
public FeatureConfiguration() {
2525
// set default-value for all switchable features
@@ -64,6 +64,14 @@ public Long getAsLong(Feature f) {
6464
return Long.valueOf(String.valueOf(getValue(f)));
6565
}
6666

67+
public int getAsInt(Feature f) {
68+
return Integer.parseInt(String.valueOf(getValue(f)));
69+
}
70+
71+
public Integer getAsInteger(Feature f) {
72+
return Integer.parseInt(String.valueOf(getValue(f)));
73+
}
74+
6775
public String getAsString(Feature f) {
6876
Object value = getValue(f);
6977
return value == null ? null : String.valueOf(value);

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public class Column extends ASTNodeAccessImpl implements Expression, MultiPartNa
2929
private ArrayConstructor arrayConstructor;
3030
private String tableDelimiter = ".";
3131

32+
// holds the physical table when resolved against an actual schema information
33+
private Table resolvedTable = null;
34+
3235
public Column() {}
3336

3437
public Column(Table table, String columnName) {
@@ -223,4 +226,24 @@ public String getCommentText() {
223226
public void setCommentText(String commentText) {
224227
this.commentText = commentText;
225228
}
229+
230+
/**
231+
* Gets the actual table when resolved against a physical schema information.
232+
*
233+
* @return the actual table when resolved against a physical schema information
234+
*/
235+
public Table getResolvedTable() {
236+
return resolvedTable;
237+
}
238+
239+
/**
240+
* Sets resolved table.
241+
*
242+
* @param resolvedTable the resolved table
243+
* @return this column
244+
*/
245+
public Column setResolvedTable(Table resolvedTable) {
246+
this.resolvedTable = resolvedTable;
247+
return this;
248+
}
226249
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public class Table extends ASTNodeAccessImpl implements ErrorDestination, FromIt
5757

5858
private SQLServerHints sqlServerHints;
5959

60+
// holds the physical table when resolved against an actual schema information
61+
private Table resolvedTable = null;
62+
6063
public Table() {}
6164

6265
/**
@@ -401,4 +404,24 @@ public List<String> getNameParts() {
401404
public List<String> getNamePartDelimiters() {
402405
return partDelimiters;
403406
}
407+
408+
/**
409+
* Gets the actual table when resolved against a physical schema information.
410+
*
411+
* @return the actual table when resolved against a physical schema information
412+
*/
413+
public Table getResolvedTable() {
414+
return resolvedTable;
415+
}
416+
417+
/**
418+
* Sets resolved table.
419+
*
420+
* @param resolvedTable the resolved table
421+
* @return this table
422+
*/
423+
public Table setResolvedTable(Table resolvedTable) {
424+
this.resolvedTable = resolvedTable;
425+
return this;
426+
}
404427
}

0 commit comments

Comments
 (0)