From 57e1ac0c998aaa2a383604241bbcf46e0c411ed8 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 8 Jul 2019 12:13:43 +0200 Subject: [PATCH] [jOOQ/jOOQ#8910] Parse pg_catalog.set_config('search_path') as SET SCHEMA in DDLDatabase --- .../jooq/meta/extensions/ddl/DDLDatabase.java | 3 ++ .../main/java/org/jooq/impl/ParserImpl.java | 38 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java b/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java index a865ed8e78..ea6e2b5945 100644 --- a/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java +++ b/jOOQ-meta-extensions/src/main/java/org/jooq/meta/extensions/ddl/DDLDatabase.java @@ -134,6 +134,9 @@ public class DDLDatabase extends H2Database { // [#7771] [#8011] Ignore all parsed storage clauses when executing the statements ctx.data("org.jooq.meta.extensions.ddl.ignore-storage-clauses", true); + // [#8910] Parse things a bit differently for use with the DDLDatabase + ctx.data("org.jooq.meta.extensions.ddl.parse-for-ddldatabase", true); + if (!"AS_IS".equals(defaultNameCase)) { ctx.configuration().set(new DefaultVisitListener() { @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index ce55f0b4f7..7db1a087f7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -321,6 +321,8 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jooq.AggregateFilterStep; import org.jooq.AggregateFunction; @@ -473,7 +475,11 @@ import org.jooq.conf.ParseSearchSchema; import org.jooq.conf.ParseUnknownFunctions; import org.jooq.conf.ParseUnsupportedSyntax; import org.jooq.conf.ParseWithMetaLookups; +import org.jooq.conf.RenderKeywordCase; +import org.jooq.conf.RenderNameCase; +import org.jooq.conf.RenderQuotedNames; import org.jooq.conf.Settings; +import org.jooq.conf.SettingsTools; import org.jooq.tools.reflect.Reflect; import org.jooq.types.DayToSecond; import org.jooq.types.Interval; @@ -530,7 +536,7 @@ final class ParserImpl implements Parser { if (query == IGNORE || query == IGNORE_NO_DELIMITER) continue; if (query != null) - result.add(query); + result.add(patchParsedQuery(ctx, query)); } while (query == IGNORE_NO_DELIMITER || parseDelimiterIf(ctx)); @@ -538,6 +544,36 @@ final class ParserImpl implements Parser { return dsl.queries(result); } + private static final Pattern P_SEARCH_PATH = Pattern.compile("select\\s+(pg_catalog\\s*\\.\\s*)?set_config\\s*\\(\\s*'search_path'\\s*,\\s*'([^']*)'\\s*,\\s*\\w+\\s*\\)"); + + private final Query patchParsedQuery(ParserContext ctx, Query query) { + + // [#8910] Some statements can be parsed differently when we know we're + // parsing them for the DDLDatabase. This method patches these + // statements. + if (TRUE.equals(ctx.configuration().data("org.jooq.meta.extensions.ddl.parse-for-ddldatabase"))) { + if (query instanceof Select) { + String sql = + ctx.configuration().derive(SettingsTools.clone(ctx.configuration().settings()) + .withRenderFormatted(false) + .withRenderKeywordCase(RenderKeywordCase.LOWER) + .withRenderNameCase(RenderNameCase.LOWER) + .withRenderQuotedNames(RenderQuotedNames.NEVER) + .withRenderSchema(false)) + .dsl() + .render(query); + + // [#8910] special treatment for PostgreSQL pg_dump's curious + // usage of the SET SCHEMA command + Matcher matcher = P_SEARCH_PATH.matcher(sql); + if (matcher.find()) + return ctx.configuration().dsl().setSchema(matcher.group(2)); + } + } + + return query; + } + @Override public final Query parseQuery(String sql) { return parseQuery(sql, new Object[0]);