[jOOQ/jOOQ#10572] Support parsing the HANA MAP function
This includes: - [jOOQ/jOOQ#9085] Render DECODE by default
This commit is contained in:
parent
5f546619da
commit
b29595ce06
@ -37,12 +37,18 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.SQLDialect.*;
|
||||
import static org.jooq.impl.DSL.function;
|
||||
import static org.jooq.impl.Names.N_DECODE;
|
||||
import static org.jooq.impl.Names.N_MAP;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.CaseConditionStep;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Field;
|
||||
// ...
|
||||
import org.jooq.SQLDialect;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -52,7 +58,12 @@ final class Decode<T, Z> extends AbstractField<Z> {
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -7273879239726265322L;
|
||||
private static final long serialVersionUID = -7273879239726265322L;
|
||||
private static final Set<SQLDialect> EMULATE_DISTINCT = SQLDialect.supportedBy(CUBRID, DERBY, FIREBIRD, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private final Field<T> field;
|
||||
private final Field<T> search;
|
||||
@ -71,44 +82,24 @@ final class Decode<T, Z> extends AbstractField<Z> {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
switch (ctx.family()) {
|
||||
if (EMULATE_DISTINCT.contains(ctx.dialect())) {
|
||||
CaseConditionStep<Z> when = DSL.choose().when(field.isNotDistinctFrom(search), result);
|
||||
|
||||
for (int i = 0; i + 1 < more.length; i += 2)
|
||||
when = when.when(field.isNotDistinctFrom((Field<T>) more[i]), (Field<Z>) more[i + 1]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case H2:
|
||||
case IGNITE:
|
||||
ctx.visit(function("decode", getDataType(), Tools.combine(field, search, result, more)));
|
||||
return;
|
||||
|
||||
// Other dialects emulate it with a CASE ... WHEN expression
|
||||
default:
|
||||
CaseConditionStep<Z> when = DSL
|
||||
.choose()
|
||||
.when(field.isNotDistinctFrom(search), result);
|
||||
|
||||
for (int i = 0; i < more.length; i += 2) {
|
||||
|
||||
// search/result pair
|
||||
if (i + 1 < more.length) {
|
||||
when = when.when(field.isNotDistinctFrom((Field<T>) more[i]), (Field<Z>) more[i + 1]);
|
||||
}
|
||||
|
||||
// trailing default value
|
||||
else {
|
||||
ctx.visit(when.otherwise((Field<Z>) more[i]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (more.length % 2 == 0)
|
||||
ctx.visit(when);
|
||||
return;
|
||||
else
|
||||
ctx.visit(when.otherwise((Field<Z>) more[more.length - 1]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
else
|
||||
ctx.visit(function(N_DECODE, getDataType(), Tools.combine(field, search, result, more)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +166,9 @@ final class GenerateSeries extends AbstractTable<Record1<Integer>> implements Au
|
||||
@Override
|
||||
public final Table<Record1<Integer>> autoAlias(Context<?> ctx) {
|
||||
if (EMULATE_WITH_RECURSIVE.contains(ctx.dialect()) ||
|
||||
|
||||
|
||||
|
||||
EMULATE_SYSTEM_RANGE.contains(ctx.dialect()))
|
||||
return as(N_GENERATE_SERIES, N_GENERATE_SERIES);
|
||||
else
|
||||
|
||||
@ -201,6 +201,7 @@ final class Names {
|
||||
static final Name N_LOWER = unquotedName("lower");
|
||||
static final Name N_LPAD = unquotedName("lpad");
|
||||
static final Name N_LTRIM = unquotedName("ltrim");
|
||||
static final Name N_MAP = unquotedName("map");
|
||||
static final Name N_MAX = unquotedName("max");
|
||||
static final Name N_MAXVALUE = unquotedName("maxvalue");
|
||||
static final Name N_MD5 = unquotedName("md5");
|
||||
|
||||
@ -7410,6 +7410,8 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
return field;
|
||||
else if ((field = parseFieldLeastIf()) != null)
|
||||
return field;
|
||||
else if ((field = parseFieldDecodeIf()) != null)
|
||||
return field;
|
||||
|
||||
break;
|
||||
|
||||
@ -9808,7 +9810,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
|
||||
}
|
||||
|
||||
private final Field<?> parseFieldDecodeIf() {
|
||||
if (parseFunctionNameIf("DECODE")) {
|
||||
if (parseFunctionNameIf("DECODE", "MAP")) {
|
||||
parse('(');
|
||||
List<Field<?>> fields = parseList(',', ParseContext::parseField);
|
||||
int size = fields.size();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user