[jOOQ/jOOQ#9925] Add support for XMLQUERY()

This commit is contained in:
Lukas Eder 2020-03-20 15:56:20 +01:00
parent d71359ff89
commit 35f253b269
5 changed files with 69 additions and 24 deletions

View File

@ -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<String> xpath) {
return new XMLQuery(xpath);
}
/**
* The XML exists function.
*/

View File

@ -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");

View File

@ -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<String> xpath = (Field<String>) 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> xml = (Field<XML>) 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<String> xpath = (Field<String>) parseField(ctx);
XMLPassingMechanism m = parseXMLPassingMechanism(ctx);
Field<XML> xml = (Field<XML>) 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<Field<?>> parseAliasedXMLContent(ParserContext ctx) {
List<Field<?>> result = new ArrayList<>();

View File

@ -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<String> xpath;
private final Field<XML> passing;
private final PassingMechanism passingMechanism;
private static final long serialVersionUID = -4881363881968319258L;
private final Field<String> xpath;
private final Field<XML> passing;
private final XMLPassingMechanism passingMechanism;
XMLExists(Field<String> xpath) {
this(xpath, null, null);
}
private XMLExists(Field<String> xpath, Field<XML> passing, PassingMechanism passingMechanism) {
private XMLExists(Field<String> xpath, Field<XML> 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
// -------------------------------------------------------------------------

View File

@ -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<XML> {
case POSTGRES:
default:
acceptStandard(ctx, documentOrContent, content);