Skip to content

Commit

Permalink
ESQL: Add some javadoc to some shared methods
Browse files Browse the repository at this point in the history
This adds some javadoc to some of the methods that are shared by huge
parts of ES|QL's "expression" tree. These methods have fairly
complicated contracts that play off of each other so this javadoc is
quite handy.
  • Loading branch information
nik9000 committed Dec 12, 2023
1 parent bac1736 commit 6a491ea
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
* Expressions that have a mapping to an {@link ExpressionEvaluator}.
*/
public interface EvaluatorMapper {
/**
* Build an {@link ExpressionEvaluator.Factory} for the tree of
* expressions rooted at this node. This is only guaranteed to return
* a sensible evaluator if this node has a valid type. If this node
* is a subclass of {@link Expression} then "valid type" means that
* {@link Expression#typeResolved} returns a non-error resolution.
* If {@linkplain Expression#typeResolved} returns an error then
* this method may throw. Or return an evaluator that produces
* garbage. Or return an evaluator that throws when run.
*/
ExpressionEvaluator.Factory toEvaluator(Function<Expression, ExpressionEvaluator.Factory> toEvaluator);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.xpack.ql.tree.Node;
import org.elasticsearch.xpack.ql.tree.Source;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypes;
import org.elasticsearch.xpack.ql.util.StringUtils;

import java.util.List;
Expand Down Expand Up @@ -99,13 +100,61 @@ public boolean childrenResolved() {
return lazyChildrenResolved;
}

/**
* Does the tree rooted at this expression have valid types at all nodes?
* <p>
* For example, {@code SIN(1.2)} has a valid type and should return
* {@link TypeResolution#TYPE_RESOLVED} to signal "this type is fine".
* Another example, {@code SIN("cat")} has an invalid type in the
* tree. The value passed to the {@code SIN} function is a string which
* doesn't make any sense. So this method should return a "failure"
* resolution which it can build by calling {@link TypeResolution#TypeResolution(String)}.
* </p>
* <p>
* Take {@code SIN(1.2) + COS(ATAN("cat"))}, this tree should also
* fail, specifically because {@code ATAN("cat")} is invalid. This should
* fail even though {@code +} is perfectly valid when run on the results
* of {@code SIN} and {@code COS}. And {@code COS} can operate on the results
* of any valid call to {@code ATAN}. For this method to return a "valid"
* result the <strong>whole</strong> tree rooted at this expression must
* be valid.
* </p>
* <p>
* Implementations will rarely interact with the {@link TypeResolution}
* class directly, instead usually calling the utility methods on {@link TypeResolutions}.
* </p>
*/
public final TypeResolution typeResolved() {
if (lazyTypeResolution == null) {
lazyTypeResolution = resolveType();
}
return lazyTypeResolution;
}

/**
* Does the tree rooted at this expression have valid types at all nodes?
* <p>
* For example, {@code SIN(1.2)} has a valid type and should return
* {@link TypeResolution#TYPE_RESOLVED} to signal "this type is fine".
* Another example, {@code SIN("cat")} has an invalid type in the
* tree. The value passed to the {@code SIN} function is a string which
* doesn't make any sense. So this method should return a "failure"
* resolution which it can build by calling {@link TypeResolution#TypeResolution(String)}.
* </p>
* <p>
* Take {@code SIN(1.2) + COS(ATAN("cat"))}, this tree should also
* fail, specifically because {@code ATAN("cat")} is invalid. This should
* fail even though {@code +} is perfectly valid when run on the results
* of {@code SIN} and {@code COS}. And {@code COS} can operate on the results
* of any valid call to {@code ATAN}. For this method to return a "valid"
* result the <strong>whole</strong> tree rooted at this expression must
* be valid.
* </p>
* <p>
* Implementations will rarely interact with the {@link TypeResolution}
* class directly, instead usually calling the utility methods on {@link TypeResolutions}.
* </p>
*/
protected TypeResolution resolveType() {
return TypeResolution.TYPE_RESOLVED;
}
Expand Down Expand Up @@ -142,6 +191,13 @@ public boolean resolved() {
return childrenResolved() && typeResolved().resolved();
}

/**
* The {@link DataType} returned by executing the tree rooted at this
* expression. If {@link #typeResolved()} returns an error then the behavior
* of this method is undefined. It <strong>may</strong> return a valid
* type. Or it may throw an exception. Or it may return a totally nonsensical
* type.
*/
public abstract DataType dataType();

@Override
Expand Down

0 comments on commit 6a491ea

Please sign in to comment.