本文整理汇总了C++中AbstractExpression::eval方法的典型用法代码示例。如果您正苦于以下问题:C++ AbstractExpression::eval方法的具体用法?C++ AbstractExpression::eval怎么用?C++ AbstractExpression::eval使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AbstractExpression
的用法示例。
在下文中一共展示了AbstractExpression::eval方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: operator
bool operator()(TableTuple ta, TableTuple tb)
{
for (size_t i = 0; i < m_keyCount; ++i)
{
AbstractExpression* k = m_keys[i];
SortDirectionType dir = m_dirs[i];
int cmp = k->eval(&ta, NULL).compare(k->eval(&tb, NULL));
if (dir == SORT_DIRECTION_TYPE_ASC)
{
if (cmp < 0) return true;
if (cmp > 0) return false;
}
else if (dir == SORT_DIRECTION_TYPE_DESC)
{
if (cmp < 0) return false;
if (cmp > 0) return true;
}
else
{
throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
"Attempted to sort using"
" SORT_DIRECTION_TYPE_INVALID");
}
}
return false; // ta == tb on these keys
}
示例2:
bool AbstractExecutor::TupleComparer::operator()(TableTuple ta, TableTuple tb) const
{
for (size_t i = 0; i < m_keyCount; ++i)
{
AbstractExpression* k = m_keys[i];
SortDirectionType dir = m_dirs[i];
int cmp = k->eval(&ta, NULL).compare(k->eval(&tb, NULL));
if (cmp < 0) return (dir == SORT_DIRECTION_TYPE_ASC);
if (cmp > 0) return (dir == SORT_DIRECTION_TYPE_DESC);
}
return false; // ta == tb on these keys
}
示例3: p_execute
bool DistinctExecutor::p_execute(const NValueArray ¶ms) {
DistinctPlanNode* node = dynamic_cast<DistinctPlanNode*>(m_abstractNode);
assert(node);
Table* output_table = node->getOutputTable();
assert(output_table);
Table* input_table = node->getInputTables()[0];
assert(input_table);
TableIterator iterator = input_table->iterator();
TableTuple tuple(input_table->schema());
// substitute params for distinct expression
AbstractExpression *distinctExpression = node->getDistinctExpression();
distinctExpression->substitute(params);
std::set<NValue, NValue::ltNValue> found_values;
while (iterator.next(tuple)) {
//
// Check whether this value already exists in our list
//
NValue tuple_value = distinctExpression->eval(&tuple, NULL);
if (found_values.find(tuple_value) == found_values.end()) {
found_values.insert(tuple_value);
if (!output_table->insertTuple(tuple)) {
VOLT_ERROR("Failed to insert tuple from input table '%s' into"
" output table '%s'",
input_table->name().c_str(),
output_table->name().c_str());
return false;
}
}
}
return true;
}
示例4: p_execute
bool MaterializedScanExecutor::p_execute(const NValueArray ¶ms) {
MaterializedScanPlanNode* node = dynamic_cast<MaterializedScanPlanNode*>(m_abstractNode);
assert(node);
// output table has one column
Table* output_table = node->getOutputTable();
TableTuple& tmptup = output_table->tempTuple();
assert(output_table);
assert ((int)output_table->columnCount() == 1);
// get the output type
const TupleSchema::ColumnInfo *columnInfo = output_table->schema()->getColumnInfo(0);
ValueType outputType = columnInfo->getVoltType();
bool outputCantBeNull = !columnInfo->allowNull;
AbstractExpression* rowsExpression = node->getTableRowsExpression();
assert(rowsExpression);
// get array nvalue
NValue arrayNValue = rowsExpression->eval();
SortDirectionType sort_direction = node->getSortDirection();
// make a set to eliminate unique values in O(nlogn) time
std::vector<NValue> sortedUniques;
// iterate over the array of values and build a sorted/deduped set of
// values that don't overflow or violate unique constaints
arrayNValue.castAndSortAndDedupArrayForInList(outputType, sortedUniques);
// insert all items in the set in order
if (sort_direction != SORT_DIRECTION_TYPE_DESC) {
std::vector<NValue>::const_iterator iter;
for (iter = sortedUniques.begin(); iter != sortedUniques.end(); iter++) {
if ((*iter).isNull() && outputCantBeNull) {
continue;
}
tmptup.setNValue(0, *iter);
output_table->insertTuple(tmptup);
}
} else {
std::vector<NValue>::reverse_iterator reverse_iter;
for (reverse_iter = sortedUniques.rbegin(); reverse_iter != sortedUniques.rend(); reverse_iter++) {
if ((*reverse_iter).isNull() && outputCantBeNull) {
continue;
}
tmptup.setNValue(0, *reverse_iter);
output_table->insertTuple(tmptup);
}
}
VOLT_TRACE("\n%s\n", output_table->debug().c_str());
VOLT_DEBUG("Finished Materializing a Table");
return true;
}
示例5: TupleValueExpression
TEST_F(FilterTest, ComplexFilter) {
// WHERE val1=1 AND val2=2 AND val3=3 AND val4=4
// shared_ptr<AbstractExpression> equal1
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(1), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(1)));
// shared_ptr<AbstractExpression> equal2
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(2), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(2)));
// shared_ptr<AbstractExpression> equal3
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(3), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(3)));
// shared_ptr<AbstractExpression> equal4
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(4), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(4)));
//
// shared_ptr<AbstractExpression> predicate3
// = ConjunctionExpression::getInstance(EXPRESSION_TYPE_CONJUNCTION_AND, equal3, equal4);
// shared_ptr<AbstractExpression> predicate2
// = ConjunctionExpression::getInstance(EXPRESSION_TYPE_CONJUNCTION_AND, equal2, predicate3);
//
// ConjunctionExpression predicate(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, predicate2);
AbstractExpression *equal1 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL,
new TupleValueExpression(1, std::string("tablename"), std::string("colname")),
constantValueFactory(ValueFactory::getBigIntValue(1)));
AbstractExpression *equal2 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL,
new TupleValueExpression(2, std::string("tablename"), std::string("colname")),
constantValueFactory(ValueFactory::getBigIntValue(2)));
AbstractExpression *equal3 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL,
new TupleValueExpression(3, std::string("tablename"), std::string("colname")),
constantValueFactory(ValueFactory::getBigIntValue(3)));
AbstractExpression *equal4 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL,
new TupleValueExpression(4, std::string("tablename"), std::string("colname")),
constantValueFactory(ValueFactory::getBigIntValue(4)));
AbstractExpression *predicate3 = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal3, equal4);
AbstractExpression *predicate2 = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal2, predicate3);
AbstractExpression *predicate = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, predicate2);
// ::printf("\nFilter:%s\n", predicate->debug().c_str());
int count = 0;
TableIterator iter = table->iterator();
TableTuple match(table->schema());
while (iter.next(match)) {
if (predicate->eval(&match, NULL).isTrue()) {
//::printf(" match:%s\n", match->debug(table).c_str());
++count;
}
}
ASSERT_EQ(5, count);
delete predicate;
}
示例6: params
TEST_F(FilterTest, SubstituteFilter) {
// WHERE id <= 20 AND val4=$1
// shared_ptr<AbstractExpression> equal1
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO, TupleValueExpression::getInstance(0), ConstantValueExpression::getInstance(voltdb::Value::newBigIntValue(20)));
//
// shared_ptr<AbstractExpression> equal2
// = ComparisonExpression::getInstance(EXPRESSION_TYPE_COMPARE_EQUAL, TupleValueExpression::getInstance(4), ParameterValueExpression::getInstance(0));
//
// ConjunctionExpression predicate(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, equal2);
AbstractExpression *tv1 = new TupleValueExpression(0, std::string("tablename"), std::string("colname"));
AbstractExpression *cv1 = constantValueFactory(ValueFactory::getBigIntValue(20));
AbstractExpression *equal1 = comparisonFactory(EXPRESSION_TYPE_COMPARE_LESSTHANOREQUALTO, tv1, cv1);
AbstractExpression *tv2 = new TupleValueExpression(4, std::string("tablename"), std::string("colname"));
AbstractExpression *pv2 = parameterValueFactory(0);
AbstractExpression *equal2 = comparisonFactory(EXPRESSION_TYPE_COMPARE_EQUAL, tv2, pv2);
AbstractExpression *predicate = conjunctionFactory(EXPRESSION_TYPE_CONJUNCTION_AND, equal1, equal2);
// ::printf("\nFilter:%s\n", predicate->debug().c_str());
for (int64_t implantedValue = 1; implantedValue < 5; ++implantedValue) {
NValueArray params(1);
params[0] = ValueFactory::getBigIntValue(implantedValue);
predicate->substitute(params);
// ::printf("\nSubstituted Filter:%s\n", predicate->debug().c_str());
// ::printf("\tLEFT: %s\n", predicate->getLeft()->debug().c_str());
// ::printf("\tRIGHT: %s\n", predicate->getRight()->debug().c_str());
int count = 0;
TableIterator iter = table->iterator();
TableTuple match(table->schema());
while (iter.next(match)) {
if (predicate->eval(&match, NULL).isTrue()) {
++count;
}
}
ASSERT_EQ(3, count);
}
delete predicate;
}
示例7: insertOutputTuple
/*
*
* Helper method responsible for inserting the results of the
* aggregation into a new tuple in the output table as well as passing
* through any additional columns from the input table.
*/
inline void WindowFunctionExecutor::insertOutputTuple()
{
TableTuple& tempTuple = m_tmpOutputTable->tempTuple();
// We copy the aggregate values into the output tuple,
// then the passthrough columns.
WindowAggregate** aggs = m_aggregateRow->getAggregates();
for (int ii = 0; ii < getAggregateCount(); ii++) {
NValue result = aggs[ii]->finalize(tempTuple.getSchema()->columnType(ii));
tempTuple.setNValue(ii, result);
}
VOLT_TRACE("Setting passthrough columns");
size_t tupleSize = tempTuple.sizeInValues();
for (int ii = getAggregateCount(); ii < tupleSize; ii += 1) {
AbstractExpression *expr = m_outputColumnExpressions[ii];
tempTuple.setNValue(ii, expr->eval(&(m_aggregateRow->getPassThroughTuple())));
}
m_tmpOutputTable->insertTempTuple(tempTuple);
VOLT_TRACE("output_table:\n%s", m_tmpOutputTable->debug().c_str());
}
示例8: p_execute
bool SeqScanExecutor::p_execute(const NValueArray ¶ms) {
SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
assert(node);
Table* output_table = node->getOutputTable();
assert(output_table);
Table* input_table = (node->isSubQuery()) ?
node->getChildren()[0]->getOutputTable():
node->getTargetTable();
assert(input_table);
//* for debug */std::cout << "SeqScanExecutor: node id " << node->getPlanNodeId() <<
//* for debug */ " input table " << (void*)input_table <<
//* for debug */ " has " << input_table->activeTupleCount() << " tuples " << std::endl;
VOLT_TRACE("Sequential Scanning table :\n %s",
input_table->debug().c_str());
VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
" allocated",
input_table->name().c_str(),
(int)input_table->activeTupleCount(),
(int)input_table->allocatedTupleCount());
//
// OPTIMIZATION: NESTED PROJECTION
//
// Since we have the input params, we need to call substitute to
// change any nodes in our expression tree to be ready for the
// projection operations in execute
//
int num_of_columns = -1;
ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
if (projection_node != NULL) {
num_of_columns = static_cast<int> (projection_node->getOutputColumnExpressions().size());
}
//
// OPTIMIZATION: NESTED LIMIT
// How nice! We can also cut off our scanning with a nested limit!
//
LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
//
// OPTIMIZATION:
//
// If there is no predicate and no Projection for this SeqScan,
// then we have already set the node's OutputTable to just point
// at the TargetTable. Therefore, there is nothing we more we need
// to do here
//
if (node->getPredicate() != NULL || projection_node != NULL ||
limit_node != NULL || m_aggExec != NULL)
{
//
// Just walk through the table using our iterator and apply
// the predicate to each tuple. For each tuple that satisfies
// our expression, we'll insert them into the output table.
//
TableTuple tuple(input_table->schema());
TableIterator iterator = input_table->iteratorDeletingAsWeGo();
AbstractExpression *predicate = node->getPredicate();
if (predicate)
{
VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
}
int limit = -1;
int offset = -1;
if (limit_node) {
limit_node->getLimitAndOffsetByReference(params, limit, offset);
}
int tuple_ctr = 0;
int tuple_skipped = 0;
TempTable* output_temp_table = dynamic_cast<TempTable*>(output_table);
ProgressMonitorProxy pmp(m_engine, this, node->isSubQuery() ? NULL : input_table);
TableTuple temp_tuple;
if (m_aggExec != NULL) {
const TupleSchema * inputSchema = input_table->schema();
if (projection_node != NULL) {
inputSchema = projection_node->getOutputTable()->schema();
}
temp_tuple = m_aggExec->p_execute_init(params, &pmp,
inputSchema, output_temp_table);
} else {
temp_tuple = output_temp_table->tempTuple();
}
while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
{
VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
tuple.debug(input_table->name()).c_str(), tuple_ctr,
(int)input_table->activeTupleCount());
pmp.countdownProgress();
//
// For each tuple we need to evaluate it against our predicate
//
if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
{
//.........这里部分代码省略.........
示例9: p_execute
bool IndexScanExecutor::p_execute(const NValueArray ¶ms)
{
assert(m_node);
assert(m_node == dynamic_cast<IndexScanPlanNode*>(m_abstractNode));
// update local target table with its most recent reference
Table* targetTable = m_node->getTargetTable();
TableIndex *tableIndex = targetTable->index(m_node->getTargetIndexName());
IndexCursor indexCursor(tableIndex->getTupleSchema());
TableTuple searchKey(tableIndex->getKeySchema());
searchKey.moveNoHeader(m_searchKeyBackingStore);
assert(m_lookupType != INDEX_LOOKUP_TYPE_EQ ||
searchKey.getSchema()->columnCount() == m_numOfSearchkeys);
int activeNumOfSearchKeys = m_numOfSearchkeys;
IndexLookupType localLookupType = m_lookupType;
SortDirectionType localSortDirection = m_sortDirection;
//
// INLINE LIMIT
//
LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(m_abstractNode->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
TableTuple temp_tuple;
ProgressMonitorProxy pmp(m_engine, this);
if (m_aggExec != NULL) {
const TupleSchema * inputSchema = tableIndex->getTupleSchema();
if (m_projectionNode != NULL) {
inputSchema = m_projectionNode->getOutputTable()->schema();
}
temp_tuple = m_aggExec->p_execute_init(params, &pmp, inputSchema, m_outputTable);
} else {
temp_tuple = m_outputTable->tempTuple();
}
// Short-circuit an empty scan
if (m_node->isEmptyScan()) {
VOLT_DEBUG ("Empty Index Scan :\n %s", m_outputTable->debug().c_str());
if (m_aggExec != NULL) {
m_aggExec->p_execute_finish();
}
return true;
}
//
// SEARCH KEY
//
bool earlyReturnForSearchKeyOutOfRange = false;
searchKey.setAllNulls();
VOLT_TRACE("Initial (all null) search key: '%s'", searchKey.debugNoHeader().c_str());
for (int ctr = 0; ctr < activeNumOfSearchKeys; ctr++) {
NValue candidateValue = m_searchKeyArray[ctr]->eval(NULL, NULL);
if (candidateValue.isNull()) {
// when any part of the search key is NULL, the result is false when it compares to anything.
// do early return optimization, our index comparator may not handle null comparison correctly.
earlyReturnForSearchKeyOutOfRange = true;
break;
}
try {
searchKey.setNValue(ctr, candidateValue);
}
catch (const SQLException &e) {
// This next bit of logic handles underflow, overflow and search key length
// exceeding variable length column size (variable lenght mismatch) when
// setting up the search keys.
// e.g. TINYINT > 200 or INT <= 6000000000
// VarChar(3 bytes) < "abcd" or VarChar(3) > "abbd"
// re-throw if not an overflow, underflow or variable length mismatch
// currently, it's expected to always be an overflow or underflow
if ((e.getInternalFlags() & (SQLException::TYPE_OVERFLOW | SQLException::TYPE_UNDERFLOW | SQLException::TYPE_VAR_LENGTH_MISMATCH)) == 0) {
throw e;
}
// handle the case where this is a comparison, rather than equality match
// comparison is the only place where the executor might return matching tuples
// e.g. TINYINT < 1000 should return all values
if ((localLookupType != INDEX_LOOKUP_TYPE_EQ) &&
(ctr == (activeNumOfSearchKeys - 1))) {
if (e.getInternalFlags() & SQLException::TYPE_OVERFLOW) {
if ((localLookupType == INDEX_LOOKUP_TYPE_GT) ||
(localLookupType == INDEX_LOOKUP_TYPE_GTE)) {
// gt or gte when key overflows returns nothing except inline agg
earlyReturnForSearchKeyOutOfRange = true;
break;
}
else {
// for overflow on reverse scan, we need to
// do a forward scan to find the correct start
// point, which is exactly what LTE would do.
// so, set the lookupType to LTE and the missing
// searchkey will be handled by extra post filters
localLookupType = INDEX_LOOKUP_TYPE_LTE;
//.........这里部分代码省略.........
示例10: p_execute
bool SeqScanExecutor::p_execute(const NValueArray ¶ms) {
SeqScanPlanNode* node = dynamic_cast<SeqScanPlanNode*>(m_abstractNode);
assert(node);
Table* output_table = node->getOutputTable();
assert(output_table);
Table* target_table = dynamic_cast<Table*>(node->getTargetTable());
assert(target_table);
//cout << "SeqScanExecutor: node id" << node->getPlanNodeId() << endl;
VOLT_TRACE("Sequential Scanning table :\n %s",
target_table->debug().c_str());
VOLT_DEBUG("Sequential Scanning table : %s which has %d active, %d"
" allocated, %d used tuples",
target_table->name().c_str(),
(int)target_table->activeTupleCount(),
(int)target_table->allocatedTupleCount(),
(int)target_table->usedTupleCount());
//
// OPTIMIZATION: NESTED PROJECTION
//
// Since we have the input params, we need to call substitute to
// change any nodes in our expression tree to be ready for the
// projection operations in execute
//
int num_of_columns = (int)output_table->columnCount();
ProjectionPlanNode* projection_node = dynamic_cast<ProjectionPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_PROJECTION));
if (projection_node != NULL) {
for (int ctr = 0; ctr < num_of_columns; ctr++) {
assert(projection_node->getOutputColumnExpressions()[ctr]);
projection_node->getOutputColumnExpressions()[ctr]->substitute(params);
}
}
//
// OPTIMIZATION: NESTED LIMIT
// How nice! We can also cut off our scanning with a nested limit!
//
int limit = -1;
int offset = -1;
LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
if (limit_node != NULL) {
limit_node->getLimitAndOffsetByReference(params, limit, offset);
}
//
// OPTIMIZATION:
//
// If there is no predicate and no Projection for this SeqScan,
// then we have already set the node's OutputTable to just point
// at the TargetTable. Therefore, there is nothing we more we need
// to do here
//
if (node->getPredicate() != NULL || projection_node != NULL ||
limit_node != NULL)
{
//
// Just walk through the table using our iterator and apply
// the predicate to each tuple. For each tuple that satisfies
// our expression, we'll insert them into the output table.
//
TableTuple tuple(target_table->schema());
TableIterator iterator = target_table->iterator();
AbstractExpression *predicate = node->getPredicate();
VOLT_TRACE("SCAN PREDICATE A:\n%s\n", predicate->debug(true).c_str());
if (predicate)
{
predicate->substitute(params);
assert(predicate != NULL);
VOLT_DEBUG("SCAN PREDICATE B:\n%s\n",
predicate->debug(true).c_str());
}
int tuple_ctr = 0;
int tuple_skipped = 0;
while (iterator.next(tuple))
{
VOLT_TRACE("INPUT TUPLE: %s, %d/%d\n",
tuple.debug(target_table->name()).c_str(), tuple_ctr,
(int)target_table->activeTupleCount());
//
// For each tuple we need to evaluate it against our predicate
//
if (predicate == NULL || predicate->eval(&tuple, NULL).isTrue())
{
// Check if we have to skip this tuple because of offset
if (tuple_skipped < offset) {
tuple_skipped++;
continue;
}
//
// Nested Projection
// Project (or replace) values from input tuple
//
if (projection_node != NULL)
{
TableTuple &temp_tuple = output_table->tempTuple();
for (int ctr = 0; ctr < num_of_columns; ctr++)
{
//.........这里部分代码省略.........
示例11: p_execute
bool IndexScanExecutor::p_execute(const NValueArray ¶ms)
{
assert(m_node);
assert(m_node == dynamic_cast<IndexScanPlanNode*>(m_abstractNode));
assert(m_outputTable);
assert(m_outputTable == static_cast<TempTable*>(m_node->getOutputTable()));
// update local target table with its most recent reference
Table* targetTable = m_node->getTargetTable();
TableIndex *tableIndex = targetTable->index(m_node->getTargetIndexName());
TableTuple searchKey(tableIndex->getKeySchema());
searchKey.moveNoHeader(m_searchKeyBackingStore);
assert(m_lookupType != INDEX_LOOKUP_TYPE_EQ ||
searchKey.getSchema()->columnCount() == m_numOfSearchkeys);
int activeNumOfSearchKeys = m_numOfSearchkeys;
IndexLookupType localLookupType = m_lookupType;
SortDirectionType localSortDirection = m_sortDirection;
// INLINE PROJECTION
// Set params to expression tree via substitute()
assert(m_numOfColumns == m_outputTable->columnCount());
if (m_projectionNode != NULL && m_projectionAllTupleArray == NULL)
{
for (int ctr = 0; ctr < m_numOfColumns; ctr++)
{
assert(m_projectionNode->getOutputColumnExpressions()[ctr]);
m_projectionExpressions[ctr]->substitute(params);
assert(m_projectionExpressions[ctr]);
}
}
//
// INLINE LIMIT
//
LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(m_abstractNode->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
//
// SEARCH KEY
//
searchKey.setAllNulls();
VOLT_TRACE("Initial (all null) search key: '%s'", searchKey.debugNoHeader().c_str());
for (int ctr = 0; ctr < activeNumOfSearchKeys; ctr++) {
m_searchKeyArray[ctr]->substitute(params);
NValue candidateValue = m_searchKeyArray[ctr]->eval(NULL, NULL);
try {
searchKey.setNValue(ctr, candidateValue);
}
catch (const SQLException &e) {
// This next bit of logic handles underflow and overflow while
// setting up the search keys.
// e.g. TINYINT > 200 or INT <= 6000000000
// re-throw if not an overflow or underflow
// currently, it's expected to always be an overflow or underflow
if ((e.getInternalFlags() & (SQLException::TYPE_OVERFLOW | SQLException::TYPE_UNDERFLOW)) == 0) {
throw e;
}
// handle the case where this is a comparison, rather than equality match
// comparison is the only place where the executor might return matching tuples
// e.g. TINYINT < 1000 should return all values
if ((localLookupType != INDEX_LOOKUP_TYPE_EQ) &&
(ctr == (activeNumOfSearchKeys - 1))) {
if (e.getInternalFlags() & SQLException::TYPE_OVERFLOW) {
if ((localLookupType == INDEX_LOOKUP_TYPE_GT) ||
(localLookupType == INDEX_LOOKUP_TYPE_GTE)) {
// gt or gte when key overflows returns nothing
return true;
}
else {
// for overflow on reverse scan, we need to
// do a forward scan to find the correct start
// point, which is exactly what LTE would do.
// so, set the lookupType to LTE and the missing
// searchkey will be handled by extra post filters
localLookupType = INDEX_LOOKUP_TYPE_LTE;
}
}
if (e.getInternalFlags() & SQLException::TYPE_UNDERFLOW) {
if ((localLookupType == INDEX_LOOKUP_TYPE_LT) ||
(localLookupType == INDEX_LOOKUP_TYPE_LTE)) {
// lt or lte when key underflows returns nothing
return true;
}
else {
// don't allow GTE because it breaks null handling
localLookupType = INDEX_LOOKUP_TYPE_GT;
}
}
// if here, means all tuples with the previous searchkey
// columns need to be scaned. Note, if only one column,
// then all tuples will be scanned
activeNumOfSearchKeys--;
if (localSortDirection == SORT_DIRECTION_TYPE_INVALID) {
//.........这里部分代码省略.........
示例12: p_execute
bool NestLoopExecutor::p_execute(const NValueArray ¶ms) {
VOLT_DEBUG("executing NestLoop...");
NestLoopPlanNode* node = dynamic_cast<NestLoopPlanNode*>(m_abstractNode);
assert(node);
assert(node->getInputTables().size() == 2);
Table* output_table_ptr = node->getOutputTable();
assert(output_table_ptr);
// output table must be a temp table
TempTable* output_table = dynamic_cast<TempTable*>(output_table_ptr);
assert(output_table);
Table* outer_table = node->getInputTables()[0];
assert(outer_table);
Table* inner_table = node->getInputTables()[1];
assert(inner_table);
VOLT_TRACE ("input table left:\n %s", outer_table->debug().c_str());
VOLT_TRACE ("input table right:\n %s", inner_table->debug().c_str());
//
// Pre Join Expression
//
AbstractExpression *preJoinPredicate = node->getPreJoinPredicate();
if (preJoinPredicate) {
preJoinPredicate->substitute(params);
VOLT_TRACE ("Pre Join predicate: %s", preJoinPredicate == NULL ?
"NULL" : preJoinPredicate->debug(true).c_str());
}
//
// Join Expression
//
AbstractExpression *joinPredicate = node->getJoinPredicate();
if (joinPredicate) {
joinPredicate->substitute(params);
VOLT_TRACE ("Join predicate: %s", joinPredicate == NULL ?
"NULL" : joinPredicate->debug(true).c_str());
}
//
// Where Expression
//
AbstractExpression *wherePredicate = node->getWherePredicate();
if (wherePredicate) {
wherePredicate->substitute(params);
VOLT_TRACE ("Where predicate: %s", wherePredicate == NULL ?
"NULL" : wherePredicate->debug(true).c_str());
}
// Join type
JoinType join_type = node->getJoinType();
assert(join_type == JOIN_TYPE_INNER || join_type == JOIN_TYPE_LEFT);
int outer_cols = outer_table->columnCount();
int inner_cols = inner_table->columnCount();
TableTuple outer_tuple(node->getInputTables()[0]->schema());
TableTuple inner_tuple(node->getInputTables()[1]->schema());
TableTuple &joined = output_table->tempTuple();
TableTuple null_tuple = m_null_tuple;
TableIterator iterator0 = outer_table->iterator();
while (iterator0.next(outer_tuple)) {
// did this loop body find at least one match for this tuple?
bool match = false;
// For outer joins if outer tuple fails pre-join predicate
// (join expression based on the outer table only)
// it can't match any of inner tuples
if (preJoinPredicate == NULL || preJoinPredicate->eval(&outer_tuple, NULL).isTrue()) {
// populate output table's temp tuple with outer table's values
// probably have to do this at least once - avoid doing it many
// times per outer tuple
joined.setNValues(0, outer_tuple, 0, outer_cols);
TableIterator iterator1 = inner_table->iterator();
while (iterator1.next(inner_tuple)) {
// Apply join filter to produce matches for each outer that has them,
// then pad unmatched outers, then filter them all
if (joinPredicate == NULL || joinPredicate->eval(&outer_tuple, &inner_tuple).isTrue()) {
match = true;
// Filter the joined tuple
if (wherePredicate == NULL || wherePredicate->eval(&outer_tuple, &inner_tuple).isTrue()) {
// Matched! Complete the joined tuple with the inner column values.
joined.setNValues(outer_cols, inner_tuple, 0, inner_cols);
output_table->insertTupleNonVirtual(joined);
}
}
}
}
//
// Left Outer Join
//
if (join_type == JOIN_TYPE_LEFT && !match) {
// Still needs to pass the filter
if (wherePredicate == NULL || wherePredicate->eval(&outer_tuple, &null_tuple).isTrue()) {
joined.setNValues(outer_cols, null_tuple, 0, inner_cols);
output_table->insertTupleNonVirtual(joined);
//.........这里部分代码省略.........
示例13: p_execute
bool NestLoopExecutor::p_execute(const NValueArray ¶ms, ReadWriteTracker *tracker) {
VOLT_DEBUG("executing NestLoop...");
NestLoopPlanNode* node = dynamic_cast<NestLoopPlanNode*>(abstract_node);
assert(node);
assert(node->getInputTables().size() == 2);
Table* output_table_ptr = node->getOutputTable();
assert(output_table_ptr);
// output table must be a temp table
TempTable* output_table = dynamic_cast<TempTable*>(output_table_ptr);
assert(output_table);
Table* outer_table = node->getInputTables()[0];
assert(outer_table);
Table* inner_table = node->getInputTables()[1];
assert(inner_table);
VOLT_TRACE ("input table left:\n %s", outer_table->debug().c_str());
VOLT_TRACE ("input table right:\n %s", inner_table->debug().c_str());
//
// Join Expression
//
AbstractExpression *predicate = node->getPredicate();
if (predicate) {
predicate->substitute(params);
VOLT_TRACE ("predicate: %s", predicate == NULL ?
"NULL" : predicate->debug(true).c_str());
}
int outer_cols = outer_table->columnCount();
int inner_cols = inner_table->columnCount();
TableTuple outer_tuple(node->getInputTables()[0]->schema());
TableTuple inner_tuple(node->getInputTables()[1]->schema());
TableTuple &joined = output_table->tempTuple();
TableIterator iterator0(outer_table);
while (iterator0.next(outer_tuple)) {
// populate output table's temp tuple with outer table's values
// probably have to do this at least once - avoid doing it many
// times per outer tuple
for (int col_ctr = 0; col_ctr < outer_cols; col_ctr++) {
joined.setNValue(col_ctr, outer_tuple.getNValue(col_ctr));
}
TableIterator iterator1(inner_table);
while (iterator1.next(inner_tuple)) {
if (predicate == NULL || predicate->eval(&outer_tuple, &inner_tuple).isTrue()) {
// Matched! Complete the joined tuple with the inner column values.
for (int col_ctr = 0; col_ctr < inner_cols; col_ctr++) {
joined.setNValue(col_ctr + outer_cols, inner_tuple.getNValue(col_ctr));
}
output_table->insertTupleNonVirtual(joined);
}
}
}
return (true);
}
示例14: p_execute
bool NestLoopExecutor::p_execute(const NValueArray ¶ms) {
VOLT_DEBUG("executing NestLoop...");
NestLoopPlanNode* node = dynamic_cast<NestLoopPlanNode*>(m_abstractNode);
assert(node);
assert(node->getInputTableCount() == 2);
// output table must be a temp table
assert(m_tmpOutputTable);
Table* outer_table = node->getInputTable();
assert(outer_table);
Table* inner_table = node->getInputTable(1);
assert(inner_table);
VOLT_TRACE ("input table left:\n %s", outer_table->debug().c_str());
VOLT_TRACE ("input table right:\n %s", inner_table->debug().c_str());
//
// Pre Join Expression
//
AbstractExpression *preJoinPredicate = node->getPreJoinPredicate();
if (preJoinPredicate) {
VOLT_TRACE ("Pre Join predicate: %s", preJoinPredicate == NULL ?
"NULL" : preJoinPredicate->debug(true).c_str());
}
//
// Join Expression
//
AbstractExpression *joinPredicate = node->getJoinPredicate();
if (joinPredicate) {
VOLT_TRACE ("Join predicate: %s", joinPredicate == NULL ?
"NULL" : joinPredicate->debug(true).c_str());
}
//
// Where Expression
//
AbstractExpression *wherePredicate = node->getWherePredicate();
if (wherePredicate) {
VOLT_TRACE ("Where predicate: %s", wherePredicate == NULL ?
"NULL" : wherePredicate->debug(true).c_str());
}
// Join type
JoinType join_type = node->getJoinType();
assert(join_type == JOIN_TYPE_INNER || join_type == JOIN_TYPE_LEFT);
LimitPlanNode* limit_node = dynamic_cast<LimitPlanNode*>(node->getInlinePlanNode(PLAN_NODE_TYPE_LIMIT));
int limit = -1;
int offset = -1;
if (limit_node) {
limit_node->getLimitAndOffsetByReference(params, limit, offset);
}
int outer_cols = outer_table->columnCount();
int inner_cols = inner_table->columnCount();
TableTuple outer_tuple(node->getInputTable(0)->schema());
TableTuple inner_tuple(node->getInputTable(1)->schema());
const TableTuple& null_tuple = m_null_tuple.tuple();
TableIterator iterator0 = outer_table->iteratorDeletingAsWeGo();
int tuple_ctr = 0;
int tuple_skipped = 0;
ProgressMonitorProxy pmp(m_engine, this, inner_table);
TableTuple join_tuple;
if (m_aggExec != NULL) {
VOLT_TRACE("Init inline aggregate...");
const TupleSchema * aggInputSchema = node->getTupleSchemaPreAgg();
join_tuple = m_aggExec->p_execute_init(params, &pmp, aggInputSchema, m_tmpOutputTable);
} else {
join_tuple = m_tmpOutputTable->tempTuple();
}
bool earlyReturned = false;
while ((limit == -1 || tuple_ctr < limit) && iterator0.next(outer_tuple)) {
pmp.countdownProgress();
// populate output table's temp tuple with outer table's values
// probably have to do this at least once - avoid doing it many
// times per outer tuple
join_tuple.setNValues(0, outer_tuple, 0, outer_cols);
// did this loop body find at least one match for this tuple?
bool match = false;
// For outer joins if outer tuple fails pre-join predicate
// (join expression based on the outer table only)
// it can't match any of inner tuples
if (preJoinPredicate == NULL || preJoinPredicate->eval(&outer_tuple, NULL).isTrue()) {
// By default, the delete as we go flag is false.
TableIterator iterator1 = inner_table->iterator();
while ((limit == -1 || tuple_ctr < limit) && iterator1.next(inner_tuple)) {
pmp.countdownProgress();
// Apply join filter to produce matches for each outer that has them,
// then pad unmatched outers, then filter them all
if (joinPredicate == NULL || joinPredicate->eval(&outer_tuple, &inner_tuple).isTrue()) {
match = true;
// Filter the joined tuple
//.........这里部分代码省略.........
示例15: p_execute
//.........这里部分代码省略.........
// The join_tuple is the tuple that contains the values that we
// actually want to put in the output of the join (or to aggregate
// if there is an inlined agg plan node). This tuple needs to
// omit the unused columns from the inner table. The inlined
// index scan itself has an inlined project node that defines the
// columns that should be output by the join, and omits those that
// are not needed. So the join_tuple contains the columns we're
// using from the outer table, followed by the "projected" schema
// for the inlined scan of the inner table.
if (m_aggExec != NULL) {
VOLT_TRACE("Init inline aggregate...");
const TupleSchema * aggInputSchema = node->getTupleSchemaPreAgg();
join_tuple = m_aggExec->p_execute_init(params, &pmp, aggInputSchema, m_tmpOutputTable, &postfilter);
}
else {
join_tuple = m_tmpOutputTable->tempTuple();
}
VOLT_TRACE("<num_of_outer_cols>: %d\n", num_of_outer_cols);
while (postfilter.isUnderLimit() && outer_iterator.next(outer_tuple)) {
VOLT_TRACE("outer_tuple:%s",
outer_tuple.debug(outer_table->name()).c_str());
pmp.countdownProgress();
// Set the join tuple columns that originate solely from the outer tuple.
// Must be outside the inner loop in case of the empty inner table.
join_tuple.setNValues(0, outer_tuple, 0, num_of_outer_cols);
// did this loop body find at least one match for this tuple?
bool outerMatch = false;
// For outer joins if outer tuple fails pre-join predicate
// (join expression based on the outer table only)
// it can't match any of inner tuples
if (prejoin_expression == NULL || prejoin_expression->eval(&outer_tuple, NULL).isTrue()) {
int activeNumOfSearchKeys = num_of_searchkeys;
VOLT_TRACE ("<Nested Loop Index exec, WHILE-LOOP...> Number of searchKeys: %d \n", num_of_searchkeys);
IndexLookupType localLookupType = m_lookupType;
SortDirectionType localSortDirection = m_sortDirection;
VOLT_TRACE("Lookup type: %d\n", m_lookupType);
VOLT_TRACE("SortDirectionType: %d\n", m_sortDirection);
// did setting the search key fail (usually due to overflow)
bool keyException = false;
//
// Now use the outer table tuple to construct the search key
// against the inner table
//
const TableTuple& index_values = m_indexValues.tuple();
index_values.setAllNulls();
for (int ctr = 0; ctr < activeNumOfSearchKeys; ctr++) {
// in a normal index scan, params would be substituted here,
// but this scan fills in params outside the loop
NValue candidateValue = m_indexNode->getSearchKeyExpressions()[ctr]->eval(&outer_tuple, NULL);
if (candidateValue.isNull()) {
// when any part of the search key is NULL, the result is false when it compares to anything.
// do early return optimization, our index comparator may not handle null comparison correctly.
keyException = true;
break;
}
try {
index_values.setNValue(ctr, candidateValue);
}
catch (const SQLException &e) {
// This next bit of logic handles underflow and overflow while
// setting up the search keys.
// e.g. TINYINT > 200 or INT <= 6000000000