[jOOQ/jOOQ#12050] PL/SQL can't have length/precision/scale in casts

This includes:

- [jOOQ/jOOQ#11250] Add a language context to the ParserContext
This commit is contained in:
Lukas Eder 2021-06-23 18:05:31 +02:00
parent fbb43fa884
commit 2d128da1eb
9 changed files with 96 additions and 1 deletions

View File

@ -783,6 +783,32 @@ public interface Context<C extends Context<C>> extends Scope {
@NotNull
C paramTypeIf(ParamType paramType, boolean condition, Consumer<? super C> runnable);
/**
* The current language context.
*/
@NotNull
LanguageContext languageContext();
/**
* Set the new language context for {@link #languageContext()}
*/
@NotNull
C languageContext(LanguageContext languageContext);
/**
* Set the new language context for {@link #languageContext()} for the scope
* of a {@link Consumer}.
*/
@NotNull
C languageContext(LanguageContext languageContext, Consumer<? super C> consumer);
/**
* Set the new language context for {@link #languageContext()}, if a
* condition is true.
*/
@NotNull
C languageContextIf(LanguageContext languageContext, boolean condition);
/**
* The currently applied cast mode for bind values.
*/
@ -800,7 +826,7 @@ public interface Context<C extends Context<C>> extends Scope {
* {@link Consumer}.
*/
@NotNull
C castMode(CastMode mode, Consumer<? super C> runnable);
C castMode(CastMode mode, Consumer<? super C> consumer);
/**
* Set the new cast mode for {@link #castMode()}, if a condition is true.

View File

@ -74,6 +74,7 @@ import org.jooq.Context;
import org.jooq.DSLContext;
import org.jooq.ForeignKey;
import org.jooq.JoinType;
import org.jooq.LanguageContext;
// ...
import org.jooq.QueryPart;
import org.jooq.QueryPartInternal;
@ -92,6 +93,8 @@ import org.jooq.conf.SettingsTools;
import org.jooq.conf.StatementType;
import org.jooq.tools.StringUtils;
import org.jetbrains.annotations.NotNull;
/**
* @author Lukas Eder
*/
@ -134,6 +137,7 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
final ParamType forcedParamType;
final boolean castModeOverride;
CastMode castMode;
LanguageContext languageContext;
ParamType paramType = ParamType.INDEXED;
boolean quote = true;
boolean qualifySchema = true;
@ -205,6 +209,7 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
: m == ParamCastMode.NEVER
? CastMode.NEVER
: CastMode.DEFAULT;
this.languageContext = LanguageContext.QUERY;
this.scopeStack = new ScopeStack<QueryPart, ScopeStackElement>(ScopeStackElement::new);
}
@ -906,6 +911,30 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
return toggle(q, this::qualifyCatalog, this::qualifyCatalog, consumer);
}
@Override
public final LanguageContext languageContext() {
return languageContext;
}
@Override
public final C languageContext(LanguageContext context) {
this.languageContext = context;
return (C) this;
}
@Override
public final C languageContext(LanguageContext context, Consumer<? super C> consumer) {
return toggle(context, this::languageContext, this::languageContext, consumer);
}
@Override
public final C languageContextIf(LanguageContext context, boolean condition) {
if (condition)
languageContext(context);
return (C) this;
}
@Override
public final CastMode castMode() {
return castMode;

View File

@ -42,6 +42,7 @@ import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
// ...
// ...
// ...
import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.impl.Internal.arrayType;
import static org.jooq.impl.SQLDataType.BLOB;
@ -82,6 +83,7 @@ import org.jooq.EnumType;
import org.jooq.Field;
import org.jooq.JSON;
import org.jooq.JSONB;
import org.jooq.LanguageContext;
import org.jooq.Name;
import org.jooq.Nullability;
// ...

View File

@ -88,6 +88,7 @@ import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.DDLQuery;
import org.jooq.Keyword;
import org.jooq.LanguageContext;
import org.jooq.Name;
// ...
import org.jooq.Query;
@ -98,6 +99,8 @@ import org.jooq.conf.ParamType;
import org.jooq.impl.ScopeMarker.ScopeContent;
import org.jooq.impl.Tools.DataExtendedKey;
import org.jetbrains.annotations.NotNull;
/**
* @author Lukas Eder
*/
@ -341,6 +344,10 @@ final class BlockImpl extends AbstractRowCountQuery implements Block {
if (wrapInBeginEnd) {
boolean topLevel = ctx.scopeLevel() == -1;
LanguageContext language = ctx.languageContext();
if (topLevel && language == LanguageContext.QUERY)
ctx.languageContext(LanguageContext.BLOCK);
@ -375,6 +382,9 @@ final class BlockImpl extends AbstractRowCountQuery implements Block {
scopeDeclarations(ctx, c -> accept1(c));
end(ctx, topLevel);
}
if (topLevel && language == LanguageContext.QUERY)
ctx.languageContext(language);
}
else
accept1(ctx);
@ -408,6 +418,9 @@ final class BlockImpl extends AbstractRowCountQuery implements Block {
if (s instanceof NullStatement && !SUPPORTS_NULL_STATEMENT.contains(ctx.dialect()))
continue statementLoop;
LanguageContext language = ctx.languageContext();
ctx.languageContextIf(LanguageContext.QUERY, s instanceof Query && !(s instanceof Block));
ctx.formatSeparator();
int position = r != null ? r.sql.length() : 0;
@ -457,6 +470,8 @@ final class BlockImpl extends AbstractRowCountQuery implements Block {
// [#11374] [#11367] TODO Improve this clunky semi colon decision logic
if (position < (r != null ? r.sql.length() : 0))
semicolonAfterStatement(ctx, s);
ctx.languageContext(language);
}
}
}

View File

@ -37,6 +37,7 @@
*/
package org.jooq.impl;
// ...
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_CAST;
@ -56,11 +57,13 @@ import static org.jooq.impl.SQLDataType.VARCHAR;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.regex.Pattern;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.Keyword;
import org.jooq.LanguageContext;
// ...
import org.jooq.QueryPart;
import org.jooq.RenderContext.CastMode;
@ -291,6 +294,12 @@ final class Cast<T> extends AbstractField<T> {
@ -330,6 +339,11 @@ final class Cast<T> extends AbstractField<T> {
if (typeAsKeyword != null)
ctx.visit(typeAsKeyword);
else
ctx.sql(type.getCastTypeName(ctx.configuration()));

View File

@ -318,6 +318,9 @@ package org.jooq.impl;

View File

@ -302,6 +302,8 @@ package org.jooq.impl;

View File

@ -523,6 +523,9 @@ package org.jooq.impl;

View File

@ -63,6 +63,7 @@ import org.jooq.Configuration;
import org.jooq.Constants;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.LanguageContext;
import org.jooq.Param;
import org.jooq.Query;
import org.jooq.QueryPart;