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

This commit is contained in:
Lukas Eder 2020-03-23 15:23:09 +01:00
parent b62f3c2f3e
commit 58c0072866
13 changed files with 731 additions and 66 deletions

View File

@ -0,0 +1,57 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
// ...
import static org.jooq.SQLDialect.POSTGRES;
/**
* A step in the construction of an <code>XMLTABLE</code> expression.
*
* @author Lukas Eder
*/
public interface XMLTableColumnForOrdinalityStep {
/**
* Specify the <code>FOR ORDINALITY</code> clause on a column in the
* <code>COLUMNS</code> clause of the <code>XMLTABLE</code> predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsStep forOrdinality();
}

View File

@ -0,0 +1,57 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
// ...
import static org.jooq.SQLDialect.POSTGRES;
/**
* A step in the construction of an <code>XMLTABLE</code> expression.
*
* @author Lukas Eder
*/
public interface XMLTableColumnPathStep extends XMLTableColumnForOrdinalityStep, XMLTableColumnsStep {
/**
* Specify the <code>PATH</code> of a column in the <code>COLUMNS</code>
* clause of the <code>XMLTABLE</code> predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsStep path(String path);
}

View File

@ -0,0 +1,92 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
// ...
import static org.jooq.SQLDialect.POSTGRES;
/**
* A step in the construction of an <code>XMLTABLE</code> expression.
*
* @author Lukas Eder
*/
public interface XMLTableColumnsFirstStep {
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnForOrdinalityStep column(String name);
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnForOrdinalityStep column(Name name);
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnPathStep column(Field<?> name);
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnPathStep column(String name, DataType<?> type);
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnPathStep column(Name name, DataType<?> type);
/**
* Add a column to the <code>COLUMNS</code> clause of the
* <code>XMLTABLE</code> expression.
*/
@Support({ POSTGRES })
XMLTableColumnPathStep column(Field<?> name, DataType<?> type);
}

View File

@ -0,0 +1,47 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
/**
* A step in the construction of an <code>XMLTABLE</code> expression.
*
* @author Lukas Eder
*/
public interface XMLTableColumnsStep extends XMLTableColumnsFirstStep, Table<Record> {
}

View File

@ -0,0 +1,92 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
// ...
import static org.jooq.SQLDialect.POSTGRES;
/**
* A step in the construction of an <code>XMLTABLE</code> expression.
*
* @author Lukas Eder
*/
public interface XMLTablePassingStep extends XMLTableColumnsFirstStep {
/**
* Add the <code>PASSING</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passing(XML xml);
/**
* Add the <code>PASSING</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passing(Field<XML> xml);
/**
* Add the <code>PASSING BY REF</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passingByRef(XML xml);
/**
* Add the <code>PASSING BY REF</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passingByRef(Field<XML> xml);
/**
* Add the <code>PASSING BY VALUE</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passingByValue(XML xml);
/**
* Add the <code>PASSING BY VALUE</code> clause to the <code>XMLEXISTS</code>
* predicate.
*/
@Support({ POSTGRES })
XMLTableColumnsFirstStep passingByValue(Field<XML> xml);
}

View File

@ -394,6 +394,7 @@ import org.jooq.XMLAggOrderByStep;
import org.jooq.XMLAttributes;
import org.jooq.XMLExistsPassingStep;
import org.jooq.XMLQueryPassingStep;
import org.jooq.XMLTablePassingStep;
import org.jooq.conf.Settings;
import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.XMLParse.DocumentOrContent;
@ -18343,6 +18344,22 @@ public class DSL {
return new XMLExists(xpath);
}
/**
* The XML table function.
*/
@Support({ POSTGRES })
public static XMLTablePassingStep xmltable(String xpath) {
return xmltable(Tools.field(xpath));
}
/**
* The XML table function.
*/
@Support({ POSTGRES })
public static XMLTablePassingStep xmltable(Field<String> xpath) {
return new XMLTable(xpath);
}
// -------------------------------------------------------------------------
// XXX JSON functions
// -------------------------------------------------------------------------

View File

@ -273,6 +273,7 @@ final class Keywords {
static final Keyword K_OR = keyword("or");
static final Keyword K_ORDER = keyword("order");
static final Keyword K_ORDER_BY = keyword("order by");
static final Keyword K_ORDINALITY = keyword("ordinality");
static final Keyword K_OUTPUT = keyword("output");
static final Keyword K_OVER = keyword("over");
static final Keyword K_OVERLAPS = keyword("overlaps");

View File

@ -165,6 +165,7 @@ final class Names {
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_XMLTABLE = DSL.unquotedName("xmltable");
static final Name N_XPATH = DSL.unquotedName("xpath");
}

View File

@ -303,6 +303,7 @@ 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.xmltable;
import static org.jooq.impl.DSL.year;
import static org.jooq.impl.DSL.zero;
import static org.jooq.impl.JSONNullClause.ABSENT_ON_NULL;
@ -519,6 +520,9 @@ import org.jooq.WindowSpecificationRowsStep;
import org.jooq.XML;
import org.jooq.XMLAggOrderByStep;
import org.jooq.XMLAttributes;
import org.jooq.XMLTableColumnPathStep;
import org.jooq.XMLTableColumnsStep;
import org.jooq.XMLTablePassingStep;
import org.jooq.conf.ParseSearchSchema;
import org.jooq.conf.ParseUnknownFunctions;
import org.jooq.conf.ParseUnsupportedSyntax;
@ -5034,6 +5038,41 @@ final class ParserImpl implements Parser {
? generateSeries(from, to)
: generateSeries(from, to, step);
}
else if (parseFunctionNameIf(ctx, "XMLTABLE")) {
parse(ctx, '(');
XMLTablePassingStep s1 = xmltable((Field) toField(ctx, parseConcat(ctx, Type.S)));
XMLPassingMechanism m = parseXMLPassingMechanismIf(ctx);
Field<XML> passing = m == null ? null : (Field<XML>) parseField(ctx);
XMLTableColumnsStep s2 = (XMLTableColumnsStep) (
m == BY_REF
? s1.passingByRef(passing)
: m == BY_VALUE
? s1.passingByValue(passing)
: m == XMLPassingMechanism.DEFAULT
? s1.passing(passing)
: s1
);
parseKeyword(ctx, "COLUMNS");
do {
Name fieldName = parseIdentifier(ctx);
if (parseKeywordIf(ctx, "FOR ORDINALITY")) {
s2 = s2.column(fieldName).forOrdinality();
}
else {
XMLTableColumnPathStep s3 = s2.column(fieldName, parseDataType(ctx));
s2 = parseKeywordIf(ctx, "PATH") ? s3.path(parseStringLiteral(ctx)) : s3;
}
}
while (parseIf(ctx, ','));
parse(ctx, ')');
result = s2;
}
else if (parseIf(ctx, '(')) {
// A table factor parenthesis can mark the beginning of any of:
@ -6867,18 +6906,25 @@ final class ParserImpl implements Parser {
}
private static final XMLPassingMechanism parseXMLPassingMechanism(ParserContext ctx) {
parseKeyword(ctx, "PASSING");
XMLPassingMechanism result = parseXMLPassingMechanismIf(ctx);
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");
}
if (result == null)
throw ctx.expected("PASSING");
return null;
return result;
}
private static final XMLPassingMechanism parseXMLPassingMechanismIf(ParserContext ctx) {
if (!parseKeywordIf(ctx, "PASSING"))
return null;
else if (!parseKeywordIf(ctx, "BY"))
return XMLPassingMechanism.DEFAULT;
else if (parseKeywordIf(ctx, "REF"))
return BY_REF;
else if (parseKeywordIf(ctx, "VALUE"))
return BY_VALUE;
else
throw ctx.expected("REF", "VALUE");
}
private static final List<Field<?>> parseAliasedXMLContent(ParserContext ctx) {

View File

@ -37,22 +37,17 @@
*/
package org.jooq.impl;
// ...
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.Keywords.K_BY;
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.XMLPassingMechanism.BY_REF;
import static org.jooq.impl.XMLPassingMechanism.BY_VALUE;
import static org.jooq.impl.XMLTable.acceptPassing;
import static org.jooq.impl.XMLTable.acceptXPath;
import org.jooq.Condition;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.XML;
import org.jooq.XMLExistsPassingStep;
import org.jooq.conf.ParamType;
/**
* @author Lukas Eder
@ -120,29 +115,10 @@ final class XMLExists extends AbstractCondition implements XMLExistsPassingStep
.formatIndentStart()
.formatNewLine();
acceptXPath(ctx, xpath);
acceptPassing(ctx, passing, passingMechanism);
ctx.visit(xpath);
ctx.formatSeparator()
.visit(K_PASSING);
if (passingMechanism == BY_REF)
ctx.sql(' ').visit(K_BY).sql(' ').visit(K_REF);
else if (passingMechanism == BY_VALUE)
ctx.sql(' ').visit(K_BY).sql(' ').visit(K_VALUE);
ctx.sql(' ').visit(passing)
.formatIndentEnd()
ctx.formatIndentEnd()
.formatNewLine()
.sql(')');
}

View File

@ -37,4 +37,4 @@
*/
package org.jooq.impl;
enum XMLPassingMechanism { BY_REF, BY_VALUE }
enum XMLPassingMechanism { BY_REF, BY_VALUE, DEFAULT }

View File

@ -37,23 +37,19 @@
*/
package org.jooq.impl;
// ...
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.unnest;
import static org.jooq.impl.DSL.xmlagg;
import static org.jooq.impl.Keywords.K_BY;
import static org.jooq.impl.Keywords.K_PASSING;
import static org.jooq.impl.Keywords.K_REF;
import static org.jooq.impl.Names.N_XMLQUERY;
import static org.jooq.impl.SQLDataType.XML;
import static org.jooq.impl.XMLPassingMechanism.BY_REF;
import static org.jooq.impl.XMLTable.acceptPassing;
import static org.jooq.impl.XMLTable.acceptXPath;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.XML;
import org.jooq.XMLQueryPassingStep;
import org.jooq.conf.ParamType;
/**
* @author Lukas Eder
@ -127,27 +123,10 @@ final class XMLQuery extends AbstractField<XML> implements XMLQueryPassingStep {
.formatIndentStart()
.formatNewLine();
acceptXPath(ctx, xpath);
acceptPassing(ctx, passing, passingMechanism);
ctx.visit(xpath);
ctx.formatSeparator()
.visit(K_PASSING);
if (passingMechanism == BY_REF)
ctx.sql(' ').visit(K_BY).sql(' ').visit(K_REF);
ctx.sql(' ').visit(passing)
.formatIndentEnd()
ctx.formatIndentEnd()
.formatNewLine()
.sql(')');

View File

@ -0,0 +1,300 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
// ...
import static org.jooq.conf.ParamType.INLINED;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Keywords.K_BY;
import static org.jooq.impl.Keywords.K_COLUMNS;
import static org.jooq.impl.Keywords.K_FOR;
import static org.jooq.impl.Keywords.K_ORDINALITY;
import static org.jooq.impl.Keywords.K_PASSING;
import static org.jooq.impl.Keywords.K_PATH;
import static org.jooq.impl.Keywords.K_REF;
import static org.jooq.impl.Keywords.K_VALUE;
import static org.jooq.impl.Keywords.K_XMLTABLE;
import static org.jooq.impl.Names.N_XMLTABLE;
import static org.jooq.impl.XMLPassingMechanism.BY_REF;
import static org.jooq.impl.XMLPassingMechanism.BY_VALUE;
import java.util.ArrayList;
import java.util.List;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.TableOptions;
import org.jooq.XML;
import org.jooq.XMLTableColumnPathStep;
import org.jooq.XMLTablePassingStep;
import org.jooq.conf.ParamType;
/**
* @author Lukas Eder
*/
final class XMLTable
extends AbstractTable<Record>
implements
XMLTablePassingStep,
XMLTableColumnPathStep {
/**
* Generated UID
*/
private static final long serialVersionUID = -4881363881968319258L;
private final Field<String> xpath;
private final Field<XML> passing;
private final XMLPassingMechanism passingMechanism;
private final QueryPartList<XMLTableColumn> columns;
private transient Fields<Record> fields;
XMLTable(Field<String> xpath) {
this(xpath, null, null, null);
}
private XMLTable(
Field<String> xpath,
Field<XML> passing,
XMLPassingMechanism passingMechanism,
QueryPartList<XMLTableColumn> columns
) {
super(TableOptions.expression(), N_XMLTABLE);
this.xpath = xpath;
this.passing = passing;
this.passingMechanism = passingMechanism;
this.columns = columns == null ? new QueryPartList<>() : columns;
}
// -------------------------------------------------------------------------
// XXX: DSL API
// -------------------------------------------------------------------------
@Override
public final XMLTable passing(XML xml) {
return passing(Tools.field(xml));
}
@Override
public final XMLTable passing(Field<XML> xml) {
return new XMLTable(xpath, xml, null, columns);
}
@Override
public final XMLTable passingByRef(XML xml) {
return passingByRef(Tools.field(xml));
}
@Override
public final XMLTable passingByRef(Field<XML> xml) {
return new XMLTable(xpath, xml, BY_REF, columns);
}
@Override
public final XMLTable passingByValue(XML xml) {
return passingByRef(Tools.field(xml));
}
@Override
public final XMLTable passingByValue(Field<XML> xml) {
return new XMLTable(xpath, xml, BY_VALUE, columns);
}
@Override
public final XMLTable column(String name) {
return column(DSL.field(name));
}
@Override
public final XMLTable column(Name name) {
return column(DSL.field(name));
}
@Override
public final XMLTable column(Field<?> name) {
return column(name, name.getDataType());
}
@Override
public final XMLTable column(String name, DataType<?> type) {
return column(DSL.field(name), type);
}
@Override
public final XMLTable column(Name name, DataType<?> type) {
return column(DSL.field(name), type);
}
@Override
public final XMLTable column(Field<?> name, DataType<?> type) {
QueryPartList<XMLTableColumn> c = new QueryPartList<>(columns);
c.add(new XMLTableColumn(name, type, false, null));
return new XMLTable(xpath, passing, passingMechanism, c);
}
@Override
public final XMLTable forOrdinality() {
return path0(true, null);
}
@Override
public final XMLTable path(String path) {
return path0(false, path);
}
private final XMLTable path0(boolean forOrdinality, String path) {
QueryPartList<XMLTableColumn> c = new QueryPartList<>(columns);
int i = c.size() - 1;
XMLTableColumn last = c.get(i);
c.set(i, new XMLTableColumn(last.field, last.type, forOrdinality, path));
return new XMLTable(xpath, passing, passingMechanism, c);
}
// -------------------------------------------------------------------------
// XXX: Table API
// -------------------------------------------------------------------------
@Override
public final Class<? extends Record> getRecordType() {
return RecordImplN.class;
}
@Override
final Fields<Record> fields0() {
if (fields == null) {
List<Field<?>> f = new ArrayList<>();
for (XMLTableColumn c : columns)
f.add(c.field.getDataType() == c.type ? c.field : field(c.field.getQualifiedName(), c.type));
fields = new Fields<>(f);
}
return fields;
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
ctx.visit(K_XMLTABLE).sql('(')
.formatIndentStart()
.formatNewLine();
acceptXPath(ctx, xpath);
if (passing != null)
acceptPassing(ctx, passing, passingMechanism);
ctx.formatSeparator()
.visit(K_COLUMNS).sql(' ').visit(columns);
ctx.formatIndentEnd()
.formatNewLine()
.sql(')');
}
static final void acceptXPath(Context<?> ctx, Field<String> xpath) {
ctx.visit(xpath);
}
static final void acceptPassing(Context<?> ctx, Field<XML> passing, XMLPassingMechanism passingMechanism) {
ctx.formatSeparator()
.visit(K_PASSING);
if (passingMechanism == BY_REF)
ctx.sql(' ').visit(K_BY).sql(' ').visit(K_REF);
else if (passingMechanism == BY_VALUE)
ctx.sql(' ').visit(K_BY).sql(' ').visit(K_VALUE);
ctx.sql(' ').visit(passing);
}
private static class XMLTableColumn extends AbstractQueryPart {
/**
* Generated UID
*/
private static final long serialVersionUID = 783627375014050176L;
final Field<?> field;
final DataType<?> type;
final boolean forOrdinality;
final String path;
XMLTableColumn(Field<?> field, DataType<?> type, boolean forOrdinality, String path) {
this.field = field;
this.type = type;
this.forOrdinality = forOrdinality;
this.path = path;
}
@Override
public final void accept(Context<?> ctx) {
boolean previous = ctx.qualify();
ctx.qualify(false)
.visit(field)
.qualify(previous)
.sql(' ');
if (forOrdinality)
ctx.visit(K_FOR).sql(' ').visit(K_ORDINALITY);
else
Tools.toSQLDDLTypeDeclaration(ctx, type);
if (path != null)
ctx.sql(' ').visit(K_PATH).sql(' ').visit(inline(path));
}
}
}