Пример #1
0
  /* Check if the Scan corresponding to the RelationSchema is already present in the join_operators. */
  boolean relationAlreadyContainedInAJoinOperator(BaseRelationSchema rs) {
    ScanOperator so = findScanOperator(rs);

    for (JoinOperator jo : join_operators)
      if ((so == jo.getLeftOperator()) || (so == jo.getRightOperator())) return true;

    return false;
  }
Пример #2
0
  /* Create a query plan, the operators etc. */
  boolean plan() {
    construct_scan_operators();

    if (query_relations.size() == 1) {
      /* It is a single table query. We are essentially done. */
      assert scan_operators.size() == 1;
      root = scan_operators.get(0);
    } else {
      /* Before creating the join operators, we will first choose an order in which to do the joins.
      For now, we will use a simple ordering that results in a left-deep plan.
      We will start with any join predicate, and create a join operator for that using the Scans.
      We will then choose some join predicate that does not require a Cartesian product. */

      /* Let's first create a Vector containing the join predicates. */
      Vector<Predicate> join_predicates_remaining = new Vector<Predicate>();
      for (Predicate p : query_predicates)
        if (p.isJoinPredicate()) join_predicates_remaining.add(p);

      if (join_predicates_remaining.size() != (scan_operators.size() - 1)) {
        System.out.println("=========> The query is not well formed");
        return false;
      }

      join_operators = new Vector<JoinOperator>();

      /* We will choose the first join operator arbitrarily. */
      int num_join_predicates = join_predicates_remaining.size();

      for (int i = 0; i < num_join_predicates; i++) {
        if (i == 0) {
          /* The first join predicate is used to create the bottommost join operator, with two scans as children. */
          Predicate jp = join_predicates_remaining.get(0);
          join_predicates_remaining.remove(0);

          ScanOperator left = findScanOperator(jp.leftRelationSchema());
          ScanOperator right = findScanOperator(jp.rightRelationSchema());

          join_operators.add(JoinOperator.createNewJoinOperator(left, right, jp));
        } else {
          /* Find the first join predicate whose left or right RelationSchema is already present. */
          Predicate next_jp = null;

          for (Predicate jp : join_predicates_remaining) {

            boolean leftContained =
                relationAlreadyContainedInAJoinOperator(jp.leftRelationSchema());
            boolean rightContained =
                relationAlreadyContainedInAJoinOperator(jp.rightRelationSchema());

            if (leftContained || rightContained) {
              if (leftContained && rightContained) {
                System.out.println(
                    "=========> Query not well-formed: There is a cycle in the query");
                return false;
              }

              /* We have found a valid join predicate. Break. */
              next_jp = jp;
              break;
            }
          }

          if (next_jp == null) {
            System.out.println(
                "=========> Query not well-formed: I think the query requires a Cartesian Product.");
            return false;
          }

          join_predicates_remaining.removeElement(next_jp);

          /* One quirk here is that we may need to swap the two arguments of the join predicate to match the left and right. */
          if (relationAlreadyContainedInAJoinOperator(next_jp.rightRelationSchema()))
            next_jp.swap();

          join_operators.add(
              JoinOperator.createNewJoinOperator(
                  join_operators.lastElement(),
                  findScanOperator(next_jp.rightRelationSchema()),
                  next_jp));
        }
      }

      /* Finally: we need to set the root to be the very last join operator. */
      root = join_operators.lastElement();
    }

    root = new ProjectOperator(root, select_attributes, distinct, order_by_attributes);

    return true;
  }