示例#1
0
TEST_F(BinderCorrectnessTest, DeleteStatementTest) {
  SetupTables();
  auto& parser = parser::PostgresParser::GetInstance();
  catalog::Catalog* catalog_ptr = catalog::Catalog::GetInstance();

  oid_t db_oid = catalog_ptr->GetDatabaseWithName(DEFAULT_DB_NAME)->GetOid();
  oid_t tableB_oid =
      catalog_ptr->GetTableWithName(DEFAULT_DB_NAME, "b")->GetOid();

  string deleteSQL = "DELETE FROM b WHERE 1 = b1 AND b2 = 'str'";
  unique_ptr<binder::BindNodeVisitor> binder(new binder::BindNodeVisitor());
  auto parse_tree = parser.BuildParseTree(deleteSQL);
  auto deleteStmt =
      dynamic_cast<parser::DeleteStatement*>(parse_tree->GetStatements().at(0));
  binder->BindNameToNode(deleteStmt);

  LOG_INFO("Checking first condition in where clause");
  auto tupleExpr =
      (expression::TupleValueExpression*)deleteStmt->expr->GetChild(0)
          ->GetChild(1);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableB_oid, 0));

  LOG_INFO("Checking second condition in where clause");
  tupleExpr = (expression::TupleValueExpression*)deleteStmt->expr->GetChild(1)
                  ->GetChild(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableB_oid, 1));

  // Delete the test database
  auto& txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog_ptr->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}
