Как отправить проект, фильтр, агрегацию в TableScan в Calcite

Я использую Apache Calcite для реализации распределенной системы OLAP, источником данных которой является RDBMS. Итак, я хочу понизить проект/фильтр/агрегацию в дереве RelNode до MyTableScan extends TableScan. В MyTableScan используйте RelBuilder, чтобы получить RelNode. Наконец, RelBuilder сгенерируйте запрос к исходной базе данных. В то же время проект/фильтр/агрегация в исходном дереве RelNode должны быть перемещены или изменены.

Насколько мне известно, Calcite не поддерживает эту функцию.

Текущие ограничения. Адаптер JDBC в настоящее время выполняет только операции сканирования таблицы; вся остальная обработка (фильтрация, объединение, агрегация и т. д.) выполняется в Calcite. Наша цель — перенести как можно больше обработки в исходную систему, переводя синтаксис, типы данных и встроенные функции по мере продвижения. Если запрос Calcite основан на таблицах из одной базы данных JDBC, в принципе, весь запрос должен направляться в эту базу данных. Если таблицы получены из нескольких источников JDBC или из комбинации JDBC и не-JDBC, Calcite будет использовать наиболее эффективный из возможных подходов к распределенным запросам.

На мой взгляд, RelOptRule может быть хорошим выбором. К сожалению, когда я создаю новый RelOptRule, я не могу легко найти родительский узел, чтобы удалить узел.

RelOptRule хороший выбор? У кого-нибудь есть хорошая идея реализовать эту функцию?

Спасибо.


person inferno    schedule 24.10.2016    source источник


Ответы (2)


Создание нового RelOptRule — это путь. Обратите внимание, что вам не следует пытаться напрямую удалить какие-либо узлы внутри правила. Вместо этого вы сопоставляете поддерево, содержащее узлы, которые вы хотите заменить (например, Filter поверх TableScan). А затем замените все это поддерево эквивалентным узлом, который снизит фильтр.

Обычно это решается путем создания подкласса соответствующей операции, который соответствует соглашению о вызовах конкретного адаптера. Например, в адаптере Cassandra есть CassandraFilterRule, который соответствует LogicalFilter поверх CassandraTableScan. Затем функция convert создает экземпляр CassandraFilter. Экземпляр CassandraFilter устанавливает необходимую информацию, чтобы при фактическом выполнении запроса фильтр был доступен.

Просмотр части кода адаптеров Cassandra, MongoDB или Elasticsearch может оказаться полезным, поскольку они более простые. Я бы также посоветовал внести это в список рассылки, так как вы, вероятно, получите там более подробные советы.

person Michael Mior    schedule 24.10.2016
comment
Функция convert - это то, что я хочу, я нашел ее в некоторых правилах. - person inferno; 24.10.2016

Я создал несколько RelOptRule, чтобы протолкнуть верхнюю часть таблицы Project/Filter/Aggregate RelNode. Может быть полезно другим.

RelOptRule используется для определения некоторых правил для сопоставления поддеревьев во всем RelNode. При совпадении вызовите метод onMatch, чтобы что-то сделать.

В методе onMatch мы можем создать один новый RelNode и вызвать метод transformTo для замены совпадающего поддерева.

Например:

Project
  |
Filter
  |
TableScan

Правило PushDownFilter выглядит следующим образом:

  public class PushDownFilter extends RelOptRule {

  public PushDownFilter(RelOptRuleOperand operand, String description) {
    super(operand, "Push_down_rule:" + description);
  }

  public static final PushDownFilter INSTANCE =
      new PushDownFilter(
          operand(
              Filter.class,
              operand(TableScan.class, none())),
          "filter_tableScan");

  @Override
  public void onMatch(RelOptRuleCall call) {
    LogicalFilter filter = (LogicalFilter) call.rels[0];
    TableScan tableScan = (TableScan) call.rels[1];
    // push down filter
    call.transformTo(tableScan);
  }
}

Это правило будет соответствовать поддереву Filter->TableScan, а затем вызовет метод onMatch. Метод только transformTo tableScan. В результате Filter->TableScan заменяется на TableScan, весь RelNode выглядит следующим образом:

Project
  |
TableScan

Обратите внимание, что RelDataType нового RelNode должен быть равен соответствующему поддереву.

Calcite поддерживает некоторые правила использования, например FilterJoinRule, FilterTableScanRule и так далее.

person inferno    schedule 25.11.2016
comment
мы должны предоставить некоторую дополнительную входную информацию для call.transformTo(<<here>>). Кажется, TableScan следует каким-то образом изменить, чтобы также добавить дополнительные атрибуты фильтра, верно? - person jasonk; 14.05.2021