[MULTIPLE ISSUES][COMP][STO] Columnar compiler and cursor fixes
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
Fixes both ASTERIXDB-3311 and ASTERIXDB-3312
Change-Id: I0415bf4876ffe0e5bc6b5fa4c60aee7f9f6afce2
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17956
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Wail Alkowaileet <wael.y.k@gmail.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
index 821be72..b965512 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/algebra/operators/physical/BTreeSearchPOperator.java
@@ -39,6 +39,7 @@
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.utils.ListSet;
import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.core.algebra.base.DefaultProjectionFiltrationInfo;
import org.apache.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -133,27 +134,20 @@
long outputLimit = -1;
boolean retainMissing = false;
IMissingWriterFactory nonMatchWriterFactory = null;
- ITupleProjectorFactory tupleProjectorFactory = DefaultTupleProjectorFactory.INSTANCE;
+ IProjectionFiltrationInfo projectionFiltrationInfo = DefaultProjectionFiltrationInfo.INSTANCE;
switch (unnestMap.getOperatorTag()) {
case UNNEST_MAP:
UnnestMapOperator unnestMapOp = (UnnestMapOperator) unnestMap;
+ projectionFiltrationInfo = unnestMapOp.getProjectionFiltrationInfo();
outputLimit = unnestMapOp.getOutputLimit();
if (unnestMapOp.getSelectCondition() != null) {
tupleFilterFactory = metadataProvider.createTupleFilterFactory(new IOperatorSchema[] { opSchema },
typeEnv, unnestMapOp.getSelectCondition().getValue(), context);
}
- DatasetFormatInfo formatInfo = dataset.getDatasetFormatInfo();
- if (isPrimaryIndex && formatInfo.getFormat() == DatasetConfig.DatasetFormat.COLUMN) {
- IProjectionFiltrationInfo projectionFiltrationInfo = unnestMapOp.getProjectionFiltrationInfo();
- ARecordType datasetType = (ARecordType) metadataProvider.findType(dataset);
- ARecordType metaItemType = (ARecordType) metadataProvider.findMetaType(dataset);
- datasetType = (ARecordType) metadataProvider.findTypeForDatasetWithoutType(datasetType,
- metaItemType, dataset);
- tupleProjectorFactory = IndexUtil.createTupleProjectorFactory(context, typeEnv, formatInfo,
- projectionFiltrationInfo, datasetType, metaItemType, dataset.getPrimaryKeys().size());
- }
break;
case LEFT_OUTER_UNNEST_MAP:
+ LeftOuterUnnestMapOperator outerUnnestMapOperator = (LeftOuterUnnestMapOperator) unnestMap;
+ projectionFiltrationInfo = outerUnnestMapOperator.getProjectionFiltrationInfo();
// By nature, LEFT_OUTER_UNNEST_MAP should generate missing (or null) values for non-matching tuples.
retainMissing = true;
nonMatchWriterFactory =
@@ -165,6 +159,17 @@
String.valueOf(unnestMap.getOperatorTag()));
}
+ ITupleProjectorFactory tupleProjectorFactory = DefaultTupleProjectorFactory.INSTANCE;
+ DatasetFormatInfo formatInfo = dataset.getDatasetFormatInfo();
+ if (isPrimaryIndex && formatInfo.getFormat() == DatasetConfig.DatasetFormat.COLUMN) {
+ ARecordType datasetType = (ARecordType) metadataProvider.findType(dataset);
+ ARecordType metaItemType = (ARecordType) metadataProvider.findMetaType(dataset);
+ datasetType =
+ (ARecordType) metadataProvider.findTypeForDatasetWithoutType(datasetType, metaItemType, dataset);
+ tupleProjectorFactory = IndexUtil.createTupleProjectorFactory(context, typeEnv, formatInfo,
+ projectionFiltrationInfo, datasetType, metaItemType, dataset.getPrimaryKeys().size());
+ }
+
Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> btreeSearch = metadataProvider.getBtreeSearchRuntime(
builder.getJobSpec(), opSchema, typeEnv, context, jobGenParams.getRetainInput(), retainMissing,
nonMatchWriterFactory, dataset, jobGenParams.getIndexName(), lowKeyIndexes, highKeyIndexes,
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownProcessorsExecutor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownProcessorsExecutor.java
index 01d3aeb..023e4da 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownProcessorsExecutor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownProcessorsExecutor.java
@@ -43,6 +43,7 @@
import org.apache.hyracks.algebricks.core.algebra.metadata.IProjectionFiltrationInfo;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterUnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
public class PushdownProcessorsExecutor {
@@ -135,6 +136,9 @@
} else if (scanOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
UnnestMapOperator unnestMapOp = (UnnestMapOperator) scanOp;
unnestMapOp.setProjectionFiltrationInfo(info);
+ } else if (scanOp.getOperatorTag() == LogicalOperatorTag.LEFT_OUTER_UNNEST_MAP) {
+ LeftOuterUnnestMapOperator outerUnnestMapOp = (LeftOuterUnnestMapOperator) scanOp;
+ outerUnnestMapOp.setProjectionFiltrationInfo(info);
}
}
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
index 2a8e999..b00f8a1 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
@@ -53,6 +53,7 @@
import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
@@ -167,6 +168,18 @@
return null;
}
+ /**
+ * From the {@link LeftOuterUnnestMapOperator}, we need to register the payload variable (record variable) to check
+ * which expression in the plan is using it.
+ */
+ @Override
+ public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Void arg) throws AlgebricksException {
+ visitInputs(op);
+ DatasetDataSource datasetDataSource = getDatasetDataSourceIfApplicable(getDataSourceFromUnnestMapOperator(op));
+ registerDatasetIfApplicable(datasetDataSource, op);
+ return null;
+ }
+
@Override
public Void visitAggregateOperator(AggregateOperator op, Void arg) throws AlgebricksException {
visitInputs(op, op.getVariables());
@@ -227,7 +240,7 @@
* @param unnest unnest map operator
* @return datasource
*/
- private DataSource getDataSourceFromUnnestMapOperator(UnnestMapOperator unnest) throws AlgebricksException {
+ private DataSource getDataSourceFromUnnestMapOperator(AbstractUnnestMapOperator unnest) throws AlgebricksException {
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) unnest.getExpressionRef().getValue();
String dataverse = ConstantExpressionUtil.getStringArgument(funcExpr, DATAVERSE_NAME_POS);
String dataset = ConstantExpressionUtil.getStringArgument(funcExpr, DATASET_NAME_POS);
@@ -478,12 +491,6 @@
}
@Override
- public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Void arg) throws AlgebricksException {
- visitInputs(op);
- return null;
- }
-
- @Override
public Void visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException {
visitInputs(op);
return null;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/composite-pks/composite-pks.005.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/composite-pks/composite-pks.005.query.sqlpp
new file mode 100644
index 0000000..63413cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/composite-pks/composite-pks.005.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT VALUE c
+FROM CompositeKey c
+WHERE k1 = "2"
+ORDER BY to_bigint(k1);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.01.ddl.sqlpp
new file mode 100644
index 0000000..65c9402
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.01.ddl.sqlpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+
+USE test;
+
+CREATE DATASET ds1Row PRIMARY KEY (id: int)
+WITH {
+ "storage-format": {"format": "row"}
+};
+
+CREATE DATASET ds2Row PRIMARY KEY (id: int)
+WITH {
+ "storage-format": {"format": "row"}
+};
+
+
+CREATE DATASET ds1Column PRIMARY KEY (id: int)
+WITH {
+ "storage-format": {"format": "column"}
+};
+
+CREATE DATASET ds2Column PRIMARY KEY (id: int)
+WITH {
+ "storage-format": {"format": "column"}
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.02.update.sqlpp
new file mode 100644
index 0000000..5afc363
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.02.update.sqlpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+use test;
+
+-- Row inserts
+INSERT INTO ds1Row ({"id": 1, "a": 1, "b": 1 });
+INSERT INTO ds1Row ({"id": 2, "a": 1, "b": 2 });
+INSERT INTO ds1Row ({"id": 3, "a": 2, "b": 3 });
+INSERT INTO ds1Row ({"id": 4, "a": 2, "b": 4 });
+INSERT INTO ds1Row ({"id": 5, "a": 3, "b": 5 });
+INSERT INTO ds1Row ({"id": 6, "a": 3, "b": 6 });
+INSERT INTO ds1Row ({"id": 7, "a": 4, "b": 7 });
+
+INSERT INTO ds2Row ({"id": 100, "x": 2, "y": 100 });
+INSERT INTO ds2Row ({"id": 101, "x": 2, "y": 101 });
+INSERT INTO ds2Row ({"id": 102, "x": 3, "y": 102 });
+
+
+-- Column inserts
+INSERT INTO ds1Column ({"id": 1, "a": 1, "b": 1 });
+INSERT INTO ds1Column ({"id": 2, "a": 1, "b": 2 });
+INSERT INTO ds1Column ({"id": 3, "a": 2, "b": 3 });
+INSERT INTO ds1Column ({"id": 4, "a": 2, "b": 4 });
+INSERT INTO ds1Column ({"id": 5, "a": 3, "b": 5 });
+INSERT INTO ds1Column ({"id": 6, "a": 3, "b": 6 });
+INSERT INTO ds1Column ({"id": 7, "a": 4, "b": 7 });
+
+INSERT INTO ds2Column ({"id": 100, "x": 2, "y": 100 });
+INSERT INTO ds2Column ({"id": 101, "x": 2, "y": 101 });
+INSERT INTO ds2Column ({"id": 102, "x": 3, "y": 102 });
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.10.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.10.query.sqlpp
new file mode 100644
index 0000000..a1f17bd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.10.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Row.b, ds2Row.y
+FROM ds1Row
+LEFT OUTER JOIN ds2Row
+ON ds1Row.a = ds2Row.x
+ORDER BY ds1Row.b, ds2Row.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.11.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.11.query.sqlpp
new file mode 100644
index 0000000..a1e5d73
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.11.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Column.b, ds2Column.y
+FROM ds1Column
+LEFT OUTER JOIN ds2Column
+ON ds1Column.a = ds2Column.x
+ORDER BY ds1Column.b, ds2Column.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.12.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.12.query.sqlpp
new file mode 100644
index 0000000..6524c49
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.12.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Row.b, ds2Row.y
+FROM ds1Row
+RIGHT OUTER JOIN ds2Row
+ON ds1Row.a = ds2Row.x
+ORDER BY ds1Row.b, ds2Row.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.13.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.13.query.sqlpp
new file mode 100644
index 0000000..e118cbd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.13.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Column.b, ds2Column.y
+FROM ds1Column
+RIGHT OUTER JOIN ds2Column
+ON ds1Column.a = ds2Column.x
+ORDER BY ds1Column.b, ds2Column.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.20.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.20.ddl.sqlpp
new file mode 100644
index 0000000..b40850b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.20.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+CREATE INDEX idxRow_a ON ds1Row(a:int);
+CREATE INDEX idxRow_x ON ds2Row(x:int);
+
+CREATE INDEX idxColumn_a ON ds1Column(a:int);
+CREATE INDEX idxColumn_x ON ds2Column(x:int);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.30.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.30.query.sqlpp
new file mode 100644
index 0000000..b674f2a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.30.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Row.b, ds2Row.y
+FROM ds1Row
+LEFT OUTER JOIN ds2Row
+ON to_bigint(ds1Row.a) /*+indexnl*/ = ds2Row.x
+ORDER BY ds1Row.b, ds2Row.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.31.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.31.query.sqlpp
new file mode 100644
index 0000000..7acb04c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.31.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Column.b, ds2Column.y
+FROM ds1Column
+LEFT OUTER JOIN ds2Column
+ON to_bigint(ds1Column.a) /*+indexnl*/ = ds2Column.x
+ORDER BY ds1Column.b, ds2Column.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.32.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.32.query.sqlpp
new file mode 100644
index 0000000..504b9f5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.32.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Row.b, ds2Row.y
+FROM ds1Row
+RIGHT OUTER JOIN ds2Row
+ON ds1Row.a /*+indexnl*/ = to_bigint(ds2Row.x)
+ORDER BY ds1Row.b, ds2Row.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.33.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.33.query.sqlpp
new file mode 100644
index 0000000..ed68895
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/secondary-index/outer-join/outer_join.33.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+USE test;
+
+SELECT ds1Column.b, ds2Column.y
+FROM ds1Column
+RIGHT OUTER JOIN ds2Column
+ON ds1Column.a /*+indexnl*/ = to_bigint(ds2Column.x)
+ORDER BY ds1Column.b, ds2Column.y;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/composite-pks/composite-pks.005.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/composite-pks/composite-pks.005.adm
new file mode 100644
index 0000000..2fa2fd8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/composite-pks/composite-pks.005.adm
@@ -0,0 +1 @@
+{ "k1": "2", "k2": "The quick brown fox jumps over the lazy dog" }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.10.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.10.adm
new file mode 100644
index 0000000..4940426
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.10.adm
@@ -0,0 +1,9 @@
+{ "b": 1 }
+{ "b": 2 }
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
+{ "b": 7 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.11.adm
new file mode 100644
index 0000000..4940426
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.11.adm
@@ -0,0 +1,9 @@
+{ "b": 1 }
+{ "b": 2 }
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
+{ "b": 7 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.12.adm
new file mode 100644
index 0000000..4882857
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.12.adm
@@ -0,0 +1,6 @@
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.13.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.13.adm
new file mode 100644
index 0000000..4882857
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.13.adm
@@ -0,0 +1,6 @@
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.30.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.30.adm
new file mode 100644
index 0000000..4940426
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.30.adm
@@ -0,0 +1,9 @@
+{ "b": 1 }
+{ "b": 2 }
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
+{ "b": 7 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.31.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.31.adm
new file mode 100644
index 0000000..4940426
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.31.adm
@@ -0,0 +1,9 @@
+{ "b": 1 }
+{ "b": 2 }
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
+{ "b": 7 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.32.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.32.adm
new file mode 100644
index 0000000..4882857
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.32.adm
@@ -0,0 +1,6 @@
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.33.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.33.adm
new file mode 100644
index 0000000..4882857
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/secondary-index/outer-join/outer_join.33.adm
@@ -0,0 +1,6 @@
+{ "b": 3, "y": 100 }
+{ "b": 3, "y": 101 }
+{ "b": 4, "y": 100 }
+{ "b": 4, "y": 101 }
+{ "b": 5, "y": 102 }
+{ "b": 6, "y": 102 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
index f65f643..10fda37 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
@@ -16399,6 +16399,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="column">
+ <compilation-unit name="secondary-index/outer-join">
+ <output-dir compare="Text">secondary-index/outer-join</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="column">
<compilation-unit name="analyze-dataset">
<output-dir compare="Text">analyze-dataset</output-dir>
</compilation-unit>
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
index 30d01d5..f5a327d 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
@@ -101,6 +101,10 @@
return rootAssembler.getValue();
}
+ public IValueReference getPreviousValue() {
+ return rootAssembler.getValue();
+ }
+
public int getNumberOfColumns() {
return assemblers.length;
}
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnTupleProjector.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnTupleProjector.java
index b7b9745..369a891 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnTupleProjector.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnTupleProjector.java
@@ -112,7 +112,7 @@
}
protected void writeMeta(ITupleReference tuple, DataOutput dos, ArrayTupleBuilder tb) throws IOException {
- //NoOp
+ // NoOp
}
protected int getNumberOfTupleFields() {
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/AbstractAsterixColumnTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/AbstractAsterixColumnTupleReference.java
index 8beae4e..87ec700 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/AbstractAsterixColumnTupleReference.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/AbstractAsterixColumnTupleReference.java
@@ -236,9 +236,10 @@
}
}
- protected void appendExceptionInformation(ColumnarValueException e) {
+ protected void appendExceptionInformation(ColumnarValueException e, int previousIndex) {
ObjectNode node = e.createNode(getClass().getSimpleName());
node.put("isAntiMatter", isAntimatter());
+ node.put("previousIndex", previousIndex);
ArrayNode pkNodes = node.putArray("primaryKeyReaders");
for (IColumnValuesReader reader : primaryKeyReaders) {
reader.appendReaderInformation(pkNodes.addObject());
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
index ba5ffb7..19cb753 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
@@ -53,6 +53,7 @@
private final IFilterApplier filterApplier;
private final List<IColumnValuesReader> filterColumnReaders;
private final AbstractBytesInputStream[] filteredColumnStreams;
+ private int previousIndex;
public QueryColumnTupleReference(int componentIndex, ColumnBTreeReadLeafFrame frame,
QueryColumnMetadata columnMetadata, IColumnReadMultiPageOp multiPageOp) {
@@ -78,6 +79,7 @@
filteredColumnStreams[i] = new ByteBufferInputStream();
}
}
+ previousIndex = -1;
}
@Override
@@ -98,6 +100,7 @@
boolean readColumns = rangeFilterEvaluator.evaluate();
assembler.reset(readColumns ? numberOfTuples : 0);
columnFilterEvaluator.reset();
+ previousIndex = -1;
return readColumns;
}
@@ -129,9 +132,13 @@
public IValueReference getAssembledValue() throws HyracksDataException {
try {
+ if (previousIndex == tupleIndex) {
+ return assembler.getPreviousValue();
+ }
+ previousIndex = tupleIndex;
return filterApplier.getTuple();
} catch (ColumnarValueException e) {
- appendExceptionInformation(e);
+ appendExceptionInformation(e, previousIndex);
throw e;
}
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
index a2d6b54..fc1f1d2 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
@@ -55,6 +55,7 @@
private final IFilterApplier filterApplier;
private final List<IColumnValuesReader> filterColumnReaders;
private final AbstractBytesInputStream[] filteredColumnStreams;
+ private int previousIndex;
public QueryColumnWithMetaTupleReference(int componentIndex, ColumnBTreeReadLeafFrame frame,
QueryColumnMetadata columnMetadata, IColumnReadMultiPageOp multiPageOp) {
@@ -81,6 +82,7 @@
filteredColumnStreams[i] = new ByteBufferInputStream();
}
}
+ previousIndex = -1;
}
@Override
@@ -102,6 +104,7 @@
assembler.reset(readColumns ? numberOfTuples : 0);
metaAssembler.reset(readColumns ? numberOfTuples : 0);
columnFilterEvaluator.reset();
+ previousIndex = -1;
return readColumns;
}
@@ -139,18 +142,26 @@
public IValueReference getAssembledValue() throws HyracksDataException {
try {
+ if (previousIndex == tupleIndex) {
+ return assembler.getPreviousValue();
+ }
return filterApplier.getTuple();
} catch (ColumnarValueException e) {
- appendExceptionInformation(e);
+ appendExceptionInformation(e, previousIndex);
throw e;
}
}
public IValueReference getMetaAssembledValue() throws HyracksDataException {
try {
+ if (previousIndex == tupleIndex) {
+ return assembler.getPreviousValue();
+ }
+ // Update the previous index only after calling meta
+ previousIndex = tupleIndex;
return metaAssembler.nextValue();
} catch (ColumnarValueException e) {
- appendExceptionInformation(e);
+ appendExceptionInformation(e, previousIndex);
throw e;
}
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/LeftOuterUnnestMapOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/LeftOuterUnnestMapOperator.java
index d91cf72..5eaecbc 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/LeftOuterUnnestMapOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/LeftOuterUnnestMapOperator.java
@@ -22,12 +22,14 @@
import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.DefaultProjectionFiltrationInfo;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IProjectionFiltrationInfo;
import org.apache.hyracks.algebricks.core.algebra.typing.ITypingContext;
import org.apache.hyracks.algebricks.core.algebra.typing.PropagatingTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;
@@ -42,12 +44,20 @@
public class LeftOuterUnnestMapOperator extends AbstractUnnestMapOperator {
private IAlgebricksConstantValue missingValue;
+ private IProjectionFiltrationInfo projectionFiltrationInfo;
public LeftOuterUnnestMapOperator(List<LogicalVariable> variables, Mutable<ILogicalExpression> expression,
List<Object> variableTypes, IAlgebricksConstantValue missingValue) {
+ this(variables, expression, variableTypes, missingValue, DefaultProjectionFiltrationInfo.INSTANCE);
+ }
+
+ public LeftOuterUnnestMapOperator(List<LogicalVariable> variables, Mutable<ILogicalExpression> expression,
+ List<Object> variableTypes, IAlgebricksConstantValue missingValue,
+ IProjectionFiltrationInfo projectionFiltrationInfo) {
// propagateInput is always set to true for this operator.
super(variables, expression, variableTypes, true);
setMissingValue(missingValue);
+ setProjectionFiltrationInfo(projectionFiltrationInfo);
}
public IAlgebricksConstantValue getMissingValue() {
@@ -101,4 +111,13 @@
throw new IllegalArgumentException(String.valueOf(value));
}
}
+
+ public void setProjectionFiltrationInfo(IProjectionFiltrationInfo projectionFiltrationInfo) {
+ this.projectionFiltrationInfo =
+ projectionFiltrationInfo == null ? DefaultProjectionFiltrationInfo.INSTANCE : projectionFiltrationInfo;
+ }
+
+ public IProjectionFiltrationInfo getProjectionFiltrationInfo() {
+ return projectionFiltrationInfo;
+ }
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
index 137dd2e..05f41a0 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/IsomorphismOperatorVisitor.java
@@ -464,7 +464,8 @@
return Boolean.FALSE;
}
LeftOuterUnnestMapOperator loUnnestOpArg = (LeftOuterUnnestMapOperator) copyAndSubstituteVar(op, arg);
- boolean isomorphic = VariableUtilities.varListEqualUnordered(op.getVariables(), loUnnestOpArg.getVariables());
+ boolean isomorphic = VariableUtilities.varListEqualUnordered(op.getVariables(), loUnnestOpArg.getVariables())
+ && Objects.equals(op.getProjectionFiltrationInfo(), loUnnestOpArg.getProjectionFiltrationInfo());;
if (!isomorphic) {
return Boolean.FALSE;
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
index 6377d44..ba49233 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
@@ -548,9 +548,11 @@
@Override
public ILogicalOperator visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, ILogicalOperator arg)
throws AlgebricksException {
+ IProjectionFiltrationInfo projectionFiltrationInfo =
+ op.getProjectionFiltrationInfo() != null ? op.getProjectionFiltrationInfo().createCopy() : null;
LeftOuterUnnestMapOperator opCopy = new LeftOuterUnnestMapOperator(deepCopyVariableList(op.getVariables()),
exprDeepCopyVisitor.deepCopyExpressionReference(op.getExpressionRef()), op.getVariableTypes(),
- op.getMissingValue());
+ op.getMissingValue(), projectionFiltrationInfo);
deepCopyInputsAnnotationsAndExecutionMode(op, arg, opCopy);
return opCopy;
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
index b3828df..fa47ae5 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
@@ -261,6 +261,7 @@
throws AlgebricksException {
ArrayList<LogicalVariable> newInputList = new ArrayList<>();
newInputList.addAll(op.getVariables());
+ IProjectionFiltrationInfo projectionFiltrationInfo = op.getProjectionFiltrationInfo().createCopy();
return new LeftOuterUnnestMapOperator(newInputList, deepCopyExpressionRef(op.getExpressionRef()),
new ArrayList<>(op.getVariableTypes()), op.getMissingValue());
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
index e1e8c50..8c50bcd 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitor.java
@@ -380,7 +380,9 @@
@Override
public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Integer indent)
throws AlgebricksException {
- printAbstractUnnestMapOperator(op, indent, "left-outer-unnest-map", op.getMissingValue());
+ AlgebricksStringBuilderWriter plan =
+ printAbstractUnnestMapOperator(op, indent, "left-outer-unnest-map", op.getMissingValue());
+ op.getProjectionFiltrationInfo().print(plan);
return null;
}
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
index a60308a..3e4e09f 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
@@ -625,8 +625,13 @@
@Override
public Void visitLeftOuterUnnestMapOperator(LeftOuterUnnestMapOperator op, Void indent) throws AlgebricksException {
- writeUnnestMapOperator(op, indent, "left-outer-unnest-map", op.getMissingValue());
- return null;
+ try {
+ writeUnnestMapOperator(op, indent, "left-outer-unnest-map", op.getMissingValue());
+ op.getProjectionFiltrationInfo().print(jsonGenerator);
+ return null;
+ } catch (IOException e) {
+ throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
+ }
}
@Override
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/ColumnBTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/ColumnBTreeRangeSearchCursor.java
index 77f161a..fd726cd 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/ColumnBTreeRangeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/ColumnBTreeRangeSearchCursor.java
@@ -169,12 +169,14 @@
//Next tuple
frameTuple.next();
//Check whether the frameTuple is not consumed and also include the search key
- return highKey == null || isLessOrEqual(frameTuple, highKey, pred.isHighKeyInclusive());
+ return highKey == null
+ || isLessOrEqual(frameTuple, highKey, pred.isHighKeyInclusive(), pred.getHighKeyComparator());
}
protected boolean shouldYieldFirstCall() throws HyracksDataException {
// Proceed if the highKey is null or the current tuple's key is less than (or equal) the highKey
- return highKey == null || isLessOrEqual(frameTuple, highKey, pred.isHighKeyInclusive());
+ return highKey == null
+ || isLessOrEqual(frameTuple, highKey, pred.isHighKeyInclusive(), pred.getHighKeyComparator());
}
protected void releasePages() throws HyracksDataException {
@@ -185,16 +187,17 @@
}
}
- private boolean isLessOrEqual(ITupleReference left, ITupleReference right, boolean inclusive)
- throws HyracksDataException {
- int cmp = originalKeyCmp.compare(left, right);
+ private boolean isLessOrEqual(ITupleReference left, ITupleReference right, boolean inclusive,
+ MultiComparator comparator) throws HyracksDataException {
+ int cmp = comparator.compare(left, right);
return cmp < 0 || inclusive && cmp == 0;
}
protected int getLowKeyIndex() throws HyracksDataException {
if (lowKey == null) {
return 0;
- } else if (isLessOrEqual(frame.getRightmostTuple(), lowKey, !pred.isLowKeyInclusive())) {
+ } else if (isLessOrEqual(frame.getRightmostTuple(), lowKey, !pred.isLowKeyInclusive(),
+ pred.getLowKeyComparator())) {
//The highest key from the frame is less than the requested lowKey
return frame.getTupleCount();
}
@@ -214,7 +217,8 @@
protected int getHighKeyIndex() throws HyracksDataException {
if (highKey == null) {
return frame.getTupleCount() - 1;
- } else if (isLessOrEqual(highKey, frame.getLeftmostTuple(), !pred.isHighKeyInclusive())) {
+ } else if (isLessOrEqual(highKey, frame.getLeftmostTuple(), !pred.isHighKeyInclusive(),
+ pred.getHighKeyComparator())) {
return -1;
}
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
index 283522a..e638a4a 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
@@ -155,6 +155,16 @@
@Override
public final void setAt(int startIndex) throws HyracksDataException {
+ if (tupleIndex == startIndex) {
+ /*
+ * This case happens when we ask for the same tuple again when utilizing a secondary index. To illustrate,
+ * assume that the secondary index search yielded the following PKs [1, 1, 1, 2] -- keys are always sorted.
+ * We see that the secondary index asked for the PK '1' three times. Asking for the same tuple multiple
+ * times is possible when we do index nested-loop join (indexnl).
+ * See ASTERIX-3311
+ */
+ return;
+ }
/*
* Let say that tupleIndex = 5 and startIndex = 12
* Then, skipCount = 12 - 5 - 1 = 6.