[jOOQ/jOOQ#12538] Add Settings.parseRetainCommentsBetweenQueries
This commit is contained in:
parent
6870ca20ba
commit
701b9c3b98
File diff suppressed because it is too large
Load Diff
@ -120,6 +120,8 @@ public final class ParserCLI {
|
||||
settings.setParseNameCase(a.parseNameCase);
|
||||
if (a.parseNamedParamPrefix != null)
|
||||
settings.setParseNamedParamPrefix(a.parseNamedParamPrefix);
|
||||
if (a.parseRetainCommentsBetweenQueries != null)
|
||||
settings.setParseRetainCommentsBetweenQueries(a.parseRetainCommentsBetweenQueries);
|
||||
if (a.parseSetCommands != null)
|
||||
settings.setParseSetCommands(a.parseSetCommands);
|
||||
if (a.parseTimestampFormat != null)
|
||||
@ -254,6 +256,12 @@ public final class ParserCLI {
|
||||
|
||||
displayParseNamedParamPrefix(a);
|
||||
}
|
||||
else if ("parse-retain-comments-between-queries".equals(flag)) {
|
||||
if (arg != null)
|
||||
a.parseRetainCommentsBetweenQueries = Boolean.parseBoolean(arg.toLowerCase());
|
||||
|
||||
displayParseRetainCommentsBetweenQueries(a);
|
||||
}
|
||||
else if ("parse-set-commands".equals(flag)) {
|
||||
if (arg != null)
|
||||
a.parseSetCommands = Boolean.parseBoolean(arg.toLowerCase());
|
||||
@ -396,6 +404,10 @@ public final class ParserCLI {
|
||||
System.out.println("Parse named param prefix : " + a.parseNamedParamPrefix);
|
||||
}
|
||||
|
||||
private static void displayParseRetainCommentsBetweenQueries(Args a) {
|
||||
System.out.println("Retain comments between queries : " + a.parseRetainCommentsBetweenQueries);
|
||||
}
|
||||
|
||||
private static void displayParseSetCommands(Args a) {
|
||||
System.out.println("Parse set commands : " + a.parseSetCommands);
|
||||
}
|
||||
@ -529,6 +541,8 @@ public final class ParserCLI {
|
||||
result.parseNamedParamPrefix = args[++i];
|
||||
else if ("--parse-set-commands".equals(args[i]))
|
||||
result.parseSetCommands = true;
|
||||
else if ("--parse-retain-comments-between-queries".equals(args[i]))
|
||||
result.parseRetainCommentsBetweenQueries = true;
|
||||
else if ("--parse-timestamp-format".equals(args[i]))
|
||||
result.parseTimestampFormat = args[++i];
|
||||
else if ("--parse-unknown-functions".equals(args[i]))
|
||||
@ -601,6 +615,7 @@ public final class ParserCLI {
|
||||
System.out.println(" --parse-locale <Locale>");
|
||||
System.out.println(" --parse-name-case <ParseNameCase>");
|
||||
System.out.println(" --parse-named-param-prefix <String>");
|
||||
System.out.println(" --parse-retain-comments-between-queries");
|
||||
System.out.println(" --parse-set-commands");
|
||||
System.out.println(" --parse-timestamp-format <String>");
|
||||
System.out.println(" --parse-unknown-functions <ParseUnknownFunctions>");
|
||||
@ -638,6 +653,7 @@ public final class ParserCLI {
|
||||
System.out.println(" /parse-locale <Locale>");
|
||||
System.out.println(" /parse-name-case <ParseNameCase>");
|
||||
System.out.println(" /parse-named-param-prefix <String>");
|
||||
System.out.println(" /parse-retain-comments-between-queries <boolean>");
|
||||
System.out.println(" /parse-set-commands <boolean>");
|
||||
System.out.println(" /parse-timestamp-format <String>");
|
||||
System.out.println(" /parse-unknown-functions <ParseUnknownFunctions>");
|
||||
@ -684,6 +700,7 @@ public final class ParserCLI {
|
||||
Locale parseLocale = d.getParseLocale();
|
||||
ParseNameCase parseNameCase = d.getParseNameCase();
|
||||
String parseNamedParamPrefix = d.getParseNamedParamPrefix();
|
||||
Boolean parseRetainCommentsBetweenQueries = d.isParseRetainCommentsBetweenQueries();
|
||||
Boolean parseSetCommands = d.isParseSetCommands();
|
||||
String parseTimestampFormat = d.getParseTimestampFormat();
|
||||
ParseUnknownFunctions parseUnknownFunctions = d.getParseUnknownFunctions();
|
||||
|
||||
@ -316,6 +316,8 @@ public class Settings
|
||||
protected String parseIgnoreCommentStart = "[jooq ignore start]";
|
||||
@XmlElement(defaultValue = "[jooq ignore stop]")
|
||||
protected String parseIgnoreCommentStop = "[jooq ignore stop]";
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean parseRetainCommentsBetweenQueries = false;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean parseMetaDefaultExpressions = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
@ -2881,6 +2883,36 @@ public class Settings
|
||||
this.parseIgnoreCommentStop = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* [#12538] Whether the parser should retain comments and whitespace between queries when parsing multiple queries through {@link org.jooq.Parser#parse(String)}.
|
||||
* <p>
|
||||
* jOOQ's query object model doesn't have a way to represent comments
|
||||
* or other whitespace, and as such, the parser simply skips them by default.
|
||||
* However, it may be desirable to retain comments before or in between top
|
||||
* level queries, when parsing multiple such queries in a script. Comments
|
||||
* inside of queries (including procedural statements) are still not supported.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isParseRetainCommentsBetweenQueries() {
|
||||
return parseRetainCommentsBetweenQueries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the parseRetainCommentsBetweenQueries property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setParseRetainCommentsBetweenQueries(Boolean value) {
|
||||
this.parseRetainCommentsBetweenQueries = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* [#8469] Whether to parse default expressions retrieved from {@link java.sql.DatabaseMetaData}.
|
||||
*
|
||||
@ -3911,6 +3943,11 @@ public class Settings
|
||||
return this;
|
||||
}
|
||||
|
||||
public Settings withParseRetainCommentsBetweenQueries(Boolean value) {
|
||||
setParseRetainCommentsBetweenQueries(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Settings withParseMetaDefaultExpressions(Boolean value) {
|
||||
setParseMetaDefaultExpressions(value);
|
||||
return this;
|
||||
@ -4102,6 +4139,7 @@ public class Settings
|
||||
builder.append("parseIgnoreComments", parseIgnoreComments);
|
||||
builder.append("parseIgnoreCommentStart", parseIgnoreCommentStart);
|
||||
builder.append("parseIgnoreCommentStop", parseIgnoreCommentStop);
|
||||
builder.append("parseRetainCommentsBetweenQueries", parseRetainCommentsBetweenQueries);
|
||||
builder.append("parseMetaDefaultExpressions", parseMetaDefaultExpressions);
|
||||
builder.append("applyWorkaroundFor7962", applyWorkaroundFor7962);
|
||||
builder.append("interpreterSearchPath", "schema", interpreterSearchPath);
|
||||
@ -5172,6 +5210,15 @@ public class Settings
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (parseRetainCommentsBetweenQueries == null) {
|
||||
if (other.parseRetainCommentsBetweenQueries!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!parseRetainCommentsBetweenQueries.equals(other.parseRetainCommentsBetweenQueries)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (parseMetaDefaultExpressions == null) {
|
||||
if (other.parseMetaDefaultExpressions!= null) {
|
||||
return false;
|
||||
@ -5340,6 +5387,7 @@ public class Settings
|
||||
result = ((prime*result)+((parseIgnoreComments == null)? 0 :parseIgnoreComments.hashCode()));
|
||||
result = ((prime*result)+((parseIgnoreCommentStart == null)? 0 :parseIgnoreCommentStart.hashCode()));
|
||||
result = ((prime*result)+((parseIgnoreCommentStop == null)? 0 :parseIgnoreCommentStop.hashCode()));
|
||||
result = ((prime*result)+((parseRetainCommentsBetweenQueries == null)? 0 :parseRetainCommentsBetweenQueries.hashCode()));
|
||||
result = ((prime*result)+((parseMetaDefaultExpressions == null)? 0 :parseMetaDefaultExpressions.hashCode()));
|
||||
result = ((prime*result)+((applyWorkaroundFor7962 == null)? 0 :applyWorkaroundFor7962 .hashCode()));
|
||||
result = ((prime*result)+((interpreterSearchPath == null)? 0 :interpreterSearchPath.hashCode()));
|
||||
|
||||
@ -791,15 +791,33 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
|
||||
|
||||
static final Set<SQLDialect> SUPPORTS_HASH_COMMENT_SYNTAX = SQLDialect.supportedBy(MARIADB, MYSQL);
|
||||
static final Pattern P_TRIM = Pattern.compile("^ *\\r?\\n?(.*?) *$");
|
||||
|
||||
final Queries parse() {
|
||||
return wrap(() -> {
|
||||
List<Query> result = new ArrayList<>();
|
||||
Query query;
|
||||
int p = positionBeforeWhitespace;
|
||||
|
||||
do {
|
||||
parseDelimiterSpecifications();
|
||||
while (parseDelimiterIf(false));
|
||||
|
||||
while (parseDelimiterIf(false))
|
||||
p = positionBeforeWhitespace;
|
||||
|
||||
skipWhitespace:
|
||||
if (TRUE.equals(settings().isParseRetainCommentsBetweenQueries()) && p < position) {
|
||||
|
||||
retainWhitespace: {
|
||||
for (int i = p; i < position; i++)
|
||||
if (character(i) != ' ')
|
||||
break retainWhitespace;
|
||||
|
||||
break skipWhitespace;
|
||||
}
|
||||
|
||||
result.add(new IgnoreQuery(P_TRIM.matcher(substring(p, position)).replaceFirst("$1")));
|
||||
}
|
||||
|
||||
query = patchParsedQuery(parseQuery(false, false));
|
||||
if (query == IGNORE || query == IGNORE_NO_DELIMITER)
|
||||
@ -807,7 +825,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
if (query != null)
|
||||
result.add(query);
|
||||
}
|
||||
while (parseDelimiterIf(true) && !done());
|
||||
while (parseDelimiterIf(true) && (p = positionBeforeWhitespace) >= 0 && !done());
|
||||
|
||||
return done("Unexpected token or missing query delimiter", dsl.queries(result));
|
||||
});
|
||||
@ -13366,9 +13384,9 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
}
|
||||
|
||||
private final boolean parseWhitespaceIf() {
|
||||
int p = position();
|
||||
position(afterWhitespace(p));
|
||||
return p != position();
|
||||
positionBeforeWhitespace = position();
|
||||
position(afterWhitespace(positionBeforeWhitespace));
|
||||
return positionBeforeWhitespace != position();
|
||||
}
|
||||
|
||||
private final int afterWhitespace(int p) {
|
||||
@ -13698,17 +13716,25 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
"FOR"
|
||||
};
|
||||
|
||||
private static final DDLQuery IGNORE = new IgnoreQuery();
|
||||
private static final Query IGNORE_NO_DELIMITER = new IgnoreQuery();
|
||||
private static final DDLQuery IGNORE = new IgnoreQuery();
|
||||
private static final Query IGNORE_NO_DELIMITER = new IgnoreQuery();
|
||||
|
||||
static final class IgnoreQuery extends AbstractDDLQuery implements UEmpty {
|
||||
private final String sql;
|
||||
|
||||
private static final class IgnoreQuery extends AbstractDDLQuery implements UEmpty {
|
||||
IgnoreQuery() {
|
||||
this("/* ignored */");
|
||||
}
|
||||
|
||||
IgnoreQuery(String sql) {
|
||||
super(CTX.configuration());
|
||||
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Context<?> ctx) {
|
||||
ctx.sql("/* ignored */");
|
||||
ctx.sql(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13719,6 +13745,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
private final ParseWithMetaLookups metaLookups;
|
||||
private boolean metaLookupsForceIgnore;
|
||||
private final Consumer<Param<?>> bindParamListener;
|
||||
private int positionBeforeWhitespace;
|
||||
private int position = 0;
|
||||
private boolean ignoreHints = true;
|
||||
private final Object[] bindings;
|
||||
|
||||
@ -58,6 +58,7 @@ import org.jooq.Query;
|
||||
import org.jooq.ResultQuery;
|
||||
import org.jooq.Results;
|
||||
import org.jooq.Traverser;
|
||||
import org.jooq.impl.DefaultParseContext.IgnoreQuery;
|
||||
import org.jooq.impl.QOM.MList;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.impl.ResultsImpl.ResultOrRowsImpl;
|
||||
@ -151,7 +152,10 @@ final class QueriesImpl extends AbstractAttachableQueryPart implements Queries {
|
||||
else
|
||||
ctx.formatSeparator();
|
||||
|
||||
ctx.visit(query).sql(';');
|
||||
ctx.visit(query);
|
||||
|
||||
if (!(query instanceof IgnoreQuery))
|
||||
ctx.sql(';');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -705,6 +705,16 @@ This feature is available in the commercial distribution only.]]></jxb:javadoc><
|
||||
<element name="parseIgnoreCommentStop" type="string" minOccurs="0" maxOccurs="1" default="[jooq ignore stop]">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#8325] The ignore comment stop token]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="parseRetainCommentsBetweenQueries" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#12538] Whether the parser should retain comments and whitespace between queries when parsing multiple queries through {@link org.jooq.Parser#parse(String)}.
|
||||
<p>
|
||||
jOOQ's query object model doesn't have a way to represent comments
|
||||
or other whitespace, and as such, the parser simply skips them by default.
|
||||
However, it may be desirable to retain comments before or in between top
|
||||
level queries, when parsing multiple such queries in a script. Comments
|
||||
inside of queries (including procedural statements) are still not supported.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="parseMetaDefaultExpressions" type="boolean" minOccurs="0" maxOccurs="1" default="true">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[[#8469] Whether to parse default expressions retrieved from {@link java.sql.DatabaseMetaData}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user