[jOOQ/jOOQ#9483] Add support for ALTER MATERIALIZED VIEW

This commit is contained in:
Lukas Eder 2023-09-15 14:19:27 +02:00
parent e6391079f6
commit 450ad85d32
7 changed files with 253 additions and 28 deletions

View File

@ -9647,6 +9647,60 @@ public interface DSLContext extends Scope {
@Support({ DUCKDB, H2, POSTGRES, YUGABYTEDB })
AlterViewStep alterViewIfExists(Table<?> view);
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
*
* @see DSL#alterMaterializedView(String)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedView(@Stringly.Name String view);
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
*
* @see DSL#alterMaterializedView(Name)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedView(Name view);
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
*
* @see DSL#alterMaterializedView(Table)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedView(Table<?> view);
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
*
* @see DSL#alterMaterializedViewIfExists(String)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedViewIfExists(@Stringly.Name String view);
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
*
* @see DSL#alterMaterializedViewIfExists(Name)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedViewIfExists(Name view);
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
*
* @see DSL#alterMaterializedViewIfExists(Table)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
AlterViewStep alterMaterializedViewIfExists(Table<?> view);
/**
* The <code>ALTER VIEW</code> statement.
*

View File

@ -76,6 +76,7 @@ implements
final Table<?> view;
final QueryPartListView<? extends Field<?>> fields;
final boolean materialized;
final boolean ifExists;
Comment comment;
Table<?> renameTo;
@ -85,12 +86,14 @@ implements
Configuration configuration,
Table<?> view,
Collection<? extends Field<?>> fields,
boolean materialized,
boolean ifExists
) {
this(
configuration,
view,
fields,
materialized,
ifExists,
null,
null,
@ -101,12 +104,14 @@ implements
AlterViewImpl(
Configuration configuration,
Table<?> view,
boolean materialized,
boolean ifExists
) {
this(
configuration,
view,
null,
materialized,
ifExists
);
}
@ -115,6 +120,7 @@ implements
Configuration configuration,
Table<?> view,
Collection<? extends Field<?>> fields,
boolean materialized,
boolean ifExists,
Comment comment,
Table<?> renameTo,
@ -124,6 +130,7 @@ implements
this.view = view;
this.fields = new QueryPartList<>(fields);
this.materialized = materialized;
this.ifExists = ifExists;
this.comment = comment;
this.renameTo = renameTo;
@ -226,11 +233,20 @@ implements
case POSTGRES:
case SQLITE:
case YUGABYTEDB:
ctx.visit(begin(dropView(view), createView(view, fields.toArray(Tools.EMPTY_FIELD)).as(as)));
if (materialized)
ctx.visit(begin(dropMaterializedView(view), createMaterializedView(view, fields.toArray(Tools.EMPTY_FIELD)).as(as)));
else
ctx.visit(begin(dropView(view), createView(view, fields.toArray(Tools.EMPTY_FIELD)).as(as)));
break;
default:
ctx.visit(K_ALTER).sql(' ').visit(K_VIEW).sql(' ').visit(view);
ctx.visit(K_ALTER).sql(' ');
if (materialized)
ctx.visit(K_MATERIALIZED).sql(' ');
ctx.visit(K_VIEW).sql(' ').visit(view);
if (!fields.isEmpty())
ctx.sql(" (").visit(QueryPartCollectionView.wrap(fields).qualify(false)).sql(')');
@ -319,13 +335,19 @@ implements
private final void accept1(Context<?> ctx) {
ctx.start(Clause.ALTER_VIEW_VIEW)
.visit(K_ALTER).sql(' ')
.visit(SUPPORT_ALTER_TABLE_RENAME.contains(ctx.dialect()) ? K_TABLE : K_VIEW);
.visit(K_ALTER).sql(' ');
if (SUPPORT_ALTER_TABLE_RENAME.contains(ctx.dialect()))
ctx.visit(K_TABLE).sql(' ');
else if (materialized)
ctx.visit(K_MATERIALIZED).sql(' ').visit(K_VIEW).sql(' ');
else
ctx.visit(K_VIEW).sql(' ');
if (ifExists && supportsIfExists(ctx))
ctx.sql(' ').visit(K_IF_EXISTS);
ctx.sql(' ').visit(view)
ctx.sql(' ').visit(view).sql(' ')
.end(Clause.ALTER_VIEW_VIEW);
if (renameTo != null)
@ -356,6 +378,11 @@ implements
return QOM.unmodifiable(fields);
}
@Override
public final boolean $materialized() {
return materialized;
}
@Override
public final boolean $ifExists() {
return ifExists;
@ -378,36 +405,41 @@ implements
@Override
public final QOM.AlterView $view(Table<?> newValue) {
return $constructor().apply(newValue, $fields(), $ifExists(), $comment(), $renameTo(), $as());
return $constructor().apply(newValue, $fields(), $materialized(), $ifExists(), $comment(), $renameTo(), $as());
}
@Override
public final QOM.AlterView $fields(Collection<? extends Field<?>> newValue) {
return $constructor().apply($view(), newValue, $ifExists(), $comment(), $renameTo(), $as());
return $constructor().apply($view(), newValue, $materialized(), $ifExists(), $comment(), $renameTo(), $as());
}
@Override
public final QOM.AlterView $materialized(boolean newValue) {
return $constructor().apply($view(), $fields(), newValue, $ifExists(), $comment(), $renameTo(), $as());
}
@Override
public final QOM.AlterView $ifExists(boolean newValue) {
return $constructor().apply($view(), $fields(), newValue, $comment(), $renameTo(), $as());
return $constructor().apply($view(), $fields(), $materialized(), newValue, $comment(), $renameTo(), $as());
}
@Override
public final QOM.AlterView $comment(Comment newValue) {
return $constructor().apply($view(), $fields(), $ifExists(), newValue, $renameTo(), $as());
return $constructor().apply($view(), $fields(), $materialized(), $ifExists(), newValue, $renameTo(), $as());
}
@Override
public final QOM.AlterView $renameTo(Table<?> newValue) {
return $constructor().apply($view(), $fields(), $ifExists(), $comment(), newValue, $as());
return $constructor().apply($view(), $fields(), $materialized(), $ifExists(), $comment(), newValue, $as());
}
@Override
public final QOM.AlterView $as(Select<?> newValue) {
return $constructor().apply($view(), $fields(), $ifExists(), $comment(), $renameTo(), newValue);
return $constructor().apply($view(), $fields(), $materialized(), $ifExists(), $comment(), $renameTo(), newValue);
}
public final Function6<? super Table<?>, ? super Collection<? extends Field<?>>, ? super Boolean, ? super Comment, ? super Table<?>, ? super Select<?>, ? extends QOM.AlterView> $constructor() {
return (a1, a2, a3, a4, a5, a6) -> new AlterViewImpl(configuration(), a1, (Collection<? extends Field<?>>) a2, a3, a4, a5, a6);
public final Function7<? super Table<?>, ? super Collection<? extends Field<?>>, ? super Boolean, ? super Boolean, ? super Comment, ? super Table<?>, ? super Select<?>, ? extends QOM.AlterView> $constructor() {
return (a1, a2, a3, a4, a5, a6, a7) -> new AlterViewImpl(configuration(), a1, (Collection<? extends Field<?>>) a2, a3, a4, a5, a6, a7);
}
@ -437,6 +469,7 @@ implements
}

View File

@ -7740,6 +7740,96 @@ public class DSL {
return dsl().alterViewIfExists(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedView(String)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedView(@Stringly.Name String view) {
return dsl().alterMaterializedView(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedView(Name)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedView(Name view) {
return dsl().alterMaterializedView(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedView(Table)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedView(Table<?> view) {
return dsl().alterMaterializedView(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedViewIfExists(String)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedViewIfExists(@Stringly.Name String view) {
return dsl().alterMaterializedViewIfExists(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedViewIfExists(Name)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedViewIfExists(Name view) {
return dsl().alterMaterializedViewIfExists(view);
}
/**
* The <code>ALTER MATERIALIZED VIEW IF EXISTS</code> statement.
* <p>
* Unlike statement construction methods in the {@link DSLContext} API, this
* creates an unattached, and thus not directly renderable or executable
* statement. It can be used as a subquery or nested in procedural logic.
*
* @see DSLContext#alterMaterializedViewIfExists(Table)
*/
@NotNull @CheckReturnValue
@Support({ POSTGRES, YUGABYTEDB })
public static org.jooq.AlterViewStep alterMaterializedViewIfExists(Table<?> view) {
return dsl().alterMaterializedViewIfExists(view);
}
/**
* The <code>ALTER VIEW</code> statement.
* <p>

View File

@ -3033,42 +3033,72 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
@Override
public org.jooq.AlterViewStep alterView(@Stringly.Name String view) {
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, false);
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, false, false);
}
@Override
public org.jooq.AlterViewStep alterView(Name view) {
return new AlterViewImpl(configuration(), DSL.table(view), null, false);
return new AlterViewImpl(configuration(), DSL.table(view), null, false, false);
}
@Override
public org.jooq.AlterViewStep alterView(Table<?> view) {
return new AlterViewImpl(configuration(), view, null, false);
return new AlterViewImpl(configuration(), view, null, false, false);
}
@Override
public org.jooq.AlterViewStep alterViewIfExists(@Stringly.Name String view) {
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, true);
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, false, true);
}
@Override
public org.jooq.AlterViewStep alterViewIfExists(Name view) {
return new AlterViewImpl(configuration(), DSL.table(view), null, true);
return new AlterViewImpl(configuration(), DSL.table(view), null, false, true);
}
@Override
public org.jooq.AlterViewStep alterViewIfExists(Table<?> view) {
return new AlterViewImpl(configuration(), view, null, true);
return new AlterViewImpl(configuration(), view, null, false, true);
}
@Override
public org.jooq.AlterViewStep alterMaterializedView(@Stringly.Name String view) {
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, true, false);
}
@Override
public org.jooq.AlterViewStep alterMaterializedView(Name view) {
return new AlterViewImpl(configuration(), DSL.table(view), null, true, false);
}
@Override
public org.jooq.AlterViewStep alterMaterializedView(Table<?> view) {
return new AlterViewImpl(configuration(), view, null, true, false);
}
@Override
public org.jooq.AlterViewStep alterMaterializedViewIfExists(@Stringly.Name String view) {
return new AlterViewImpl(configuration(), DSL.table(DSL.name(view)), null, true, true);
}
@Override
public org.jooq.AlterViewStep alterMaterializedViewIfExists(Name view) {
return new AlterViewImpl(configuration(), DSL.table(view), null, true, true);
}
@Override
public org.jooq.AlterViewStep alterMaterializedViewIfExists(Table<?> view) {
return new AlterViewImpl(configuration(), view, null, true, true);
}
@Override
public org.jooq.AlterViewStep alterView(Table<?> view, Field<?>... fields) {
return new AlterViewImpl(configuration(), view, Arrays.asList(fields), false);
return new AlterViewImpl(configuration(), view, Arrays.asList(fields), false, false);
}
@Override
public org.jooq.AlterViewStep alterView(Table<?> view, Collection<? extends Field<?>> fields) {
return new AlterViewImpl(configuration(), view, new QueryPartList<>(fields), false);
return new AlterViewImpl(configuration(), view, new QueryPartList<>(fields), false, false);
}
@Override

View File

@ -838,8 +838,10 @@ final class Interpreter {
return;
}
else if (!existing.options.type().isView())
else if (existing.options.type() != VIEW && !query.$materialized())
throw objectNotView(table);
else if (existing.options.type() != MATERIALIZED_VIEW && query.$materialized())
throw objectNotMaterializedView(table);
if (query.$renameTo() != null && checkNotExists(schema, query.$renameTo()))
existing.name((UnqualifiedName) query.$renameTo().getUnqualifiedName());

View File

@ -3017,6 +3017,11 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
break;
case 'M':
if (parseKeywordIf("MATERIALIZED VIEW"))
return parseAlterView(true);
break;
case 'P':
if (parseKeywordIf("PACKAGE"))
throw notImplemented("ALTER PACKAGE", "https://github.com/jOOQ/jOOQ/issues/9190");
@ -3063,7 +3068,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
case 'V':
if (parseKeywordIf("VIEW"))
return parseAlterView();
return parseAlterView(false);
break;
}
@ -4259,7 +4264,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
return IGNORE.get();
}
private final DDLQuery parseAlterView() {
private final DDLQuery parseAlterView(boolean materialized) {
boolean ifExists = parseKeywordIf("IF EXISTS");
Table<?> oldName = parseTableName();
Field<?>[] fields = EMPTY_FIELD;
@ -4287,14 +4292,22 @@ final class DefaultParseContext extends AbstractScope implements ParseContext {
parseKeyword("AS", "TO");
Table<?> newName = parseTableName();
return ifExists
? dsl.alterViewIfExists(oldName).renameTo(newName)
: dsl.alterView(oldName).renameTo(newName);
return (
ifExists
? materialized
? dsl.alterMaterializedViewIfExists(oldName)
: dsl.alterViewIfExists(oldName)
: materialized
? dsl.alterMaterializedView(oldName)
: dsl.alterView(oldName)
).renameTo(newName);
}
else if (parseKeywordIf("OWNER TO") && parseUser() != null)
return IGNORE.get();
else if (parseKeywordIf("SET"))
return dsl.alterView(oldName).comment(parseOptionsDescription());
return (materialized
? dsl.alterMaterializedView(oldName)
: dsl.alterView(oldName)).comment(parseOptionsDescription());
else
throw expected("AS", "OWNER TO", "RENAME", "SET");
}

View File

@ -1956,6 +1956,7 @@ public final class QOM {
{
@NotNull Table<?> $view();
@NotNull UnmodifiableList<? extends Field<?>> $fields();
boolean $materialized();
boolean $ifExists();
@Nullable Comment $comment();
@Nullable Table<?> $renameTo();
@ -1965,6 +1966,8 @@ public final class QOM {
@CheckReturnValue
@NotNull AlterView $fields(Collection<? extends Field<?>> fields);
@CheckReturnValue
@NotNull AlterView $materialized(boolean materialized);
@CheckReturnValue
@NotNull AlterView $ifExists(boolean ifExists);
@CheckReturnValue
@NotNull AlterView $comment(Comment comment);