diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index b07f725f1e..becd47e334 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -393,6 +393,7 @@ import org.jooq.XML; import org.jooq.XMLAggOrderByStep; import org.jooq.XMLAttributes; import org.jooq.XMLExistsPassingStep; +import org.jooq.XMLQueryPassingStep; import org.jooq.conf.Settings; import org.jooq.exception.SQLDialectNotSupportedException; import org.jooq.impl.XMLParse.DocumentOrContent; @@ -18310,6 +18311,22 @@ public class DSL { return new XMLAgg(field); } + /** + * The XML query function. + */ + @Support({ POSTGRES }) + public static XMLQueryPassingStep xmlquery(String xpath) { + return xmlquery(Tools.field(xpath)); + } + + /** + * The XML query function. + */ + @Support({ POSTGRES }) + public static XMLQueryPassingStep xmlquery(Field xpath) { + return new XMLQuery(xpath); + } + /** * The XML exists function. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/Names.java b/jOOQ/src/main/java/org/jooq/impl/Names.java index 9ceef5805e..2285f0650f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Names.java +++ b/jOOQ/src/main/java/org/jooq/impl/Names.java @@ -163,6 +163,7 @@ final class Names { static final Name N_XMLFOREST = DSL.unquotedName("xmlforest"); static final Name N_XMLPARSE = DSL.unquotedName("xmlparse"); static final Name N_XMLPI = DSL.unquotedName("xmlpi"); + static final Name N_XMLQUERY = DSL.unquotedName("xmlquery"); static final Name N_XMLROOT = DSL.unquotedName("xmlroot"); static final Name N_XPATH = DSL.unquotedName("xpath"); diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 86de82e91e..2846dde529 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -302,6 +302,7 @@ import static org.jooq.impl.DSL.xmlforest; import static org.jooq.impl.DSL.xmlparseContent; import static org.jooq.impl.DSL.xmlparseDocument; import static org.jooq.impl.DSL.xmlpi; +import static org.jooq.impl.DSL.xmlquery; import static org.jooq.impl.DSL.year; import static org.jooq.impl.DSL.zero; import static org.jooq.impl.JSONNullClause.ABSENT_ON_NULL; @@ -329,6 +330,8 @@ import static org.jooq.impl.Tools.EMPTY_QUERYPART; import static org.jooq.impl.Tools.EMPTY_ROW; import static org.jooq.impl.Tools.EMPTY_SORTFIELD; import static org.jooq.impl.Tools.normaliseNameCase; +import static org.jooq.impl.XMLPassingMechanism.BY_REF; +import static org.jooq.impl.XMLPassingMechanism.BY_VALUE; import java.io.ByteArrayOutputStream; import java.math.BigDecimal; @@ -525,7 +528,6 @@ import org.jooq.conf.RenderNameCase; import org.jooq.conf.RenderQuotedNames; import org.jooq.conf.Settings; import org.jooq.conf.SettingsTools; -import org.jooq.impl.XMLExists.PassingMechanism; import org.jooq.impl.XMLParse.DocumentOrContent; import org.jooq.tools.StringUtils; import org.jooq.tools.reflect.Reflect; @@ -4706,24 +4708,13 @@ final class ParserImpl implements Parser { else if (parseKeywordIf(ctx, "XMLEXISTS")) { parse(ctx, '('); Field xpath = (Field) parseField(ctx); - parseKeyword(ctx, "PASSING"); - PassingMechanism m = null; - - if (parseKeywordIf(ctx, "BY")) { - if (parseKeywordIf(ctx, "REF")) - m = PassingMechanism.BY_REF; - else if (parseKeywordIf(ctx, "VALUE")) - m = PassingMechanism.BY_VALUE; - else - throw ctx.expected("REF", "VALUE"); - } - + XMLPassingMechanism m = parseXMLPassingMechanism(ctx); Field xml = (Field) parseField(ctx); parse(ctx, ')'); - if (m == PassingMechanism.BY_REF) + if (m == BY_REF) return xmlexists(xpath).passingByRef(xml); - else if (m == PassingMechanism.BY_VALUE) + else if (m == BY_VALUE) return xmlexists(xpath).passingByValue(xml); else return xmlexists(xpath).passing(xml); @@ -6448,6 +6439,8 @@ final class ParserImpl implements Parser { return field; else if ((field = parseFieldXMLDocumentIf(ctx)) != null) return field; + else if ((field = parseFieldXMLQueryIf(ctx)) != null) + return field; break; @@ -6856,6 +6849,38 @@ final class ParserImpl implements Parser { return null; } + private static final Field parseFieldXMLQueryIf(ParserContext ctx) { + if (parseFunctionNameIf(ctx, "XMLQUERY")) { + parse(ctx, '('); + Field xpath = (Field) parseField(ctx); + XMLPassingMechanism m = parseXMLPassingMechanism(ctx); + Field xml = (Field) parseField(ctx); + parse(ctx, ')'); + + if (m == BY_REF) + return xmlquery(xpath).passingByRef(xml); + else + return xmlquery(xpath).passing(xml); + } + + return null; + } + + private static final XMLPassingMechanism parseXMLPassingMechanism(ParserContext ctx) { + parseKeyword(ctx, "PASSING"); + + if (parseKeywordIf(ctx, "BY")) { + if (parseKeywordIf(ctx, "REF")) + return BY_REF; + else if (parseKeywordIf(ctx, "VALUE")) + return BY_VALUE; + else + throw ctx.expected("REF", "VALUE"); + } + + return null; + } + private static final List> parseAliasedXMLContent(ParserContext ctx) { List> result = new ArrayList<>(); diff --git a/jOOQ/src/main/java/org/jooq/impl/XMLExists.java b/jOOQ/src/main/java/org/jooq/impl/XMLExists.java index 2b7c025715..8173ab58d1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/XMLExists.java +++ b/jOOQ/src/main/java/org/jooq/impl/XMLExists.java @@ -44,8 +44,8 @@ import static org.jooq.impl.Keywords.K_PASSING; import static org.jooq.impl.Keywords.K_REF; import static org.jooq.impl.Keywords.K_VALUE; import static org.jooq.impl.Keywords.K_XMLEXISTS; -import static org.jooq.impl.XMLExists.PassingMechanism.BY_REF; -import static org.jooq.impl.XMLExists.PassingMechanism.BY_VALUE; +import static org.jooq.impl.XMLPassingMechanism.BY_REF; +import static org.jooq.impl.XMLPassingMechanism.BY_VALUE; import org.jooq.Condition; import org.jooq.Context; @@ -62,16 +62,16 @@ final class XMLExists extends AbstractCondition implements XMLExistsPassingStep /** * Generated UID */ - private static final long serialVersionUID = -4881363881968319258L; - private final Field xpath; - private final Field passing; - private final PassingMechanism passingMechanism; + private static final long serialVersionUID = -4881363881968319258L; + private final Field xpath; + private final Field passing; + private final XMLPassingMechanism passingMechanism; XMLExists(Field xpath) { this(xpath, null, null); } - private XMLExists(Field xpath, Field passing, PassingMechanism passingMechanism) { + private XMLExists(Field xpath, Field passing, XMLPassingMechanism passingMechanism) { this.xpath = xpath; this.passing = passing; this.passingMechanism = passingMechanism; @@ -110,8 +110,6 @@ final class XMLExists extends AbstractCondition implements XMLExistsPassingStep return new XMLExists(xpath, xml, BY_VALUE); } - enum PassingMechanism { BY_REF, BY_VALUE } - // ------------------------------------------------------------------------- // XXX: QueryPart API // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/XMLParse.java b/jOOQ/src/main/java/org/jooq/impl/XMLParse.java index cc4e4ad40e..f5eb026b5f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/XMLParse.java +++ b/jOOQ/src/main/java/org/jooq/impl/XMLParse.java @@ -39,6 +39,7 @@ package org.jooq.impl; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.xmlparseDocument; +import static org.jooq.impl.DSL.xmlquery; import static org.jooq.impl.Keywords.K_CONTENT; import static org.jooq.impl.Keywords.K_DOCUMENT; import static org.jooq.impl.Names.N_XMLPARSE; @@ -88,6 +89,9 @@ final class XMLParse extends AbstractField { + + + case POSTGRES: default: acceptStandard(ctx, documentOrContent, content);