// Test single clauses void QueryEvaluatorTest::testEvaluator() { QueryEvaluator e = *new QueryEvaluator(); // Test Follows(a1, a2) FollowsClause* fol = new FollowsClause(); fol->setFirstArg("a1"); fol->setSecondArg("a2"); fol->setFirstArgFixed(false); fol->setSecondArgFixed(false); fol->setFirstArgType(ARG_ASSIGN); fol->setSecondArgType(ARG_ASSIGN); StringPair p = *new StringPair(); p.setFirst("a2"); p.setSecond(ARG_STATEMENT); Query q = *new Query(); q.addSelectSynonym(p); q.addClause(fol); set<string> res = e.evaluateQuery(q); CPPUNIT_ASSERT(res.size() == 1); // test Follows(_,_) FollowsClause* fol2 = new FollowsClause(); fol2->setFirstArgFixed(false); fol2->setSecondArgFixed(false); fol2->setFirstArgType(ARG_GENERIC); fol2->setSecondArgType(ARG_GENERIC); fol2->isValid(); StringPair p6 = *new StringPair(); p6.setFirst("s"); p6.setSecond(ARG_STATEMENT); Query q6 = *new Query(); q6.addSelectSynonym(p6); q6.addClause(fol2); set<string> res6 = e.evaluateQuery(q6); CPPUNIT_ASSERT(res6.size() == 7); //test ParentStar FixedSyn With While ParentStarClause* m1 = new ParentStarClause(); m1->setFirstArg("w"); m1->setFirstArgFixed(false); m1->setFirstArgType(ARG_STATEMENT); m1->setSecondArg("5"); m1->setSecondArgFixed(true); m1->setSecondArgType(ARG_WHILE); StringPair p2 = *new StringPair(); p2.setFirst("w"); p2.setSecond(ARG_WHILE); Query q2 = *new Query(); q2.addSelectSynonym(p2); q2.addClause(m1); Results r = m1->evaluate(); set<string> res2 = e.evaluateQuery(q2); CPPUNIT_ASSERT(res2.size() == 2); //test ParentStar FixedSyn With While ParentStarClause* m2 = new ParentStarClause(); m2->setFirstArg("w1"); m2->setFirstArgFixed(false); m2->setFirstArgType(ARG_STATEMENT); m2->setSecondArg("5"); m2->setSecondArgFixed(true); m2->setSecondArgType(ARG_WHILE); StringPair p3 = *new StringPair(); p3.setFirst("w"); p3.setSecond(ARG_WHILE); Query q3 = *new Query(); q3.addSelectSynonym(p3); q3.addClause(m2); set<string> res3 = e.evaluateQuery(q3); CPPUNIT_ASSERT(res3.size() == 2); // Test FollowsStar FollowsStarClause* f1 = new FollowsStarClause(); f1->setFirstArg("3"); f1->setFirstArgFixed(true); f1->setFirstArgType(ARG_STATEMENT); f1->setSecondArg("a"); f1->setSecondArgFixed(false); f1->setSecondArgType(ARG_STATEMENT); StringPair p4 = *new StringPair(); p4.setFirst("a"); p4.setSecond(ARG_STATEMENT); Query q4 = *new Query(); q4.addSelectSynonym(p4); q4.addClause(f1); set<string> res4 = e.evaluateQuery(q4); CPPUNIT_ASSERT(res4.size() == 2); // Test FollowsStar with select type constant FollowsStarClause* f2 = new FollowsStarClause(); f2->setFirstArg("3"); f2->setFirstArgFixed(true); f2->setFirstArgType(ARG_STATEMENT); f2->setSecondArg("a"); f2->setSecondArgFixed(false); f2->setSecondArgType(ARG_STATEMENT); StringPair p5 = *new StringPair(); p5.setFirst("c"); p5.setSecond(ARG_CONSTANT); Query q5 = *new Query(); q5.addSelectSynonym(p5); q5.addClause(f2); set<string> res5 = e.evaluateQuery(q5); /* for (set<string>::iterator iter=res5.begin(); iter != res5.end(); iter++) { cout << "result: " << *iter << "!"; } */ // to check CPPUNIT_ASSERT(res5.size() == 5); }
// Test 2 clauses void QueryEvaluatorTest::testEvaluator2() { QueryEvaluator e = *new QueryEvaluator(); // Test all syn different ParentStarClause* m1 = new ParentStarClause(); m1->setFirstArg("w"); m1->setFirstArgFixed(false); m1->setFirstArgType(ARG_WHILE); m1->setSecondArg("5"); m1->setSecondArgFixed(true); m1->setSecondArgType(ARG_STATEMENT); PatternAssgClause* p1 = new PatternAssgClause("a"); p1->setVar("_"); p1->setVarFixed(true); p1->setExpression("_"); StringPair pr1 = *new StringPair(); pr1.setFirst("s"); pr1.setSecond(ARG_ASSIGN); Query q1 = *new Query(); q1.addSelectSynonym(pr1); q1.addClause(m1); q1.addClause(p1); set<string> res = e.evaluateQuery(q1); CPPUNIT_ASSERT(res.size() == 5); // Test 1 same fixed syn between 2 clauses // Select a s.t. Modifies(5, "i") pattern a("i",_) ModifiesClause* m2 = new ModifiesClause(); m2->setFirstArg("5"); m2->setFirstArgFixed(true); m2->setFirstArgType(ARG_STATEMENT); m2->setSecondArg("i"); m2->setSecondArgFixed(true); m2->setSecondArgType(ARG_VARIABLE); PatternAssgClause* p2 = new PatternAssgClause("a"); p2->setVar("i"); p2->setVarFixed(true); p2->setExpression("_"); StringPair pr2 = *new StringPair(); pr2.setFirst("a"); pr2.setSecond(ARG_VARIABLE); Query q2 = *new Query(); q2.addSelectSynonym(pr2); q2.addClause(m2); q2.addClause(p2); set<string> res2 = e.evaluateQuery(q2); /* for (set<string>::iterator iter=res2.begin(); iter != res2.end(); iter++) { cout << "result: " << *iter << "!"; } */ CPPUNIT_ASSERT(res2.size() == 1); // Test 1 same unfixed syn between 2 clauses // Select a s.t. Modifies(a,v1) pattern a(v2,_) ModifiesClause* m3 = new ModifiesClause(); m3->setFirstArg("a"); m3->setFirstArgFixed(false); m3->setFirstArgType(ARG_STATEMENT); m3->setSecondArg("v1"); m3->setSecondArgFixed(false); m3->setSecondArgType(ARG_VARIABLE); PatternAssgClause* p3 = new PatternAssgClause("a"); p3->setVar("v2"); p3->setVarFixed(false); p3->setExpression("_"); StringPair pr3 = *new StringPair(); pr3.setFirst("a"); pr3.setSecond(ARG_VARIABLE); Query q3 = *new Query(); q3.addSelectSynonym(pr3); q3.addClause(m3); q3.addClause(p3); set<string> res3 = e.evaluateQuery(q3); CPPUNIT_ASSERT(res3.size() == 5); // Test 2 same unfixed syn between 2 clauses // Select a s.t. Modifies(a,v) pattern a(v,_) ModifiesClause* m4 = new ModifiesClause(); m4->setFirstArg("a"); m4->setFirstArgFixed(false); m4->setFirstArgType(ARG_STATEMENT); m4->setSecondArg("v"); m4->setSecondArgFixed(false); m4->setSecondArgType(ARG_VARIABLE); PatternAssgClause* p4 = new PatternAssgClause("a"); p4->setVar("v"); p4->setVarFixed(false); p4->setExpression("_"); StringPair pr4 = *new StringPair(); pr4.setFirst("a"); pr4.setSecond(ARG_STATEMENT); Query q4 = *new Query(); q4.addSelectSynonym(pr4); q4.addClause(m4); q4.addClause(p4); set<string> res4 = e.evaluateQuery(q4); CPPUNIT_ASSERT(res4.size() == 5); // Test 2 same unfixed syn between 2 clauses // Select v s.t. Follows*(a1,a2) pattern a2(v,_) FollowsStarClause* f1 = new FollowsStarClause(); f1->setFirstArg("a1"); f1->setFirstArgFixed(false); f1->setFirstArgType(ARG_STATEMENT); f1->setSecondArg("a2"); f1->setSecondArgFixed(false); f1->setSecondArgType(ARG_STATEMENT); CPPUNIT_ASSERT(f1->isValid()); PatternAssgClause* p5 = new PatternAssgClause("a2"); p5->setVar("v"); p5->setVarFixed(false); p5->setExpression("_"); CPPUNIT_ASSERT(p5->isValid()); StringPair pr5 = *new StringPair(); pr5.setFirst("v"); pr5.setSecond(ARG_VARIABLE); Query q5 = *new Query(); q5.addSelectSynonym(pr5); q5.addClause(f1); q5.addClause(p5); set<string> res5 = e.evaluateQuery(q5); CPPUNIT_ASSERT(res5.size() == 2); // Test 2 same unfixed syn between 2 clauses // Select v s.t. Follows*(a1,a2) pattern a2(v,_) FollowsStarClause* f2 = new FollowsStarClause(); f2->setFirstArg("a1"); f2->setFirstArgFixed(false); f2->setFirstArgType(ARG_STATEMENT); f2->setSecondArg("a2"); f2->setSecondArgFixed(false); f2->setSecondArgType(ARG_STATEMENT); CPPUNIT_ASSERT(f1->isValid()); PatternAssgClause* p6 = new PatternAssgClause("a2"); p6->setVar("v"); p6->setVarFixed(false); p6->setExpression("_"); CPPUNIT_ASSERT(p6->isValid()); StringPair pr6 = *new StringPair(); pr6.setFirst("c"); pr6.setSecond(ARG_CONSTANT); Query q6 = *new Query(); q6.addSelectSynonym(pr6); q6.addClause(f2); q6.addClause(p6); set<string> res6 = e.evaluateQuery(q6); // To be checked //BOOST_FOREACH(auto p, res6) { // cout << p << endl; //} CPPUNIT_ASSERT(res6.size() == 5); }
void queryDriver(string query, list<string> &result, PKB *pkb){ //// cout<<"Begin parse query"<<endl; pkb->printParentTable(); pkb->printModifiesTable(); pkb->printModifiesProcTable(); /*cout<<"test here"<<endl; cout<<"getChildren 15"<<endl; set<STMTNUM> temp = pkb->getChildren(15); for(set<STMTNUM>::iterator it = temp.begin();it!=temp.end();it++){ cout<<*it<<endl; } cout<<"getParent 63"<<endl; cout<<pkb->getParent(63)<<endl;*/ QueryParser qp; QueryEvaluator qe = QueryEvaluator::QueryEvaluator(pkb); bool isValid = true; Query parsedQuery = qp.queryParse(query,isValid); if(!isValid){ //// cout << "Query Invalid" << endl; return; } //// cout<<"End parse query"<<endl; //// cout<<"Begin evaluate query"<<endl; vector<Relationship> newRelations; unordered_map<string, int> synIndexMap; unordered_map<int, vector<Pair>> clauseAnswers = qe.evaluateQuery(parsedQuery, &newRelations); //// cout<<"End evaluate query"<<endl; //// cout <<"Begin projecting results"<< endl; vector<vector<int>> tupleTable = createTupleTable(clauseAnswers, newRelations, &synIndexMap ); vector<string> selectedSyn = parsedQuery.getSelectedSyn(); unordered_map<string, TypeTable::SynType> synTable = parsedQuery.getSynTable(); set<string> ansSet; ansSet.insert(""); if(synTable.find(selectedSyn.at(0))->second == TypeTable::BOOLEAN) { if(tupleTable.size()!=0) result.push_back("true"); else result.push_back("false"); return; } //// cout << "Begin handling unprocessed selected synonyms" << endl; for(int i=0; i<int(selectedSyn.size()); i++) { //// cout << "Checking for the following syn: " << selectedSyn.at(i) << endl; if(synIndexMap.count(selectedSyn.at(i)) == 0) { //// cout << selectedSyn.at(i) << " has not been processed" << endl; unordered_map<string, TypeTable::SynType>::iterator it = synTable.find(selectedSyn.at(i)); vector<vector<int>> newTable; set<int> allOfType; if(it->second == TypeTable::VARIABLE) { allOfType = pkb->getAllVarIndex(); } else if(it->second == TypeTable::CONSTANT) { set<int> allConstIndex = pkb->getAllConstIndex(); ConstTable* constTable = pkb->getConstTable(); for(set<int>::iterator it=allConstIndex.begin(); it!=allConstIndex.end(); it++) { allOfType.insert(atoi(constTable->getConst(*it).c_str())); } } else if(it->second == TypeTable::PROCEDURE) { allOfType = pkb->getAllProcIndexes(); } else if(it->second == TypeTable::STMTLST) { allOfType = pkb->getAllStmtList(); } else { allOfType = pkb->getAllStmts(it->second); } for(vector<vector<int>>::iterator it1=tupleTable.begin(); it1!=tupleTable.end(); it1++) { for(set<int>::iterator it2=allOfType.begin(); it2!=allOfType.end(); it2++) { vector<int> newTuple; newTuple.insert(newTuple.begin(), it1->begin(), it1->end()); newTuple.push_back(*it2); newTable.push_back(newTuple); } } synIndexMap.insert(make_pair(selectedSyn.at(i), synIndexMap.size())); tupleTable = newTable; } else { //// cout << "Syn has already been processed." << endl; ;} } //// cout << "End handling unprocessed selected synonyms" << endl; if(tupleTable.size()==0) return; //// cout << "Begin creating tuple of answers" << endl; for(int i=0; i<int(tupleTable.size()); i++) { //// cout << "Creating tuple of answer " << i << endl; string ans = ""; for(int j=0; j<int(selectedSyn.size()); j++) { //// cout << "Adding \"" << selectedSyn.at(j) << " \"to tuple." << endl; unordered_map<string, TypeTable::SynType>::iterator it = synTable.find(selectedSyn.at(j)); int index = synIndexMap.at(selectedSyn.at(j)); //// cout << selectedSyn.at(j) << " has index " << index << endl; int tempAns = tupleTable.at(i).at(index); if(it->second == TypeTable::VARIABLE) { VarTable* varTable = pkb->getVarTable(); ans = ans + varTable->getVarName(tempAns) + " "; //// cout << "Adding " << varTable->getVarName(tempAns) << " to tuple" << endl; } /*else if(it->second == TypeTable::CONSTANT) { ConstTable* constTable = pkb->getConstTable(); ans = ans + constTable->getConst(tempAns) + " "; //// cout << "Adding " << constTable->getConst(tempAns) << " to tuple" << endl; }*/ else if(it->second == TypeTable::PROCEDURE && !parsedQuery.getSelectedSynIsCallProcedure().at(j)) { ProcTable* procTable = pkb->getProcTable(); ans = ans + procTable->getProcName(tempAns) + " "; //// cout << "Adding " << procTable->getProcName(tempAns) << " to tuple" << endl; } else { ans = ans + to_string(static_cast<long long>(tempAns)) + " "; //// cout << "Adding " << to_string(static_cast<long long>(tempAns)) << " to tuple" << endl; } //// cout << endl; } ans = ans.substr(0, ans.length()-1); //// cout << "Final Tuple: " << ans << endl; //// cout << endl; //// cout << endl; if(ansSet.find(ans) == ansSet.end()) { result.push_back(ans); ansSet.insert(ans); } } //// cout << "End creating tuple of answers" << endl; //// cout <<"End projecting results"<< endl; }