Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,17 @@ public java.util.Optional<String> generateListAgg(CharSequence operand, boolean
return java.util.Optional.of((buf).toString());
}

/** The n-th value of the group's rows in their order: an ordered array, its n-th element (V-82). */
/**
* The n-th value of the group's rows in their order: an ordered array, its n-th element (V-82). H2 fails an
* element reference past the end ("Array element error", also ARRAY_GET), so the element is sliced out and a NULL
* appended: a group with fewer values gives NULL, as the aggregate promises.
*/
@Override
public java.util.Optional<String> generateNthValueAgg(CharSequence operand, boolean ignoreNulls, Integer n,
List<OrderedColumn> columns) {
return java.util.Optional.of(buildNthValueOfArray("ARRAY_AGG", operand, ignoreNulls, columns, "(",
")[" + AggregationGenerator.nthIndex(n) + "]").toString());
int index = AggregationGenerator.nthIndex(n);
return java.util.Optional.of(buildNthValueOfArray("ARRAY_AGG", operand, ignoreNulls, columns, "(ARRAY_SLICE(",
", " + index + ", " + index + ") || ARRAY[NULL])[1]").toString());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2026 Contributors to the Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* SmartCity Jena - initial
*/
package org.eclipse.daanse.sql.dialect.db.h2;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.daanse.sql.dialect.api.DialectInitData;
import org.eclipse.daanse.sql.model.sql.OrderedColumn;
import org.eclipse.daanse.sql.model.sql.SortDirection;
import org.junit.jupiter.api.Test;

/**
* The n-th value aggregate runs on H2 and gives NULL for a group with fewer values: H2 fails an array element past
* the end, so the n-th value of four values asked for the fifth broke the query (TheNthValueIsPerCellTest on H2,
* database run 18.10.2026).
*/
class H2NthValuePastTheEndTest {

private static List<Object> nth(int n, String rows) throws SQLException {
try (Connection connection = DriverManager.getConnection("jdbc:h2:mem:nth" + n)) {
H2Dialect dialect = new H2Dialect(DialectInitData.fromConnection(connection));
String nth = dialect.generateNthValueAgg("\"x\"", false, n,
List.of(new OrderedColumn("x", null, SortDirection.DESC))).orElseThrow();
List<Object> values = new ArrayList<>();
try (ResultSet result = connection.createStatement()
.executeQuery("SELECT \"g\", " + nth + " FROM (VALUES " + rows + ") t(\"g\", \"x\") GROUP BY \"g\" ORDER BY \"g\"")) {
while (result.next()) {
values.add(result.getObject(2));
}
}
return values;
}
}

@Test
void theNthValueOfEachGroupInTheOrderOfTheColumns() throws SQLException {
assertEquals(List.of(2, 7), nth(2, "(1, 1), (1, 2), (1, 3), (2, 7), (2, 8)"));
}

@Test
void aGroupWithFewerValuesGivesNull() throws SQLException {
List<Object> values = nth(5, "(1, 1), (1, 2), (1, 3), (1, 4)");
assertEquals(1, values.size());
assertNull(values.get(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,13 @@ public boolean supportsCreateOrReplaceTrigger() {
return true;
}

/**
* From Oracle 23 ({@code DROP TABLE IF EXISTS} came with 23ai); before, a drop of a missing table fails with
* ORA-00942. A dialect made without a connection knows no version and says no.
*/
@Override
public boolean supportsDropTableIfExists() {
return false;
return dialectVersion.atLeast(23, 0);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2026 Contributors to the Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* SmartCity Jena - initial
*/
package org.eclipse.daanse.sql.dialect.db.oracle;

import static org.assertj.core.api.Assertions.assertThat;

import org.eclipse.daanse.sql.dialect.api.DialectInitData;
import org.junit.jupiter.api.Test;

/**
* Oracle drops a table only if it exists from version 23 on: before, the plain {@code DROP TABLE} of a missing table
* fails with ORA-00942, which aborted every CSV fixture of the ROLAP suite on Oracle Free 23ai (database run
* 18.10.2026).
*/
class OracleDropTableIfExistsTest {

private static OracleDialect dialect(int major) {
return new OracleDialect(DialectInitData.ansiDefaults().withVersion(major, 0));
}

@Test
void oracle23DropsATableIfItExists() {
assertThat(dialect(23).supportsDropTableIfExists()).isTrue();
assertThat(dialect(23).dropTable("S", "T", true)).isEqualTo("DROP TABLE IF EXISTS \"S\".\"T\"");
}

@Test
void oracle19AndADialectWithoutAVersionDropPlainly() {
assertThat(dialect(19).supportsDropTableIfExists()).isFalse();
assertThat(new OracleDialect().supportsDropTableIfExists()).isFalse();
}
}
Loading