Class DruidQuery

java.lang.Object
org.apache.calcite.rel.AbstractRelNode
org.apache.calcite.adapter.druid.DruidQuery
All Implemented Interfaces:
Cloneable, BindableRel, InterpretableRel, RelOptNode, RelNode, ArrayBindable, Bindable<@Nullable Object[]>, Typed

public class DruidQuery extends AbstractRelNode implements BindableRel
Relational expression representing a scan of a Druid data set.
  • Field Details

    • DEFAULT_OPERATORS_LIST

      public static final List<DruidSqlOperatorConverter> DEFAULT_OPERATORS_LIST
      Provides a standard list of supported Calcite operators that can be converted to Druid Expressions. This can be used as is or re-adapted based on underline engine operator syntax.
    • querySpec

      protected DruidQuery.QuerySpec querySpec
    • DRUID_QUERY_FETCH

      protected static final String DRUID_QUERY_FETCH
      See Also:
  • Constructor Details

    • DruidQuery

      protected DruidQuery(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, DruidTable druidTable, List<org.joda.time.Interval> intervals, List<RelNode> rels, Map<SqlOperator,DruidSqlOperatorConverter> converterOperatorMap)
      Creates a DruidQuery.
      Parameters:
      cluster - Cluster
      traitSet - Traits
      table - Table
      druidTable - Druid table
      intervals - Intervals for the query
      rels - Internal relational expressions
      converterOperatorMap - mapping of Calcite Sql Operator to Druid Expression API.
  • Method Details

    • create

      public static DruidQuery create(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, DruidTable druidTable, List<RelNode> rels)
      Creates a DruidQuery.
    • create

      public static DruidQuery create(RelOptCluster cluster, RelTraitSet traitSet, RelOptTable table, DruidTable druidTable, List<RelNode> rels, Map<SqlOperator,DruidSqlOperatorConverter> converterOperatorMap)
      Creates a DruidQuery.
    • extendQuery

      public static DruidQuery extendQuery(DruidQuery query, RelNode r)
      Extends a DruidQuery.
    • extendQuery

      public static DruidQuery extendQuery(DruidQuery query, List<org.joda.time.Interval> intervals)
      Extends a DruidQuery.
    • toDruidColumn

      protected static Pair<String,ExtractionFunction> toDruidColumn(RexNode rexNode, RelDataType rowType, DruidQuery druidQuery)
      Converts a RexNode to a Druid column.
      Parameters:
      rexNode - leaf Input Ref to Druid Column
      rowType - row type
      druidQuery - Druid query
      Returns:
      Pair of Column name and Extraction Function on the top of the input ref, or Pair.of(null, null) when cannot translate to a valid Druid column
    • extractColumnName

      protected static @Nullable String extractColumnName(RexNode rexNode, RelDataType rowType, DruidQuery query)
      Returns Druid column name or null when it is not possible to translate.
      Parameters:
      rexNode - Druid input ref node
      rowType - Row type
      query - Druid query
    • format

      public static String format(String message, Object... formatArgs)
      Equivalent of String.format(Locale.ENGLISH, message, formatArgs).
    • isValid

      public boolean isValid(Litmus litmus, RelNode.Context context)
      Description copied from interface: RelNode
      Returns whether this relational expression is valid.

      If assertions are enabled, this method is typically called with litmus = THROW, as follows:

      assert rel.isValid(Litmus.THROW)

      This signals that the method can throw an AssertionError if it is not valid.

      Specified by:
      isValid in interface RelNode
      Overrides:
      isValid in class AbstractRelNode
      Parameters:
      litmus - What to do if invalid
      context - Context for validity checking
      Returns:
      Whether relational expression is valid
    • getOperatorConversionMap

      protected Map<SqlOperator,DruidSqlOperatorConverter> getOperatorConversionMap()
    • copy

      public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs)
      Description copied from interface: RelNode
      Creates a copy of this relational expression, perhaps changing traits and inputs.

      Sub-classes with other important attributes are encouraged to create variants of this method with more parameters.

      Specified by:
      copy in interface RelNode
      Overrides:
      copy in class AbstractRelNode
      Parameters:
      traitSet - Trait set
      inputs - Inputs
      Returns:
      Copy of this relational expression, substituting traits and inputs
    • deriveRowType

      public RelDataType deriveRowType()
      Overrides:
      deriveRowType in class AbstractRelNode
    • getTableScan

      public TableScan getTableScan()
    • getTopNode

      public RelNode getTopNode()
    • getTable

      public RelOptTable getTable()
      Description copied from interface: RelNode
      If this relational expression represents an access to a table, returns that table, otherwise returns null.
      Specified by:
      getTable in interface RelNode
      Overrides:
      getTable in class AbstractRelNode
      Returns:
      If this relational expression represents an access to a table, returns that table, otherwise returns null
    • getDruidTable

      public DruidTable getDruidTable()
    • explainTerms

      public RelWriter explainTerms(RelWriter pw)
      Description copied from class: AbstractRelNode
      Describes the inputs and attributes of this relational expression. Each node should call super.explainTerms, then call the RelWriter.input(String, RelNode) and RelWriter.item(String, Object) methods for each input and attribute.
      Overrides:
      explainTerms in class AbstractRelNode
      Parameters:
      pw - Plan writer
      Returns:
      Plan writer for fluent-explain pattern
    • computeSelfCost

      public @Nullable RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq)
      Description copied from interface: RelNode
      Returns the cost of this plan (not including children). The base implementation throws an error; derived classes should override.

      NOTE jvs 29-Mar-2006: Don't call this method directly. Instead, use RelMetadataQuery.getNonCumulativeCost(org.apache.calcite.rel.RelNode), which gives plugins a chance to override the rel's default ideas about cost.

      Specified by:
      computeSelfCost in interface RelNode
      Overrides:
      computeSelfCost in class AbstractRelNode
      Parameters:
      planner - Planner for cost calculation
      mq - Metadata query
      Returns:
      Cost of this plan (not including children)
    • register

      public void register(RelOptPlanner planner)
      Description copied from interface: RelNode
      Registers any special rules specific to this kind of relational expression.

      The planner calls this method this first time that it sees a relational expression of this class. The derived class should call RelOptPlanner.addRule(org.apache.calcite.plan.RelOptRule) for each rule, and then call super.register.

      Specified by:
      register in interface RelNode
      Overrides:
      register in class AbstractRelNode
      Parameters:
      planner - Planner to be used to register additional relational expressions
    • getElementType

      public Class<Object[]> getElementType()
      Description copied from interface: Typed
      Gets the type of the element(s) that are returned in this collection.
      Specified by:
      getElementType in interface ArrayBindable
      Specified by:
      getElementType in interface Typed
    • bind

      public Enumerable<@Nullable Object[]> bind(DataContext dataContext)
      Description copied from interface: Bindable
      Executes this statement and returns an enumerable which will yield rows. The environment parameter provides the values in the root of the environment (usually schemas).
      Specified by:
      bind in interface Bindable<@Nullable Object[]>
      Parameters:
      dataContext - Environment that provides tables
      Returns:
      Enumerable over rows
    • implement

      public Node implement(InterpretableRel.InterpreterImplementor implementor)
      Description copied from interface: InterpretableRel
      Creates an interpreter node to implement this relational expression.
      Specified by:
      implement in interface InterpretableRel
    • getQuerySpec

      public DruidQuery.QuerySpec getQuerySpec()
    • deriveQuerySpec

      protected DruidQuery.QuerySpec deriveQuerySpec()
    • getQueryType

      public QueryType getQueryType()
    • getQueryString

      public String getQueryString()
    • getConnectionConfig

      protected CalciteConnectionConfig getConnectionConfig()
    • computeProjectAsScan

      protected static @Nullable Pair<List<String>,List<VirtualColumn>> computeProjectAsScan(@Nullable Project projectRel, RelDataType inputRowType, DruidQuery druidQuery)
      Translates a list of projects to Druid Column names and Virtual Columns if any.

      We cannot use Pair.zip(Object[], Object[]), since size may be different.

      Parameters:
      projectRel - Project
      druidQuery - Druid query
      Returns:
      Pair of list of Druid Columns and Expression Virtual Columns, or null when cannot translate one of the projects
    • computeProjectGroupSet

      protected static @Nullable Pair<List<DimensionSpec>,List<VirtualColumn>> computeProjectGroupSet(@Nullable Project projectNode, ImmutableBitSet groupSet, RelDataType inputRowType, DruidQuery druidQuery)
      Computes the project group set.
      Parameters:
      projectNode - Project under the Aggregates if any
      groupSet - Ids of grouping keys as they are listed in projects list
      inputRowType - Input row type under the project
      druidQuery - Druid query
      Returns:
      A list of DimensionSpec containing the group by dimensions, and a list of VirtualColumn containing Druid virtual column projections; or null, if translation is not possible. Note that the size of lists can be different.
    • computeDruidJsonAgg

      protected static @Nullable List<org.apache.calcite.adapter.druid.DruidQuery.JsonAggregation> computeDruidJsonAgg(List<AggregateCall> aggCalls, List<String> aggNames, @Nullable Project project, DruidQuery druidQuery)
      Translates aggregate calls to Druid DruidQuery.JsonAggregations when possible.
      Parameters:
      aggCalls - List of AggregateCalls to translate
      aggNames - List of aggregate names
      project - Input project under the aggregate calls, or null if we have TableScan immediately under the Aggregate
      druidQuery - Druid query
      Returns:
      List of valid Druid DruidQuery.JsonAggregations, or null if any of the aggregates is not supported
    • getQuery

      protected DruidQuery.QuerySpec getQuery(RelDataType rowType, Filter filter, Project project, ImmutableBitSet groupSet, List<AggregateCall> aggCalls, List<String> aggNames, List<Integer> collationIndexes, List<RelFieldCollation.Direction> collationDirections, ImmutableBitSet numericCollationIndexes, Integer fetch, Project postProject, Filter havingFilter)
    • writeField

      protected static void writeField(com.fasterxml.jackson.core.JsonGenerator generator, String fieldName, Object o) throws IOException
      Throws:
      IOException
    • writeFieldIf

      protected static void writeFieldIf(com.fasterxml.jackson.core.JsonGenerator generator, String fieldName, Object o) throws IOException
      Throws:
      IOException
    • writeArray

      protected static void writeArray(com.fasterxml.jackson.core.JsonGenerator generator, List<?> elements) throws IOException
      Throws:
      IOException
    • writeObject

      protected static void writeObject(com.fasterxml.jackson.core.JsonGenerator generator, Object o) throws IOException
      Throws:
      IOException
    • getTimestampFieldIndex

      protected int getTimestampFieldIndex()
      Returns the index of the timestamp ref, or -1 if not present.