[jOOQ/jOOQ#8805] Support OVERLAY() function

This commit is contained in:
Lukas Eder 2020-02-24 12:53:21 +01:00
parent b1598ccbd9
commit 630c7736eb
5 changed files with 189 additions and 0 deletions

View File

@ -13954,6 +13954,38 @@ public class DSL {
return new Position(nullSafe(search), nullSafe(in), nullSafe(startIndex));
}
/**
* Get the overlay(in, placing, startIndex) function.
*/
@Support
public static Field<String> overlay(Field<String> in, String placing, Number startIndex) {
return new Overlay(nullSafe(in), Tools.field(placing), Tools.field(startIndex));
}
/**
* Get the overlay(in, placing, startIndex) function.
*/
@Support
public static Field<String> overlay(Field<String> in, Field<String> placing, Field<? extends Number> startIndex) {
return new Overlay(nullSafe(in), nullSafe(placing), nullSafe(startIndex));
}
/**
* Get the overlay(in, placing, startIndex, length) function.
*/
@Support
public static Field<String> overlay(Field<String> in, String placing, Number startIndex, Number length) {
return new Overlay(nullSafe(in), Tools.field(placing), Tools.field(startIndex), Tools.field(length));
}
/**
* Get the overlay(in, placing, startIndex, length) function.
*/
@Support
public static Field<String> overlay(Field<String> in, Field<String> placing, Field<? extends Number> startIndex, Field<? extends Number> length) {
return new Overlay(nullSafe(in), nullSafe(placing), nullSafe(startIndex), nullSafe(length));
}
/**
* Get the ascii(field) function.
*

View File

@ -273,6 +273,7 @@ final class Keywords {
static final Keyword K_PERCENT = keyword("percent");
static final Keyword K_PERIOD = keyword("period");
static final Keyword K_PIVOT = keyword("pivot");
static final Keyword K_PLACING = keyword("placing");
static final Keyword K_POSITION = keyword("position");
static final Keyword K_PRECEDING = keyword("preceding");
static final Keyword K_PREVIOUS_VALUE_FOR = keyword("previous value for");
@ -446,6 +447,7 @@ final class Keywords {
static final Keyword F_NUMTODSINTERVAL = keyword("numtodsinterval");
static final Keyword F_NVL = keyword("nvl");
static final Keyword F_NVL2 = keyword("nvl2");
static final Keyword F_OVERLAY = keyword("overlay");
static final Keyword F_POSITION = keyword("position");
static final Keyword F_POWER = keyword("power");
static final Keyword F_RAND = keyword("rand");

View File

@ -93,6 +93,7 @@ final class Names {
static final Name N_NULLIF = DSL.name("nullif");
static final Name N_NVL = DSL.name("nvl");
static final Name N_NVL2 = DSL.name("nvl2");
static final Name N_OVERLAY = DSL.name("overlay");
static final Name N_PIVOT = DSL.name("pivot");
static final Name N_POSITION = DSL.name("position");
static final Name N_POWER = DSL.name("power");

View File

@ -0,0 +1,131 @@
/*
* 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.SQLDialect.DERBY;
import static org.jooq.SQLDialect.H2;
// ...
import static org.jooq.SQLDialect.HSQLDB;
// ...
// ...
import static org.jooq.SQLDialect.MARIADB;
// ...
import static org.jooq.SQLDialect.MYSQL;
// ...
// ...
// ...
import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
// ...
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Keywords.F_OVERLAY;
import static org.jooq.impl.Keywords.K_FOR;
import static org.jooq.impl.Keywords.K_FROM;
import static org.jooq.impl.Keywords.K_PLACING;
import static org.jooq.impl.Names.N_OVERLAY;
import java.util.Set;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.SQLDialect;
/**
* @author Lukas Eder
*/
final class Overlay extends AbstractField<String> {
private static final long serialVersionUID = 3544690069533526544L;
private static final Set<SQLDialect> NO_SUPPORT = SQLDialect.supportedBy(DERBY, H2, HSQLDB, MARIADB, MYSQL, SQLITE);
private final Field<String> in;
private final Field<String> placing;
private final Field<? extends Number> startIndex;
private final Field<? extends Number> length;
Overlay(Field<String> in, Field<String> placing, Field<? extends Number> startIndex) {
this(in, placing, startIndex, null);
}
Overlay(Field<String> in, Field<String> placing, Field<? extends Number> startIndex, Field<? extends Number> length) {
super(N_OVERLAY, in.getDataType());
this.in = in;
this.placing = placing;
this.startIndex = startIndex;
this.length = length;
}
@Override
public final void accept(Context<?> ctx) {
if (length != null) {
if (NO_SUPPORT.contains(ctx.family())) {
ctx.visit(
DSL.substring(in, inline(1), startIndex.minus(inline(1)))
.concat(placing)
.concat(DSL.substring(in, startIndex.plus(length)))
);
}
else {
ctx.visit(F_OVERLAY).sql('(').visit(in).sql(' ')
.visit(K_PLACING).sql(' ').visit(placing).sql(' ')
.visit(K_FROM).sql(' ').visit(startIndex).sql(' ')
.visit(K_FOR).sql(' ').visit(length).sql(')');
}
}
else {
if (NO_SUPPORT.contains(ctx.family())) {
ctx.visit(
DSL.substring(in, inline(1), startIndex.minus(inline(1)))
.concat(placing)
.concat(DSL.substring(in, startIndex.plus(DSL.length(placing))))
);
}
else {
ctx.visit(F_OVERLAY).sql('(').visit(in).sql(' ')
.visit(K_PLACING).sql(' ').visit(placing).sql(' ')
.visit(K_FROM).sql(' ').visit(startIndex).sql(')');
}
}
}
}

View File

@ -194,6 +194,7 @@ import static org.jooq.impl.DSL.nvl2;
import static org.jooq.impl.DSL.octetLength;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.DSL.orderBy;
import static org.jooq.impl.DSL.overlay;
import static org.jooq.impl.DSL.partitionBy;
import static org.jooq.impl.DSL.percentRank;
import static org.jooq.impl.DSL.percentileCont;
@ -6116,6 +6117,8 @@ final class ParserImpl implements Parser {
if (S.is(type))
if ((field = parseFieldReplaceIf(ctx)) != null)
return field;
else if ((field = parseFieldOverlayIf(ctx)) != null)
return field;
if (N.is(type))
if ((field = parseFieldOctetLengthIf(ctx)) != null)
@ -7547,6 +7550,26 @@ final class ParserImpl implements Parser {
return null;
}
private static final Field<?> parseFieldOverlayIf(ParserContext ctx) {
if (parseFunctionNameIf(ctx, "OVERLAY")) {
parse(ctx, '(');
Field<String> f1 = (Field) parseField(ctx, S);
parseKeyword(ctx, "PLACING");
Field<String> f2 = (Field) parseField(ctx, S);
parseKeyword(ctx, "FROM");
Field<Number> f3 = (Field) parseField(ctx, N);
Field<Number> f4 =
parseKeywordIf(ctx, "FOR")
? (Field) parseField(ctx, N)
: null;
parse(ctx, ')');
return f4 == null ? overlay(f1, f2, f3) : overlay(f1, f2, f3, f4);
}
return null;
}
private static final Field<?> parseFieldPositionIf(ParserContext ctx) {
if (parseFunctionNameIf(ctx, "POSITION")) {
parse(ctx, '(');