TEST(Expression, Run) { Expression expression; expression.compile("(10 + 20 + 1.1)"); Context context; EXPECT_EQ(31.1, expression.run(context)); EXPECT_EQ(31.1, expression.run(context)); EXPECT_EQ(31.1, expression.run(context)); context["eur"] = 20.0; expression.compile("(10 + eur + 1.1)"); EXPECT_EQ(31.1, expression.run(context)); context["eur"] = 21.0; expression.compile("(10 + eur + 1.1)"); EXPECT_EQ(32.1, expression.run(context)); context.erase("eur"); expression.compile("(10 + eur + 1.1)"); EXPECT_EQ(11.1, expression.run(context)); expression.compile("average(1, 2) * 21 + 1.1"); EXPECT_EQ(32.6, expression.run(context)); expression.compile("1 + 2*3"); EXPECT_EQ(7, expression.run(context)); expression.compile("(1 + 2)*3"); EXPECT_EQ(9, expression.run(context)); expression.compile("(3 - 1) / 0.4"); EXPECT_EQ(5, expression.run(context)); }
TEST(Expression, Symbols) { Expression expression; EXPECT_EQ(0, expression.symbols().size()); expression.compile("eur + gbp"); ASSERT_EQ(2, expression.symbols().size()); EXPECT_EQ(std::string("eur"), expression.symbols()[0]); EXPECT_EQ(std::string("gbp"), expression.symbols()[1]); }
ArrayDesc inferSchema(std::vector< ArrayDesc> schemas, boost::shared_ptr< Query> query) { assert(schemas.size() == 1); assert(_parameters[0]->getParamType() == PARAM_ATTRIBUTE_REF); assert(_parameters[1]->getParamType() == PARAM_LOGICAL_EXPRESSION); if ( _parameters.size() % 2 != 0 ) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_WRONG_OPERATOR_ARGUMENTS_COUNT2) << "tile_apply"; } Attributes outAttrs; AttributeID nextAttrId =0; for (size_t i=0; i<schemas[0].getAttributes().size(); i++) { AttributeDesc const& attr = schemas[0].getAttributes()[i]; if(attr.getType()!=TID_INDICATOR) { outAttrs.push_back( AttributeDesc(nextAttrId++, attr.getName(), attr.getType(), attr.getFlags(), attr.getDefaultCompressionMethod(), attr.getAliases(), attr.getReserve(), &attr.getDefaultValue(), attr.getDefaultValueExpr(), attr.getVarSize())); } } size_t k; for (k=0; k<_parameters.size(); k+=2) { const string &attributeName = ((boost::shared_ptr<OperatorParamReference>&)_parameters[k])->getObjectName(); Expression expr; expr.compile(((boost::shared_ptr<OperatorParamLogicalExpression>&)_parameters[k+1])->getExpression(), query, _properties.tile, TID_VOID, schemas); assert(!_properties.tile); int flags = 0; if (expr.isNullable()) { flags = (int)AttributeDesc::IS_NULLABLE; } for (size_t j = 0; j < nextAttrId; j++) { AttributeDesc const& attr = outAttrs[j]; if (attr.getName() == attributeName) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_DUPLICATE_ATTRIBUTE_NAME) << attributeName; } } outAttrs.push_back(AttributeDesc(nextAttrId++, attributeName, expr.getType(), flags, 0)); } if(schemas[0].getEmptyBitmapAttribute()) { AttributeDesc const* emptyTag = schemas[0].getEmptyBitmapAttribute(); for (size_t j = 0; j < nextAttrId; j++) { AttributeDesc const& attr = outAttrs[j]; if (attr.getName() == emptyTag->getName()) { throw USER_EXCEPTION(SCIDB_SE_INFER_SCHEMA, SCIDB_LE_DUPLICATE_ATTRIBUTE_NAME) << attr.getName(); } } outAttrs.push_back( AttributeDesc(nextAttrId, emptyTag->getName(), emptyTag->getType(), emptyTag->getFlags(), emptyTag->getDefaultCompressionMethod(), emptyTag->getAliases(), emptyTag->getReserve(), &emptyTag->getDefaultValue(), emptyTag->getDefaultValueExpr(), emptyTag->getVarSize())); } return ArrayDesc(schemas[0].getName(), outAttrs, schemas[0].getDimensions()); }
shared_ptr< Array > execute(vector< shared_ptr< Array> >& inputArrays, shared_ptr<Query> query) { // I maintain the log of the operator in a local file named after Correlation_N.log, N is the instance ID. stringstream logFileName; logFileName << "/home/scidb/preselect_" << query->getInstanceID() << ".log"; FILE *logFile; logFile = fopen(logFileName.str().c_str(), "w"); shared_ptr<Array> originalArray = inputArrays[0]; shared_ptr<Array> correlationArray = inputArrays[1]; ArrayDesc originalSchema = originalArray->getArrayDesc(); ArrayDesc corrSchema = correlationArray->getArrayDesc(); Dimensions originalDims = originalSchema.getDimensions(); Dimensions corrDims = corrSchema.getDimensions(); DimensionDesc originalDimsP = originalDims[1]; DimensionDesc corrDimsP = corrDims[0]; // Note the correlation array doesn't have Y column. Coordinate p = corrDimsP.getCurrLength(); fprintf(logFile, "p = %ld\n # of chunk = %ld\n", p, corrSchema.getNumberOfChunks()); fflush(logFile); shared_ptr<ConstArrayIterator> corrArrayIter = correlationArray->getIterator(0); if(! corrArrayIter->end() ) { correlation *corr = new correlation[p]; // The correlation array will always have only 1 chunk (we designed correlation array like this), so no loops here. shared_ptr<ConstChunkIterator> corrChunkIter = corrArrayIter->getChunk().getConstIterator(); for(Coordinate i=0; i<p; ++i) { corr[i].id = i+1; corr[i].corr = corrChunkIter->getItem().getDouble(); //fprintf(logFile, "%d, %f\n", corr[i].id, corr[i].corr); ++(*corrChunkIter); } //fflush(logFile); qsort(corr, p, sizeof(correlation), &comp); for(Coordinate i=0; i<p; ++i) { fprintf(logFile, "%d, %f\n", corr[i].id, corr[i].corr); } fflush(logFile); Coordinate d = ((boost::shared_ptr<OperatorParamPhysicalExpression>&)_parameters[0])->getExpression()->evaluate().getInt64(); fprintf(logFile, "d=%ld\n", d); stringstream ss; vector<string> names; names.push_back("j"); vector<TypeId> types; types.push_back(TID_INT64); for(Coordinate i=0; i<d; ++i) { ss << "j=" << corr[i].id << " or "; } ss << "j=" << p+1; fprintf(logFile, "%s\n", ss.str().c_str()); fflush(logFile); Expression e; e.compile(ss.str(), names, types); fclose(logFile); boost::shared_ptr<scidb::Query> emptyQuery; return boost::shared_ptr<Array>(new FilterArray(_schema, inputArrays[0], boost::make_shared<Expression>(e), emptyQuery, _tileMode)); } else { shared_ptr<Array> outputArray(new MemArray(_schema, query)); fclose(logFile); return outputArray; } }