Exemple #1
0
//---------------------------------------------------------------------------
static void collectVariables(const QueryGraph& query,set<unsigned>& vars,const void* except)
   // Collect all variables used in a query
{
   for (QueryGraph::projection_iterator iter=query.projectionBegin(),limit=query.projectionEnd();iter!=limit;++iter)
      vars.insert(*iter);
   if (except!=(&(query.getQuery())))
      collectVariables(query.getQuery(),vars,except);
}
Exemple #2
0
//---------------------------------------------------------------------------
static void runQuery(Database& db,const string& query,bool explain)
   // Evaluate a query
{
   QueryGraph queryGraph;
   {
      // Parse the query
      SPARQLLexer lexer(query);
      SPARQLParser parser(lexer);
      try {
         parser.parse();
      } catch (const SPARQLParser::ParserException& e) {
         cerr << "parse error: " << e.message << endl;
         return;
      }

      // And perform the semantic anaylsis
      try {
         SemanticAnalysis semana(db);
         semana.transform(parser,queryGraph);
      } catch (const SemanticAnalysis::SemanticException& e) {
         cerr << "semantic error: " << e.message << endl;
         return;
      }
      if (queryGraph.knownEmpty()) {
         if (explain)
            cerr << "static analysis determined that the query result will be empty" << endl; else
            cout << "<empty result>" << endl;
         return;
      }
   }

   // Run the optimizer
   PlanGen plangen;
   Plan* plan=plangen.translate(db,queryGraph);
   //plan->print(6);
   if (!plan) {
      cerr << "internal error plan generation failed" << endl;
      return;
   }

   // Build a physical plan
   Runtime runtime(db);
   Operator* operatorTree=CodeGen().translate(runtime,queryGraph,plan,false);

   // Explain if requested
   if (explain) {
      DebugPlanPrinter out(runtime,false);
      operatorTree->print(out);
   } else {
      // Else execute it
      if (operatorTree->first()) {
         while (operatorTree->next()) ;
      }
   }

   delete operatorTree;
}
Exemple #3
0
//---------------------------------------------------------------------------
static bool isUnused(const QueryGraph& query,const QueryGraph::Node& node,unsigned val)
   // Check if a variable is unused outside its primary pattern
{
   for (QueryGraph::projection_iterator iter=query.projectionBegin(),limit=query.projectionEnd();iter!=limit;++iter)
      if ((*iter)==val)
         return false;

   return isUnused(query.getQuery(),node,val);
}
Exemple #4
0
void SemanticAnalyzer::execute(QueryGraph& queryGraph) {
  init();

  ::Attribute tableAttr;
  for (Parser::Attribute& attr : result.projections) {
    analyzeAttribute(attr, "SELECT", tableAttr);
  }

  for (auto relation : result.relations) {
    queryGraph.createNode(relation, database.getTable(relation.relation));
  }

  // Check that all selections are valid
  for (auto selection : result.selections) {
    Parser::Attribute& attr = selection.first;
    Parser::Constant& c = selection.second;

    ::Attribute tableAttr;
    analyzeAttribute(attr, "WHERE", tableAttr);

    if (tableAttr.getType() != c.type) {
      throw SemanticError("Attribute '" + attr.name + "' and constant '" + c.value + "' do not have the same type (WHERE clause)");
    }

    queryGraph.addSelection(attr, c);
  }

  // Check that all joins are valid
  for (auto joinCondition : result.joinConditions) {
    Parser::Attribute& attr1 = joinCondition.first;
    Parser::Attribute& attr2 = joinCondition.second;

    ::Attribute tableAttr1;
    ::Attribute tableAttr2;
    analyzeAttribute(attr1, "WHERE", tableAttr1);
    analyzeAttribute(attr2, "WHERE", tableAttr2);

    if (tableAttr1.getType() != tableAttr2.getType()) {
      throw SemanticError("Attributes '" + attr1.name + "' and '" + attr2.name + "' do not have the same type (WHERE clause");
    }

    queryGraph.createEdge(attr1, attr2, tableAttr1, tableAttr2);
  }
}
Exemple #5
0
//---------------------------------------------------------------------------
static void evalQuery(Database& db,const string& query,bool silent)
   // Evaluate a query
{
   QueryGraph queryGraph;
   {
      // Parse the query
      SPARQLLexer lexer(query);
      SPARQLParser parser(lexer);
      try {
         parser.parse();
      } catch (const SPARQLParser::ParserException& e) {
         cout << "parse error: " << e.message << endl;
         return;
      }

      // And perform the semantic anaylsis
      try {
         SemanticAnalysis semana(db);
         semana.transform(parser,queryGraph);
      } catch (const SemanticAnalysis::SemanticException& e) {
         cout << "semantic error: " << e.message << endl;
         return;
      }
      if (queryGraph.knownEmpty()) {
         cout << "<empty result>" << endl;
         return;
      }
   }

   // Run the optimizer
   PlanGen plangen;
   Plan* plan=plangen.translate(db,queryGraph);
   if (!plan) {
      cout << "plan generation failed" << endl;
      return;
   }
   if (getenv("SHOWCOSTS"))
      plan->print(0);
   if (getenv("DISABLESKIPPING"))
      Operator::disableSkipping=true;

   // Build a physical plan
   TemporaryDictionary tempDict(db.getDictionary());
   Runtime runtime(db,0,&tempDict);
   Operator* operatorTree=CodeGen().translate(runtime,queryGraph,plan,silent);

   if (getenv("SHOWPLAN")) {
      DebugPlanPrinter out(runtime,false);
      operatorTree->print(out);
   }

   // And execute it
   Scheduler scheduler;
   Timestamp start;
   scheduler.execute(operatorTree);
   Timestamp stop;
   cout << "Execution time: " << (stop-start) << " ms" << endl;

   if (getenv("SHOWCARD")) {
      DebugPlanPrinter out(runtime,true);
      operatorTree->print(out);
   }

   delete operatorTree;
}
//---------------------------------------------------------------------------
static bool evalQuery(Database& db,SPARQLLexer& lexer,ostream& planOut,ostream& statsOut,bool showJoins)
   // Evaluate a query
{
   QueryGraph queryGraph;
   std::string::const_iterator queryStart=lexer.getReader();
   {
      // Parse the query
      SPARQLParser parser(lexer);
      try {
         parser.parse(true);
      } catch (const SPARQLParser::ParserException& e) {
         cerr << "parse error: " << e.message << endl;
         return false;
      }

      // And perform the semantic anaylsis
      SemanticAnalysis semana(db);
      semana.transform(parser,queryGraph);
      if (queryGraph.knownEmpty()) {
         cerr << "known empty result ignored" << endl;
         return true;
      }
   }

   // Run the optimizer
   PlanGen plangen;
   Plan* plan=plangen.translate(db,queryGraph);
   if (!plan) {
      cerr << "plan generation failed" << endl;
      return true;
   }
   Operator::disableSkipping=true;

   // Build a physical plan
   Runtime runtime(db);
   Operator* operatorTree=CodeGen().translate(runtime,queryGraph,plan,true);
   Operator* root=dynamic_cast<ResultsPrinter*>(operatorTree)->getInput();

   // And execute it
   Scheduler scheduler;
   scheduler.execute(root);
   Timestamp stop;

   // Write the plan
   planOut << "# SPARQL Query:" << endl << "# ";
   std::string::const_iterator queryEnd=lexer.getReader();
   for (string::const_iterator iter=queryStart;iter!=queryEnd;++iter)
      if ((*iter)=='\n')
         planOut << endl << "# "; else
         planOut << *iter;
   planOut << endl << endl << "# Execution plan: <Operator expectedCardinality observedCardinalit [args] [input]>" << endl << endl;
   {
      DebugPlanPrinter out(planOut,runtime,true);
      root->print(out);
   }

   // Write the selectivities
   {
      if (showJoins)
         statsOut << "# relations joinVar1 joinVar2 bindings expectedSelectivity observedSelectivity" << endl; else
         statsOut << "# Stats: {relations} {new predicates(s)} {previous predicate(s)} expectedCardinality observedCardinality expectedSelectivity observedSelectivity" << endl;
      PredicateCollector out(statsOut,runtime,showJoins);
      root->print(out);
   }

   delete operatorTree;
   return true;
}
//---------------------------------------------------------------------------
void SemanticAnalysis::transform(const SPARQLParser& input,QueryGraph& output)
   // Perform the transformation
{
   output.clear();

   if (!transformSubquery(dict,diffIndex,input.getPatterns(),output.getQuery())) {
      // A constant could not be resolved. This will produce an empty result
      output.markAsKnownEmpty();
      return;
   }

   // Compute the edges
   output.constructEdges();

   // Add the projection entry
   for (SPARQLParser::projection_iterator iter=input.projectionBegin(),limit=input.projectionEnd();iter!=limit;++iter)
      output.addProjection(*iter);

   // Set the duplicate handling
   switch (input.getProjectionModifier()) {
      case SPARQLParser::Modifier_None: output.setDuplicateHandling(QueryGraph::AllDuplicates); break;
      case SPARQLParser::Modifier_Distinct: output.setDuplicateHandling(QueryGraph::NoDuplicates); break;
      case SPARQLParser::Modifier_Reduced: output.setDuplicateHandling(QueryGraph::ReducedDuplicates); break;
      case SPARQLParser::Modifier_Count: output.setDuplicateHandling(QueryGraph::CountDuplicates); break;
      case SPARQLParser::Modifier_Duplicates: output.setDuplicateHandling(QueryGraph::ShowDuplicates); break;
   }

   // Order by clause
   for (SPARQLParser::order_iterator iter=input.orderBegin(),limit=input.orderEnd();iter!=limit;++iter) {
      QueryGraph::Order o;
      if (~(*iter).id) {
         if (!binds(input.getPatterns(),(*iter).id))
            continue;
         o.id=(*iter).id;
      } else {
         o.id=~0u;
      }
      o.descending=(*iter).descending;
      output.addOrder(o);
   }

   // Set the limit
   output.setLimit(input.getLimit());
}