use of org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor in project phoenix by apache.
the class WhereCompiler method setScanFilter.
/**
* Sets the start/stop key range based on the whereClause expression.
* @param context the shared context during query compilation
* @param whereClause the final where clause expression.
*/
private static void setScanFilter(StatementContext context, FilterableStatement statement, Expression whereClause, boolean disambiguateWithFamily, boolean hashJoinOptimization) {
Scan scan = context.getScan();
if (LiteralExpression.isBooleanFalseOrNull(whereClause)) {
context.setScanRanges(ScanRanges.NOTHING);
} else if (whereClause != null && !ExpressionUtil.evaluatesToTrue(whereClause) && !hashJoinOptimization) {
Filter filter = null;
final Counter counter = new Counter();
whereClause.accept(new KeyValueExpressionVisitor() {
@Override
public Iterator<Expression> defaultIterator(Expression node) {
// Stop traversal once we've found multiple KeyValue columns
if (counter.getCount() == Counter.Count.MULTIPLE) {
return Collections.emptyIterator();
}
return super.defaultIterator(node);
}
@Override
public Void visit(KeyValueColumnExpression expression) {
counter.increment(expression);
return null;
}
});
PTable table = context.getCurrentTable().getTable();
QualifierEncodingScheme encodingScheme = table.getEncodingScheme();
ImmutableStorageScheme storageScheme = table.getImmutableStorageScheme();
Counter.Count count = counter.getCount();
boolean allCFs = false;
byte[] essentialCF = null;
if (counter.getCount() == Counter.Count.SINGLE && whereClause.requiresFinalEvaluation()) {
if (table.getViewType() == ViewType.MAPPED) {
allCFs = true;
} else {
byte[] emptyCF = SchemaUtil.getEmptyColumnFamily(table);
if (Bytes.compareTo(emptyCF, counter.getColumn().getColumnFamily()) != 0) {
essentialCF = emptyCF;
count = Counter.Count.MULTIPLE;
}
}
}
switch(count) {
case NONE:
essentialCF = table.getType() == PTableType.VIEW ? ByteUtil.EMPTY_BYTE_ARRAY : SchemaUtil.getEmptyColumnFamily(table);
filter = new RowKeyComparisonFilter(whereClause, essentialCF);
break;
case SINGLE:
filter = disambiguateWithFamily ? new SingleCFCQKeyValueComparisonFilter(whereClause) : new SingleCQKeyValueComparisonFilter(whereClause);
break;
case MULTIPLE:
filter = isPossibleToUseEncodedCQFilter(encodingScheme, storageScheme) ? new MultiEncodedCQKeyValueComparisonFilter(whereClause, encodingScheme, allCFs, essentialCF) : (disambiguateWithFamily ? new MultiCFCQKeyValueComparisonFilter(whereClause, allCFs, essentialCF) : new MultiCQKeyValueComparisonFilter(whereClause, allCFs, essentialCF));
break;
}
scan.setFilter(filter);
}
ScanRanges scanRanges = context.getScanRanges();
if (scanRanges.useSkipScanFilter()) {
ScanUtil.andFilterAtBeginning(scan, scanRanges.getSkipScanFilter());
}
}
use of org.apache.phoenix.expression.visitor.KeyValueExpressionVisitor in project phoenix by apache.
the class IndexMaintainer method initCachedState.
/**
* Init calculated state reading/creating
*/
private void initCachedState() {
byte[] emptyKvQualifier = EncodedColumnsUtil.getEmptyKeyValueInfo(encodingScheme).getFirst();
dataEmptyKeyValueRef = new ColumnReference(emptyKeyValueCFPtr.copyBytesIfNecessary(), emptyKvQualifier);
this.allColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size() + coveredColumnsMap.size());
// columns that are required to evaluate all expressions in indexedExpressions (not including columns in data row key)
this.indexedColumns = Sets.newLinkedHashSetWithExpectedSize(indexedExpressions.size());
for (Expression expression : indexedExpressions) {
KeyValueExpressionVisitor visitor = new KeyValueExpressionVisitor() {
@Override
public Void visit(KeyValueColumnExpression expression) {
if (indexedColumns.add(new ColumnReference(expression.getColumnFamily(), expression.getColumnQualifier()))) {
indexedColumnTypes.add(expression.getDataType());
}
return null;
}
};
expression.accept(visitor);
}
allColumns.addAll(indexedColumns);
for (ColumnReference colRef : coveredColumnsMap.keySet()) {
if (immutableStorageScheme == ImmutableStorageScheme.ONE_CELL_PER_COLUMN) {
allColumns.add(colRef);
} else {
allColumns.add(new ColumnReference(colRef.getFamily(), QueryConstants.SINGLE_KEYVALUE_COLUMN_QUALIFIER_BYTES));
}
}
int dataPkOffset = (isDataTableSalted ? 1 : 0) + (isMultiTenant ? 1 : 0);
int nIndexPkColumns = getIndexPkColumnCount();
dataPkPosition = new int[nIndexPkColumns];
Arrays.fill(dataPkPosition, EXPRESSION_NOT_PRESENT);
int numViewConstantColumns = 0;
BitSet viewConstantColumnBitSet = rowKeyMetaData.getViewConstantColumnBitSet();
for (int i = dataPkOffset; i < dataRowKeySchema.getFieldCount(); i++) {
if (!viewConstantColumnBitSet.get(i)) {
int indexPkPosition = rowKeyMetaData.getIndexPkPosition(i - dataPkOffset);
this.dataPkPosition[indexPkPosition] = i;
} else {
numViewConstantColumns++;
}
}
// Calculate the max number of trailing nulls that we should get rid of after building the index row key.
// We only get rid of nulls for variable length types, so we have to be careful to consider the type of the
// index table, not the data type of the data table
int expressionsPos = indexedExpressions.size();
int indexPkPos = nIndexPkColumns - numViewConstantColumns - 1;
while (indexPkPos >= 0) {
int dataPkPos = dataPkPosition[indexPkPos];
boolean isDataNullable;
PDataType dataType;
if (dataPkPos == EXPRESSION_NOT_PRESENT) {
isDataNullable = true;
dataType = indexedExpressions.get(--expressionsPos).getDataType();
} else {
Field dataField = dataRowKeySchema.getField(dataPkPos);
dataType = dataField.getDataType();
isDataNullable = dataField.isNullable();
}
PDataType indexDataType = IndexUtil.getIndexColumnDataType(isDataNullable, dataType);
if (indexDataType.isFixedWidth()) {
break;
}
indexPkPos--;
}
maxTrailingNulls = nIndexPkColumns - indexPkPos - 1;
}
Aggregations