Remove makeMathExpressionSelector from ColumnSelectorFactory.#3815
Remove makeMathExpressionSelector from ColumnSelectorFactory.#3815fjy merged 4 commits intoapache:masterfrom
Conversation
| // Unknown ValueType. Try making an Object selector and see if that gives us anything useful. | ||
| final ObjectColumnSelector selector = columnSelectorFactory.makeObjectColumnSelector(columnName); | ||
| final Class clazz = selector == null ? null : selector.classOfObject(); | ||
| if (selector == null || (clazz != Object.class && Number.class.isAssignableFrom(clazz))) { |
There was a problem hiding this comment.
Shouldn't it be !Number.class.isAssignableFrom(clazz)?
There was a problem hiding this comment.
Oops, you're right, will fix.
| }; | ||
| } | ||
|
|
||
| @Override |
There was a problem hiding this comment.
Could you please label this method and the interface method @Nullable?
| final Supplier<Number> supplier; | ||
|
|
||
| if (nativeType == ValueType.FLOAT) { | ||
| final FloatColumnSelector selector = columnSelectorFactory.makeFloatColumnSelector(columnName); |
There was a problem hiding this comment.
Do you think FloatColumnSelector could just extend Supplier<Float> and then "unsafe" cast is done here instead of wrapping?
(This also requires renaming of float get() to avoid name clash)
There was a problem hiding this comment.
It could but I'm not sure that change is warranted.
Is your concern performance or is it the amount of code in this method? If it's the latter then how about adding a method like FloatColumnSelector.asSupplier(floatColumnSelector)?
If it's performance, I guess I'm not super worried about performance in the Expressions related code since it's already doing a lot of sub-optimal stuff anyway (like interpreting expressions on top of boxed numbers). Changing that might involve no longer using Suppliers anyway.
There was a problem hiding this comment.
It was about performance, but given that proper optimization might involve moving away from Supplier<Number>, the change that I suggested will become pointless, so let's not make it.
| } | ||
| }; | ||
| } else if (nativeType == ValueType.LONG) { | ||
| final LongColumnSelector selector = columnSelectorFactory.makeLongColumnSelector(columnName); |
There was a problem hiding this comment.
Same question as about FloatColumnSelector a few lines above
| return new ExpressionObjectSelector(createBindings(columnSelectorFactory, expression), expression); | ||
| } | ||
|
|
||
| private static Expr.ObjectBinding createBindings(ColumnSelectorFactory columnSelectorFactory, Expr expression) |
There was a problem hiding this comment.
Consider splitting this 50-line method into some smaller methods
There was a problem hiding this comment.
It doesn't feel to me like there's much going on in this method; there are a lot of lines but most of them aren't doing much. I guess I could break out the nativeType == null branch into a method like createNumberSupplierFromObjectColumnSelector but I'm not sure that would actually make it easier to understand.
Do you think it would?
There was a problem hiding this comment.
I think it would be easier to understand this method if all three blocks (float, long, object) are extracted as static methods
There was a problem hiding this comment.
All right, I'll trust your opinion on readability more than mine since you didn't write the code.
|
@leventov, I pushed some updates you suggested, please let me know what you think about the others. Thanks for the review. |
| // We know there are no numbers here. Use a null supplier. | ||
| supplier = null; | ||
| } else { | ||
| if (selector != null && (clazz == Object.class || Number.class.isAssignableFrom(clazz))) { |
There was a problem hiding this comment.
Could you please add a test for this condition? Also clazz.isAssignableFrom(Number.class) feels clearer than clazz == Object.class
There was a problem hiding this comment.
Sure I'll add a test.
clazz.isAssignableFrom(Number.class) is not exactly what I'm trying to go for, though. This code path might also be parsing Strings (see tryParse). I guess this could be clazz.isAssignableFrom(Number.class) || clazz.isAssignableFrom(String.class).
| supplier = null; | ||
| } | ||
| } else { | ||
| // Unhandleable ValueType (possibly STRING or COMPLEX). |
There was a problem hiding this comment.
Could this attempt to handle String/Complex by going through the nativeType == null tryParse block above (e.g., for columns that contain numbers as strings)?
There was a problem hiding this comment.
It could, and we could actually also do an impl based on DimensionSelector, but I avoided that on purpose because that would lead to expressions and field accesses behaving differently for aggregators: longSum over fieldName "x" and expression "x" would behave differently if "x" were a string column. There's a test case in SchemaEvolutionTest that verifies this and would fail if the behavior were different.
There was a problem hiding this comment.
I guess we could go in the direction of having aggregators work over string columns though?
There was a problem hiding this comment.
Hm, okay, let's leave that area in this PR as-is for consistency then
|
@leventov, I broke up that big method and added tests. |
|
👍 |
1 similar comment
|
👍 |
Half of the second part of https://groups.google.com/forum/#!msg/druid-development/_Sd78s7yU5U/RJ8qLOJ5DwAJ, skipping the aggregator api changes.