/** * Parse and save predicates. */ void ElasticContext::updatePredicates(const std::vector<std::string> &predicateStrings) { //If there is already a predicate and thus presumably an index, make sure the request is a subset of what exists //That should always be the case, but wrong answers will follow if we are wrong if (m_predicates.size() > 0 && dynamic_cast<HashRangeExpression*>(&m_predicates[0]) != NULL && predicateStrings.size() > 0) { PlannerDomRoot domRoot(predicateStrings[0].c_str()); if (!domRoot.isNull()) { PlannerDomValue predicateObject = domRoot.rootObject(); HashRangeExpression *expression = dynamic_cast<HashRangeExpression*>(&m_predicates[0]); if (predicateObject.hasKey("predicateExpression")) { PlannerDomValue predicateExpression = predicateObject.valueForKey("predicateExpression"); PlannerDomValue rangesArray = predicateExpression.valueForKey("RANGES"); for (int ii = 0; ii < rangesArray.arrayLen(); ii++) { PlannerDomValue arrayObject = rangesArray.valueAtIndex(ii); PlannerDomValue rangeStartValue = arrayObject.valueForKey("RANGE_START"); PlannerDomValue rangeEndValue = arrayObject.valueForKey("RANGE_END"); if (!expression->binarySearch(rangeStartValue.asInt()).isTrue()) { throwFatalException("ElasticContext activate failed because a context already existed with conflicting ranges, conflicting range start is %d", rangeStartValue.asInt()); } if (!expression->binarySearch(rangeEndValue.asInt()).isTrue()) { throwFatalException("ElasticContext activate failed because a context already existed with conflicting ranges, conflicting range end is %d", rangeStartValue.asInt()); } } } } } m_predicateStrings = predicateStrings; // retain for possible clone after TRUNCATE TABLE TableStreamerContext::updatePredicates(predicateStrings); }
void PartitionByPlanNode::loadFromJSONObject(PlannerDomValue obj) { // Start with the base class. AggregatePlanNode::loadFromJSONObject(obj); // Read the sort expressions and directions. PlannerDomValue sortByColumnArray = obj.valueForKey("SORT_COLUMNS"); for (int idx = 0; idx < sortByColumnArray.arrayLen(); idx += 1) { PlannerDomValue sortColumnValue = sortByColumnArray.valueAtIndex(idx); if (sortColumnValue.hasNonNullKey("SORT_EXPRESSION")) { PlannerDomValue exprDom = sortColumnValue.valueForKey("SORT_EXPRESSION"); m_sortExpressions.push_back(AbstractExpression::buildExpressionTree(exprDom)); } else { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "PartitionByPlanNode::loadFromJSONObject:" " Missing sort expression."); } if (sortColumnValue.hasNonNullKey("SORT_DIRECTION")) { std::string dirStr = sortColumnValue.valueForKey("SORT_DIRECTION").asStr(); m_sortDirections.push_back(stringToSortDirection(dirStr)); } else { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "PartitionByPlanNode::loadFromJSONObject:" " Missing sort direction."); } } }
void AbstractScanPlanNode::loadFromJSONObject(PlannerDomValue obj) { m_target_table_name = obj.valueForKey("TARGET_TABLE_NAME").asStr(); m_isEmptyScan = obj.hasNonNullKey("PREDICATE_FALSE"); // Set the predicate (if any) only if it's not a trivial FALSE expression if (!m_isEmptyScan) { m_predicate.reset(loadExpressionFromJSONObject("PREDICATE", obj)); } m_tcd = NULL; m_cteStmtId = -1; if (obj.hasKey("IS_CTE_SCAN") && obj.valueForKey("IS_CTE_SCAN").asBool()) { m_scanType = CTE_SCAN; m_cteStmtId = obj.valueForKey("CTE_STMT_ID").asInt(); } else if (obj.hasNonNullKey("SUBQUERY_INDICATOR")) { m_scanType = SUBQUERY_SCAN; } else { m_scanType = PERSISTENT_TABLE_SCAN; VoltDBEngine* engine = ExecutorContext::getEngine(); m_tcd = engine->getTableDelegate(m_target_table_name); if ( ! m_tcd) { VOLT_ERROR("Failed to retrieve target table from execution engine for PlanNode '%s'", debug().c_str()); //TODO: throw something } } }
void AbstractPlanNode::loadSortListFromJSONObject(PlannerDomValue obj, std::vector<AbstractExpression*> *sortExprs, std::vector<SortDirectionType> *sortDirs) { PlannerDomValue sortColumnsArray = obj.valueForKey("SORT_COLUMNS"); for (int i = 0; i < sortColumnsArray.arrayLen(); i++) { PlannerDomValue sortColumn = sortColumnsArray.valueAtIndex(i); bool hasDirection = (sortDirs == NULL), hasExpression = (sortExprs == NULL); if (sortDirs && sortColumn.hasNonNullKey("SORT_DIRECTION")) { hasDirection = true; std::string sortDirectionStr = sortColumn.valueForKey("SORT_DIRECTION").asStr(); sortDirs->push_back(stringToSortDirection(sortDirectionStr)); } if (sortExprs && sortColumn.hasNonNullKey("SORT_EXPRESSION")) { hasExpression = true; PlannerDomValue exprDom = sortColumn.valueForKey("SORT_EXPRESSION"); sortExprs->push_back(AbstractExpression::buildExpressionTree(exprDom)); } if (!(hasExpression && hasDirection)) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "OrderByPlanNode::loadFromJSONObject:" " Does not have expression and direction."); } } }
/* * Produce a list of StreamPredicateHashRange objects by parsing predicate range strings. * Add error messages to errmsg. * Return true on success. */ bool StreamPredicateList::parseStrings( const std::vector<std::string> &predicateStrings, std::ostringstream& errmsg, std::vector<bool> &predicateDeletes) { bool failed = false; for (std::vector<std::string>::const_iterator iter = predicateStrings.begin(); iter != predicateStrings.end(); ++iter) { bool predFailed = false; std::string predicateString = *iter; if (!predicateString.empty()) { try { PlannerDomRoot domRoot((*iter).c_str()); if (!domRoot.isNull()) { PlannerDomValue predicateObject = domRoot.rootObject(); predicateDeletes.push_back(predicateObject.valueForKey("triggersDelete").asBool()); AbstractExpression *expr = NULL; if (predicateObject.hasKey("predicateExpression")) { expr = AbstractExpression::buildExpressionTree( predicateObject.valueForKey("predicateExpression")); if (expr != NULL) { // Got ourselves a predicate expression tree! push_back(expr); } else { errmsg << "Predicate JSON generated a NULL expression tree"; predFailed = true; } } else { // NULL represents an empty predicate object that should not be evaluated. push_back(NULL); } } else { errmsg << "Stream predicate JSON document is NULL"; predFailed = true; } } catch(std::exception &exc) { errmsg << "Exception occurred while parsing stream predicate: " << exc.what(); predFailed = true; } if (predFailed) { errmsg << std::endl << (*iter) << std::endl; failed = true; } } else { // NULL predicates are okay. push_back(NULL); } } return !failed; }
/** Parse JSON parameters to create a hash range expression */ static AbstractExpression* hashRangeFactory(PlannerDomValue obj) { PlannerDomValue hashColumnValue = obj.valueForKey("HASH_COLUMN"); PlannerDomValue rangesArray = obj.valueForKey("RANGES"); srange_type *ranges = new srange_type[rangesArray.arrayLen()]; for (int ii = 0; ii < rangesArray.arrayLen(); ii++) { PlannerDomValue arrayObject = rangesArray.valueAtIndex(ii); PlannerDomValue rangeStartValue = arrayObject.valueForKey("RANGE_START"); PlannerDomValue rangeEndValue = arrayObject.valueForKey("RANGE_END"); ranges[ii] = srange_type(rangeStartValue.asInt(), rangeEndValue.asInt()); } return new HashRangeExpression(hashColumnValue.asInt(), ranges, static_cast<int>(rangesArray.arrayLen())); }
void AggregatePlanNode::loadFromJSONObject(PlannerDomValue obj) { PlannerDomValue aggregateColumnsArray = obj.valueForKey("AGGREGATE_COLUMNS"); for (int i = 0; i < aggregateColumnsArray.arrayLen(); i++) { PlannerDomValue aggregateColumnValue = aggregateColumnsArray.valueAtIndex(i); bool containsType = false; bool containsDistinct = false; bool containsOutputColumn = false; bool containsExpression = false; if (aggregateColumnValue.hasNonNullKey("AGGREGATE_TYPE")) { containsType = true; string aggregateColumnTypeString = aggregateColumnValue.valueForKey("AGGREGATE_TYPE").asStr(); m_aggregates.push_back(stringToExpression(aggregateColumnTypeString)); } if (aggregateColumnValue.hasNonNullKey("AGGREGATE_DISTINCT")) { containsDistinct = true; bool distinct = aggregateColumnValue.valueForKey("AGGREGATE_DISTINCT").asInt() == 1; m_distinctAggregates.push_back(distinct); } if (aggregateColumnValue.hasNonNullKey("AGGREGATE_OUTPUT_COLUMN")) { containsOutputColumn = true; int column = aggregateColumnValue.valueForKey("AGGREGATE_OUTPUT_COLUMN").asInt(); m_aggregateOutputColumns.push_back(column); } if (aggregateColumnValue.hasNonNullKey("AGGREGATE_EXPRESSION")) { containsExpression = true; PlannerDomValue exprDom = aggregateColumnValue.valueForKey("AGGREGATE_EXPRESSION"); m_aggregateInputExpressions.push_back(AbstractExpression::buildExpressionTree(exprDom)); } if(!(containsType && containsDistinct && containsOutputColumn)) { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "AggregatePlanNode::loadFromJSONObject:" " Missing type, distinct, or outputcolumn."); } if ( ! containsExpression) { m_aggregateInputExpressions.push_back(NULL); } } if (obj.hasNonNullKey("GROUPBY_EXPRESSIONS")) { PlannerDomValue groupByExpressionsArray = obj.valueForKey("GROUPBY_EXPRESSIONS"); for (int i = 0; i < groupByExpressionsArray.arrayLen(); i++) { m_groupByExpressions.push_back(AbstractExpression::buildExpressionTree(groupByExpressionsArray.valueAtIndex(i))); } } if (obj.hasNonNullKey("PRE_PREDICATE")) { m_prePredicate = AbstractExpression::buildExpressionTree(obj.valueForKey("PRE_PREDICATE")); } if (obj.hasNonNullKey("POST_PREDICATE")) { m_postPredicate = AbstractExpression::buildExpressionTree(obj.valueForKey("POST_PREDICATE")); } }
void IndexCountPlanNode::loadFromJSONObject(PlannerDomValue obj) { AbstractScanPlanNode::loadFromJSONObject(obj); std::string endTypeString = obj.valueForKey("END_TYPE").asStr(); m_end_type = stringToIndexLookup(endTypeString); std::string lookupTypeString = obj.valueForKey("LOOKUP_TYPE").asStr(); m_lookup_type = stringToIndexLookup(lookupTypeString); m_target_index_name = obj.valueForKey("TARGET_INDEX_NAME").asStr(); m_searchkey_expressions.loadExpressionArrayFromJSONObject("SEARCHKEY_EXPRESSIONS", obj); m_endkey_expressions.loadExpressionArrayFromJSONObject("ENDKEY_EXPRESSIONS", obj); m_skip_null_predicate.reset(loadExpressionFromJSONObject("SKIP_NULL_PREDICATE", obj)); }
void PlanNodeFragment::loadFromJSONObject(PlannerDomValue obj) { PlannerDomValue executeListArray = obj.valueForKey("EXECUTE_LIST"); for (int i = 0; i < executeListArray.arrayLen(); i++) { m_executionList.push_back(m_idToNodeMap[executeListArray.valueAtIndex(i).asInt()]); } if (obj.hasKey("PARAMETERS")) { PlannerDomValue parametersArray = obj.valueForKey("PARAMETERS"); for (int i = 0; i < parametersArray.arrayLen(); i++) { PlannerDomValue parameterArray = parametersArray.valueAtIndex(i); int index = parameterArray.valueAtIndex(0).asInt(); std::string typeString = parameterArray.valueAtIndex(1).asStr(); parameters.push_back(std::pair< int, voltdb::ValueType>(index, stringToValue(typeString))); } } }
void AbstractPlanNode::loadIntArrayFromJSONObject(const char* label, PlannerDomValue obj, std::vector<int>& result) { if (obj.hasNonNullKey(label)) { PlannerDomValue intArray = obj.valueForKey(label); for (int i = 0; i < intArray.arrayLen(); i++) { result.push_back(intArray.valueAtIndex(i).asInt()); } } }
void InsertPlanNode::loadFromJSONObject(PlannerDomValue obj) { AbstractOperationPlanNode::loadFromJSONObject(obj); m_multiPartition = obj.valueForKey("MULTI_PARTITION").asBool(); if (obj.hasNonNullKey("FIELD_MAP")) { PlannerDomValue fieldMap = obj.valueForKey("FIELD_MAP"); for (int i = 0; i < fieldMap.arrayLen(); ++i) { m_fieldMap.push_back(fieldMap.valueAtIndex(i).asInt()); } } m_isUpsert = false; if (obj.hasNonNullKey("UPSERT")) { m_isUpsert = true; } m_sourceIsPartitioned = false; if (obj.hasNonNullKey("SOURCE_IS_PARTITIONED")) { m_sourceIsPartitioned = true; } }
void AbstractOperationPlanNode::loadFromJSONObject(PlannerDomValue obj) { m_target_table_name = obj.valueForKey("TARGET_TABLE_NAME").asStr(); VoltDBEngine* engine = ExecutorContext::getEngine(); m_tcd = engine->getTableDelegate(m_target_table_name); if ( ! m_tcd) { VOLT_ERROR("Failed to retrieve target table from execution engine for PlanNode '%s'", debug().c_str()); //TODO: throw something } }
// Load boolean array from JSON object. // In IndexScanPlanNode (indexscannode.h and indexscannode.cpp), // we added a boolean vector "m_compare_not_distinct" // to indicate whether null values should be skipped for each search key column. // This function is used to deseralize that boolean vector. (ENG-11096) void AbstractPlanNode::loadBooleanArrayFromJSONObject(const char* label, PlannerDomValue obj, std::vector<bool>& result) { if (obj.hasNonNullKey(label)) { PlannerDomValue stringArray = obj.valueForKey(label); int len = stringArray.arrayLen(); for (int i = 0; i < len; ++i) { result.push_back(stringArray.valueAtIndex(i).asBool()); } } }
void AbstractPlanNode::OwningExpressionVector::loadExpressionArrayFromJSONObject(const char* label, PlannerDomValue obj) { clear(); if ( ! obj.hasNonNullKey(label)) { return; } PlannerDomValue arrayObj = obj.valueForKey(label); for (int i = 0; i < arrayObj.arrayLen(); i++) { AbstractExpression *expr = AbstractExpression::buildExpressionTree(arrayObj.valueAtIndex(i)); push_back(expr); } }
void PlanNodeFragment::loadParamsFromJSONObject(PlanNodeFragment *pnf, PlannerDomValue obj) { if (obj.hasKey("PARAMETERS")) { PlannerDomValue parametersArray = obj.valueForKey("PARAMETERS"); for (int i = 0; i < parametersArray.arrayLen(); i++) { PlannerDomValue parameterArray = parametersArray.valueAtIndex(i); int index = parameterArray.valueAtIndex(0).asInt(); std::string typeString = parameterArray.valueAtIndex(1).asStr(); pnf->m_parameters.push_back(std::pair< int, voltdb::ValueType>(index, stringToValue(typeString))); } } }
void SwapTablesPlanNode::loadFromJSONObject(PlannerDomValue obj) { AbstractOperationPlanNode::loadFromJSONObject(obj); m_otherTargetTableName = obj.valueForKey("OTHER_TARGET_TABLE_NAME").asStr(); loadStringArrayFromJSONObject("INDEXES", obj, m_theIndexes); loadStringArrayFromJSONObject("OTHER_INDEXES", obj, m_otherIndexes); VoltDBEngine* engine = ExecutorContext::getEngine(); m_otherTcd = engine->getTableDelegate(m_otherTargetTableName); if ( ! m_otherTcd) { VOLT_ERROR("Failed to retrieve second target table from execution engine for PlanNode: %s", debug().c_str()); //TODO: throw something } }
void UnionPlanNode::loadFromJSONObject(PlannerDomValue obj) { std::string unionTypeStr = obj.valueForKey("UNION_TYPE").asStr(); if (unionTypeStr == "UNION") { m_unionType = UNION_TYPE_UNION; } else if (unionTypeStr == "UNION_ALL") { m_unionType = UNION_TYPE_UNION_ALL; } else if (unionTypeStr == "INTERSECT") { m_unionType = UNION_TYPE_INTERSECT; } else if (unionTypeStr == "INTERSECT_ALL") { m_unionType = UNION_TYPE_INTERSECT_ALL; } else if (unionTypeStr == "EXCEPT") { m_unionType = UNION_TYPE_EXCEPT; } else if (unionTypeStr == "EXCEPT_ALL") { m_unionType = UNION_TYPE_EXCEPT_ALL; } else if (unionTypeStr == "NOUNION") { m_unionType = UNION_TYPE_NOUNION; } else { throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION, "UnionPlanNode::loadFromJSONObject:" " Unsupported UNION_TYPE value " + unionTypeStr); } }
void DeletePlanNode::loadFromJSONObject(PlannerDomValue obj) { AbstractOperationPlanNode::loadFromJSONObject(obj); m_truncate = obj.valueForKey("TRUNCATE").asBool(); }
void UpdatePlanNode::loadFromJSONObject(PlannerDomValue obj) { AbstractOperationPlanNode::loadFromJSONObject(obj); m_updatesIndexes = obj.valueForKey("UPDATES_INDEXES").asBool(); }
void MaterializePlanNode::loadFromJSONObject(PlannerDomValue obj) { ProjectionPlanNode::loadFromJSONObject(obj); batched = obj.valueForKey("BATCHED").asBool(); }