ConcatArray::ConcatArray(ArrayDesc const& array, boost::shared_ptr<Array> const& left, boost::shared_ptr<Array> const& right) : DelegateArray(array, left), leftArray(left->getArrayDesc().getAttributes().size() == array.getAttributes().size() ? left : boost::shared_ptr<Array>(new NonEmptyableArray(left))), rightArray(right->getArrayDesc().getAttributes().size() == array.getAttributes().size() ? right : boost::shared_ptr<Array>(new NonEmptyableArray(right))), dims(desc.getDimensions()) { Dimensions const& leftDimensions = left->getArrayDesc().getDimensions(); Dimensions const& rightDimensions = right->getArrayDesc().getDimensions(); lastLeft = leftDimensions[CONCAT_DIM].getEndMax(); firstRight = rightDimensions[CONCAT_DIM].getStartMin(); concatChunkInterval = leftDimensions[CONCAT_DIM].getChunkInterval() + leftDimensions[CONCAT_DIM].getChunkOverlap(); size_t nDims = leftDimensions.size(); if (leftDimensions[CONCAT_DIM].getChunkOverlap() != 0 || leftDimensions[CONCAT_DIM].getLength() % leftDimensions[CONCAT_DIM].getChunkInterval() != 0) { simpleAppend = false; } else { simpleAppend = true; for (size_t i = 0; i < nDims; i++) { if (leftDimensions[i].getChunkInterval() != rightDimensions[i].getChunkInterval() || leftDimensions[i].getChunkOverlap() != rightDimensions[i].getChunkOverlap()) { simpleAppend = false; break; } } } }
RemoteArray::RemoteArray(const ArrayDesc& arrayDesc, QueryID queryId, InstanceID instanceID) : StreamArray(arrayDesc), _queryId(queryId), _instanceID(instanceID), _received(arrayDesc.getAttributes().size()), _messages(arrayDesc.getAttributes().size()), _requested(arrayDesc.getAttributes().size()) { }
void fillUsedPlugins(const ArrayDesc& desc, vector<string>& plugins) const { for (size_t i = 0; i < desc.getAttributes().size(); i++) { const string& libName = TypeLibrary::getTypeLibraries().getObjectLibrary(desc.getAttributes()[i].getType()); if (libName != "scidb") plugins.push_back(libName); } }
RemoteMergedArray::RemoteMergedArray(const ArrayDesc& arrayDesc, QueryID queryId, Statistics& statistics): MultiStreamArray(Query::getQueryByID(queryId)->getInstancesCount(), arrayDesc), _queryId(queryId), _received(arrayDesc.getAttributes().size(), vector<Semaphore>(getStreamsCount())), _messages(arrayDesc.getAttributes().size(), vector< boost::shared_ptr<MessageDesc> >(getStreamsCount())), _nextPositions(arrayDesc.getAttributes().size(), vector<Coordinates>(getStreamsCount())), _hasPositions(arrayDesc.getAttributes().size(), vector<bool>(getStreamsCount(), false)) { boost::shared_ptr<Query> query = Query::getQueryByID(queryId); _localArray = query->getCurrentResultArray(); }
InputArray::InputArray(ArrayDesc const& array, string const& format, boost::shared_ptr<Query>& query, bool emptyMode, bool enforceDataIntegrity, int64_t maxCnvErrors, string const& shadowArrayName, bool parallel) : SinglePassArray(array), _chunkLoader(ChunkLoader::create(format)), _currChunkIndex(0), strVal(TypeLibrary::getType(TID_STRING)), emptyTagAttrID(array.getEmptyBitmapAttribute() != NULL ? array.getEmptyBitmapAttribute()->getId() : INVALID_ATTRIBUTE_ID), nLoadedCells(0), nLoadedChunks(0), nErrors(0), maxErrors(maxCnvErrors), state(emptyMode ? S_Empty : S_Normal), nAttrs(array.getAttributes(true).size()), parallelLoad(parallel), _enforceDataIntegrity(enforceDataIntegrity) { SCIDB_ASSERT(query); _query=query; myInstanceID = query->getInstanceID(); SCIDB_ASSERT(_chunkLoader); // else inferSchema() messed up _chunkLoader->bind(this, query); if (!shadowArrayName.empty()) { shadowArray.reset(new MemArray(generateShadowArraySchema(array, shadowArrayName), query)); } }
MergeArray::MergeArray(ArrayDesc const& desc, vector< boost::shared_ptr<Array> > const& arrays) : DelegateArray(desc, arrays[0]), inputArrays(arrays) { for (size_t i = 0; i < inputArrays.size(); i++) { if (inputArrays[i]->getArrayDesc().getAttributes().size() != desc.getAttributes().size()) { inputArrays[i] = boost::shared_ptr<Array>(new NonEmptyableArray(inputArrays[i])); } } }
ArrayDesc InputArray::generateShadowArraySchema(ArrayDesc const& targetArray, string const& shadowArrayName) { Attributes const& srcAttrs = targetArray.getAttributes(true); size_t nAttrs = srcAttrs.size(); Attributes dstAttrs(nAttrs+2); for (size_t i = 0; i < nAttrs; i++) { dstAttrs[i] = AttributeDesc(i, srcAttrs[i].getName(), TID_STRING, AttributeDesc::IS_NULLABLE, 0); } dstAttrs[nAttrs] = AttributeDesc(nAttrs, "row_offset", TID_INT64, 0, 0); dstAttrs[nAttrs+1] = AttributeDesc(nAttrs+1, DEFAULT_EMPTY_TAG_ATTRIBUTE_NAME, TID_INDICATOR, AttributeDesc::IS_EMPTY_INDICATOR, 0); return ArrayDesc(shadowArrayName, dstAttrs, targetArray.getDimensions()); }
ApplyArray::ApplyArray(ArrayDesc const& desc, boost::shared_ptr<Array> const& array, vector<shared_ptr<Expression> > expressions, const boost::shared_ptr<Query>& query, bool tile) : DelegateArray(desc, array), _expressions(expressions), _attributeNullable(desc.getAttributes().size(), false), _runInTileMode(desc.getAttributes().size(), tile), _bindingSets(desc.getAttributes().size(), vector<BindInfo>(0)) { assert(query); _query=query; for(size_t i =0; i<expressions.size(); i++) { _attributeNullable[i] = desc.getAttributes()[i].isNullable(); if (expressions[i].get()) { _runInTileMode[i] = tile && expressions[i]->supportsTileMode(); _bindingSets[i]= expressions[i]->getBindings(); } } }
ScanRLEArray::ScanRLEArray(ArrayDesc const& arr, std::string path) : RLEArray(arr), _dirPath(path), _maxChunkNo(0), logger(log4cxx::Logger::getLogger("scidb.query.ops.ScanRQArray")) { filesystem::path full_path = filesystem::system_complete(filesystem::path(_dirPath)); if (!filesystem::exists(full_path)) { throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_CANT_OPEN_PATH) << _dirPath; } if (!filesystem::is_directory(full_path)) { throw SYSTEM_EXCEPTION(SCIDB_SE_INTERNAL, SCIDB_LE_DIRECTORY_EXPECTED) << _dirPath; } _maxChunkNo = arr.getNumberOfChunks() / arr.getAttributes().size(); }
FITSInputArray::FITSInputArray(ArrayDesc const& array, string const& filePath, uint32_t hdu, std::shared_ptr<Query>& query) : parser(filePath), hdu(hdu), desc(array), dims(array.getDimensions()), nDims(dims.size()), nAttrs(array.getAttributes(true).size()), values(nAttrs), chunks(nAttrs), chunkIterators(nAttrs), chunkIndex(0), chunkPos(nDims), query(query) { initValueHolders(); // Most initialization steps are only done later, when the first // chunk is requested by an iterator. See getChunkByIndex() }
inline ArrayDesc createWindowDesc(ArrayDesc const& desc) { Dimensions const& dims = desc.getDimensions(); Dimensions aggDims(dims.size()); for (size_t i = 0, n = dims.size(); i < n; i++) { DimensionDesc const& srcDim = dims[i]; aggDims[i] = DimensionDesc(srcDim.getBaseName(), srcDim.getNamesAndAliases(), srcDim.getStartMin(), srcDim.getCurrStart(), srcDim.getCurrEnd(), srcDim.getEndMax(), srcDim.getChunkInterval(), 0, srcDim.getType(), srcDim.getFlags(), srcDim.getMappingArrayName(), srcDim.getComment(), srcDim.getFuncMapOffset(), srcDim.getFuncMapScale()); } ArrayDesc output (desc.getName(), Attributes(), aggDims); for (size_t i = dims.size() * 2, size = _parameters.size(); i < size; i++) { addAggregatedAttribute( (shared_ptr <OperatorParamAggregateCall> &) _parameters[i], desc, output); } if ( desc.getEmptyBitmapAttribute()) { AttributeDesc const* eAtt = desc.getEmptyBitmapAttribute(); output.addAttribute(AttributeDesc(output.getAttributes().size(), eAtt->getName(), eAtt->getType(), eAtt->getFlags(), eAtt->getDefaultCompressionMethod())); } return output; }
//param desc --> the input array schema ArrayDesc createWindowDesc(ArrayDesc const& desc) { //get dimensions for output array Attributes const &attrs = desc.getAttributes(); /* Dimensions aggrDims(dims.size()); for (size_t i = 0; i < dims.size(); i++) { DimensionDesc const& srcDim = dims[i]; aggrDims[i] = DimensionDesc(srcDim.getBaseName(), srcDim.getNamesAndAliases(), srcDim.getStartMin(), srcDim.getCurrStart(), srcDim.getCurrEnd(), srcDim.getEndMax(), srcDim.getChunkInterval(), 0); } */ Attributes newAttributes; size_t n = 0; for (size_t i=desc.getDimensions().size()*2; i < _parameters.size()-1; i=i+2) { const AttributeDesc &attr = attrs[((boost::shared_ptr<OperatorParamReference>&)_parameters[i])->getObjectNo()]; newAttributes.push_back(AttributeDesc(n, attr.getName(), attr.getType(), attr.getFlags(), attr.getDefaultCompressionMethod(), attr.getAliases())); } return ArrayDesc(desc.getName(), newAttributes, desc.getDimensions()); }
ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, boost::shared_ptr< Query> query) { assert(schemas.size() == 1); ArrayDesc const& srcDesc = schemas[0]; ArrayDesc dstDesc = ((boost::shared_ptr<OperatorParamSchema>&)_parameters[0])->getSchema(); //Compile a desc of all possible attributes (aggregate calls first) and source dimensions ArrayDesc aggregationDesc (srcDesc.getName(), Attributes(), srcDesc.getDimensions()); vector<string> aggregatedNames; //add aggregate calls first for (size_t i = 1; i < _parameters.size(); i++) { addAggregatedAttribute( (shared_ptr <OperatorParamAggregateCall>&) _parameters[i], srcDesc, aggregationDesc); string aggName = aggregationDesc.getAttributes()[aggregationDesc.getAttributes().size()-1].getName(); bool aggFound = false; BOOST_FOREACH(const AttributeDesc &dstAttr, dstDesc.getAttributes()) { if (dstAttr.getName() == aggName) { aggFound = true; break; } } if (!aggFound) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ATTRIBUTE_DOESNT_EXIST) << aggName << dstDesc.getName(); } aggregatedNames.push_back(aggName); } //add other attributes BOOST_FOREACH(const AttributeDesc &srcAttr, srcDesc.getAttributes()) { //if there's an attribute with same name as an aggregate call - skip the attribute bool found = false; BOOST_FOREACH(const AttributeDesc &aggAttr, aggregationDesc.getAttributes()) { if( aggAttr.getName() == srcAttr.getName()) { found = true; } } if (!found) { aggregationDesc.addAttribute(AttributeDesc( aggregationDesc.getAttributes().size(), srcAttr.getName(), srcAttr.getType(), srcAttr.getFlags(), srcAttr.getDefaultCompressionMethod(), srcAttr.getAliases(), &srcAttr.getDefaultValue(), srcAttr.getDefaultValueExpr(), srcAttr.getVarSize())); } } //Ensure attributes names uniqueness. if (!dstDesc.getEmptyBitmapAttribute()) throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OP_REDIMENSION_ERROR1); BOOST_FOREACH(const AttributeDesc &dstAttr, dstDesc.getAttributes()) { BOOST_FOREACH(const AttributeDesc &srcAttr, aggregationDesc.getAttributes()) { if (srcAttr.getName() == dstAttr.getName()) { if (srcAttr.getType() != dstAttr.getType()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_TYPE) << srcAttr.getName() << srcAttr.getType() << dstAttr.getType(); } if (!dstAttr.isNullable() && srcAttr.isNullable()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_FLAGS) << srcAttr.getName(); } goto NextAttr; } } BOOST_FOREACH(const DimensionDesc &srcDim, aggregationDesc.getDimensions()) { if (srcDim.hasNameAndAlias(dstAttr.getName())) { if (dstAttr.getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_DESTINATION_ATTRIBUTE_TYPE) << dstAttr.getName() << TID_INT64; } if (dstAttr.getFlags() != 0) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_DESTINATION_ATTRIBUTE_FLAGS) << dstAttr.getName(); } goto NextAttr; } } if (dstAttr.isEmptyIndicator() == false) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_UNEXPECTED_DESTINATION_ATTRIBUTE) << dstAttr.getName(); } NextAttr:; } Dimensions outputDims; size_t nNewDims = 0; BOOST_FOREACH(const DimensionDesc &dstDim, dstDesc.getDimensions()) { if (dstDim.getChunkOverlap() > dstDim.getChunkInterval()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OVERLAP_CANT_BE_LARGER_CHUNK); } BOOST_FOREACH(const AttributeDesc &srcAttr, aggregationDesc.getAttributes()) { if (dstDim.hasNameAndAlias(srcAttr.getName())) { for (size_t i = 0; i< aggregatedNames.size(); i++) { if (srcAttr.getName() == aggregatedNames[i]) throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OP_REDIMENSION_ERROR2); } if ( !IS_INTEGRAL(srcAttr.getType()) || srcAttr.getType() == TID_UINT64 ) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_SOURCE_ATTRIBUTE_TYPE) << srcAttr.getName() << TID_INT64; } outputDims.push_back(dstDim); goto NextDim; } } BOOST_FOREACH(const DimensionDesc &srcDim, aggregationDesc.getDimensions()) { if (srcDim.hasNameAndAlias(dstDim.getBaseName())) { DimensionDesc outputDim = dstDim; outputDims.push_back(outputDim); goto NextDim; } } //one synthetic dimension allowed if (nNewDims++ != 0 || !aggregatedNames.empty() ) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_UNEXPECTED_DESTINATION_DIMENSION) << dstDim.getBaseName(); } outputDims.push_back(dstDim); NextDim:; } return ArrayDesc(srcDesc.getName(), dstDesc.getAttributes(), outputDims, dstDesc.getFlags()); }
ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, boost::shared_ptr< Query> query) { assert(schemas.size() == 1); ArrayDesc const& srcDesc = schemas[0]; ArrayDesc dstDesc = ((boost::shared_ptr<OperatorParamSchema>&)_parameters[0])->getSchema(); //Compile a desc of all possible attributes (aggregate calls first) and source dimensions ArrayDesc aggregationDesc (srcDesc.getName(), Attributes(), srcDesc.getDimensions()); vector<string> aggregatedNames; //add aggregate calls first for (size_t i = 1; i < _parameters.size(); i++) { addAggregatedAttribute( (shared_ptr <OperatorParamAggregateCall>&) _parameters[i], srcDesc, aggregationDesc); aggregatedNames.push_back(aggregationDesc.getAttributes()[aggregationDesc.getAttributes().size()-1].getName()); } //add other attributes BOOST_FOREACH(const AttributeDesc &srcAttr, srcDesc.getAttributes()) { //if there's an attribute with same name as an aggregate call - skip the attribute bool found = false; BOOST_FOREACH(const AttributeDesc &aggAttr, aggregationDesc.getAttributes()) { if( aggAttr.getName() == srcAttr.getName()) { found = true; } } if (!found) { aggregationDesc.addAttribute(AttributeDesc( aggregationDesc.getAttributes().size(), srcAttr.getName(), srcAttr.getType(), srcAttr.getFlags(), srcAttr.getDefaultCompressionMethod(), srcAttr.getAliases(), &srcAttr.getDefaultValue(), srcAttr.getDefaultValueExpr(), srcAttr.getComment(), srcAttr.getVarSize())); } } //Ensure attributes names uniqueness. if (!dstDesc.getEmptyBitmapAttribute()) throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OP_REDIMENSION_ERROR1); BOOST_FOREACH(const AttributeDesc &dstAttr, dstDesc.getAttributes()) { BOOST_FOREACH(const AttributeDesc &srcAttr, aggregationDesc.getAttributes()) { if (srcAttr.getName() == dstAttr.getName()) { if (srcAttr.getType() != dstAttr.getType()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_TYPE) << srcAttr.getName() << srcAttr.getType() << dstAttr.getType(); } if (!dstAttr.isNullable() && srcAttr.isNullable()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_FLAGS) << srcAttr.getName(); } goto NextAttr; } } BOOST_FOREACH(const DimensionDesc &srcDim, aggregationDesc.getDimensions()) { if (srcDim.hasNameOrAlias(dstAttr.getName())) { if (dstAttr.getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_DESTINATION_ATTRIBUTE_TYPE) << dstAttr.getName() << TID_INT64; } if (srcDim.getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_SOURCE_DIMENSION_TYPE) << dstAttr.getName() << TID_INT64; } if (dstAttr.getFlags() != 0) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_DESTINATION_ATTRIBUTE_FLAGS) << dstAttr.getName(); } goto NextAttr; } } if (dstAttr.isEmptyIndicator() == false) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_UNEXPECTED_DESTINATION_ATTRIBUTE) << dstAttr.getName(); } NextAttr:; } BOOST_FOREACH(const DimensionDesc &dstDim, dstDesc.getDimensions()) { if (dstDim.getChunkOverlap() != 0) throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OP_REDIMENSION_STORE_ERROR3); BOOST_FOREACH(const AttributeDesc &srcAttr, aggregationDesc.getAttributes()) { if (dstDim.hasNameOrAlias(srcAttr.getName())) { for (size_t i = 0; i< aggregatedNames.size(); i++) { if (srcAttr.getName() == aggregatedNames[i]) throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_OP_REDIMENSION_ERROR2); } if (srcAttr.getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_SOURCE_ATTRIBUTE_TYPE) << srcAttr.getName() << TID_INT64; } if (srcAttr.getFlags() != 0) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_SOURCE_ATTRIBUTE_FLAGS) << srcAttr.getName() << TID_INT64; } if (dstDim.getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_DESTINATION_DIMENSION_TYPE) << srcAttr.getName() << TID_INT64; } goto NextDim; } } BOOST_FOREACH(const DimensionDesc &srcDim, aggregationDesc.getDimensions()) { if (srcDim.hasNameOrAlias(dstDim.getBaseName())) { if (dstDim.getType() != srcDim.getType() || dstDim.getStart() != srcDim.getStart() || dstDim.getLength() != srcDim.getLength() || dstDim.getChunkInterval() != srcDim.getChunkInterval()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_DIMENSIONS_DONT_MATCH) << srcDim.getBaseName() << dstDim.getBaseName(); } goto NextDim; } } throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_UNEXPECTED_DESTINATION_DIMENSION) << dstDim.getBaseName(); NextDim:; } return ArrayDesc(srcDesc.getName()+"_redimension", dstDesc.getAttributes(), dstDesc.getDimensions(), dstDesc.getFlags()); }
inline bool hasSingleAttribute(ArrayDesc const& desc) { return desc.getAttributes().size() == 1 || (desc.getAttributes().size() == 2 && desc.getAttributes()[1].isEmptyIndicator()); }
/** * Perform operator-specific checks of input and return the shape of the output. Currently, * the output array must exist. * @param schemas the shapes of the input arrays * @param query the query context */ ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, shared_ptr< Query> query) { assert(schemas.size() == 1); assert(_parameters.size() == 1); string arrayName = ((shared_ptr<OperatorParamReference>&)_parameters[0])->getObjectName(); ArrayDesc const& srcDesc = schemas[0]; //Ensure attributes names uniqueness. ArrayDesc dstDesc; if (!SystemCatalog::getInstance()->getArrayDesc(arrayName, dstDesc, false)) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ARRAY_DOESNT_EXIST) << arrayName; } if(dstDesc.isImmutable()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ILLEGAL_OPERATION) << "Target of INSERT must be a mutable array"; } Dimensions const& srcDims = srcDesc.getDimensions(); Dimensions const& dstDims = dstDesc.getDimensions(); if (srcDims.size() != dstDims.size()) { //TODO: this will get lifted when we allow redimension+insert in the same op //and when we DO implement redimension+insert - we will need to match attributes/dimensions by name, not position. throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ILLEGAL_OPERATION) << "Temporary restriction: target of INSERT must have same dimensions as the source"; } for (size_t i = 0, n = srcDims.size(); i < n; i++) { if( srcDims[i].getType() != TID_INT64 || dstDims[i].getType() != TID_INT64) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ILLEGAL_OPERATION) << "Temporary restriction: INSERT only supports integer dimensions"; } //TODO: we can also allow arrays that are smaller whose length is not evenly divided by chunk interval //but then we have to detect "edge chunks" and rewrite them cleverly if( srcDims[i].getStartMin() != dstDims[i].getStartMin() || srcDims[i].getChunkInterval() != dstDims[i].getChunkInterval() || srcDims[i].getChunkOverlap() != dstDims[i].getChunkOverlap() || srcDims[i].getEndMax() > dstDims[i].getEndMax() || ( srcDims[i].getEndMax() < dstDims[i].getEndMax() && srcDims[i].getLength() % srcDims[i].getChunkInterval() != 0)) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_DIMENSIONS_DONT_MATCH) << srcDims[i].getBaseName() << dstDims[i].getBaseName(); } } Attributes const& srcAttrs = srcDesc.getAttributes(true); Attributes const& dstAttrs = dstDesc.getAttributes(true); if (srcAttrs.size() != dstAttrs.size()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ILLEGAL_OPERATION) << "Temporary restriction: target of INSERT must have same attributes as the source"; } for (size_t i = 0, n = srcAttrs.size(); i < n; i++) { if(srcAttrs[i].getType() != dstAttrs[i].getType()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_TYPE) << srcAttrs[i].getName() << srcAttrs[i].getType() << dstAttrs[i].getType(); } //can't store nulls into a non-nullable attribute if(!dstAttrs[i].isNullable() && srcAttrs[i].isNullable()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_ATTRIBUTE_FLAGS) << srcAttrs[i].getName(); } } //Note: let us NOT add arrayID numbers to the schema - because we do not have our ArrayID yet. //We will get our ArrayID when we execute and create the array. Until then - don't bother. //Old store code adds the arrayID to the schema - but that's the arrayID of the previous version, //not the new version created by the op. A dangerous fallacy - stupid and unnecessary. return ArrayDesc(arrayName, dstDesc.getAttributes(), dstDesc.getDimensions(), dstDesc.getFlags()); }