/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.qp.storeadapter.indexcursor; import com.foundationdb.ais.model.Column; import com.foundationdb.server.types.value.ValueRecord; import com.foundationdb.qp.operator.API; import com.foundationdb.qp.operator.QueryContext; import com.foundationdb.qp.row.Row; import com.foundationdb.server.PersistitKeyValueSource; import com.foundationdb.server.PersistitKeyValueTarget; import com.foundationdb.server.collation.AkCollator; import com.foundationdb.server.types.TClass; import com.foundationdb.server.types.TInstance; import com.foundationdb.server.types.value.ValueSource; import com.foundationdb.server.types.texpressions.Comparison; import com.foundationdb.server.types.texpressions.TComparisonExpression; import com.foundationdb.server.types.texpressions.TEvaluatableExpression; import com.foundationdb.server.types.texpressions.TPreparedExpression; import com.foundationdb.server.types.texpressions.TPreparedLiteral; import com.persistit.Key; public class ValueSortKeyAdapter extends SortKeyAdapter<ValueSource, TPreparedExpression> { private ValueSortKeyAdapter() {} public static final SortKeyAdapter<ValueSource, TPreparedExpression> INSTANCE = new ValueSortKeyAdapter(); @Override public TInstance[] createTInstances(int size) { return new TInstance[size]; } @Override public void setColumnMetadata(Column column, int f, TInstance[] tInstances) { tInstances[f] = column.getType(); } @Override public void checkConstraints(ValueRecord loExpressions, ValueRecord hiExpressions, int f, AkCollator[] collators, TInstance[] types) { ValueSource loValueSource = loExpressions.value(f); ValueSource hiValueSource = hiExpressions.value(f); if (!TClass.areEqual(loValueSource, hiValueSource)) { throw new IllegalArgumentException(String.format("lo: %s <> hi: %s", loValueSource, hiValueSource)); } } @Override public ValueSource[] createSourceArray(int size) { return new ValueSource[size]; } @Override public ValueSource get(ValueRecord valueRecord, int f) { return valueRecord.value(f); } @Override public SortKeyTarget<ValueSource> createTarget(Object descForError) { return new ValueSortKeyTarget(descForError); } @Override public boolean isNull(ValueSource source) { return source.isNull(); } @Override public SortKeySource<ValueSource> createSource(TInstance type) { return new ValueSortKeySource(type); } @Override public long compare(TInstance type, ValueSource one, ValueSource two) { return TClass.compare(type, one, type, two); } @Override public TPreparedExpression createComparison(TInstance type, ValueSource one, Comparison comparison, ValueSource two) { TPreparedExpression arg1 = new TPreparedLiteral(type, one); TPreparedExpression arg2 = new TPreparedLiteral(type, two); return new TComparisonExpression(arg1, comparison, arg2); } @Override public boolean evaluateComparison(TPreparedExpression comparison, QueryContext queryContext) { TEvaluatableExpression eval = comparison.build(); eval.evaluate(); return eval.resultValue().getBoolean(); } @Override public ValueSource eval(Row row, int field) { return row.value(field); } @Override public void setOrderingMetadata(API.Ordering ordering, int index, TInstance[] tInstances) { tInstances[index] = ordering.type(index); } private static class ValueSortKeyTarget implements SortKeyTarget<ValueSource> { public ValueSortKeyTarget(Object descForError) { this.target = new PersistitKeyValueTarget(descForError); } @Override public void attach(Key key) { target.attach(key); } @Override public void append(ValueSource source, int f, TInstance[] tInstances) { append(source, tInstances[f]); } @Override public void append(ValueSource source, TInstance type) { if (source.isNull()) { target.putNull(); } else { type.writeCollating(source, target); } } protected final PersistitKeyValueTarget target; } private static class ValueSortKeySource implements SortKeySource<ValueSource> { @Override public void attach(Key key, int i, TInstance type) { source.attach(key, i, type); } @Override public ValueSource asSource() { return source; } public ValueSortKeySource(TInstance type) { source = new PersistitKeyValueSource(type); } private final PersistitKeyValueSource source; } }