[#7171] Add support for parsing Oracle-style hints

This commit is contained in:
lukaseder 2018-02-22 11:03:06 +01:00
parent d0acc17226
commit 7c80289e35

View File

@ -888,6 +888,7 @@ final class ParserImpl implements Parser {
}
parseKeyword(ctx, "SELECT");
String hints = parseHints(ctx);
boolean distinct = parseKeywordIf(ctx, "DISTINCT") || parseKeywordIf(ctx, "UNIQUE");
List<Field<?>> distinctOn = null;
@ -1019,6 +1020,9 @@ final class ParserImpl implements Parser {
// TODO support WINDOW
SelectQueryImpl<Record> result = new SelectQueryImpl<Record>(ctx.dsl.configuration(), with);
if (hints != null)
result.addHint(hints);
if (distinct)
result.setDistinct(distinct);
@ -3410,6 +3414,41 @@ final class ParserImpl implements Parser {
return toField(ctx, parseConcat(ctx, type));
}
private static final String parseHints(ParserContext ctx) {
ctx.ignoreHints = false;
StringBuilder sb = new StringBuilder();
while (parseWhitespaceIf(ctx)) {
int position = ctx.position;
if (parseIf(ctx, '/')) {
parse(ctx, '*');
int i = ctx.position;
loop:
while (i < ctx.sql.length) {
switch (ctx.sql[i]) {
case '*':
if (i + 1 < ctx.sql.length && ctx.sql[i + 1] == '/')
break loop;
}
i++;
}
ctx.position = i + 2;
if (sb.length() > 0)
sb.append(' ');
sb.append(new String(ctx.sql, position, ctx.position - position));
}
}
ctx.ignoreHints = true;
return sb.length() > 0 ? sb.toString() : null;
}
private static final Condition toCondition(ParserContext ctx, QueryPart part) {
if (part == null)
return null;
@ -7046,16 +7085,22 @@ final class ParserImpl implements Parser {
while (i < ctx.sql.length) {
switch (ctx.sql[i]) {
case '+':
if (!ctx.ignoreHints && i + 1 < ctx.sql.length && Character.isAlphabetic(ctx.sql[i + 1]))
break loop;
break;
case '*':
if (i + 1 < ctx.sql.length && ctx.sql[i + 1] == '/') {
position = i = i + 1;
continue loop;
}
// No break
default:
i++;
break;
}
i++;
}
}
@ -7104,7 +7149,8 @@ final class ParserImpl implements Parser {
final ParseWithMetaLookups metaLookups;
final String sqlString;
final char[] sql;
int position = 0;
int position = 0;
boolean ignoreHints = true;
final Object[] bindings;
int bindIndex = 0;
String delimiter = ";";