int WindowFunctionExecutor::compareTuples(const TableTuple &tuple1, const TableTuple &tuple2) const { const TupleSchema *schema = tuple1.getSchema(); assert (schema == tuple2.getSchema()); for (int ii = schema->columnCount() - 1; ii >= 0; --ii) { int cmp = tuple2.getNValue(ii) .compare(tuple1.getNValue(ii)); if (cmp != 0) { return cmp; } } return 0; }
bool TableIndex::replaceEntryNoKeyChange(const TableTuple &destinationTuple, const TableTuple &originalTuple) { assert(originalTuple.address() != destinationTuple.address()); if (isPartialIndex()) { const AbstractExpression* predicate = getPredicate(); if (!predicate->eval(&destinationTuple, NULL).isTrue() && !predicate->eval(&originalTuple, NULL).isTrue()) { // both tuples fail the predicate. Nothing to do. Return TRUE return true; } else if (predicate->eval(&destinationTuple, NULL).isTrue() && !predicate->eval(&originalTuple, NULL).isTrue()) { // The original tuple fails the predicate meaning the tuple is not indexed. // Simply add the new tuple TableTuple conflict(destinationTuple.getSchema()); addEntryDo(&destinationTuple, &conflict); return conflict.isNullTuple(); } else if (!predicate->eval(&destinationTuple, NULL).isTrue() && predicate->eval(&originalTuple, NULL).isTrue()) { // The destination tuple fails the predicate. Simply delete the original tuple return deleteEntryDo(&originalTuple); } else { // both tuples pass the predicate. assert(predicate->eval(&destinationTuple, NULL).isTrue() && predicate->eval(&originalTuple, NULL).isTrue()); return replaceEntryNoKeyChangeDo(destinationTuple, originalTuple); } } else { return replaceEntryNoKeyChangeDo(destinationTuple, originalTuple); } }
NValue compare_tuple(const TableTuple& tuple1, const TableTuple& tuple2) { assert(tuple1.getSchema()->columnCount() == tuple2.getSchema()->columnCount()); NValue fallback_result = OP::includes_equality() ? NValue::getTrue() : NValue::getFalse(); int schemaSize = tuple1.getSchema()->columnCount(); for (int columnIdx = 0; columnIdx < schemaSize; ++columnIdx) { NValue value1 = tuple1.getNValue(columnIdx); if (value1.isNull()) { fallback_result = NValue::getNullValue(VALUE_TYPE_BOOLEAN); if (OP::implies_null_for_row()) { return fallback_result; } continue; } NValue value2 = tuple2.getNValue(columnIdx); if (value2.isNull()) { fallback_result = NValue::getNullValue(VALUE_TYPE_BOOLEAN); if (OP::implies_null_for_row()) { return fallback_result; } continue; } if (OP::compare_withoutNull(value1, tuple2.getNValue(columnIdx)).isTrue()) { if (OP::implies_true_for_row(value1, value2)) { // allow early return on strict inequality return NValue::getTrue(); } } else { if (OP::implies_false_for_row(value1, value2)) { // allow early return on strict inequality return NValue::getFalse(); } } } // The only cases that have not already short-circuited involve all equal columns. // Each op either includes or excludes that particular case. return fallback_result; }
NValue compare(const TableTuple& tuple) const { assert(tuple.getSchema()->columnCount() == 1); return compare<OP>(tuple.getNValue(0)); }