diff --git a/core/src/main/java/io/substrait/expression/AbstractExpressionVisitor.java b/core/src/main/java/io/substrait/expression/AbstractExpressionVisitor.java index 2b1c346aa..70bcce635 100644 --- a/core/src/main/java/io/substrait/expression/AbstractExpressionVisitor.java +++ b/core/src/main/java/io/substrait/expression/AbstractExpressionVisitor.java @@ -2,215 +2,567 @@ import io.substrait.util.VisitationContext; +/** + * Base expression visitor that routes all visits to a fallback handler. Subclasses can override + * specific visit methods as needed. + * + * @param the visit result type + * @param the visitation context type + * @param the checked exception type thrown during visitation + */ public abstract class AbstractExpressionVisitor implements ExpressionVisitor { + + /** + * Fallback handler for expressions not explicitly overridden. + * + * @param expr the expression to visit + * @param context the visitation context + * @return the visit result + */ public abstract O visitFallback(Expression expr, C context); + /** + * Visits a null literal. + * + * @param expr the null literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.NullLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a boolean literal. + * + * @param expr the boolean literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.BoolLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an 8-bit integer literal. + * + * @param expr the I8 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.I8Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a 16-bit integer literal. + * + * @param expr the I16 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.I16Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a 32-bit integer literal. + * + * @param expr the I32 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.I32Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a 64-bit integer literal. + * + * @param expr the I64 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.I64Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a 32-bit floating-point literal. + * + * @param expr the FP32 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.FP32Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a 64-bit floating-point literal. + * + * @param expr the FP64 literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.FP64Literal expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a string literal. + * + * @param expr the string literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.StrLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a binary literal. + * + * @param expr the binary literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.BinaryLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a time literal. + * + * @param expr the time literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.TimeLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a date literal. + * + * @param expr the date literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.DateLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a timestamp literal. + * + * @param expr the timestamp literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.TimestampLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a timestamp-with-time-zone literal. + * + * @param expr the timestamp TZ literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.TimestampTZLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a precision timestamp literal. + * + * @param expr the precision timestamp literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.PrecisionTimestampLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a precision timestamp-with-time-zone literal. + * + * @param expr the precision timestamp TZ literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.PrecisionTimestampTZLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an interval (years/months) literal. + * + * @param expr the year interval literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.IntervalYearLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an interval (days/time) literal. + * + * @param expr the day interval literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.IntervalDayLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a compound interval literal. + * + * @param expr the compound interval literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.IntervalCompoundLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a UUID literal. + * + * @param expr the UUID literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.UUIDLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a fixed-length character literal. + * + * @param expr the fixed char literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.FixedCharLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a variable-length character literal. + * + * @param expr the varchar literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.VarCharLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a fixed-length binary literal. + * + * @param expr the fixed binary literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.FixedBinaryLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a decimal literal. + * + * @param expr the decimal literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.DecimalLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a map literal. + * + * @param expr the map literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.MapLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an empty map literal. + * + * @param expr the empty map literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.EmptyMapLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a list literal. + * + * @param expr the list literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.ListLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an empty list literal. + * + * @param expr the empty list literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.EmptyListLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a struct literal. + * + * @param expr the struct literal + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.StructLiteral expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a nested struct expression. + * + * @param expr the nested struct + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.NestedStruct expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a switch expression. + * + * @param expr the switch expression + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.Switch expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an if-then expression. + * + * @param expr the if-then expression + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.IfThen expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a scalar function invocation. + * + * @param expr the scalar function invocation + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.ScalarFunctionInvocation expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a window function invocation. + * + * @param expr the window function invocation + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.WindowFunctionInvocation expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a cast expression. + * + * @param expr the cast expression + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.Cast expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a single-or-list expression. + * + * @param expr the single-or-list + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.SingleOrList expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a multi-or-list expression. + * + * @param expr the multi-or-list + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.MultiOrList expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a nested list expression. + * + * @param expr the nested list + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.NestedList expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a field reference. + * + * @param expr the field reference + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(FieldReference expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a set predicate. + * + * @param expr the set predicate + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.SetPredicate expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits a scalar subquery. + * + * @param expr the scalar subquery + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.ScalarSubquery expr, C context) throws E { return visitFallback(expr, context); } + /** + * Visits an IN predicate. + * + * @param expr the IN predicate + * @param context the visitation context + * @return the visit result + * @throws E if visitation fails + */ @Override public O visit(Expression.InPredicate expr, C context) throws E { return visitFallback(expr, context); diff --git a/core/src/main/java/io/substrait/expression/AbstractFunctionInvocation.java b/core/src/main/java/io/substrait/expression/AbstractFunctionInvocation.java index d1b67526d..0f1aee79f 100644 --- a/core/src/main/java/io/substrait/expression/AbstractFunctionInvocation.java +++ b/core/src/main/java/io/substrait/expression/AbstractFunctionInvocation.java @@ -4,21 +4,63 @@ import io.substrait.type.Type; import java.util.List; +/** + * Represents a generic function invocation, including its declaration, arguments, aggregation + * phase, sort fields, output type, and invocation details. + * + * @param the function type (from {@link SimpleExtension}) + * @param the invocation-specific type + */ public abstract class AbstractFunctionInvocation { + /** + * Returns the function declaration associated with this invocation. + * + * @return the function declaration + */ public abstract T declaration(); + /** + * Returns the ordered list of function arguments. + * + * @return list of function arguments + */ public abstract List arguments(); + /** + * Returns the aggregation phase for this invocation, if applicable. + * + * @return aggregation phase or {@code null} if not an aggregate + */ public abstract Expression.AggregationPhase aggregationPhase(); + /** + * Returns the sort fields applied to this invocation, if any. + * + * @return list of sort fields + */ public abstract List sort(); + /** + * Returns the output type produced by this invocation. + * + * @return the output type + */ public abstract Type outputType(); + /** + * Returns the type of this invocation (same as {@link #outputType()}). + * + * @return the output type + */ public Type getType() { return outputType(); } + /** + * Returns the invocation-specific details. + * + * @return invocation details + */ public abstract I invocation(); } diff --git a/core/src/main/java/io/substrait/expression/AggregateFunctionInvocation.java b/core/src/main/java/io/substrait/expression/AggregateFunctionInvocation.java index 2bdfb00e3..f3890e559 100644 --- a/core/src/main/java/io/substrait/expression/AggregateFunctionInvocation.java +++ b/core/src/main/java/io/substrait/expression/AggregateFunctionInvocation.java @@ -5,36 +5,88 @@ import java.util.List; import org.immutables.value.Value; +/** + * Represents an aggregate function invocation, including its declaration, arguments, options, + * aggregation phase, sort fields, output type, and invocation semantics. + */ @Value.Immutable public abstract class AggregateFunctionInvocation { + + /** + * Returns the aggregate function variant declaration. + * + * @return the function variant declaration + */ public abstract SimpleExtension.AggregateFunctionVariant declaration(); + /** + * Returns the ordered list of function arguments. + * + * @return list of function arguments + */ public abstract List arguments(); + /** + * Returns the options applied to this aggregate function. + * + * @return list of function options + */ public abstract List options(); + /** + * Returns the aggregation phase (e.g., initial, intermediate, final). + * + * @return aggregation phase + */ public abstract Expression.AggregationPhase aggregationPhase(); + /** + * Returns the sort fields applied to this invocation, if any. + * + * @return list of sort fields + */ public abstract List sort(); + /** + * Returns the output type produced by this invocation. + * + * @return the output type + */ public abstract Type outputType(); + /** + * Returns the type of this invocation (same as {@link #outputType()}). + * + * @return the output type + */ public Type getType() { return outputType(); } + /** + * Returns the aggregation invocation semantics (e.g., aggregate, merge). + * + * @return aggregation invocation + */ public abstract Expression.AggregationInvocation invocation(); /** * Validates that variadic arguments satisfy the parameter consistency requirement. When * CONSISTENT, all variadic arguments must have the same type (ignoring nullability). When * INCONSISTENT, arguments can have different types. + * + * @throws IllegalArgumentException if validation fails */ @Value.Check protected void check() { VariadicParameterConsistencyValidator.validate(declaration(), arguments()); } + /** + * Creates a builder for {@link AggregateFunctionInvocation}. + * + * @return a new immutable builder + */ public static ImmutableAggregateFunctionInvocation.Builder builder() { return ImmutableAggregateFunctionInvocation.builder(); } diff --git a/core/src/main/java/io/substrait/extendedexpression/ExtendedExpression.java b/core/src/main/java/io/substrait/extendedexpression/ExtendedExpression.java index f4f09c039..3ea90c6df 100644 --- a/core/src/main/java/io/substrait/extendedexpression/ExtendedExpression.java +++ b/core/src/main/java/io/substrait/extendedexpression/ExtendedExpression.java @@ -8,37 +8,89 @@ import java.util.Optional; import org.immutables.value.Value; +/** + * Represents an extended expression that references multiple expressions and schema details. + * + *

Includes references to expressions, expected type URLs, and optional advanced extensions. + */ @Value.Immutable public abstract class ExtendedExpression { + + /** + * Returns the list of referred expression references. + * + * @return list of expression references + */ public abstract List getReferredExpressions(); + /** + * Returns the base schema associated with this extended expression. + * + * @return the base schema + */ public abstract NamedStruct getBaseSchema(); + /** + * Returns the expected type URLs for validation. + * + * @return list of expected type URLs + */ public abstract List getExpectedTypeUrls(); - // creating simple extensions, such as extensionURIs and extensions, is performed on the fly - + /** + * Returns the optional advanced extension metadata. + * + * @return optional advanced extension + */ public abstract Optional getAdvancedExtension(); + /** + * Creates a builder for {@link ExtendedExpression}. + * + * @return a new builder + */ public static ImmutableExtendedExpression.Builder builder() { return ImmutableExtendedExpression.builder(); } + /** Base interface for expression references. */ public interface ExpressionReferenceBase { + /** + * Returns the output names associated with this reference. + * + * @return list of output names + */ List getOutputNames(); } + /** Represents a reference to a single expression. */ @Value.Immutable public abstract static class ExpressionReference implements ExpressionReferenceBase { + /** + * Returns the referenced expression. + * + * @return the expression + */ public abstract Expression getExpression(); + /** + * Creates a builder for {@link ExpressionReference}. + * + * @return a new builder + */ public static ImmutableExpressionReference.Builder builder() { return ImmutableExpressionReference.builder(); } } + /** Represents a reference to an aggregate function measure. */ @Value.Immutable public abstract static class AggregateFunctionReference implements ExpressionReferenceBase { + /** + * Returns the referenced aggregate measure. + * + * @return the measure + */ public abstract Aggregate.Measure getMeasure(); } } diff --git a/core/src/main/java/io/substrait/extension/DefaultExtensionCatalog.java b/core/src/main/java/io/substrait/extension/DefaultExtensionCatalog.java index 89aad954e..b2f6611d8 100644 --- a/core/src/main/java/io/substrait/extension/DefaultExtensionCatalog.java +++ b/core/src/main/java/io/substrait/extension/DefaultExtensionCatalog.java @@ -4,28 +4,64 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Provides default extension catalog constants and utilities for loading built-in Substrait + * function definitions. + */ public class DefaultExtensionCatalog { + + /** Extension identifier for approximate aggregate functions. */ public static final String FUNCTIONS_AGGREGATE_APPROX = "extension:io.substrait:functions_aggregate_approx"; + + /** Extension identifier for generic aggregate functions. */ public static final String FUNCTIONS_AGGREGATE_GENERIC = "extension:io.substrait:functions_aggregate_generic"; + + /** Extension identifier for arithmetic functions. */ public static final String FUNCTIONS_ARITHMETIC = "extension:io.substrait:functions_arithmetic"; + + /** Extension identifier for decimal arithmetic functions. */ public static final String FUNCTIONS_ARITHMETIC_DECIMAL = "extension:io.substrait:functions_arithmetic_decimal"; + + /** Extension identifier for boolean functions. */ public static final String FUNCTIONS_BOOLEAN = "extension:io.substrait:functions_boolean"; + + /** Extension identifier for comparison functions. */ public static final String FUNCTIONS_COMPARISON = "extension:io.substrait:functions_comparison"; + + /** Extension identifier for datetime functions. */ public static final String FUNCTIONS_DATETIME = "extension:io.substrait:functions_datetime"; + + /** Extension identifier for geometry functions. */ public static final String FUNCTIONS_GEOMETRY = "extension:io.substrait:functions_geometry"; + + /** Extension identifier for logarithmic functions. */ public static final String FUNCTIONS_LOGARITHMIC = "extension:io.substrait:functions_logarithmic"; + + /** Extension identifier for rounding functions. */ public static final String FUNCTIONS_ROUNDING = "extension:io.substrait:functions_rounding"; + + /** Extension identifier for decimal rounding functions. */ public static final String FUNCTIONS_ROUNDING_DECIMAL = "extension:io.substrait:functions_rounding_decimal"; + + /** Extension identifier for set functions. */ public static final String FUNCTIONS_SET = "extension:io.substrait:functions_set"; + + /** Extension identifier for string functions. */ public static final String FUNCTIONS_STRING = "extension:io.substrait:functions_string"; + /** Default collection of built-in extensions loaded from YAML resources. */ public static final SimpleExtension.ExtensionCollection DEFAULT_COLLECTION = loadDefaultCollection(); + /** + * Loads the default extension collection from predefined YAML files. + * + * @return the loaded extension collection + */ private static SimpleExtension.ExtensionCollection loadDefaultCollection() { List defaultFiles = Arrays.asList( diff --git a/core/src/main/java/io/substrait/relation/ConsistentPartitionWindow.java b/core/src/main/java/io/substrait/relation/ConsistentPartitionWindow.java index 1c736d34c..3db521743 100644 --- a/core/src/main/java/io/substrait/relation/ConsistentPartitionWindow.java +++ b/core/src/main/java/io/substrait/relation/ConsistentPartitionWindow.java @@ -13,16 +13,41 @@ import java.util.stream.Stream; import org.immutables.value.Value; +/** + * A window relation that ensures consistent partitioning and ordering across all window function + * invocations in a single input relation. Provides partition expressions, sort keys, and window + * functions. + */ @Value.Immutable @Value.Enclosing public abstract class ConsistentPartitionWindow extends SingleInputRel implements HasExtension { + /** + * Returns the window function invocations applied over the input. + * + * @return list of window function invocations + */ public abstract List getWindowFunctions(); + /** + * Returns the expressions used to partition the input rows. + * + * @return list of partitioning expressions + */ public abstract List getPartitionExpressions(); + /** + * Returns the sort fields defining row order within each partition. + * + * @return list of sort fields + */ public abstract List getSorts(); + /** + * Derives the output record type by appending window outputs to the input type. + * + * @return the resulting struct type + */ @Override protected Type.Struct deriveRecordType() { Type.Struct initial = getInput().getRecordType(); @@ -33,37 +58,107 @@ protected Type.Struct deriveRecordType() { getWindowFunctions().stream().map(WindowRelFunctionInvocation::outputType))); } + /** + * Accepts a relation visitor. + * + * @param the result type + * @param the visitation context type + * @param the exception type that may be thrown + * @param visitor the relation visitor + * @param context the visitation context + * @return the visit result + * @throws E if the visitor signals an error + */ @Override public O accept( RelVisitor visitor, C context) throws E { return visitor.visit(this, context); } + /** + * Creates a builder for {@link ConsistentPartitionWindow}. + * + * @return a new immutable builder + */ public static ImmutableConsistentPartitionWindow.Builder builder() { return ImmutableConsistentPartitionWindow.builder(); } + /** + * A single window function invocation with its arguments, options, output type, phase/invocation, + * and window bounds. + */ @Value.Immutable public abstract static class WindowRelFunctionInvocation { + /** + * Returns the window function variant declaration. + * + * @return the function variant declaration + */ public abstract SimpleExtension.WindowFunctionVariant declaration(); + /** + * Returns the ordered list of function arguments. + * + * @return list of function arguments + */ public abstract List arguments(); + /** + * Returns the options applied to the function invocation. + * + * @return list of function options + */ public abstract List options(); + /** + * Returns the type produced by this invocation. + * + * @return output type of the window function + */ public abstract Type outputType(); + /** + * Returns the aggregation phase (e.g., initial, intermediate, final). + * + * @return aggregation phase + */ public abstract Expression.AggregationPhase aggregationPhase(); + /** + * Returns the aggregation invocation semantics (e.g., aggregate, merge). + * + * @return aggregation invocation + */ public abstract Expression.AggregationInvocation invocation(); + /** + * Returns the inclusive lower bound of the window frame. + * + * @return lower window bound + */ public abstract WindowBound lowerBound(); + /** + * Returns the inclusive upper bound of the window frame. + * + * @return upper window bound + */ public abstract WindowBound upperBound(); + /** + * Returns the bounds type (e.g., ROWS or RANGE). + * + * @return window bounds type + */ public abstract Expression.WindowBoundsType boundsType(); + /** + * Creates a builder for {@link WindowRelFunctionInvocation}. + * + * @return a new immutable builder + */ public static ImmutableConsistentPartitionWindow.WindowRelFunctionInvocation.Builder builder() { return ImmutableConsistentPartitionWindow.WindowRelFunctionInvocation.builder(); } diff --git a/core/src/main/java/io/substrait/relation/CopyOnWriteUtils.java b/core/src/main/java/io/substrait/relation/CopyOnWriteUtils.java index e470c526b..517db6e8b 100644 --- a/core/src/main/java/io/substrait/relation/CopyOnWriteUtils.java +++ b/core/src/main/java/io/substrait/relation/CopyOnWriteUtils.java @@ -10,11 +10,25 @@ /** Provides common utilities for copy-on-write visitations */ public class CopyOnWriteUtils { + /** + * Returns {@code true} if all provided optionals are empty. + * + * @param optionals the optionals to inspect + * @return {@code true} when none are present; {@code false} otherwise + */ public static boolean allEmpty(Optional... optionals) { return Arrays.stream(optionals).noneMatch(Optional::isPresent); } /** The `or` method on Optional instances is a Java 9+ feature */ + /** + * Returns {@code left} if present; otherwise returns the result of {@code right.get()}. + * + * @param the value type + * @param left the first optional + * @param right supplier of the fallback optional + * @return {@code left} when present; otherwise the supplied optional + */ public static Optional or(Optional left, Supplier> right) { if (left.isPresent()) { return left; @@ -25,6 +39,15 @@ public static Optional or(Optional left, Supplier { + + /** + * Applies a potential transformation to the given value. + * + * @param t the input value + * @param context the visitation context + * @return an optional containing a replacement value if changed; empty if unchanged + * @throws E if the transformation fails + */ Optional apply(T t, C context) throws E; } @@ -37,10 +60,15 @@ public interface TransformFunctionthe original item in the position it was in * * + * @param the item type + * @param the visitation context type + * @param the exception type thrown by the transform * @param items the list of items to transform + * @param context the visitation context * @param transform the transformation function to apply to each item * @return An empty optional if none of the items have changed. An optional containing a new list * otherwise. + * @throws E if the transform function throws */ public static Optional> transformList( diff --git a/core/src/main/java/io/substrait/relation/Expand.java b/core/src/main/java/io/substrait/relation/Expand.java index 67bed0220..33af9033b 100644 --- a/core/src/main/java/io/substrait/relation/Expand.java +++ b/core/src/main/java/io/substrait/relation/Expand.java @@ -7,12 +7,26 @@ import java.util.List; import org.immutables.value.Value; +/** + * Expands the input relation into a set of projected fields where each field is either consistent + * or switches among duplicate expressions. + */ @Value.Enclosing @Value.Immutable public abstract class Expand extends SingleInputRel { + /** + * Returns the fields produced by the expand operation. + * + * @return the list of expand fields + */ public abstract List getFields(); + /** + * Derives the output record type from the expand fields. + * + * @return the resulting struct type + */ @Override public Type.Struct deriveRecordType() { Type.Struct initial = getInput().getRecordType(); @@ -20,38 +34,93 @@ public Type.Struct deriveRecordType() { .struct(getFields().stream().map(ExpandField::getType)); } + /** + * Accepts a relation visitor. + * + * @param the result type + * @param the visitation context type + * @param the exception type that may be thrown + * @param visitor the relation visitor + * @param context the visitation context + * @return the visit result + * @throws E if the visitor signals an error + */ @Override public O accept( RelVisitor visitor, C context) throws E { return visitor.visit(this, context); } + /** + * Creates a builder for {@link Expand}. + * + * @return a new immutable builder + */ public static ImmutableExpand.Builder builder() { return ImmutableExpand.builder(); } + /** A field produced by the expand operation. */ public interface ExpandField { + + /** + * Returns the field type. + * + * @return the type of the field + */ Type getType(); } + /** A field whose value is defined by a single expression. */ @Value.Immutable public abstract static class ConsistentField implements ExpandField { + + /** + * Returns the expression that defines the field value. + * + * @return the defining expression + */ public abstract Expression getExpression(); + /** + * Returns the type derived from the expression. + * + * @return the field type + */ @Override public Type getType() { return getExpression().getType(); } + /** + * Creates a builder for {@link ConsistentField}. + * + * @return a new immutable builder + */ public static ImmutableExpand.ConsistentField.Builder builder() { return ImmutableExpand.ConsistentField.builder(); } } + /** + * A field that may switch among duplicate expressions; nullability propagates if any duplicate is + * nullable. + */ @Value.Immutable public abstract static class SwitchingField implements ExpandField { + + /** + * Returns the duplicate expressions this field may switch between. + * + * @return list of duplicate expressions + */ public abstract List getDuplicates(); + /** + * Returns the type derived from duplicates, adjusting nullability if needed. + * + * @return the field type + */ @Override public Type getType() { boolean nullable = getDuplicates().stream().anyMatch(d -> d.getType().nullable()); @@ -59,6 +128,11 @@ public Type getType() { return nullable ? TypeCreator.asNullable(type) : TypeCreator.asNotNullable(type); } + /** + * Creates a builder for {@link SwitchingField}. + * + * @return a new immutable builder + */ public static ImmutableExpand.SwitchingField.Builder builder() { return ImmutableExpand.SwitchingField.builder(); } diff --git a/core/src/main/java/io/substrait/relation/physical/AbstractExchangeRel.java b/core/src/main/java/io/substrait/relation/physical/AbstractExchangeRel.java index 10520647b..e5dfef787 100644 --- a/core/src/main/java/io/substrait/relation/physical/AbstractExchangeRel.java +++ b/core/src/main/java/io/substrait/relation/physical/AbstractExchangeRel.java @@ -6,22 +6,59 @@ import java.util.List; import org.immutables.value.Value; +/** + * Physical exchange relation with a single input and extension metadata. Provides partitioning and + * target information for data exchange. + */ public abstract class AbstractExchangeRel extends SingleInputRel implements HasExtension { + + /** + * Returns the number of partitions for this exchange. + * + * @return the partition count, or {@code null} if unspecified + */ public abstract Integer getPartitionCount(); + /** + * Returns the configured exchange targets. + * + * @return the list of exchange targets (never {@code null}) + */ public abstract List getTargets(); + /** + * Derives the output record type from the input. + * + * @return the output struct type + */ @Override protected Type.Struct deriveRecordType() { return getInput().getRecordType(); } + /** Exchange target specification: partition IDs and target type. */ @Value.Immutable public abstract static class ExchangeTarget { + + /** + * Returns the partition IDs served by this target. + * + * @return list of partition IDs + */ public abstract List getPartitionIds(); + /** + * Returns the target type (e.g., local, remote). + * + * @return the target type + */ public abstract TargetType getType(); + /** + * Creates a builder for {@link ImmutableExchangeTarget}. + * + * @return a new builder instance + */ public static ImmutableExchangeTarget.Builder builder() { return ImmutableExchangeTarget.builder(); } diff --git a/core/src/main/java/io/substrait/util/DecimalUtil.java b/core/src/main/java/io/substrait/util/DecimalUtil.java index 18886059d..84c7cc739 100644 --- a/core/src/main/java/io/substrait/util/DecimalUtil.java +++ b/core/src/main/java/io/substrait/util/DecimalUtil.java @@ -33,13 +33,13 @@ public class DecimalUtil { }; /** - * Given an input of little-endian twos-complement with byeWidth bytes of a scaled big integer, - * convert it back to BigDecimal. This method is the opposite of encodeDecimalIntoBytes() + * Converts a little-endian two's-complement byte array of a scaled big integer into a {@link + * BigDecimal}. Opposite of {@link #encodeDecimalIntoBytes(BigDecimal, int, int)}. * - * @param value - * @param scale - * @param byteWidth - * @return + * @param value the little-endian two's-complement bytes + * @param scale the decimal scale to apply + * @param byteWidth the number of bytes used for the integer representation + * @return the reconstructed {@code BigDecimal} */ public static BigDecimal getBigDecimalFromBytes(byte[] value, int scale, int byteWidth) { byte[] reversed = new byte[value.length]; @@ -51,13 +51,14 @@ public static BigDecimal getBigDecimalFromBytes(byte[] value, int scale, int byt } /** - * Given a big decimal and its scale, convert into a scaled big integer, and then convert the - * scaled big integer into little-endian twos-complement with byeWidth bytes. + * Encodes a {@link BigDecimal} into a scaled big integer and serializes it as little-endian + * two's-complement bytes of fixed {@code byteWidth}. * - * @param decimal - * @param scale - * @param byteWidth - * @return + * @param decimal the decimal value to encode + * @param scale the scale used to produce the scaled integer + * @param byteWidth the target width in bytes for the output + * @return the encoded little-endian two's-complement byte array + * @throws UnsupportedOperationException if the encoded integer exceeds {@code byteWidth} */ public static byte[] encodeDecimalIntoBytes(BigDecimal decimal, int scale, int byteWidth) { BigDecimal scaledDecimal = decimal.multiply(powerOfTen(scale));