示例#2
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // alias widget
    SetupWidgetAlias();
    // init
    CreateActions();
    CreateMainMenus();
    CreateToolBar();
    // setup table
    editWindow = new EditWindow(0);
    setCentralWidget(editWindow);
    // setup table
    SetupTables();

    //connect signal-slot
    SetupConnectWidgets();

}
示例#3
0
文件: loopsplit.cpp 项目: wh5a/xgill
void SplitLoops(BlockCFG *base_cfg, Vector<BlockCFG*> *result_cfg_list)
{
    // get the CFG which will eventually become the loop-free outer function CFG.
    BlockCFG *func_cfg;
    if (base_cfg->GetId()->Kind() == B_FunctionWhole) {
        // make an ID for the outer function body.
        Variable *function_info = base_cfg->GetId()->BaseVar();
        function_info->IncRef();
        BlockId *outer_id = BlockId::Make(B_Function, function_info);

        // make the function CFG by cloning the base CFG with the new ID.
        func_cfg = BlockCFG::Make(outer_id);
        CopyCFGLocationsVariables(base_cfg, func_cfg);
        CopyCFGPointsEdges(base_cfg, func_cfg);
    }
    else if (base_cfg->GetId()->Kind() == B_Function) {
        // this call came from a recursive invocation of SplitLoops after we
        // removed an irreducible loop from the function.
        func_cfg = base_cfg;
    }
    else {
        // just destructively update the original CFG.
        base_cfg->IncRef();
        func_cfg = base_cfg;
    }

    // add a new entry point with a skip edge to the original entry point.
    // loop splitting breaks if the entry point is marked as a loop head.

    PPoint entry = func_cfg->GetEntryPoint();
    Location *loc = func_cfg->GetPointLocation(entry);
    loc->IncRef();
    PPoint new_entry = func_cfg->AddPoint(loc);

    PEdge *skip_edge = PEdge::MakeSkip(new_entry, entry);
    func_cfg->AddEdge(skip_edge);
    func_cfg->SetEntryPoint(new_entry);

    // setup the tables we need to do loop splitting.
    SetupTables();

    // compute the points reachable from the entry point.
    GetEntryReachable(func_cfg);

    // the real loops in the program with back edges.
    Vector<PPoint> loops;

    for (size_t lind = 0; lind < func_cfg->GetLoopHeadCount(); lind++) {
        PPoint head = func_cfg->GetLoopHead(lind).point;
        if (GetLoopBackedges(func_cfg, head))
            loops.PushBack(head);
    }

    // compute reachability and check for irreducible loops.
    for (size_t lind = 0; lind < func_cfg->GetLoopHeadCount(); lind++) {
        const LoopHead &head = func_cfg->GetLoopHead(lind);

        if (GetLoopReachable(func_cfg, head.point)) {
            // loop is irreducible.

            // get the loop's irreducible edges.
            Vector<PEdge*> irreducible_edges;
            GetLoopBody(func_cfg, head.point, &irreducible_edges);
            Assert(!irreducible_edges.Empty());

            // clone the loop's body and remove the irreducible edges.
            ReduceLoop(func_cfg, head.point, irreducible_edges);

            // try again on the modified CFG.
            CleanupTables();
            SplitLoops(func_cfg, result_cfg_list);
            return;
        }
    }

    // there are no irreducible loops at this point so this should
    // never have any entries added.
    Vector<PEdge*> irreducible_edges;

    // compute loop bodies.
    for (size_t lind = 0; lind < loops.Size(); lind++) {
        PPoint head = loops[lind];
        GetLoopBody(func_cfg, head, &irreducible_edges);
        Assert(irreducible_edges.Empty());
    }

    // construct a tree of all the loops. loop A contains loop B
    // if A != B and the head of B is in the body of A.
    PPointListHash loop_tree;

    // split off all the loops in the CFG. make sure we split inner loops
    // before outer, so that the Loop edges on inner loops will appear in
    // the split body for outer loops.
    while (!loops.Empty()) {

        // find a candidate loop to split. this is one whose loop children
        // have already been split off and are no longer in the loops list.
        PPoint loophead = 0;
        for (size_t lind = 0; lind < loops.Size(); lind++) {

            bool is_viable = true;
            for (size_t xlind = 0; xlind < loops.Size(); xlind++) {
                if (xlind == lind)
                    continue;
                Assert(loops[lind] != loops[xlind]);

                if (body_table->Lookup(PPointPair(loops[lind], loops[xlind]))) {
                    is_viable = false;
                    break;
                }
            }

            if (is_viable) {
                loophead = loops[lind];
                loops[lind] = loops.Back();
                loops.PopBack();
                break;
            }
        }

        Assert(loophead);
        BlockCFG *loop_cfg = SplitSingleLoop(loophead, loops, func_cfg);
        result_cfg_list->PushBack(loop_cfg);
    }

    // clear out the loopheads, we don't want them around anymore.
    func_cfg->ClearLoopHeads();

    // trim unreachable points in the function CFG (i.e. bodies of loops that
    // now redirect to point zero), collapse skips and topo sort.
    TrimUnreachable(func_cfg, true);
    TopoSortCFG(func_cfg);

    result_cfg_list->PushBack(func_cfg);
    CleanupTables();

    // fill in any loop parents for the inner loop CFGs, and make sure the
    // result CFGs are ordered correctly, with inner loops before outer loops
    // and the outer function.
    for (size_t cind = 0; cind < result_cfg_list->Size(); cind++) {
        BlockCFG *cfg = result_cfg_list->At(cind);

        for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) {
            if (PEdgeLoop *edge = cfg->GetEdge(eind)->IfLoop()) {
                BlockId *target_id = edge->GetLoopId();

                bool found_target = false;
                for (size_t xcind = 0; xcind < cind; xcind++) {
                    BlockCFG *xcfg = result_cfg_list->At(xcind);
                    if (xcfg->GetId() == target_id) {
                        found_target = true;

                        cfg->GetId()->IncRef();
                        BlockPPoint where(cfg->GetId(), edge->GetSource());
                        xcfg->AddLoopParent(where);

                        // mark the isomorphic points in the parent CFG.
                        GetLoopIsomorphicPoints(cfg, edge, xcfg);

                        break;
                    }
                }

                Assert(found_target);
            }
        }
    }

    // assign the final names to the various loop CFGs.
    FillLoopNames(func_cfg, "loop", *result_cfg_list);
}
示例#4
0
TEST_F(BinderCorrectnessTest, SelectStatementTest) {
  SetupTables();
  auto& parser = parser::PostgresParser::GetInstance();
  catalog::Catalog* catalog_ptr = catalog::Catalog::GetInstance();

  // Test regular table name
  LOG_INFO("Parsing sql query");
  unique_ptr<binder::BindNodeVisitor> binder(new binder::BindNodeVisitor());
  string selectSQL =
      "SELECT A.a1, B.b2 FROM A INNER JOIN b ON a.a1 = b.b1 "
      "WHERE a1 < 100 GROUP BY A.a1, B.b2 HAVING a1 > 50 "
      "ORDER BY a1";

  auto parse_tree = parser.BuildParseTree(selectSQL);
  auto selectStmt =
      dynamic_cast<parser::SelectStatement*>(parse_tree->GetStatements().at(0));
  binder->BindNameToNode(selectStmt);

  oid_t db_oid = catalog_ptr->GetDatabaseWithName(DEFAULT_DB_NAME)->GetOid();
  oid_t tableA_oid =
      catalog_ptr->GetTableWithName(DEFAULT_DB_NAME, "a")->GetOid();
  oid_t tableB_oid =
      catalog_ptr->GetTableWithName(DEFAULT_DB_NAME, "b")->GetOid();

  // Check select_list
  LOG_INFO("Checking select list");
  auto tupleExpr =
      (expression::TupleValueExpression*)(*selectStmt->select_list)[0];
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableA_oid, 0));  // A.a1
  EXPECT_EQ(type::TypeId::INTEGER, tupleExpr->GetValueType());
  tupleExpr = (expression::TupleValueExpression*)(*selectStmt->select_list)[1];
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableB_oid, 1));  // B.b2
  EXPECT_EQ(type::TypeId::VARCHAR, tupleExpr->GetValueType());
  

  // Check join condition
  LOG_INFO("Checking join condition");
  tupleExpr = (expression::TupleValueExpression*)
                  selectStmt->from_table->join->condition->GetChild(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableA_oid, 0));  // a.a1
  tupleExpr = (expression::TupleValueExpression*)
                  selectStmt->from_table->join->condition->GetChild(1);
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableB_oid, 0));  // b.b1

  // Check Where clause
  LOG_INFO("Checking where clause");
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->where_clause->GetChild(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 0));  // a1

  // Check Group By and Having
  LOG_INFO("Checking group by");
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->group_by->columns->at(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableA_oid, 0));  // A.a1
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->group_by->columns->at(1);
  EXPECT_EQ(tupleExpr->GetBoundOid(),
            make_tuple(db_oid, tableB_oid, 1));  // B.b2
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->group_by->having->GetChild(
          0);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 0));  // a1

  // Check Order By
  LOG_INFO("Checking order by");
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->order->exprs->at(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 0));  // a1

  // Check alias ambiguous
  LOG_INFO("Checking duplicate alias and table name.");
  binder.reset(new binder::BindNodeVisitor());
  selectSQL = "SELECT * FROM A, B as A";
  parse_tree = parser.BuildParseTree(selectSQL);
  selectStmt = (parser::SelectStatement*)(parse_tree->GetStatements().at(0));
  try {
    binder->BindNameToNode(selectStmt);
    EXPECT_TRUE(false);
  } catch (Exception& e) {
    LOG_INFO("Correct! Exception(%s) catched", e.what());
  }

  // Test select from different table instances from the same physical schema
  binder.reset(new binder::BindNodeVisitor());
  selectSQL = "SELECT * FROM A, A as AA where A.a1 = AA.a2";
  parse_tree = parser.BuildParseTree(selectSQL);
  selectStmt = (parser::SelectStatement*)(parse_tree->GetStatements().at(0));
  binder->BindNameToNode(selectStmt);
  LOG_INFO("Checking where clause");
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->where_clause->GetChild(0);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 0));  // a1
  tupleExpr =
      (expression::TupleValueExpression*)selectStmt->where_clause->GetChild(1);
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 1));  // a1

  // Test alias and select_list
  LOG_INFO("Checking select_list and table alias binding");
  binder.reset(new binder::BindNodeVisitor());
  selectSQL = "SELECT AA.a1, b2 FROM A as AA, B WHERE AA.a1 = B.b1";
  parse_tree = parser.BuildParseTree(selectSQL);
  selectStmt = (parser::SelectStatement*)(parse_tree->GetStatements().at(0));
  binder->BindNameToNode(selectStmt);
  tupleExpr =
      (expression::TupleValueExpression*)(selectStmt->select_list->at(0));
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableA_oid, 0));
  tupleExpr =
      (expression::TupleValueExpression*)(selectStmt->select_list->at(1));
  EXPECT_EQ(tupleExpr->GetBoundOid(), make_tuple(db_oid, tableB_oid, 1));

  // Delete the test database
  auto& txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog_ptr->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}