You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2017/10/02 21:00:06 UTC
[06/15] calcite git commit: [CALCITE-1986] Add RelBuilder.match and
methods for building patterns (Dian Fu)
[CALCITE-1986] Add RelBuilder.match and methods for building patterns (Dian Fu)
Add methods for building patterns, and documentation. (Julian Hyde)
Close apache/calcite#538
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/3e97cff7
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/3e97cff7
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/3e97cff7
Branch: refs/heads/master
Commit: 3e97cff7253691bbd7df690721981de4c2d9f88b
Parents: 2773c48
Author: Dian Fu <fu...@alibaba-inc.com>
Authored: Thu Sep 14 12:47:41 2017 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Oct 2 11:13:42 2017 -0700
----------------------------------------------------------------------
.../apache/calcite/rel/core/RelFactories.java | 16 +-
.../calcite/rel/logical/LogicalMatch.java | 3 +-
.../java/org/apache/calcite/rex/RexBuilder.java | 13 ++
.../calcite/sql2rel/SqlToRelConverter.java | 2 +-
.../org/apache/calcite/tools/RelBuilder.java | 154 +++++++++++++++++++
.../org/apache/calcite/test/RelBuilderTest.java | 90 +++++++++++
site/_docs/algebra.md | 24 ++-
7 files changed, 288 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
index 477bbd4..b4ebbca 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/RelFactories.java
@@ -49,7 +49,7 @@ import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeSet;
+import java.util.SortedSet;
/**
* Contains factory interface and default implementation for creating various
@@ -396,11 +396,12 @@ public class RelFactories {
*/
public interface MatchFactory {
/** Creates a {@link Match}. */
- RelNode createMatchRecognize(RelNode input, RexNode pattern,
+ RelNode createMatch(RelNode input, RexNode pattern,
RelDataType rowType, boolean strictStart, boolean strictEnd,
Map<String, RexNode> patternDefinitions, Map<String, RexNode> measures,
- RexNode after, Map<String, TreeSet<String>> subsets, boolean allRows,
- List<RexNode> partitionKeys, RelCollation orderKeys, RexNode interval);
+ RexNode after, Map<String, ? extends SortedSet<String>> subsets,
+ boolean allRows, List<RexNode> partitionKeys, RelCollation orderKeys,
+ RexNode interval);
}
/**
@@ -408,11 +409,12 @@ public class RelFactories {
* that returns a {@link LogicalMatch}.
*/
private static class MatchFactoryImpl implements MatchFactory {
- public RelNode createMatchRecognize(RelNode input, RexNode pattern,
+ public RelNode createMatch(RelNode input, RexNode pattern,
RelDataType rowType, boolean strictStart, boolean strictEnd,
Map<String, RexNode> patternDefinitions, Map<String, RexNode> measures,
- RexNode after, Map<String, TreeSet<String>> subsets, boolean allRows,
- List<RexNode> partitionKeys, RelCollation orderKeys, RexNode interval) {
+ RexNode after, Map<String, ? extends SortedSet<String>> subsets,
+ boolean allRows, List<RexNode> partitionKeys, RelCollation orderKeys,
+ RexNode interval) {
return LogicalMatch.create(input, rowType, pattern, strictStart,
strictEnd, patternDefinitions, measures, after, subsets, allRows,
partitionKeys, orderKeys, interval);
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/main/java/org/apache/calcite/rel/logical/LogicalMatch.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalMatch.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalMatch.java
index f0e3729..1a840f5 100644
--- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalMatch.java
+++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalMatch.java
@@ -29,7 +29,6 @@ import org.apache.calcite.rex.RexNode;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
-import java.util.TreeSet;
/**
* Sub-class of {@link Match}
@@ -74,7 +73,7 @@ public class LogicalMatch extends Match {
public static LogicalMatch create(RelNode input, RelDataType rowType,
RexNode pattern, boolean strictStart, boolean strictEnd,
Map<String, RexNode> patternDefinitions, Map<String, RexNode> measures,
- RexNode after, Map<String, TreeSet<String>> subsets, boolean allRows,
+ RexNode after, Map<String, ? extends SortedSet<String>> subsets, boolean allRows,
List<RexNode> partitionKeys, RelCollation orderKeys, RexNode interval) {
final RelOptCluster cluster = input.getCluster();
final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE);
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index 2144ab8..bd6579d 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -809,6 +809,19 @@ public class RexBuilder {
}
/**
+ * Creates a reference to a given field of the pattern.
+ *
+ * @param alpha the pattern name
+ * @param type Type of field
+ * @param i Ordinal of field
+ * @return Reference to field of pattern
+ */
+ public RexPatternFieldRef makePatternFieldRef(String alpha, RelDataType type, int i) {
+ type = SqlTypeUtil.addCharsetAndCollation(type, typeFactory);
+ return new RexPatternFieldRef(alpha, i, type);
+ }
+
+ /**
* Creates a literal representing a flag.
*
* @param flag Flag value
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 235dfb4..9967bd5 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -2239,7 +2239,7 @@ public class SqlToRelConverter {
final RelFactories.MatchFactory factory =
RelFactories.DEFAULT_MATCH_FACTORY;
final RelNode rel =
- factory.createMatchRecognize(input, patternNode,
+ factory.createMatch(input, patternNode,
rowType, matchRecognize.getStrictStart().booleanValue(),
matchRecognize.getStrictEnd().booleanValue(),
definitionNodes.build(), measureNodes.build(), after,
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
index 0a726c7..e55015a 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -75,6 +75,7 @@ import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -89,6 +90,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
@@ -132,6 +134,7 @@ public class RelBuilder {
private final RelFactories.CorrelateFactory correlateFactory;
private final RelFactories.ValuesFactory valuesFactory;
private final RelFactories.TableScanFactory scanFactory;
+ private final RelFactories.MatchFactory matchFactory;
private final Deque<Frame> stack = new ArrayDeque<>();
private final boolean simplify;
private final RexSimplify simplifier;
@@ -175,6 +178,9 @@ public class RelBuilder {
this.scanFactory =
Util.first(context.unwrap(RelFactories.TableScanFactory.class),
RelFactories.DEFAULT_TABLE_SCAN_FACTORY);
+ this.matchFactory =
+ Util.first(context.unwrap(RelFactories.MatchFactory.class),
+ RelFactories.DEFAULT_MATCH_FACTORY);
final RexExecutor executor =
Util.first(context.unwrap(RexExecutor.class),
Util.first(cluster.getPlanner().getExecutor(), RexUtil.EXECUTOR));
@@ -773,6 +779,89 @@ public class RelBuilder {
return aggregateCall(SqlStdOperatorTable.MAX, false, null, alias, operand);
}
+ // Methods for patterns
+
+ /**
+ * Creates a reference to a given field of the pattern.
+ *
+ * @param alpha the pattern name
+ * @param type Type of field
+ * @param i Ordinal of field
+ * @return Reference to field of pattern
+ */
+ public RexNode patternField(String alpha, RelDataType type, int i) {
+ return getRexBuilder().makePatternFieldRef(alpha, type, i);
+ }
+
+ /** Creates a call that concatenates patterns;
+ * for use in {@link #match}. */
+ public RexNode patternConcat(Iterable<? extends RexNode> nodes) {
+ final ImmutableList<RexNode> list = ImmutableList.copyOf(nodes);
+ if (list.size() > 2) {
+ // Convert into binary calls
+ return patternConcat(patternConcat(Util.skipLast(list)), Util.last(list));
+ }
+ final RelDataType t = getTypeFactory().createSqlType(SqlTypeName.NULL);
+ return getRexBuilder().makeCall(t, SqlStdOperatorTable.PATTERN_CONCAT,
+ list);
+ }
+
+ /** Creates a call that concatenates patterns;
+ * for use in {@link #match}. */
+ public RexNode patternConcat(RexNode... nodes) {
+ return patternConcat(ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates alternate patterns;
+ * for use in {@link #match}. */
+ public RexNode patternAlter(Iterable<? extends RexNode> nodes) {
+ final RelDataType t = getTypeFactory().createSqlType(SqlTypeName.NULL);
+ return getRexBuilder().makeCall(t, SqlStdOperatorTable.PATTERN_ALTER,
+ ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates alternate patterns;
+ * for use in {@link #match}. */
+ public RexNode patternAlter(RexNode... nodes) {
+ return patternAlter(ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates quantify patterns;
+ * for use in {@link #match}. */
+ public RexNode patternQuantify(Iterable<? extends RexNode> nodes) {
+ final RelDataType t = getTypeFactory().createSqlType(SqlTypeName.NULL);
+ return getRexBuilder().makeCall(t, SqlStdOperatorTable.PATTERN_QUANTIFIER,
+ ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates quantify patterns;
+ * for use in {@link #match}. */
+ public RexNode patternQuantify(RexNode... nodes) {
+ return patternQuantify(ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates permute patterns;
+ * for use in {@link #match}. */
+ public RexNode patternPermute(Iterable<? extends RexNode> nodes) {
+ final RelDataType t = getTypeFactory().createSqlType(SqlTypeName.NULL);
+ return getRexBuilder().makeCall(t, SqlStdOperatorTable.PATTERN_PERMUTE,
+ ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates permute patterns;
+ * for use in {@link #match}. */
+ public RexNode patternPermute(RexNode... nodes) {
+ return patternPermute(ImmutableList.copyOf(nodes));
+ }
+
+ /** Creates a call that creates an exclude pattern;
+ * for use in {@link #match}. */
+ public RexNode patternExclude(RexNode node) {
+ final RelDataType t = getTypeFactory().createSqlType(SqlTypeName.NULL);
+ return getRexBuilder().makeCall(t, SqlStdOperatorTable.PATTERN_EXCLUDE,
+ ImmutableList.of(node));
+ }
+
// Methods that create relational expressions
/** Creates a {@link org.apache.calcite.rel.core.TableScan} of the table
@@ -1711,6 +1800,71 @@ public class RelBuilder {
}));
}
+ /** Creates a {@link org.apache.calcite.rel.core.Match}. */
+ public RelBuilder match(RexNode pattern, boolean strictStart,
+ boolean strictEnd, Map<String, RexNode> patternDefinitions,
+ Iterable<? extends RexNode> measureList, RexNode after,
+ Map<String, ? extends SortedSet<String>> subsets, boolean allRows,
+ Iterable<? extends RexNode> partitionKeys,
+ Iterable<? extends RexNode> orderKeys, RexNode interval) {
+ final List<RelFieldCollation> fieldCollations = new ArrayList<>();
+ for (RexNode orderKey : orderKeys) {
+ final RelFieldCollation.Direction direction;
+ switch (orderKey.getKind()) {
+ case DESCENDING:
+ direction = RelFieldCollation.Direction.DESCENDING;
+ orderKey = ((RexCall) orderKey).getOperands().get(0);
+ break;
+ case NULLS_FIRST:
+ case NULLS_LAST:
+ throw new AssertionError();
+ default:
+ direction = RelFieldCollation.Direction.ASCENDING;
+ break;
+ }
+ final RelFieldCollation.NullDirection nullDirection =
+ direction.defaultNullDirection();
+ final RexInputRef ref = (RexInputRef) orderKey;
+ fieldCollations.add(
+ new RelFieldCollation(ref.getIndex(), direction, nullDirection));
+ }
+
+ final RelDataTypeFactory.Builder typeBuilder = cluster.getTypeFactory().builder();
+ for (RexNode partitionKey : partitionKeys) {
+ typeBuilder.add(partitionKey.toString(), partitionKey.getType());
+ }
+ if (allRows) {
+ for (RexNode orderKey : orderKeys) {
+ if (!typeBuilder.nameExists(orderKey.toString())) {
+ typeBuilder.add(orderKey.toString(), orderKey.getType());
+ }
+ }
+
+ final RelDataType inputRowType = peek().getRowType();
+ for (RelDataTypeField fs : inputRowType.getFieldList()) {
+ if (!typeBuilder.nameExists(fs.getName())) {
+ typeBuilder.add(fs);
+ }
+ }
+ }
+
+ final ImmutableMap.Builder<String, RexNode> measures = ImmutableMap.builder();
+ for (RexNode measure : measureList) {
+ List<RexNode> operands = ((RexCall) measure).getOperands();
+ String alias = operands.get(1).toString();
+ typeBuilder.add(alias, operands.get(0).getType());
+ measures.put(alias, operands.get(0));
+ }
+
+ final RelNode match = matchFactory.createMatch(peek(), pattern,
+ typeBuilder.build(), strictStart, strictEnd, patternDefinitions,
+ measures.build(), after, subsets, allRows,
+ ImmutableList.copyOf(partitionKeys), RelCollations.of(fieldCollations),
+ interval);
+ stack.push(new Frame(match));
+ return this;
+ }
+
/** Clears the stack.
*
* <p>The builder's state is now the same as when it was created. */
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
index 0f66db3..93e3b30 100644
--- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java
@@ -27,12 +27,14 @@ import org.apache.calcite.rel.core.TableFunctionScan;
import org.apache.calcite.rel.core.TableModify;
import org.apache.calcite.rel.core.Window;
import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexCorrelVariable;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.runtime.CalciteException;
import org.apache.calcite.schema.SchemaPlus;
+import org.apache.calcite.sql.SqlMatchRecognize;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.type.SqlTypeName;
@@ -46,6 +48,7 @@ import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.Mappings;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
@@ -54,6 +57,7 @@ import org.junit.Test;
import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.List;
+import java.util.TreeSet;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
@@ -1861,6 +1865,92 @@ public class RelBuilderTest {
assertThat(e.getMessage(), containsString("cannot derive type"));
}
}
+
+ @Test public void testMatchRecognize() {
+ // Equivalent SQL:
+ // SELECT *
+ // FROM emp
+ // MATCH_RECOGNIZE (
+ // PARTITION BY deptno
+ // ORDER BY empno asc
+ // MEASURES
+ // STRT.mgr as start_nw,
+ // LAST(DOWN.mgr) as bottom_nw,
+ // PATTERN (STRT DOWN+ UP+) WITHIN INTERVAL '5' SECOND
+ // DEFINE
+ // DOWN as DOWN.mgr < PREV(DOWN.mgr),
+ // UP as UP.mgr > PREV(UP.mgr)
+ // )
+ final RelBuilder builder = RelBuilder.create(config().build()).scan("EMP");
+ final RelDataTypeFactory typeFactory = builder.getTypeFactory();
+ final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
+
+ RexNode pattern = builder.patternConcat(
+ builder.literal("STRT"),
+ builder.patternQuantify(builder.literal("DOWN"), builder.literal(1),
+ builder.literal(-1), builder.literal(false)),
+ builder.patternQuantify(builder.literal("UP"), builder.literal(1),
+ builder.literal(-1), builder.literal(false)));
+
+ ImmutableMap.Builder<String, RexNode> pdBuilder = new ImmutableMap.Builder<>();
+ RexNode downDefinition = builder.call(SqlStdOperatorTable.LESS_THAN,
+ builder.call(SqlStdOperatorTable.PREV,
+ builder.patternField("DOWN", intType, 3),
+ builder.literal(0)),
+ builder.call(SqlStdOperatorTable.PREV,
+ builder.patternField("DOWN", intType, 3),
+ builder.literal(1)));
+ pdBuilder.put("DOWN", downDefinition);
+ RexNode upDefinition = builder.call(SqlStdOperatorTable.GREATER_THAN,
+ builder.call(SqlStdOperatorTable.PREV,
+ builder.patternField("UP", intType, 3),
+ builder.literal(0)),
+ builder.call(SqlStdOperatorTable.PREV,
+ builder.patternField("UP", intType, 3),
+ builder.literal(1)));
+ pdBuilder.put("UP", upDefinition);
+
+ ImmutableList.Builder<RexNode> measuresBuilder = new ImmutableList.Builder<>();
+ measuresBuilder.add(
+ builder.alias(builder.patternField("STRT", intType, 3),
+ "start_nw"));
+ measuresBuilder.add(
+ builder.alias(
+ builder.call(SqlStdOperatorTable.LAST,
+ builder.patternField("DOWN", intType, 3),
+ builder.literal(0)),
+ "bottom_nw"));
+
+ RexNode after = builder.getRexBuilder().makeFlag(
+ SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW);
+
+ ImmutableList.Builder<RexNode> partitionKeysBuilder = new ImmutableList.Builder<>();
+ partitionKeysBuilder.add(builder.field("DEPTNO"));
+
+ ImmutableList.Builder<RexNode> orderKeysBuilder = new ImmutableList.Builder<>();
+ orderKeysBuilder.add(builder.field("EMPNO"));
+
+ RexNode interval = builder.literal("INTERVAL '5' SECOND");
+
+ final ImmutableMap<String, TreeSet<String>> subsets = ImmutableMap.of();
+ final RelNode root = builder
+ .match(pattern, false, false, pdBuilder.build(),
+ measuresBuilder.build(), after, subsets, false,
+ partitionKeysBuilder.build(), orderKeysBuilder.build(), interval)
+ .build();
+ final String expected = "LogicalMatch(partition=[[$7]], order=[[0]], "
+ + "outputFields=[[$7, 'start_nw', 'bottom_nw']], allRows=[false], "
+ + "after=[FLAG(SKIP TO NEXT ROW)], pattern=[(('STRT', "
+ + "PATTERN_QUANTIFIER('DOWN', 1, -1, false)), "
+ + "PATTERN_QUANTIFIER('UP', 1, -1, false))], "
+ + "isStrictStarts=[false], isStrictEnds=[false], "
+ + "interval=['INTERVAL ''5'' SECOND'], subsets=[[]], "
+ + "patternDefinitions=[[<(PREV(DOWN.$3, 0), PREV(DOWN.$3, 1)), "
+ + ">(PREV(UP.$3, 0), PREV(UP.$3, 1))]], "
+ + "inputFields=[[EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO]])\n"
+ + " LogicalTableScan(table=[[scott, EMP]])\n";
+ assertThat(str(root), is(expected));
+ }
}
// End RelBuilderTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/3e97cff7/site/_docs/algebra.md
----------------------------------------------------------------------
diff --git a/site/_docs/algebra.md b/site/_docs/algebra.md
index 490ca4f..527b2e1 100644
--- a/site/_docs/algebra.md
+++ b/site/_docs/algebra.md
@@ -274,12 +274,14 @@ return the `RelBuilder`.
| `union(all [, n])` | Creates a [Union]({{ site.apiRoot }}/org/apache/calcite/rel/core/Union.html) of the `n` (default two) most recent relational expressions.
| `intersect(all [, n])` | Creates an [Intersect]({{ site.apiRoot }}/org/apache/calcite/rel/core/Intersect.html) of the `n` (default two) most recent relational expressions.
| `minus(all)` | Creates a [Minus]({{ site.apiRoot }}/org/apache/calcite/rel/core/Minus.html) of the two most recent relational expressions.
+| `match(pattern, strictStart,` `strictEnd, patterns, measures,` `after, subsets, allRows,` `partitionKeys, orderKeys,` `interval)` | Creates a [Match]({{ site.apiRoot }}/org/apache/calcite/rel/core/Match.html).
Argument types:
-* `expr` [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `expr`, `interval` [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
* `expr...` Array of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
-* `exprList` Iterable of [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `exprList`, `measureList`, `partitionKeys`, `orderKeys` Iterable of
+ [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
* `fieldOrdinal` Ordinal of a field within its row (starting from 0)
* `fieldName` Name of a field, unique within its row
* `fieldName...` Array of String
@@ -291,12 +293,14 @@ Argument types:
* `value...` Array of Object
* `value` Object
* `tupleList` Iterable of List of [RexLiteral]({{ site.apiRoot }}/org/apache/calcite/rex/RexLiteral.html)
-* `all` boolean
-* `distinct` boolean
+* `all`, `distinct`, `strictStart`, `strictEnd`, `allRows` boolean
* `alias` String
* `varHolder` [Holder]({{ site.apiRoot }}/org/apache/calcite/util/Holder.html) of [RexCorrelVariable]({{ site.apiRoot }}/org/apache/calcite/rex/RexCorrelVariable.html)
+* `patterns` Map whose key is String, value is [RexNode]({{ site.apiRoot }}/org/apache/calcite/rex/RexNode.html)
+* `subsets` Map whose key is String, value is a sorted set of String
The builder methods perform various optimizations, including:
+
* `project` returns its input if asked to project all columns in order
* `filter` flattens the condition (so an `AND` and `OR` may have more than 2 children),
simplifies (converting say `x = 1 AND TRUE` to `x = 1`)
@@ -355,6 +359,18 @@ added to the stack.
| `nullsFirst(expr)` | Changes sort order to nulls first (only valid as an argument to `sort` or `sortLimit`)
| `nullsLast(expr)` | Changes sort order to nulls last (only valid as an argument to `sort` or `sortLimit`)
+#### Pattern methods
+
+The following methods return patterns for use in `match`.
+
+| Method | Description
+|:------------------- |:-----------
+| `patternConcat(pattern...)` | Concatenates patterns
+| `patternAlter(pattern...)` | Alternates patterns
+| `patternQuantify(pattern, min, max)` | Quantifies a pattern
+| `patternPermute(pattern...)` | Permutes a pattern
+| `patternExclude(pattern)` | Excludes a pattern
+
### Group key methods
The following methods return a