diff --git a/.github/workflows/ci-jooq-dialect.yaml b/.github/workflows/ci-jooq-dialect.yaml index 9a6f5252..d75e0f51 100644 --- a/.github/workflows/ci-jooq-dialect.yaml +++ b/.github/workflows/ci-jooq-dialect.yaml @@ -20,7 +20,7 @@ jobs: strategy: matrix: - java: [ '17', '21' ] + java: [ '21' , '25'] steps: - uses: actions/checkout@v5 diff --git a/.github/workflows/publish-jooq-dialect.yaml b/.github/workflows/publish-jooq-dialect.yaml index b82e7e9c..442db44d 100644 --- a/.github/workflows/publish-jooq-dialect.yaml +++ b/.github/workflows/publish-jooq-dialect.yaml @@ -38,7 +38,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v5 with: - java-version: 17 + java-version: 21 distribution: 'temurin' cache: 'maven' @@ -70,7 +70,7 @@ jobs: - name: Set up Maven Central Repository uses: actions/setup-java@v5 with: - java-version: 17 + java-version: 21 distribution: 'temurin' cache: 'maven' server-id: ossrh-s01 diff --git a/jooq-dialect/README.md b/jooq-dialect/README.md index b72cc14e..f6840327 100644 --- a/jooq-dialect/README.md +++ b/jooq-dialect/README.md @@ -21,8 +21,8 @@ This project introduces a JOOQ dialect specifically tailored for the Yandex Data To utilize this JOOQ YDB Dialect, ensure you have: -- Java 11 or above. -- JOOQ 3.15 or higher. +- Java 21 or above. +- JOOQ 3.21 or higher. - [YDB JDBC Driver](https://github.com/ydb-platform/ydb-jdbc-driver) - Access to a YDB Database instance. diff --git a/jooq-dialect/pom.xml b/jooq-dialect/pom.xml index 2e42e019..9cf6c2fe 100644 --- a/jooq-dialect/pom.xml +++ b/jooq-dialect/pom.xml @@ -46,11 +46,11 @@ UTF-8 - 17 - 17 - 17 + 21 + 21 + 21 - 3.19.0 + 3.21.0 2.3.8 2.3.11 diff --git a/jooq-dialect/src/main/java/org/jooq/impl/AbstractYdbAggregateFunction.java b/jooq-dialect/src/main/java/org/jooq/impl/AbstractYdbAggregateFunction.java index b40fa31f..47339886 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/AbstractYdbAggregateFunction.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/AbstractYdbAggregateFunction.java @@ -4,7 +4,11 @@ import org.jooq.Field; import org.jooq.Name; -public abstract class AbstractYdbAggregateFunction extends AbstractAggregateFunction { +import java.util.function.Function; + +import static org.jooq.impl.Tools.EMPTY_FIELD; + +public abstract class AbstractYdbAggregateFunction extends AbstractAggregateFunction> { protected AbstractYdbAggregateFunction(String name, DataType type, Field... arguments) { super(name, type, arguments); } @@ -20,4 +24,16 @@ protected AbstractYdbAggregateFunction(boolean distinct, String name, DataType type, Field... arguments) { super(distinct, name, type, arguments); } + + @Override + AbstractYdbAggregateFunction copyAggregateFunction( + Function, ? extends AbstractYdbAggregateFunction> function) { + return function.apply(new Copy<>(distinct, getQualifiedName(), getDataType(), getArguments().toArray(EMPTY_FIELD))); + } + + private static final class Copy extends AbstractYdbAggregateFunction { + private Copy(boolean distinct, Name name, DataType type, Field... arguments) { + super(distinct, name, type, arguments); + } + } } diff --git a/jooq-dialect/src/main/java/org/jooq/impl/BatchReplace.java b/jooq-dialect/src/main/java/org/jooq/impl/BatchReplace.java index 645cb9af..ede16377 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/BatchReplace.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/BatchReplace.java @@ -8,6 +8,8 @@ import tech.ydb.jooq.ReplaceQuery; import tech.ydb.jooq.YdbDSLContext; +import java.util.function.Function; + public class BatchReplace extends AbstractBatch { private final YdbDSLContext ydbDSLContext; private final TableRecord[] records; @@ -20,11 +22,20 @@ public BatchReplace(YdbDSLContext ydbDSLContext, TableRecord[] records) { @Override public int[] execute() throws DataAccessException { + return execute0(BatchBindStep::execute, new int[0]); + } + + @Override + public long[] executeLarge() throws DataAccessException { + return execute0(BatchBindStep::executeLarge, new long[0]); + } + + private T execute0(Function executor, T empty) { BatchBindStep batchBindStep = prepareBatch(); if (batchBindStep == null) { - return new int[0]; + return empty; } - int[] result = batchBindStep.execute(); + T result = executor.apply(batchBindStep); updateChangedFlag(); return result; } @@ -35,7 +46,7 @@ public int size() { } @Override - public void subscribe(Subscriber subscriber) { + void subscribe0(Subscriber subscriber) { throw new UnsupportedOperationException("BatchReplace operation is not supported in a reactive way"); } diff --git a/jooq-dialect/src/main/java/org/jooq/impl/DataTypesUtils.java b/jooq-dialect/src/main/java/org/jooq/impl/DataTypesUtils.java index bdabf863..06d2f970 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/DataTypesUtils.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/DataTypesUtils.java @@ -27,6 +27,7 @@ public static DataType newDataType(DataType sqlDataType, String typeName, name(typeName), typeName, typeName, + typeName, sqlDataType.precisionDefined() ? sqlDataType.precision() : null, sqlDataType.scaleDefined() ? sqlDataType.scale() : null, sqlDataType.lengthDefined() ? sqlDataType.length() : null, diff --git a/jooq-dialect/src/main/java/org/jooq/impl/FieldMapsForUpsertReplace.java b/jooq-dialect/src/main/java/org/jooq/impl/FieldMapsForUpsertReplace.java index f669e543..78bc9b3b 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/FieldMapsForUpsertReplace.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/FieldMapsForUpsertReplace.java @@ -29,7 +29,7 @@ public final class FieldMapsForUpsertReplace extends AbstractQueryPart { private final Table table; private final Map, Field> empty; private final Map, List>> values; - private int rows; + int rows; private int nextRow = -1; public FieldMapsForUpsertReplace(Table table) { diff --git a/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceImpl.java b/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceImpl.java index be628735..e788ada0 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceImpl.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceImpl.java @@ -543,7 +543,7 @@ private void addValue(UpsertReplaceQueryImpl delegate, Field field, in } else if (object instanceof FieldLike f) { delegate.addValue(field, index, f.asField()); } else if (field != null) { - delegate.addValue(field, index, field.getDataType().convert(object)); + delegate.addValue(field, index, AbstractDataType.convert0(field.getDataType(), object, Internal.converterContext())); } else { delegate.addValue(field, index, (T) object); } @@ -782,7 +782,7 @@ public SELF set(Map map) { } public SELF set(Record record) { - return set(Tools.mapOfChangedValues(record)); + return set(Tools.mapOfTouchedValues(getDelegate(), record)); } public SELF set(Record... records) { diff --git a/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceQueryImpl.java b/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceQueryImpl.java index b74c40eb..68b0235d 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceQueryImpl.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/UpsertReplaceQueryImpl.java @@ -5,6 +5,7 @@ import org.jooq.Field; import org.jooq.Keyword; import org.jooq.Record; +import org.jooq.Scope; import org.jooq.Select; import org.jooq.Table; import tech.ydb.jooq.ReplaceQuery; @@ -150,6 +151,17 @@ public boolean isExecutable() { return upsertReplaceMaps.isExecutable() || select != null; } + @Override + int estimatedRowCount(Scope ctx) { + if (select != null) { + return Integer.MAX_VALUE; + } else if (InlineDerivedTable.inlineDerivedTable(ctx, table(ctx)) instanceof InlineDerivedTable) { + return Integer.MAX_VALUE; + } else { + return upsertReplaceMaps.rows; + } + } + private UpsertReplaceQueryImpl copy(Consumer> finisher) { return copy(finisher, table); } diff --git a/jooq-dialect/src/main/java/org/jooq/impl/YdbTableImpl.java b/jooq-dialect/src/main/java/org/jooq/impl/YdbTableImpl.java index 6d6f6bac..0b1fb2da 100644 --- a/jooq-dialect/src/main/java/org/jooq/impl/YdbTableImpl.java +++ b/jooq-dialect/src/main/java/org/jooq/impl/YdbTableImpl.java @@ -2,6 +2,7 @@ import org.jooq.Comment; import org.jooq.Condition; +import org.jooq.Context; import org.jooq.Field; import org.jooq.Name; import org.jooq.Record; @@ -21,6 +22,24 @@ protected YdbTableImpl(Name name, Schema schema, Table aliased, Field[] pa } public Table viewPrimaryKey() { - return new HintedTable<>(this, DSL.keyword("use primary key"), new QueryPartList<>(PRIMARY_KEY)); + return new YdbHintedTable<>(this); + } + + private static final class YdbHintedTable extends AbstractDelegatingTable { + private YdbHintedTable(AbstractTable delegate) { + super(delegate); + } + + @Override + AbstractDelegatingTable construct(AbstractTable newDelegate) { + return new YdbHintedTable<>(newDelegate); + } + + @Override + public void accept(Context ctx) { + ctx.visit(delegate) + .sql(' ').visit(Keywords.K_VIEW) + .sql(' ').visit(PRIMARY_KEY); + } } } diff --git a/jooq-dialect/src/main/java/tech/ydb/jooq/codegen/YdbDatabase.java b/jooq-dialect/src/main/java/tech/ydb/jooq/codegen/YdbDatabase.java index 8a764e6b..0d410805 100644 --- a/jooq-dialect/src/main/java/tech/ydb/jooq/codegen/YdbDatabase.java +++ b/jooq-dialect/src/main/java/tech/ydb/jooq/codegen/YdbDatabase.java @@ -6,6 +6,7 @@ import java.util.List; import org.jooq.DSLContext; import org.jooq.Record12; +import org.jooq.Record15; import org.jooq.Record4; import org.jooq.Record5; import org.jooq.Record6; @@ -279,4 +280,24 @@ public ResultQuery> sources(List public ResultQuery> comments(List schemas) { return null; } + + @Override + public ResultQuery> attributes(List schemas) { + return null; + } + + @Override + public ResultQuery> identities(List schemas) { + return null; + } + + @Override + public ResultQuery> generators(List schemas) { + return null; + } + + @Override + public ResultQuery> checks(List schemas) { + return null; + } }