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; }
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; }