diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java index 8b00799c043..3ee72a35d17 100644 --- a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java +++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableWindow.java @@ -85,6 +85,11 @@ public class EnumerableWindow extends Window implements EnumerableRel { constants, getRowType(), groups); } + @Override public Window copy(List constants) { + return new EnumerableWindow(getCluster(), getTraitSet(), getInput(), + constants, getRowType(), groups); + } + @Override public @Nullable RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { RelOptCost cost = super.computeSelfCost(planner, mq); diff --git a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java index cc52e7c6d8e..8d622ddcd4e 100644 --- a/core/src/main/java/org/apache/calcite/interpreter/Bindables.java +++ b/core/src/main/java/org/apache/calcite/interpreter/Bindables.java @@ -836,6 +836,11 @@ public static class BindableWindow extends Window implements BindableRel { constants, getRowType(), groups); } + @Override public Window copy(List constants) { + return new BindableWindow(getCluster(), traitSet, getInput(), + constants, getRowType(), groups); + } + @Override public @Nullable RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { RelOptCost cost = super.computeSelfCost(planner, mq); diff --git a/core/src/main/java/org/apache/calcite/rel/core/Window.java b/core/src/main/java/org/apache/calcite/rel/core/Window.java index 8cdaa90fff4..4f76256930e 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Window.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Window.java @@ -111,6 +111,14 @@ public Window(RelOptCluster cluster, RelTraitSet traitSet, RelNode input, this(cluster, traitSet, Collections.emptyList(), input, constants, rowType, groups); } + /** + * Creates a copy of this {@code Window}. + * + * @param constants Replaces the list of constants in the returned copy + * @return New {@code Window} + */ + public abstract Window copy(List constants); + @Override public boolean isValid(Litmus litmus, @Nullable Context context) { // In the window specifications, an aggregate call such as // 'SUM(RexInputRef #10)' refers to expression #10 of inputProgram. diff --git a/core/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java b/core/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java index 7a1253b32e3..3bc23b31f87 100644 --- a/core/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java +++ b/core/src/main/java/org/apache/calcite/rel/logical/LogicalWindow.java @@ -103,6 +103,11 @@ public LogicalWindow(RelOptCluster cluster, RelTraitSet traitSet, RelNode input, getRowType(), groups); } + @Override public Window copy(List constants) { + return new LogicalWindow(getCluster(), getTraitSet(), getInput(), + constants, getRowType(), groups); + } + /** * Creates a LogicalWindow. * diff --git a/core/src/test/java/org/apache/calcite/adapter/enumerable/EnumerableWindowTest.java b/core/src/test/java/org/apache/calcite/adapter/enumerable/EnumerableWindowTest.java new file mode 100644 index 00000000000..781f8fafa96 --- /dev/null +++ b/core/src/test/java/org/apache/calcite/adapter/enumerable/EnumerableWindowTest.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.adapter.enumerable; + +import org.apache.calcite.plan.Contexts; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.AbstractRelNode; +import org.apache.calcite.rel.RelNode; +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.RelDataTypeSystem; +import org.apache.calcite.rel.type.RelDataTypeSystemImpl; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexLiteral; +import org.apache.calcite.sql.type.BasicSqlType; +import org.apache.calcite.sql.type.SqlTypeFactoryImpl; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.test.MockRelOptPlanner; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Test for {@link org.apache.calcite.adapter.enumerable.EnumerableWindow}. + */ +public class EnumerableWindowTest { + @Test void testCopyWithConstants() { + final MockRelOptPlanner planner = new MockRelOptPlanner(Contexts.empty()); + final RelDataTypeFactory typeFactory = + new SqlTypeFactoryImpl(org.apache.calcite.rel.type.RelDataTypeSystem.DEFAULT); + final RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory)); + final RelTraitSet traitSet = RelTraitSet.createEmpty(); + final RelNode relNode = new AbstractRelNode(cluster, traitSet) { + }; + final RelDataTypeSystem dataTypeSystem = new RelDataTypeSystemImpl() { + }; + + final RelDataType dataType = new BasicSqlType(dataTypeSystem, SqlTypeName.BOOLEAN); + final List constants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "TRUE")); + final RelDataType rowDataType = new BasicSqlType(dataTypeSystem, SqlTypeName.ROW); + final List groups = Collections.emptyList(); + + final EnumerableWindow original = + new EnumerableWindow(cluster, traitSet, relNode, constants, rowDataType, groups); + final List newConstants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "FALSE")); + final Window updated = original.copy(newConstants); + + assertNotSame(original, updated); + assertEquals(1, original.getConstants().size()); + assertSame(constants.get(0), original.getConstants().get(0)); + assertEquals(1, updated.getConstants().size()); + assertSame(newConstants.get(0), updated.getConstants().get(0)); + } +} diff --git a/core/src/test/java/org/apache/calcite/interpreter/BindableWindowTest.java b/core/src/test/java/org/apache/calcite/interpreter/BindableWindowTest.java new file mode 100644 index 00000000000..3d28b3ad5d3 --- /dev/null +++ b/core/src/test/java/org/apache/calcite/interpreter/BindableWindowTest.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.interpreter; + +import org.apache.calcite.plan.Contexts; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.AbstractRelNode; +import org.apache.calcite.rel.RelNode; +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.RelDataTypeSystem; +import org.apache.calcite.rel.type.RelDataTypeSystemImpl; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexLiteral; +import org.apache.calcite.sql.type.BasicSqlType; +import org.apache.calcite.sql.type.SqlTypeFactoryImpl; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.test.MockRelOptPlanner; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Test for {@link org.apache.calcite.interpreter.Bindables.BindableWindow}. + */ +public class BindableWindowTest { + @Test void testCopyWithConstants() { + final MockRelOptPlanner planner = new MockRelOptPlanner(Contexts.empty()); + final RelDataTypeFactory typeFactory = + new SqlTypeFactoryImpl(org.apache.calcite.rel.type.RelDataTypeSystem.DEFAULT); + final RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory)); + final RelTraitSet traitSet = RelTraitSet.createEmpty(); + final RelNode relNode = new AbstractRelNode(cluster, traitSet) { + }; + final RelDataTypeSystem dataTypeSystem = new RelDataTypeSystemImpl() { + }; + + final RelDataType dataType = new BasicSqlType(dataTypeSystem, SqlTypeName.BOOLEAN); + final List constants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "TRUE")); + final RelDataType rowDataType = new BasicSqlType(dataTypeSystem, SqlTypeName.ROW); + final List groups = Collections.emptyList(); + + final Bindables.BindableWindow original = + new Bindables.BindableWindow(cluster, traitSet, relNode, constants, rowDataType, groups); + final List newConstants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "FALSE")); + final Window updated = original.copy(newConstants); + + assertNotSame(original, updated); + assertEquals(1, original.getConstants().size()); + assertSame(constants.get(0), original.getConstants().get(0)); + assertEquals(1, updated.getConstants().size()); + assertSame(newConstants.get(0), updated.getConstants().get(0)); + } +} diff --git a/core/src/test/java/org/apache/calcite/rel/logical/LogicalWindowTest.java b/core/src/test/java/org/apache/calcite/rel/logical/LogicalWindowTest.java new file mode 100644 index 00000000000..9da4865bdc6 --- /dev/null +++ b/core/src/test/java/org/apache/calcite/rel/logical/LogicalWindowTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.calcite.rel.logical; + +import org.apache.calcite.plan.Contexts; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; +import org.apache.calcite.rel.AbstractRelNode; +import org.apache.calcite.rel.RelNode; +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.RelDataTypeSystem; +import org.apache.calcite.rel.type.RelDataTypeSystemImpl; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexLiteral; +import org.apache.calcite.sql.type.BasicSqlType; +import org.apache.calcite.sql.type.SqlTypeFactoryImpl; +import org.apache.calcite.sql.type.SqlTypeName; +import org.apache.calcite.test.MockRelOptPlanner; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; + +import static org.apache.calcite.rel.core.Window.Group; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; + +/** + * Test for {@link org.apache.calcite.rel.logical.LogicalWindow}. + */ +public class LogicalWindowTest { + @Test void testCopyWithConstants() { + final MockRelOptPlanner planner = new MockRelOptPlanner(Contexts.empty()); + final RelDataTypeFactory typeFactory = + new SqlTypeFactoryImpl(org.apache.calcite.rel.type.RelDataTypeSystem.DEFAULT); + final RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory)); + final RelTraitSet traitSet = RelTraitSet.createEmpty(); + final RelNode relNode = new AbstractRelNode(cluster, traitSet) { + }; + final RelDataTypeSystem dataTypeSystem = new RelDataTypeSystemImpl() { + }; + + final RelDataType dataType = new BasicSqlType(dataTypeSystem, SqlTypeName.BOOLEAN); + final List constants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "TRUE")); + final RelDataType rowDataType = new BasicSqlType(dataTypeSystem, SqlTypeName.ROW); + final List groups = Collections.emptyList(); + + final LogicalWindow original = + new LogicalWindow(cluster, traitSet, relNode, constants, rowDataType, groups); + final List newConstants = + Collections.singletonList( + RexLiteral.fromJdbcString(dataType, + SqlTypeName.BOOLEAN, + "FALSE")); + final Window updated = original.copy(newConstants); + + assertNotSame(original, updated); + assertEquals(1, original.getConstants().size()); + assertSame(constants.get(0), original.getConstants().get(0)); + assertEquals(1, updated.getConstants().size()); + assertSame(newConstants.get(0), updated.getConstants().get(0)); + } +} diff --git a/site/_docs/history.md b/site/_docs/history.md index f3140e7d268..2e2b8c74bb7 100644 --- a/site/_docs/history.md +++ b/site/_docs/history.md @@ -46,6 +46,8 @@ z. * In the context of [CALCITE-6015] the visibility of the method `SqlCall.getCallSignature` has been converted from `protected` to `public`. Any subclass overriding it will need to be adjusted accordingly. +* [CALCITE-6321] + Add `copy(List)` method to `Window` class Compatibility: This release is tested on Linux, macOS, Microsoft Windows; using JDK/OpenJDK versions 8 to 19;