githubEdit

Opchain Converter Plugin

Learn how to implement a custom OpChain converter for multi-stage engine extensibility

Overview

The OpChainConverter SPI (Service Provider Interface) allows plugin developers to provide alternative implementations for converting logical query plans into executable OpChain objects in the multi-stage query engine. This enables extensibility for alternative execution backends, such as integrating specialized execution engines (e.g., timeseries engines) with Pinot's multi-stage execution (MSE).

Why Use OpChain Converter SPI?

The OpChainConverter SPI is useful when you need to:

  • Implement alternative plan-to-OpChain conversion logic for specific execution scenarios

  • Integrate custom execution backends with the multi-stage engine

  • Optimize query execution for specialized workloads or hardware

  • Support alternative query execution strategies

Implementing an OpChain Converter

To create a custom OpChain converter, implement the OpChainConverter interface:

package org.apache.pinot.query.runtime.operator;

public interface OpChainConverter {
  /**
   * Converts a logical plan node into an OpChain for execution.
   *
   * @param context the plan request context containing query metadata
   * @param planNode the logical query plan node to convert
   * @return an OpChain ready for execution, or null if this converter cannot handle this plan
   */
  OpChain convert(PlanRequestContext context, PlanNode planNode);

  /**
   * Returns the priority of this converter. Higher priority converters are selected first.
   * When multiple converters have the same priority, they are ordered by converter ID.
   *
   * @return the priority value (higher = higher priority)
   */
  int priority();

  /**
   * Returns a unique identifier for this converter.
   *
   * @return the converter ID
   */
  String getId();
}

Registering Your OpChain Converter

Once you've implemented the OpChainConverter interface, register it using Java's ServiceLoader mechanism:

  1. Add the @AutoService annotation from Google's com.google.auto:auto-service library:

  1. Create a ServiceLoader configuration file at META-INF/services/org.apache.pinot.query.runtime.operator.OpChainConverter in your JAR:

Priority and Selection

The OpChainConverterDispatcher manages all registered converters and selects the active one based on:

  1. Priority: Higher priority values are evaluated first

  2. Tie-breaking: When multiple converters have the same priority, they are ordered by converter ID (alphabetically)

  3. Explicit override: You can explicitly set the active converter using OpChainConverterDispatcher.setActiveConverterIdOverride(String converterId)

Example: Custom Converter Implementation

Here's a complete example of a custom OpChain converter that handles specific plan node types:

Default Implementation

Pinot includes a DefaultOpChainConverter that delegates to the existing PlanNodeToOpChain converter. This converter has the lowest priority and serves as a fallback when no other converter can handle a query plan.

Testing Your OpChain Converter

When testing your OpChain converter:

  1. Ensure it properly implements the OpChainConverter interface

  2. Test that it correctly handles the types of query plans it's designed for

  3. Verify that returning null gracefully delegates to the next converter

  4. Test priority-based selection when multiple converters are available

  5. Verify explicit override functionality works correctly

Last updated

Was this helpful?