mirror of https://github.com/apache/druid.git
Fix IndexOutOfBoundsException for MSQ window function queries with empty RAC (#16865)
* Fix IndexOutOfBoundsException for MSQ window function queries with empty RAC
This commit is contained in:
parent
cb09b572e6
commit
3d6cedb25f
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.apache.druid.query.rowsandcols;
|
package org.apache.druid.query.rowsandcols;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import org.apache.druid.java.util.common.ISE;
|
import org.apache.druid.java.util.common.ISE;
|
||||||
import org.apache.druid.query.rowsandcols.column.Column;
|
import org.apache.druid.query.rowsandcols.column.Column;
|
||||||
import org.apache.druid.query.rowsandcols.column.ColumnAccessor;
|
import org.apache.druid.query.rowsandcols.column.ColumnAccessor;
|
||||||
|
@ -30,6 +31,7 @@ import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -53,6 +55,7 @@ public class ConcatRowsAndColumns implements RowsAndColumns
|
||||||
ArrayList<RowsAndColumns> racBuffer
|
ArrayList<RowsAndColumns> racBuffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Preconditions.checkNotNull(racBuffer, "racBuffer cannot be null");
|
||||||
this.racBuffer = racBuffer;
|
this.racBuffer = racBuffer;
|
||||||
|
|
||||||
int numRows = 0;
|
int numRows = 0;
|
||||||
|
@ -76,6 +79,9 @@ public class ConcatRowsAndColumns implements RowsAndColumns
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getColumnNames()
|
public Collection<String> getColumnNames()
|
||||||
{
|
{
|
||||||
|
if (racBuffer.isEmpty()) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
return racBuffer.get(0).getColumnNames();
|
return racBuffer.get(0).getColumnNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +98,9 @@ public class ConcatRowsAndColumns implements RowsAndColumns
|
||||||
if (columnCache.containsKey(name)) {
|
if (columnCache.containsKey(name)) {
|
||||||
return columnCache.get(name);
|
return columnCache.get(name);
|
||||||
} else {
|
} else {
|
||||||
|
if (racBuffer.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final Column firstCol = racBuffer.get(0).findColumn(name);
|
final Column firstCol = racBuffer.get(0).findColumn(name);
|
||||||
if (firstCol == null) {
|
if (firstCol == null) {
|
||||||
for (int i = 1; i < racBuffer.size(); ++i) {
|
for (int i = 1; i < racBuffer.size(); ++i) {
|
||||||
|
|
|
@ -19,7 +19,13 @@
|
||||||
|
|
||||||
package org.apache.druid.query.rowsandcols;
|
package org.apache.druid.query.rowsandcols;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.apache.druid.query.rowsandcols.column.IntArrayColumn;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class ConcatRowsAndColumnsTest extends RowsAndColumnsTestBase
|
public class ConcatRowsAndColumnsTest extends RowsAndColumnsTestBase
|
||||||
|
@ -42,4 +48,55 @@ public class ConcatRowsAndColumnsTest extends RowsAndColumnsTestBase
|
||||||
|
|
||||||
return new ConcatRowsAndColumns(theRac);
|
return new ConcatRowsAndColumns(theRac);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstructorWithNullRacBuffer()
|
||||||
|
{
|
||||||
|
final NullPointerException e = Assert.assertThrows(
|
||||||
|
NullPointerException.class,
|
||||||
|
() -> new ConcatRowsAndColumns(null)
|
||||||
|
);
|
||||||
|
Assert.assertEquals("racBuffer cannot be null", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindColumn()
|
||||||
|
{
|
||||||
|
MapOfColumnsRowsAndColumns rac = MapOfColumnsRowsAndColumns.fromMap(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"column1", new IntArrayColumn(new int[]{1, 2, 3, 4, 5, 6}),
|
||||||
|
"column2", new IntArrayColumn(new int[]{6, 5, 4, 3, 2, 1})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ConcatRowsAndColumns apply = MAKER.apply(rac);
|
||||||
|
Assert.assertEquals(1, apply.findColumn("column1").toAccessor().getInt(0));
|
||||||
|
Assert.assertEquals(6, apply.findColumn("column2").toAccessor().getInt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindColumnWithEmptyRacBuffer()
|
||||||
|
{
|
||||||
|
ConcatRowsAndColumns concatRowsAndColumns = new ConcatRowsAndColumns(new ArrayList<>());
|
||||||
|
Assert.assertNull(concatRowsAndColumns.findColumn("columnName"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetColumns()
|
||||||
|
{
|
||||||
|
MapOfColumnsRowsAndColumns rac = MapOfColumnsRowsAndColumns.fromMap(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"column1", new IntArrayColumn(new int[]{0, 0, 0, 1, 1, 2, 4, 4, 4}),
|
||||||
|
"column2", new IntArrayColumn(new int[]{3, 54, 21, 1, 5, 54, 2, 3, 92})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ConcatRowsAndColumns apply = MAKER.apply(rac);
|
||||||
|
Assert.assertEquals(Arrays.asList("column1", "column2"), new ArrayList<>(apply.getColumnNames()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetColumnsWithEmptyRacBuffer()
|
||||||
|
{
|
||||||
|
ConcatRowsAndColumns concatRowsAndColumns = new ConcatRowsAndColumns(new ArrayList<>());
|
||||||
|
Assert.assertTrue(concatRowsAndColumns.getColumnNames().isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7622,6 +7622,13 @@ public class DrillWindowQueryTest extends BaseCalciteQueryTest
|
||||||
windowQueryTest();
|
windowQueryTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DrillTest("druid_queries/empty_over_clause/single_empty_over_3")
|
||||||
|
@Test
|
||||||
|
public void test_empty_over_single_empty_over_3()
|
||||||
|
{
|
||||||
|
windowQueryTest();
|
||||||
|
}
|
||||||
|
|
||||||
@DrillTest("druid_queries/empty_over_clause/multiple_empty_over_1")
|
@DrillTest("druid_queries/empty_over_clause/multiple_empty_over_1")
|
||||||
@Test
|
@Test
|
||||||
public void test_empty_over_multiple_empty_over_1()
|
public void test_empty_over_multiple_empty_over_1()
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
select countryName, row_number() over () as c1
|
||||||
|
from wikipedia
|
||||||
|
where countryName in ('non-existent-country')
|
||||||
|
group by countryName, cityName, channel
|
Loading…
Reference in New Issue