/** * 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, std::shared_ptr< Query> query) { SCIDB_ASSERT(schemas.size() == 1); SCIDB_ASSERT(_parameters.size() == 1); string arrayNameOrg = ((std::shared_ptr<OperatorParamReference>&)_parameters[0])->getObjectName(); SCIDB_ASSERT(ArrayDesc::isNameUnversioned(arrayNameOrg)); //Ensure attributes names uniqueness. std::string arrayName; std::string namespaceName; query->getNamespaceArrayNames(arrayNameOrg, namespaceName, arrayName); ArrayDesc dstDesc; ArrayDesc const& srcDesc = schemas[0]; ArrayID arrayId = query->getCatalogVersion(namespaceName, arrayName); bool fArrayDesc = scidb::namespaces::Communicator::getArrayDesc( namespaceName, arrayName, arrayId, dstDesc, false); if (!fArrayDesc) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_ARRAY_DOESNT_EXIST) << arrayName; } ArrayDesc::checkConformity(srcDesc, dstDesc, ArrayDesc::IGNORE_PSCHEME | ArrayDesc::IGNORE_OVERLAP | ArrayDesc::IGNORE_INTERVAL); // allows auto-repart() SCIDB_ASSERT(dstDesc.getId() == dstDesc.getUAId()); SCIDB_ASSERT(dstDesc.getName() == arrayName); SCIDB_ASSERT(dstDesc.getUAId() > 0); return dstDesc; }
DBArray::DBArray(ArrayDesc const& desc, const boost::shared_ptr<Query>& query) : _desc(desc), _query(query) { _desc.setPartitioningSchema(SystemCatalog::getInstance()->getPartitioningSchema(desc.getId())); if (query) { query->sharedLock(getRealName()); } }
void InputArray::redistributeShadowArray(boost::shared_ptr<Query> const& query) { SCIDB_ASSERT(shadowArray); //All arrays are currently stored as round-robin. Let's store shadow arrays round-robin as well //TODO: revisit this when we allow users to store arrays with specified distributions PartitioningSchema ps = psHashPartitioned; ArrayDesc shadowArrayDesc = shadowArray->getArrayDesc(); string shadowArrayVersionName; LOG4CXX_DEBUG(logger, "Redistribute shadow array " << shadowArrayDesc.getName()); if (! query->isCoordinator()) { // worker string shadowArrayName = shadowArrayDesc.getName(); SCIDB_ASSERT(ArrayDesc::isNameUnversioned(shadowArrayName)); shared_ptr<SystemCatalog::LockDesc> lock(new SystemCatalog::LockDesc(shadowArrayName, query->getQueryID(), Cluster::getInstance()->getLocalInstanceId(), SystemCatalog::LockDesc::WORKER, SystemCatalog::LockDesc::WR)); shared_ptr<Query::ErrorHandler> ptr(new UpdateErrorHandler(lock)); query->pushErrorHandler(ptr); Query::Finalizer f = bind(&UpdateErrorHandler::releaseLock, lock, _1); query->pushFinalizer(f); SystemCatalog::ErrorChecker errorChecker = bind(&Query::validate, query); if (!SystemCatalog::getInstance()->lockArray(lock, errorChecker)) { throw USER_EXCEPTION(SCIDB_SE_SYSCAT, SCIDB_LE_CANT_INCREMENT_LOCK) << shadowArrayName; } ArrayDesc desc; bool arrayExists = SystemCatalog::getInstance()->getArrayDesc(shadowArrayName, desc, false); VersionID lastVersion = 0; if (arrayExists) { lastVersion = SystemCatalog::getInstance()->getLastVersion(desc.getId()); } VersionID version = lastVersion+1; lock->setArrayVersion(version); bool rc = SystemCatalog::getInstance()->updateArrayLock(lock); SCIDB_ASSERT(rc); LOG4CXX_DEBUG(logger, "Use version " << version << " of shadow array " << shadowArrayName); shadowArrayVersionName = ArrayDesc::makeVersionedName(shadowArrayName, version); } else { // coordinator shadowArrayVersionName = shadowArrayDesc.getName(); SCIDB_ASSERT(ArrayDesc::isNameVersioned(shadowArrayVersionName)); } shared_ptr<Array> persistentShadowArray(DBArray::newDBArray(shadowArrayVersionName, query)); ArrayDesc const& dstArrayDesc = persistentShadowArray->getArrayDesc(); query->getReplicationContext()->enableInboundQueue(dstArrayDesc.getId(), persistentShadowArray); set<Coordinates, CoordinatesLess> newChunkCoordinates; redistributeToArray(shadowArray, persistentShadowArray, &newChunkCoordinates, query, ps, ALL_INSTANCE_MASK, boost::shared_ptr <DistributionMapper>(), 0, shared_ptr<PartitioningSchemaData>()); StorageManager::getInstance().removeDeadChunks(dstArrayDesc, newChunkCoordinates, query); query->getReplicationContext()->replicationSync(dstArrayDesc.getId()); query->getReplicationContext()->removeInboundQueue(dstArrayDesc.getId()); StorageManager::getInstance().flush(); PhysicalBoundaries bounds = PhysicalBoundaries::createFromChunkList(persistentShadowArray, newChunkCoordinates); SystemCatalog::getInstance()->updateArrayBoundaries(dstArrayDesc, bounds); // XXX TODO: add: getInjectedErrorListener().check(); }