-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Now unnest allows bound, in and selector filters on the unnested column #13799
Changes from all commits
e8de6dc
9743911
933ccbe
e77643a
ce5e5a6
a2ca449
ff4d6ea
663292a
f138c6d
bb643ac
e969e6a
5031f9f
737771b
744fb7b
0bb44c5
c9074b6
c617443
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,15 +22,17 @@ | |
import org.apache.druid.java.util.common.UOE; | ||
import org.apache.druid.query.BaseQuery; | ||
import org.apache.druid.query.dimension.DimensionSpec; | ||
import org.apache.druid.query.filter.Filter; | ||
import org.apache.druid.query.filter.ValueMatcher; | ||
import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector; | ||
import org.apache.druid.segment.column.ColumnCapabilities; | ||
import org.apache.druid.segment.column.ColumnCapabilitiesImpl; | ||
import org.apache.druid.segment.filter.BooleanValueMatcher; | ||
import org.joda.time.DateTime; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.LinkedHashSet; | ||
import java.util.List; | ||
|
||
/** | ||
|
@@ -50,7 +52,7 @@ | |
* unnestCursor.advance() -> 'e' | ||
* <p> | ||
* <p> | ||
* The allowSet if available helps skip over elements which are not in the allowList by moving the cursor to | ||
* The filter if available helps skip over elements which are not in the allowList by moving the cursor to | ||
* the next available match. | ||
* <p> | ||
* The index reference points to the index of each row that the unnest cursor is accessing through currentVal | ||
|
@@ -65,7 +67,7 @@ public class UnnestColumnValueSelectorCursor implements Cursor | |
private final ColumnValueSelector columnValueSelector; | ||
private final String columnName; | ||
private final String outputName; | ||
private final LinkedHashSet<String> allowSet; | ||
private final ValueMatcher valueMatcher; | ||
private int index; | ||
private Object currentVal; | ||
private List<Object> unnestListForCurrentRow; | ||
|
@@ -76,7 +78,7 @@ public UnnestColumnValueSelectorCursor( | |
ColumnSelectorFactory baseColumSelectorFactory, | ||
String columnName, | ||
String outputColumnName, | ||
LinkedHashSet<String> allowSet | ||
@Nullable Filter filter | ||
) | ||
{ | ||
this.baseCursor = cursor; | ||
|
@@ -86,7 +88,11 @@ public UnnestColumnValueSelectorCursor( | |
this.index = 0; | ||
this.outputName = outputColumnName; | ||
this.needInitialization = true; | ||
this.allowSet = allowSet; | ||
if (filter != null) { | ||
this.valueMatcher = filter.makeMatcher(getColumnSelectorFactory()); | ||
} else { | ||
this.valueMatcher = BooleanValueMatcher.of(true); | ||
} | ||
} | ||
|
||
@Override | ||
|
@@ -191,11 +197,7 @@ public boolean isNull() | |
public Object getObject() | ||
{ | ||
if (!unnestListForCurrentRow.isEmpty()) { | ||
if (allowSet == null || allowSet.isEmpty()) { | ||
return unnestListForCurrentRow.get(index); | ||
} else if (allowSet.contains((String) unnestListForCurrentRow.get(index))) { | ||
return unnestListForCurrentRow.get(index); | ||
} | ||
return unnestListForCurrentRow.get(index); | ||
} | ||
return null; | ||
} | ||
|
@@ -243,9 +245,17 @@ public void advance() | |
@Override | ||
public void advanceUninterruptibly() | ||
{ | ||
do { | ||
// the index currently points to an element at position i ($e_i) | ||
// while $e_i does not match the filter | ||
// keep advancing the pointer to the first valid match | ||
// calling advanceAndUpdate increments the index position so needs a call to matches() again for new match status | ||
while (true) { | ||
advanceAndUpdate(); | ||
} while (matchAndProceed()); | ||
boolean match = valueMatcher.matches(); | ||
if (match || baseCursor.isDone()) { | ||
return; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: while (true) {
boolean match = valueMatcher.matches();
advanceAndUpdate();
if (match || baseCursor.isDone()) {
return;
}
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks this should be
The match changes after the update so the call should be below. I'll add it |
||
} | ||
|
||
@Override | ||
|
@@ -311,12 +321,11 @@ private void initialize() | |
{ | ||
this.unnestListForCurrentRow = new ArrayList<>(); | ||
getNextRow(needInitialization); | ||
if (allowSet != null) { | ||
if (!allowSet.isEmpty()) { | ||
if (!allowSet.contains((String) unnestListForCurrentRow.get(index))) { | ||
advance(); | ||
} | ||
} | ||
|
||
// If the first value the index is pointing to does not match the filter | ||
// advance the index to the first value which will match | ||
if (!valueMatcher.matches() && !baseCursor.isDone()) { | ||
advance(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redundant. |
||
} | ||
needInitialization = false; | ||
} | ||
|
@@ -339,22 +348,4 @@ private void advanceAndUpdate() | |
index++; | ||
} | ||
} | ||
|
||
/** | ||
* This advances the unnest cursor in cases where an allowList is specified | ||
* and the current value at the unnest cursor is not in the allowList. | ||
* The cursor in such cases is moved till the next match is found. | ||
* | ||
* @return a boolean to indicate whether to stay or move cursor | ||
*/ | ||
private boolean matchAndProceed() | ||
{ | ||
boolean matchStatus; | ||
if (allowSet == null || allowSet.isEmpty()) { | ||
matchStatus = true; | ||
} else { | ||
matchStatus = allowSet.contains((String) unnestListForCurrentRow.get(index)); | ||
} | ||
return !baseCursor.isDone() && !matchStatus; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is called in the constructor and then also returned as a public method, maybe switch it around to have the constructor create the
ColumnSelectorFactory
, store the reference and then use that here/return it from thegetColumnSelectorFactory
method.