int ObLogicalPlan::fill_result_set(ObResultSet& result_set, ObSQLSessionInfo* session_info, common::StackAllocator &alloc)
        {
            int ret = OB_SUCCESS;
            result_set.set_affected_rows(0);
            result_set.set_warning_count(0);
            result_set.set_message("");

            ObSelectStmt *select_stmt = NULL;
            ObResultSet::Field field;
            switch (stmts_[0]->get_stmt_type())
            {
                case ObStmt::T_PREPARE:
                {
                    ObPrepareStmt *prepare_stmt = static_cast<ObPrepareStmt*> (stmts_[0]);
                    ObBasicStmt *stmt = get_query(prepare_stmt->get_prepare_query_id());
                    if (stmt == NULL)
                    {
                        ret = OB_ERR_ILLEGAL_ID;
                        jlog(WARN, "wrong prepared query id, id = %lu, ret = %d", prepare_stmt->get_prepare_query_id(), ret);
                        break;
                    }
                        // only select prepare statement need to fill result set
                    else if (stmt->get_stmt_type() != ObBasicStmt::T_SELECT)
                    {
                        break;
                    }
                    else
                    {
                        select_stmt = static_cast<ObSelectStmt*> (stmt);
                        /* then get through */
                    }
                }
                case ObStmt::T_SELECT:
                {
                    if (stmts_[0]->get_stmt_type() == ObBasicStmt::T_SELECT)
                        select_stmt = static_cast<ObSelectStmt*> (stmts_[0]);
                    if (select_stmt == NULL)
                    {
                        ret = OB_ERR_PARSE_SQL;
                        jlog(WARN, "logical plan of select statement error");
                        break;
                    }
                    uint32_t size = select_stmt->get_select_item_size();
                    for (uint32_t i = 0; ret == OB_SUCCESS && i < size; i++)
                    {
                        const SelectItem& select_item = select_stmt->get_select_item(i);
                        if ((ret = ob_write_string(select_item.expr_name_, field.cname_)) != OB_SUCCESS)
                        {
                            jlog(WARN, "fail to alloc string[%.*s] ret=%d", select_item.expr_name_.size(), select_item.expr_name_.data(), ret);
                            break;
                        }

                        ObSqlRawExpr* sql_expr = get_expr(select_item.expr_id_);
                        if (sql_expr == NULL)
                        {
                            jlog(WARN, "fail to get expr. select_item.expr_id_=%lu", select_item.expr_id_);
                            ret = OB_ERR_ILLEGAL_ID;
                            break;
                        }
                        field.type_.set_type(sql_expr->get_result_type());
                        ObRawExpr* expr = sql_expr->get_expr();
                        if (select_stmt->get_set_op() != ObSelectStmt::NONE)
                        {
                            if ((ret = ob_write_string(select_item.expr_name_, field.org_cname_)) != OB_SUCCESS)
                            {
                                jlog(WARN, "fail to alloc string[%.*s] ret=%d", select_item.expr_name_.size(), select_item.expr_name_.data(), ret);
                                break;
                            }
                        }
                        else if (expr->get_expr_type() == T_REF_COLUMN)
                        {
                            ObBinaryRefRawExpr *column_expr = static_cast<ObBinaryRefRawExpr*> (expr);
                            uint64_t table_id = column_expr->get_first_ref_id();
                            uint64_t column_id = column_expr->get_second_ref_id();
                            if (table_id != OB_INVALID_ID)
                            {
                                ColumnItem *column_item = select_stmt->get_column_item_by_id(table_id, column_id);
                                if (column_item == NULL)
                                {
                                    jlog(WARN, "fail to get column item by id. table_id=%lu column_id=%lu", table_id, column_id);
                                    ret = OB_ERR_ILLEGAL_ID;
                                    break;
                                }
                                if (OB_SUCCESS != (ret = ob_write_string(column_item->column_name_, field.org_cname_)))
                                {
                                    jlog(WARN, "fail to alloc string[%.*s] ret=%d", column_item->column_name_.size(), column_item->column_name_.data(), ret);
                                    break;
                                }
                                TableItem *table_item = select_stmt->get_table_item_by_id(table_id);
                                if (table_item == NULL)
                                {
                                    jlog(WARN, "fail to get table item by id. table_id=%lu", table_id);
                                    ret = OB_ERR_ILLEGAL_ID;
                                    break;
                                }
                                if (table_item->alias_name_.size() > 0)
                                {
                                    if (OB_SUCCESS != (ret = ob_write_string(table_item->alias_name_, field.tname_)))
                                    {
                                        jlog(WARN, "fail to alloc string[%.*s] ret=%d", table_item->alias_name_.size(), table_item->alias_name_.data(), ret);
                                        break;
                                    }
                                }
                                else
                                {
                                    if (OB_SUCCESS != (ret = ob_write_string(table_item->table_name_, field.tname_)))
                                    {
                                        jlog(WARN, "fail to alloc string[%.*s] ret=%d", table_item->table_name_.size(), table_item->table_name_.data(), ret);
                                        break;
                                    }
                                }
                                if (OB_SUCCESS != (ret = ob_write_string(table_item->table_name_, field.org_tname_)))
                                {
                                    jlog(WARN, "fail to alloc string[%.*s] ret=%d", table_item->table_name_.size(), table_item->table_name_.data(), ret);
                                    break;
                                }
                            }
                        }
                        if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                        {
                            jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                            break;
                        }

                        field.cname_.assign("");
                        field.org_cname_.assign("");
                        field.tname_.assign("");
                        field.org_tname_.assign("");
                        field.type_.set_type(ObMinType);
                    }
                    break;
                }
                case ObStmt::T_EXPLAIN:
                {
                    ObString tname = ObString::make_string("explain_table");
                    ObString cname = ObString::make_string("Query Plan");
                    field.tname_ = tname;
                    field.org_tname_ = tname;
                    field.cname_ = cname;
                    field.org_cname_ = cname;
                    field.type_.set_type(ObVarcharType);
                    if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                    {
                        jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                        break;
                    }
                    break;
                }
                case ObStmt::T_SHOW_TABLES:
                case ObStmt::T_SHOW_VARIABLES:
                case ObStmt::T_SHOW_COLUMNS:
                case ObStmt::T_SHOW_SCHEMA:
                case ObStmt::T_SHOW_CREATE_TABLE:
                case ObStmt::T_SHOW_TABLE_STATUS:
                case ObStmt::T_SHOW_SERVER_STATUS:
                case ObStmt::T_SHOW_PARAMETERS:
                {
                    ObShowStmt *show_stmt = static_cast<ObShowStmt*> (stmts_[0]);
                    if (show_stmt == NULL)
                    {
                        jlog(WARN, "fail to get Show statement");
                        ret = OB_ERR_PARSE_SQL;
                        break;
                    }
                    TableItem *table_item = show_stmt->get_table_item_by_id(show_stmt->get_sys_table_id());
                    if (table_item == NULL)
                    {
                        jlog(WARN, "fail to get table item by id. table_id=%lu", show_stmt->get_sys_table_id());
                        ret = OB_ERR_ILLEGAL_ID;
                        break;
                    }
                    ObString tname;
                    if (OB_SUCCESS != (ret = ob_write_string(table_item->table_name_, tname)))
                    {
                        jlog(WARN, "fail to alloc string \"%.*s\" ret=%d", table_item->table_name_.size(), table_item->table_name_.data(), ret);
                        break;
                    }
                    field.tname_ = tname;
                    field.org_tname_ = tname;
                    for (uint32_t i = 0; ret == OB_SUCCESS && i < show_stmt->get_column_size(); i++)
                    {
                        ObString cname;
                        const ColumnItem *col_item = show_stmt->get_column_item(i);
                        if (col_item != NULL)
                        {
                            if (OB_SUCCESS != (ret = ob_write_string(col_item->column_name_, cname)))
                            {
                                jlog(WARN, "fail to alloc string \"%.*s\" ret=%d", col_item->column_name_.size(), col_item->column_name_.data(), ret);
                                break;
                            }
                            field.cname_ = cname;
                            field.org_cname_ = cname;
                            field.type_.set_type(col_item->data_type_);
                            if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                            {
                                jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                                break;
                            }
                            field.cname_.assign("");
                            field.org_cname_.assign("");
                            field.type_.set_type(ObMinType);
                        }
                    }
                    break;
                }
                case ObStmt::T_SHOW_WARNINGS:
                {
                    ObString tname = ObString::make_string("show warnings");
                    ObShowStmt *show_stmt = static_cast<ObShowStmt*> (stmts_[0]);
                    if (show_stmt == NULL)
                    {
                        jlog(WARN, "fail to get Show statement");
                        ret = OB_ERR_PARSE_SQL;
                        break;
                    }
                    else
                    {
                        field.tname_ = tname;
                        field.org_tname_ = tname;
                    }
                    if (show_stmt->is_count_warnings())
                    {
                        ObString cname = ObString::make_string("warning_count");
                        field.cname_ = cname;
                        field.org_cname_ = cname;
                        field.type_.set_type(ObIntType);
                        if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                        {
                            jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                            break;
                        }
                    }
                    else
                    {
                        ObString cname[3];
                        cname[0] = ObString::make_string("level");
                        cname[1] = ObString::make_string("code");
                        cname[2] = ObString::make_string("message");
                        for (uint32_t i = 0; ret == OB_SUCCESS && i < 3; i++)
                        {
                            field.cname_ = cname[i];
                            field.org_cname_ = cname[i];
                            if (i == 1)
                                field.type_.set_type(ObIntType);
                            else
                                field.type_.set_type(ObVarcharType);
                            if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                            {
                                jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                                break;
                            }
                        }
                    }
                    break;
                }
                case ObStmt::T_SHOW_GRANTS:
                {
                    ObString tname = ObString::make_string("show grants");
                    ObString cname = ObString::make_string("grants");
                    field.tname_ = tname;
                    field.org_tname_ = tname;
                    field.cname_ = cname;
                    field.org_cname_ = cname;
                    field.type_.set_type(ObVarcharType);
                    if (OB_SUCCESS != (ret = result_set.add_field_column(field)))
                    {
                        jlog(WARN, "fail to add field column to result_set. ret=%d", ret);
                        break;
                    }
                    break;
                }
                case ObStmt::T_EXECUTE:
                {
                    ObExecuteStmt *execute_stmt = static_cast<ObExecuteStmt*> (stmts_[0]);
                    ObResultSet *stored_plan = NULL;
                    if (session_info == NULL)
                    {
                        ret = OB_ERROR;
                        jlog(ERROR, "Session Info is needed. ret=%d", ret);
                    }
                    else if (execute_stmt == NULL)
                    {
                        ret = OB_ERR_PARSE_SQL;
                        jlog(WARN, "fail to get Execute statement");
                    }
                    else if ((stored_plan = session_info->get_plan(execute_stmt->get_stmt_name())) == NULL)
                    {
                        ret = OB_ERR_PREPARE_STMT_UNKNOWN;
                        jlog(USER_ERROR, "statement %.*s not prepared",
                                execute_stmt->get_stmt_name().size(), execute_stmt->get_stmt_name().data());
                    }
                    else if ((ret = result_set.from_prepared(*stored_plan)) != OB_SUCCESS)
                    {
                        jlog(WARN, "fail to fill result set");
                    }
                    else
                    {
                        jlog(DEBUG, "get physical plan, addr=%p", stored_plan->get_physical_plan());
                        jlog(DEBUG, "StoredPlan: %s", to_cstring(*stored_plan->get_physical_plan()));
                    }
                    break;
                }
                default:
                    break;
            }
            if (ret == OB_SUCCESS && question_marks_count_ > 0)
            {
                ret = result_set.pre_assign_params_room(question_marks_count_, alloc);
            }

            return ret;
        }
