mirror of https://github.com/apache/druid.git
Add javadocs and small improvements to join code. (#9196)
A follow-up to #9111.
This commit is contained in:
parent
42359c93dd
commit
bfcb30e48f
|
@ -41,6 +41,9 @@ public interface ColumnProcessorFactory<T>
|
|||
{
|
||||
/**
|
||||
* This default type will be used when the underlying column has an unknown type.
|
||||
*
|
||||
* This allows a column processor factory to specify what type it prefers to deal with (the most 'natural' type for
|
||||
* whatever it is doing) when all else is equal.
|
||||
*/
|
||||
ValueType defaultType();
|
||||
|
||||
|
|
|
@ -45,8 +45,11 @@ public class HashJoinEngine
|
|||
* joinable clause's prefix (see {@link JoinableClause#getPrefix()}) will come from the Joinable's column selector
|
||||
* factory, and all other columns will come from the leftCursor's column selector factory.
|
||||
*
|
||||
* Ensuing that the joinable clause's prefix does not conflict with any columns from "leftCursor" is the
|
||||
* responsibility of the caller.
|
||||
* Ensuring that the joinable clause's prefix does not conflict with any columns from "leftCursor" is the
|
||||
* responsibility of the caller. If there is such a conflict (for example, if the joinable clause's prefix is "j.",
|
||||
* and the leftCursor has a field named "j.j.abrams"), then the field from the leftCursor will be shadowed and will
|
||||
* not be queryable through the returned Cursor. This happens even if the right-hand joinable doesn't actually have a
|
||||
* column with this name.
|
||||
*/
|
||||
public static Cursor makeJoinCursor(final Cursor leftCursor, final JoinableClause joinableClause)
|
||||
{
|
||||
|
|
|
@ -62,6 +62,14 @@ public class JoinConditionAnalysis
|
|||
this.nonEquiConditions = nonEquiConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze a join condition.
|
||||
*
|
||||
* @param condition the condition expression
|
||||
* @param rightPrefix prefix for the right-hand side of the join; will be used to determine which identifiers in
|
||||
* the condition come from the right-hand side and which come from the left-hand side
|
||||
* @param macroTable macro table for parsing the condition expression
|
||||
*/
|
||||
public static JoinConditionAnalysis forExpression(
|
||||
final String condition,
|
||||
final String rightPrefix,
|
||||
|
|
|
@ -48,7 +48,15 @@ public class JoinableClause
|
|||
}
|
||||
|
||||
/**
|
||||
* The prefix to apply to all columns from the Joinable.
|
||||
* The prefix to apply to all columns from the Joinable. The idea is that during a join, any columns that start with
|
||||
* this prefix should be retrieved from our Joinable's {@link JoinMatcher#getColumnSelectorFactory()}. Any other
|
||||
* columns should be returned from the left-hand side of the join.
|
||||
*
|
||||
* The prefix can be any string, as long as it is nonempty and not itself a prefix of the reserved column name
|
||||
* {@code __time}.
|
||||
*
|
||||
* @see #getAvailableColumnsPrefixed() the list of columns from our {@link Joinable} with prefixes attached
|
||||
* @see #unprefix a method for removing prefixes
|
||||
*/
|
||||
public String getPrefix()
|
||||
{
|
||||
|
|
|
@ -26,6 +26,10 @@ import org.apache.druid.segment.ColumnValueSelector;
|
|||
import javax.annotation.Nullable;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* A {@link ColumnValueSelector} that wraps a base selector but might also generate null values on demand. This
|
||||
* is used for "righty" joins (see {@link JoinType#isRighty()}), which may need to generate nulls on the left-hand side.
|
||||
*/
|
||||
public class PossiblyNullColumnValueSelector<T> implements ColumnValueSelector<T>
|
||||
{
|
||||
private final ColumnValueSelector<T> baseSelector;
|
||||
|
|
|
@ -26,27 +26,67 @@ import javax.annotation.Nullable;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An interface to a table where some columns (the 'key columns') have indexes that enable fast lookups.
|
||||
*
|
||||
* The main user of this class is {@link IndexedTableJoinable}, and its main purpose is to participate in joins.
|
||||
*/
|
||||
public interface IndexedTable
|
||||
{
|
||||
/**
|
||||
* Returns the columns of this table that have indexes.
|
||||
*/
|
||||
List<String> keyColumns();
|
||||
|
||||
/**
|
||||
* Returns all columns of this table, including the key and non-key columns.
|
||||
*/
|
||||
List<String> allColumns();
|
||||
|
||||
/**
|
||||
* Returns the signature of this table: a map where each key is a column from {@link #allColumns()} and each value
|
||||
* is a type code.
|
||||
*/
|
||||
Map<String, ValueType> rowSignature();
|
||||
|
||||
/**
|
||||
* Returns the number of rows in this table. It must not change over time, since it is used for things like algorithm
|
||||
* selection and reporting of cardinality metadata.
|
||||
*/
|
||||
int numRows();
|
||||
|
||||
/**
|
||||
* Returns the index for a particular column. The provided column number must be that column's position in
|
||||
* {@link #allColumns()}.
|
||||
*/
|
||||
Index columnIndex(int column);
|
||||
|
||||
/**
|
||||
* Returns a reader for a particular column. The provided column number must be that column's position in
|
||||
* {@link #allColumns()}.
|
||||
*/
|
||||
Reader columnReader(int column);
|
||||
|
||||
/**
|
||||
* Indexes support fast lookups on key columns.
|
||||
*/
|
||||
interface Index
|
||||
{
|
||||
/**
|
||||
* Returns the list of row numbers where the column this Reader is based on contains 'key'.
|
||||
*/
|
||||
IntList find(Object key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Readers support reading values out of any column.
|
||||
*/
|
||||
interface Reader
|
||||
{
|
||||
/**
|
||||
* Read the value at a particular row number. Throws an exception if the row is out of bounds (must be between zero
|
||||
* and {@link #numRows()}).
|
||||
*/
|
||||
@Nullable
|
||||
Object read(int row);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class IndexedTableJoinMatcher implements JoinMatcher
|
|||
if (condition.isAlwaysTrue()) {
|
||||
this.conditionMatchers = Collections.singletonList(() -> IntIterators.fromTo(0, table.numRows()));
|
||||
} else if (condition.isAlwaysFalse()) {
|
||||
this.conditionMatchers = Collections.singletonList(() -> IntIterators.fromTo(0, 0));
|
||||
this.conditionMatchers = Collections.singletonList(() -> IntIterators.EMPTY_ITERATOR);
|
||||
} else if (condition.getNonEquiConditions().isEmpty()) {
|
||||
this.conditionMatchers = condition.getEquiConditions()
|
||||
.stream()
|
||||
|
|
Loading…
Reference in New Issue