kadirozde commented on code in PR #2067: URL: https://github.com/apache/phoenix/pull/2067#discussion_r1988049867
########## phoenix-core-client/src/main/java/org/apache/phoenix/schema/CompiledConditionalTTLExpression.java: ########## @@ -0,0 +1,307 @@ +/* + * 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.phoenix.schema; + +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_TTL; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.CellUtil; +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.hadoop.hbase.util.ByteStringer; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.io.WritableUtils; +import org.apache.phoenix.coprocessor.generated.PTableProtos; +import org.apache.phoenix.coprocessor.generated.ServerCachingProtos; +import org.apache.phoenix.expression.Expression; +import org.apache.phoenix.expression.ExpressionType; +import org.apache.phoenix.hbase.index.covered.update.ColumnReference; +import org.apache.phoenix.schema.tuple.MultiKeyValueTuple; +import org.apache.phoenix.schema.types.PBoolean; +import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting; +import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions; +import org.apache.phoenix.thirdparty.com.google.common.collect.Lists; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CompiledConditionalTTLExpression implements CompiledTTLExpression { + private static final Logger LOGGER = LoggerFactory.getLogger(CompiledConditionalTTLExpression.class); + + // expression as passed in the DDL statement and stored in syscat + private final String ttlExpr; + // compiled expression according to the table schema. For indexes the expression is + // first re-written to use index column references and then compiled. + private final Expression compiledExpr; + // columns referenced in the ttl expression to be added to scan + private final Set<ColumnReference> conditionExprColumns; + + // Since DeleteColumn updates are not propagated to indexes we mask older columns + // within GlobalIndexChecker. We need to do the same masking in TTLRegionScanner + // before we evaluate the ttl expression on the row. We apply this masking on server + // maintained indexes. + private final boolean maskOlderCells; + + public CompiledConditionalTTLExpression(String ttlExpr, + Expression compiledExpression, + Set<ColumnReference> conditionExprColumns, + boolean maskOlderCells) { + Preconditions.checkNotNull(compiledExpression); + Preconditions.checkNotNull(conditionExprColumns); + this.ttlExpr = ttlExpr; + this.compiledExpr = compiledExpression; + this.conditionExprColumns = conditionExprColumns; + this.maskOlderCells = maskOlderCells; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CompiledConditionalTTLExpression that = (CompiledConditionalTTLExpression) o; + return ttlExpr.equals(that.ttlExpr); + } + + @Override + public int hashCode() { + return Objects.hash(ttlExpr); + } + + @Override + public String getTTLExpression() { + return ttlExpr; + } + + @Override + public String toString() { + return getTTLExpression(); + } + + /** + * The cells of the row (i.e., result) read from HBase store are lexicographically ordered + * for tables using the key part of the cells which includes row, family, qualifier, + * timestamp and type. The cells belong of a column are ordered from the latest to + * the oldest. The method leverages this ordering and groups the cells into their columns + * based on the pair of family name and column qualifier. + */ + private List<Cell> getLatestRowVersion(List<Cell> result) { + List<Cell> latestRowVersion = new ArrayList<>(); + Cell currentColumnCell = null; + long maxDeleteFamilyTS = 0; + for (Cell cell : result) { + if (currentColumnCell == null || + !CellUtil.matchingColumn(cell, currentColumnCell)) { + // found a new column cell which has the latest timestamp + currentColumnCell = cell; + if (currentColumnCell.getType() == Cell.Type.DeleteFamily || + currentColumnCell.getType() == Cell.Type.DeleteFamilyVersion) { Review Comment: DeleteFamilyVersion should not be treated as DeleteFamily here. In other words, DeleteFamilyVersion deletes only a specific version of the row such that the timestamp of the DeleteFamilyVersion equals to the timestamp of the row version. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@phoenix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org