int ObSelectStmt::check_having_ident(
  ResultPlan& result_plan,
  ObString& column_name,
  TableItem* table_item,
  ObRawExpr*& ret_expr) const
{
  ObSqlRawExpr  *sql_expr;
  ObRawExpr     *expr;
  ret_expr = NULL;
  int& ret = result_plan.err_stat_.err_code_ = OB_SUCCESS;
  ObLogicalPlan* logical_plan = static_cast<ObLogicalPlan*>(result_plan.plan_tree_);
  if (logical_plan == NULL)
  {
    ret = OB_ERR_LOGICAL_PLAN_FAILD;
    snprintf(result_plan.err_stat_.err_msg_, MAX_ERROR_MSG,
              "Wrong invocation of ObStmt::add_table_item, logical_plan must exist!!!");
  }

  ObSchemaChecker* schema_checker = NULL;
  if (ret == OB_SUCCESS)
  {
    schema_checker = static_cast<ObSchemaChecker*>(result_plan.schema_checker_);
    if (schema_checker == NULL)
    {
      ret = OB_ERR_SCHEMA_UNSET;
      snprintf(result_plan.err_stat_.err_msg_, MAX_ERROR_MSG,
              "Schema(s) are not set");
    }
  }

  for (int32_t i = 0; ret == OB_SUCCESS && i < select_items_.size(); i++)
  {
    const SelectItem& select_item = get_select_item(i);
    // for single column expression, we already set it as alias name
    if (column_name == select_item.alias_name_)
    {
      sql_expr = logical_plan->get_expr(select_item.expr_id_);
      expr = sql_expr->get_expr();
      if (table_item)
      {
        if (expr->get_expr_type() == T_REF_COLUMN)
        {
          ObBinaryRefRawExpr* col_expr = dynamic_cast<ObBinaryRefRawExpr *>(expr);
          if (col_expr && col_expr->get_first_ref_id() == table_item->table_id_)
          {
            ColumnItem* column_item = get_column_item_by_id(col_expr->get_first_ref_id(), col_expr->get_second_ref_id());
            if (column_item && column_item->column_name_ == column_name)
            {
              ObBinaryRefRawExpr *b_expr = (ObBinaryRefRawExpr*)parse_malloc(sizeof(ObBinaryRefRawExpr), name_pool_);
              b_expr = new(b_expr) ObBinaryRefRawExpr();
              b_expr->set_expr_type(T_REF_COLUMN);
              b_expr->set_first_ref_id(col_expr->get_first_ref_id());
              b_expr->set_second_ref_id(col_expr->get_second_ref_id());
              ret_expr = b_expr;
              break;
            }
          }
        }
      }
      else
      {
        if (ret_expr)
        {
          ret = OB_ERR_COLUMN_AMBIGOUS;
          snprintf(result_plan.err_stat_.err_msg_, MAX_ERROR_MSG,
              "column %.*s of having clause is ambiguous", column_name.length(), column_name.ptr());
          parse_free(ret_expr);
          ret_expr = NULL;
          break;
        }
        // for having clause: having cc > 0
        // type 1: select t1.cc
        if (expr->get_expr_type() == T_REF_COLUMN && !select_item.is_real_alias_)
        {
          ObBinaryRefRawExpr *col_expr = dynamic_cast<ObBinaryRefRawExpr *>(expr);
          ObBinaryRefRawExpr *b_expr = (ObBinaryRefRawExpr*)parse_malloc(sizeof(ObBinaryRefRawExpr), name_pool_);
          b_expr = new(b_expr) ObBinaryRefRawExpr();
          b_expr->set_expr_type(T_REF_COLUMN);
          b_expr->set_first_ref_id(col_expr->get_first_ref_id());
          b_expr->set_second_ref_id(col_expr->get_second_ref_id());
          ret_expr = b_expr;
        }
        // type 2: select t1.cc as cc
        // type 3: select t1.c1 as cc
        // type 4: select t1.c1 + t2.c1 as cc
        else
        {
          ObBinaryRefRawExpr *b_expr = (ObBinaryRefRawExpr*)parse_malloc(sizeof(ObBinaryRefRawExpr), name_pool_);
          b_expr = new(b_expr) ObBinaryRefRawExpr();
          b_expr->set_expr_type(T_REF_COLUMN);
          b_expr->set_first_ref_id(OB_INVALID_ID);
          b_expr->set_second_ref_id(sql_expr->get_column_id());
          ret_expr = b_expr;
        }
      }
    }
  }

  // No non-duplicated ident found
  if (ret == OB_SUCCESS && ret_expr == NULL)
  {
    for (int32_t i = 0; ret == OB_SUCCESS && i < group_expr_ids_.size(); i++)
    {
      sql_expr = logical_plan->get_expr(group_expr_ids_[i]);
      expr = sql_expr->get_expr();
      //ObRawExpr* expr = logical_plan->get_expr(group_expr_ids_[i])->get_expr();
      if (expr->get_expr_type() != T_REF_COLUMN)
        continue;

      ObBinaryRefRawExpr* col_expr = dynamic_cast<ObBinaryRefRawExpr *>(expr);
      // Only need to check original columns, alias columns are already checked before
      if (table_item == NULL || table_item->table_id_ == col_expr->get_first_ref_id())
      {
        ColumnItem* column_item = get_column_item_by_id(
                                      col_expr->get_first_ref_id(),
                                      col_expr->get_second_ref_id());
        if (column_item && column_name == column_item->column_name_)
        {
          ObBinaryRefRawExpr *b_expr = (ObBinaryRefRawExpr*)parse_malloc(sizeof(ObBinaryRefRawExpr), name_pool_);
          b_expr = new(b_expr) ObBinaryRefRawExpr();
          b_expr->set_expr_type(T_REF_COLUMN);
          b_expr->set_first_ref_id(column_item->table_id_);
          b_expr->set_second_ref_id(column_item->column_id_);
          ret_expr = b_expr;
          break;
        }
      }
    }
  }

  if (ret == OB_SUCCESS && ret_expr == NULL)
  {
    ret = OB_ERR_COLUMN_UNKNOWN;
    snprintf(result_plan.err_stat_.err_msg_, MAX_ERROR_MSG,
        "Unknown %.*s in having clause", column_name.length(), column_name.ptr());
  }
  return ret;
}
Exemple #3
0
    int ObLogicalPlan::fill_result_set(ObResultSet& result_set)
    {
      int ret = OB_SUCCESS;
      
      ObResultSet::Field field;
      switch(stmts_[0]->get_stmt_type())
      {
        case ObStmt::T_SELECT:
        {
          result_set.set_is_with_rows(false);
          result_set.set_affected_rows(0);
          result_set.set_warning_count(0);
          result_set.set_message("");

          ObSelectStmt *select_stmt = static_cast<ObSelectStmt*>(stmts_[0]);
          int32_t size = select_stmt->get_select_item_size();
          for (int32_t i = 0; ret == OB_SUCCESS && i < size; i++)
          {
            const SelectItem& select_item = select_stmt->get_select_item(i);
            if (select_item.alias_name_.length() > 0)
            {
              if ((ret = alloc_str_by_obstring(select_item.alias_name_, field.cname_, name_pool_)) != OB_SUCCESS)
                break;
            }
            else
            {
              if ((ret = alloc_str_by_obstring(select_item.expr_name_, field.cname_, name_pool_)) != OB_SUCCESS)
                break;
            }

            ObSqlRawExpr* sql_expr = get_expr(select_item.expr_id_);
            if (sql_expr == NULL)
            {
              ret = OB_ERR_ILLEGAL_ID;
              break;
            }
            field.type_.set_type(sql_expr->get_result_type());
            ObRawExpr* expr = sql_expr->get_expr();
            if (select_stmt->get_set_op() != ObSelectStmt::NONE)
            {
              if ((ret = alloc_str_by_obstring(select_item.expr_name_, field.org_cname_, name_pool_)) != OB_SUCCESS)
                break;
            }
            else if (expr->get_expr_type() == T_REF_COLUMN)
            {
              ObBinaryRefRawExpr *column_expr = static_cast<ObBinaryRefRawExpr*>(expr);
              uint64_t table_id = column_expr->get_first_ref_id();
              uint64_t column_id = column_expr->get_second_ref_id();
              if (table_id != OB_INVALID_ID)
              {
                ColumnItem *column_item = select_stmt->get_column_item_by_id(table_id, column_id);
                if (column_item == NULL)
                {
                  ret = OB_ERR_ILLEGAL_ID;
                  break;
                }
                ret = alloc_str_by_obstring(column_item->column_name_, field.org_cname_, name_pool_);
                if (ret != OB_SUCCESS)
                  break;
                TableItem *table_item = select_stmt->get_table_item_by_id(table_id);
                if (table_item == NULL)
                {
                  ret = OB_ERR_ILLEGAL_ID;
                  break;
                }
                if (table_item->alias_name_.length() > 0)
                  ret = alloc_str_by_obstring(table_item->alias_name_, field.tname_, name_pool_);
                else
                  ret = alloc_str_by_obstring(table_item->table_name_, field.tname_, name_pool_);
                if (ret != OB_SUCCESS)
                  break;
                ret = alloc_str_by_obstring(table_item->table_name_, field.org_tname_, name_pool_);
                if (ret != OB_SUCCESS)
                  break;
              }
            }
            ret = result_set.add_field_column(field);
            if (ret != OB_SUCCESS)
              break;

            field.cname_.assign(NULL, 0);
            field.org_cname_.assign(NULL, 0);
            field.tname_.assign(NULL, 0);
            field.org_tname_.assign(NULL, 0);
            field.type_.set_type(ObMinType);
          }
          break;
        }
        case ObStmt::T_INSERT:
        {
          break;
        }
        case ObStmt::T_DELETE:
        {
          break;
        }
        case ObStmt::T_UPDATE:
        {
          break;
        }
        default:
          break;
      }

      return ret;
    }