Пример #1
0
static LogicalOperator *solve_insubquery(Node *exprnode,
                                         LogicalOperator *input) {
  switch (exprnode->type) {
    case t_expr_cal: {
      Expr_cal *node = (Expr_cal *)exprnode;
      if (strcmp(node->sign, "INS") == 0) {
        if (node->rnext->type == t_query_stmt) {
          LogicalOperator *sublogicalplan = parsetree2logicalplan(
              node->rnext);  // 1.获得原子查询的logicalplan
          Query_stmt *subquery = (Query_stmt *)(node->rnext);
          vector<Attribute> group_by_attributes;
          vector<Attribute> aggregation_attributes;
          for (Node *p = subquery->select_list;
               p != NULL;)  // 2.1获得groupby的属性
          {
            Select_list *selectlist = (Select_list *)p;
            Select_expr *sexpr = (Select_expr *)selectlist->args;
            group_by_attributes.push_back(
                sublogicalplan->GetPlanContext().GetAttribute(
                    sexpr->ascolname));  ///????
            p = selectlist->next;
          }  // 2.2在1中的logicalplan上做groupby
          LogicalOperator *aggrection_sublogicalplan = new LogicalAggregation(
              group_by_attributes, std::vector<Attribute>(),
              std::vector<PhysicalAggregation::State::Aggregation>(),
              sublogicalplan);
          vector<LogicalEqualJoin::JoinPair> join_pair_list;
          Node *lp, *sp;
          for (lp = node->lnext, sp = ((Query_stmt *)node->rnext)->select_list;
               lp != NULL;)  // 3.1获得equaljoin的左右属性
          {
            Expr_list *lpexpr = (Expr_list *)lp;
            Columns *lcol = (Columns *)lpexpr->data;
            Select_list *spexpr = (Select_list *)sp;
            Columns *rcol = (Columns *)spexpr->args;
            join_pair_list.push_back(LogicalEqualJoin::JoinPair(
                input->GetPlanContext().GetAttribute(lcol->parameter2),
                sublogicalplan->GetPlanContext().GetAttribute(
                    rcol->parameter2)));
            lp = lpexpr->next;
            sp = spexpr->next;
          }
          LogicalOperator *join_logicalplan = new LogicalEqualJoin(
              join_pair_list, input, aggrection_sublogicalplan);
          return join_logicalplan;
        }
      }
    } break;
    default: {}
  }

  return NULL;
}
Пример #2
0
static LogicalOperator *where_from2logicalplan(
    Node *
        parsetree)  //实现where_from_parsetree(即将where转换到from_list后的)到logicalplan的转换
{
  if (parsetree == NULL) {
    return NULL;
  }
  switch (parsetree->type) {
    case t_table:  // table节点获得scan 和在该节点上condition的filter
    {
      Table *node = (Table *)parsetree;
      LogicalOperator *tablescan;
      if (node->issubquery == 0) {
        tablescan = new LogicalScan(Environment::getInstance()
                                        ->getCatalog()
                                        ->getTable(std::string(node->tablename))
                                        ->getProjectoin(0));  // todo

        //				// change for selecting best projection
        //				tablescan=new
        // LogicalScan(Environment::getInstance()->getCatalog()->getTable(std::string(node->tablename))->get_table_id());//
      } else  // need to modify the output_schema_attrname from the subquery to
              // the form of subquery's alias.attrname
      {
        tablescan = parsetree2logicalplan(node->subquery);
        vector<Attribute> output_attribute =
            tablescan->GetPlanContext().attribute_list_;
        vector<QNode *> exprTree;
        string subquery_alias = string(node->astablename);
        for (int i = 0; i < output_attribute.size(); i++) {
          string attrname = output_attribute[i].attrName;
          int pos;
          for (pos = 0; pos < attrname.size() && attrname[pos] != '.'; pos++)
            ;
          if (pos < attrname.size()) {
            attrname = attrname.substr(pos + 1, attrname.size() - pos - 1);
          }
          exprTree.push_back(
              new QColcumns(subquery_alias.c_str(), attrname.c_str(),
                            output_attribute[i].attrType->type,
                            string(subquery_alias + "." + attrname).c_str()));
          //					cout<<"The "<<i<<"
          //"<<subquery_alias+"."+attrname<<endl;
        }
        tablescan = new LogicalProject(tablescan, exprTree);
      }
      Expr_list_header *whcdn = (Expr_list_header *)node->whcdn;
      if (whcdn->header != NULL) {
        assert(tablescan != NULL);
        Node *p;
        bool hasin = false;
        vector<QNode *> v_qual;
        for (p = whcdn->header; p != NULL; p = ((Expr_list *)p)->next) {
          QNode *qual =
              transformqual((Node *)((Expr_list *)p)->data, tablescan);
          v_qual.push_back(qual);
        }
        LogicalOperator *filter = new LogicalFilter(tablescan, v_qual);
        if (hasin == true) {
          for (p = whcdn->header; p != NULL; p = ((Expr_list *)p)->next) {
            filter = solve_insubquery(((Expr_list *)p)->data, filter);
          }
        }
        return filter;
      } else {
        return tablescan;
      }

    } break;
    case t_from_list:  //由from_list递归进入args/next,并获得在其上的equaljoin
    {
      From_list *node = (From_list *)parsetree;
      LogicalOperator *filter_1 = where_from2logicalplan(node->args);
      LogicalOperator *filter_2 =
          where_from2logicalplan(node->next);  // maybe NULL
      LogicalOperator *lopfrom = NULL;
      if (filter_2 == NULL)  // a join b on c where a.a>0;
      {
        Expr_list_header *whcdn = (Expr_list_header *)node->whcdn;
        if (whcdn->header != NULL) {
          Node *p;
          vector<QNode *> v_qual;
          for (
              p = whcdn->header; p != NULL;
              p = ((Expr_list *)
                   p)->next)  //应该根据getdataflow的信息确定joinpair跟filter1/2是否一致
          {
            QNode *qual =
                transformqual((Node *)((Expr_list *)p)->data, filter_1);
            v_qual.push_back(qual);
          }
          if (v_qual.size() > 0) {
            lopfrom = new LogicalFilter(filter_1, v_qual);
          } else {
            lopfrom = filter_1;
          }
          return lopfrom;
        } else {
          return filter_1;
        }
      }
      Expr_list_header *whcdn = (Expr_list_header *)node->whcdn;
      if (whcdn->header != NULL) {
        vector<LogicalEqualJoin::JoinPair> join_pair_list;
        Node *p;
        vector<QNode *> v_qual;
        vector<Node *> raw_qual;
        for (p = whcdn->header; p != NULL; p = ((Expr_list *)p)->next) {
          int fg = getjoinpairlist((Node *)((Expr_list *)p)->data,
                                   join_pair_list, filter_1, filter_2);
          if (fg == 0)  // get raw qualification from whcdn
          {
            raw_qual.push_back((Node *)((Expr_list *)p)->data);
          }
        }
        if (join_pair_list.size() > 0) {
          lopfrom = new LogicalEqualJoin(join_pair_list, filter_1, filter_2);
        } else  // other join
        {
          lopfrom = new LogicalCrossJoin(filter_1, filter_2);
        }
        for (int i = 0; i < raw_qual.size(); i++) {
          v_qual.push_back(transformqual(raw_qual[i], lopfrom));
        }
        if (v_qual.size() > 0) {
          lopfrom = new LogicalFilter(lopfrom, v_qual);
        }
        return lopfrom;
      } else  // other to crossjoin
      {
        lopfrom = new LogicalCrossJoin(filter_1, filter_2);
        return lopfrom;
      }

    } break;
    case t_join: {
      Join *node = (Join *)parsetree;
      LogicalOperator *filter_1 = where_from2logicalplan(node->lnext);
      LogicalOperator *filter_2 = where_from2logicalplan(node->rnext);
      if (node->condition != NULL) {
        vector<LogicalEqualJoin::JoinPair> join_pair_list;
        Node *p;
        vector<QNode *> v_qual;
        vector<Node *> raw_qual;
        for (p = node->condition; p != NULL; p = ((Expr_list *)p)->next) {
          int fg = getjoinpairlist((Node *)((Expr_list *)p)->data,
                                   join_pair_list, filter_1, filter_2);
          if (fg == 0)  // get raw qualification from whcdn
          {
            raw_qual.push_back((Node *)((Expr_list *)p)->data);
          }
        }

        LogicalOperator *join;
        if (join_pair_list.size() > 0) {
          join = new LogicalEqualJoin(join_pair_list, filter_1, filter_2);
        } else  // other join
        {
          join = new LogicalCrossJoin(filter_1, filter_2);
        }
        for (int i = 0; i < raw_qual.size(); i++) {
          v_qual.push_back(transformqual(raw_qual[i], join));
        }
        if (v_qual.size() > 0) {
          join = new LogicalFilter(join, v_qual);
        }
        return join;
      } else  // other to crossjoin
      {
        LogicalOperator *join = new LogicalCrossJoin(filter_1, filter_2);
        return join;
      }

    } break;
    default: {
      SQLParse_elog("parsetree2logicalplan type error");
      return NULL;
    }
  }
  return NULL;
}