<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Javier López-Gómez <jalopezg@inf.uc3m.es>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "DefinitionShadower.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Utils/AST.h"

#include "clang/AST/Decl.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/Stmt.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace cling {
  /// \brief Returns whether the given source location is a Cling input line. If
  /// it came from the prompt, the file is a virtual file with overriden contents.
  static bool typedInClingPrompt(FullSourceLoc L) {
    if (L.isInvalid())
      return false;
    const SourceManager &SM = L.getManager();
    const FileID FID = SM.getFileID(L);
    return SM.isFileOverridden(SM.getFileEntryForID(FID))
           && (SM.getFileID(SM.getIncludeLoc(FID)) == SM.getMainFileID());
  }

  /// \brief Returns whether the given {Function,Tag,Var}Decl/TemplateDecl is a definition.
  static bool isDefinition(const Decl *D) {
    if (auto FD = dyn_cast<FunctionDecl>(D))
      return FD->isThisDeclarationADefinition();
    if (auto TD = dyn_cast<TagDecl>(D))
      return TD->isThisDeclarationADefinition();
    if (auto VD = dyn_cast<VarDecl>(D))
      return VD->isThisDeclarationADefinition();
    if (auto TD = dyn_cast<TemplateDecl>(D))
      return isDefinition(TD->getTemplatedDecl());
    return true;
  }

  DefinitionShadower::DefinitionShadower(Sema& S, Interpreter& I)
          : ASTTransformer(&S), m_Context(S.getASTContext()), m_Interp(I),
            m_TU(S.getASTContext().getTranslationUnitDecl())
  {}

  bool DefinitionShadower::isClingShadowNamespace(const DeclContext *DC) {
    auto NS = dyn_cast<NamespaceDecl>(DC);
    return NS && NS->getName().startswith("__cling_N5");
  }

  void DefinitionShadower::hideDecl(clang::NamedDecl *D) const {
    assert(isClingShadowNamespace(D->getDeclContext())
             && "D not in a __cling_N5xxx namespace?");

    // FIXME: this hides a decl from SemaLookup (there is no unloading). For
    // (large) L-values, this might be a memory leak. Should this be fixed?
    if (Scope* S = m_Sema->getScopeForContext(m_TU)) {
      S->RemoveDecl(D);
      if (utils::Analyze::isOnScopeChains(D, *m_Sema))
        m_Sema->IdResolver.RemoveDecl(D);
    }
    clang::StoredDeclsList &SDL = (*m_TU->getLookupPtr())[D->getDeclName()];
    if (SDL.getAsVector() || SDL.getAsDecl() == D)
      SDL.remove(D);

    if (InterpreterCallbacks *IC = m_Interp.getCallbacks())
      IC->DefinitionShadowed(D);
  }

  void DefinitionShadower::invalidatePreviousDefinitions(NamedDecl *D) const {
    LookupResult Previous(*m_Sema, D->getDeclName(), D->getLocation(),
                   Sema::LookupOrdinaryName, Sema::ForRedeclaration);
    m_Sema->LookupQualifiedName(Previous, m_TU);

    for (auto Prev : Previous) {
      if (Prev == D)
        continue;
      if (!isClingShadowNamespace(Prev->getDeclContext()))
        continue;
      if (isDefinition(Prev) && !isDefinition(D))
        continue;
      // If the found declaration is a function overload, do not invalidate it.
      // For templated functions, Sema::IsOverload() does the right thing as per
      // C++ [temp.over.link]p4.
      if (isa<FunctionDecl>(Prev) && isa<FunctionDecl>(D)
          && m_Sema->IsOverload(cast<FunctionDecl>(D),
                                cast<FunctionDecl>(Prev), /*IsForUsingDecl=*/false))
        continue;
      if (isa<FunctionTemplateDecl>(Prev) && isa<FunctionTemplateDecl>(D)
          && m_Sema->IsOverload(cast<FunctionTemplateDecl>(D)->getTemplatedDecl(),
                                cast<FunctionTemplateDecl>(Prev)->getTemplatedDecl(),
                                /*IsForUsingDecl=*/false))
        continue;

      hideDecl(Prev);

      // For unscoped enumerations, also invalidate all enumerators.
      if (EnumDecl *ED = dyn_cast<EnumDecl>(Prev)) {
        if (!ED->isTransparentContext())
          continue;
        for (auto &J : ED->decls())
          if (NamedDecl *ND = dyn_cast<NamedDecl>(J))
            hideDecl(ND);
      }
    }

    // Ignore any forward declaration issued after a definition. Fixes "error
    // : reference to 'xxx' is ambiguous" in `class C {}; class C; C foo;`.
    if (!Previous.empty() && !isDefinition(D))
      D->setInvalidDecl();
  }

  void DefinitionShadower::invalidatePreviousDefinitions(FunctionDecl *D) const {
    const CompilationOptions &CO = getTransaction()->getCompilationOpts();
    if (utils::Analyze::IsWrapper(D)) {
      if (!CO.DeclarationExtraction)
        return;

      // DeclExtractor shall move local declarations to the TU. Invalidate all
      // previous definitions (that may clash) before it runs.
      auto CS = dyn_cast<CompoundStmt>(D->getBody());
      for (auto &I : CS->body()) {
        auto DS = dyn_cast<DeclStmt>(I);
        if (!DS)
          continue;
        for (auto &J : DS->decls())
          if (auto ND = dyn_cast<NamedDecl>(J))
            invalidatePreviousDefinitions(ND);
      }
    } else
      invalidatePreviousDefinitions(cast<NamedDecl>(D));
  }

  void DefinitionShadower::invalidatePreviousDefinitions(Decl *D) const {
    if (auto FD = dyn_cast<FunctionDecl>(D))
      invalidatePreviousDefinitions(FD);
    else if (auto ND = dyn_cast<NamedDecl>(D))
      invalidatePreviousDefinitions(ND);
  }

  ASTTransformer::Result DefinitionShadower::Transform(Decl* D) {
    Transaction *T = getTransaction();
    const CompilationOptions &CO = T->getCompilationOpts();
    // Global declarations whose origin is the Cling prompt are subject to be
    // nested in a `__cling_N5' namespace.
    if (!CO.EnableShadowing
        || D->getLexicalDeclContext() != m_TU || D->isInvalidDecl()
        || isa<UsingDirectiveDecl>(D) || isa<UsingDecl>(D)
        // FIXME: NamespaceDecl requires additional processing (TBD)
        || isa<NamespaceDecl>(D)
        || (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isTemplateInstantiation())
        || !typedInClingPrompt(FullSourceLoc{D->getLocation(),
                                             m_Context.getSourceManager()}))
      return Result(D, true);

    // Each transaction gets at most a `__cling_N5xxx' namespace. If `T' already
    // has one, reuse it.
    auto NS = T->getDefinitionShadowNS();
    if (!NS) {
      NS = NamespaceDecl::Create(m_Context, m_TU, /*inline=*/true,
                                 SourceLocation(), SourceLocation(),
                                 &m_Context.Idents.get("__cling_N5"
                                       + std::to_string(m_UniqueNameCounter++)),
                                 nullptr);
      //NS->setImplicit();
      m_TU->addDecl(NS);
      T->setDefinitionShadowNS(NS);
    }

    m_TU->removeDecl(D);
    if (isa<CXXRecordDecl>(D->getDeclContext()))
      D->setLexicalDeclContext(NS);
    else
      D->setDeclContext(NS);
    // An instantiated function template inherits the declaration context of the
    // templated decl. This is used for name mangling; fix it to avoid clashing.
    if (auto FTD = dyn_cast<FunctionTemplateDecl>(D))
      FTD->getTemplatedDecl()->setDeclContext(NS);
    NS->addDecl(D);

    // Invalidate previous definitions so that LookupResult::resolveKind() does not
    // mark resolution as ambiguous.
    invalidatePreviousDefinitions(D);
    return Result(D, true);
  }
} // end namespace cling
<commit_msg>[cling] DefinitionShadower: allow shadowing of non-user-defined declarations (#6571)<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Javier López-Gómez <jalopezg@inf.uc3m.es>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "DefinitionShadower.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Utils/AST.h"

#include "clang/AST/Decl.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/Stmt.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace cling {
  /// \brief Returns whether the given source location is a Cling input line. If
  /// it came from the prompt, the file is a virtual file with overriden contents.
  static bool typedInClingPrompt(FullSourceLoc L) {
    if (L.isInvalid())
      return false;
    const SourceManager &SM = L.getManager();
    const FileID FID = SM.getFileID(L);
    return SM.isFileOverridden(SM.getFileEntryForID(FID))
           && (SM.getFileID(SM.getIncludeLoc(FID)) == SM.getMainFileID());
  }

  /// \brief Returns whether the given {Function,Tag,Var}Decl/TemplateDecl is a definition.
  static bool isDefinition(const Decl *D) {
    if (auto FD = dyn_cast<FunctionDecl>(D))
      return FD->isThisDeclarationADefinition();
    if (auto TD = dyn_cast<TagDecl>(D))
      return TD->isThisDeclarationADefinition();
    if (auto VD = dyn_cast<VarDecl>(D))
      return VD->isThisDeclarationADefinition();
    if (auto TD = dyn_cast<TemplateDecl>(D))
      return isDefinition(TD->getTemplatedDecl());
    return true;
  }

  /// \brief Returns whether the given declaration is a template instantiation
  /// or specialization.
  static bool isInstantiationOrSpecialization(const Decl *D) {
    if (auto FD = dyn_cast<FunctionDecl>(D))
      return FD->isTemplateInstantiation() || FD->isFunctionTemplateSpecialization();
    if (auto CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
      return CTSD->getSpecializationKind() != TSK_Undeclared;
    if (auto VTSD = dyn_cast<VarTemplateSpecializationDecl>(D))
      return VTSD->getSpecializationKind() != TSK_Undeclared;
    return false;
  }

  DefinitionShadower::DefinitionShadower(Sema& S, Interpreter& I)
          : ASTTransformer(&S), m_Context(S.getASTContext()), m_Interp(I),
            m_TU(S.getASTContext().getTranslationUnitDecl())
  {}

  bool DefinitionShadower::isClingShadowNamespace(const DeclContext *DC) {
    auto NS = dyn_cast<NamespaceDecl>(DC);
    return NS && NS->getName().startswith("__cling_N5");
  }

  void DefinitionShadower::hideDecl(clang::NamedDecl *D) const {
    // FIXME: this hides a decl from SemaLookup (there is no unloading). For
    // (large) L-values, this might be a memory leak. Should this be fixed?
    if (Scope* S = m_Sema->getScopeForContext(m_TU)) {
      S->RemoveDecl(D);
      if (utils::Analyze::isOnScopeChains(D, *m_Sema))
        m_Sema->IdResolver.RemoveDecl(D);
    }
    clang::StoredDeclsList &SDL = (*m_TU->getLookupPtr())[D->getDeclName()];
    if (SDL.getAsVector() || SDL.getAsDecl() == D)
      SDL.remove(D);

    if (InterpreterCallbacks *IC = m_Interp.getCallbacks())
      IC->DefinitionShadowed(D);
  }

  void DefinitionShadower::invalidatePreviousDefinitions(NamedDecl *D) const {
    LookupResult Previous(*m_Sema, D->getDeclName(), D->getLocation(),
                   Sema::LookupOrdinaryName, Sema::ForRedeclaration);
    m_Sema->LookupQualifiedName(Previous, m_TU);

    for (auto Prev : Previous) {
      if (Prev == D)
        continue;
      if (isDefinition(Prev) && !isDefinition(D))
        continue;
      // If the found declaration is a function overload, do not invalidate it.
      // For templated functions, Sema::IsOverload() does the right thing as per
      // C++ [temp.over.link]p4.
      if (isa<FunctionDecl>(Prev) && isa<FunctionDecl>(D)
          && m_Sema->IsOverload(cast<FunctionDecl>(D),
                                cast<FunctionDecl>(Prev), /*IsForUsingDecl=*/false))
        continue;
      if (isa<FunctionTemplateDecl>(Prev) && isa<FunctionTemplateDecl>(D)
          && m_Sema->IsOverload(cast<FunctionTemplateDecl>(D)->getTemplatedDecl(),
                                cast<FunctionTemplateDecl>(Prev)->getTemplatedDecl(),
                                /*IsForUsingDecl=*/false))
        continue;

      hideDecl(Prev);

      // For unscoped enumerations, also invalidate all enumerators.
      if (EnumDecl *ED = dyn_cast<EnumDecl>(Prev)) {
        if (!ED->isTransparentContext())
          continue;
        for (auto &J : ED->decls())
          if (NamedDecl *ND = dyn_cast<NamedDecl>(J))
            hideDecl(ND);
      }
    }

    // Ignore any forward declaration issued after a definition. Fixes "error
    // : reference to 'xxx' is ambiguous" in `class C {}; class C; C foo;`.
    if (!Previous.empty() && !isDefinition(D))
      D->setInvalidDecl();
  }

  void DefinitionShadower::invalidatePreviousDefinitions(FunctionDecl *D) const {
    const CompilationOptions &CO = getTransaction()->getCompilationOpts();
    if (utils::Analyze::IsWrapper(D)) {
      if (!CO.DeclarationExtraction)
        return;

      // DeclExtractor shall move local declarations to the TU. Invalidate all
      // previous definitions (that may clash) before it runs.
      auto CS = dyn_cast<CompoundStmt>(D->getBody());
      for (auto &I : CS->body()) {
        auto DS = dyn_cast<DeclStmt>(I);
        if (!DS)
          continue;
        for (auto &J : DS->decls())
          if (auto ND = dyn_cast<NamedDecl>(J))
            invalidatePreviousDefinitions(ND);
      }
    } else
      invalidatePreviousDefinitions(cast<NamedDecl>(D));
  }

  void DefinitionShadower::invalidatePreviousDefinitions(Decl *D) const {
    if (auto FD = dyn_cast<FunctionDecl>(D))
      invalidatePreviousDefinitions(FD);
    else if (auto ND = dyn_cast<NamedDecl>(D))
      invalidatePreviousDefinitions(ND);
  }

  ASTTransformer::Result DefinitionShadower::Transform(Decl* D) {
    Transaction *T = getTransaction();
    if (!T->getCompilationOpts().EnableShadowing)
      return Result(D, true);

    // For variable templates, Transform() is invoked with a VarDecl; get the
    // corresponding VarTemplateDecl.
    if (auto VD = dyn_cast<VarDecl>(D))
      if (auto VTD = VD->getDescribedVarTemplate())
        D = VTD;

    // Disable definition shadowing for some specific cases.
    if (D->getLexicalDeclContext() != m_TU || D->isInvalidDecl()
        || isa<UsingDirectiveDecl>(D) || isa<UsingDecl>(D) || isa<NamespaceDecl>(D)
        || isInstantiationOrSpecialization(D)
        || !typedInClingPrompt(FullSourceLoc{D->getLocation(),
                                             m_Context.getSourceManager()}))
      return Result(D, true);

    // Each transaction gets at most a `__cling_N5xxx' namespace. If `T' already
    // has one, reuse it.
    auto NS = T->getDefinitionShadowNS();
    if (!NS) {
      NS = NamespaceDecl::Create(m_Context, m_TU, /*inline=*/true,
                                 SourceLocation(), SourceLocation(),
                                 &m_Context.Idents.get("__cling_N5"
                                       + std::to_string(m_UniqueNameCounter++)),
                                 nullptr);
      //NS->setImplicit();
      m_TU->addDecl(NS);
      T->setDefinitionShadowNS(NS);
    }

    m_TU->removeDecl(D);
    if (isa<CXXRecordDecl>(D->getDeclContext()))
      D->setLexicalDeclContext(NS);
    else
      D->setDeclContext(NS);
    // An instantiated function template inherits the declaration context of the
    // templated decl. This is used for name mangling; fix it to avoid clashing.
    if (auto FTD = dyn_cast<FunctionTemplateDecl>(D))
      FTD->getTemplatedDecl()->setDeclContext(NS);
    NS->addDecl(D);

    // Invalidate previous definitions so that LookupResult::resolveKind() does not
    // mark resolution as ambiguous.
    invalidatePreviousDefinitions(D);
    return Result(D, true);
  }
} // end namespace cling
<|endoftext|>


<commit_before>
// Qt includes
#include <QLayout>
#include <QDebug>

// Visomics includes
#include "voCorrelationGraphView.h"
#include "voDataObject.h"

// VTK includes
#include <QVTKWidget.h>
#include <vtkArcParallelEdgeStrategy.h>
#include <vtkGraph.h>
#include <vtkGraphLayoutView.h>
#include <vtkLookupTable.h>
#include <vtkRenderedGraphRepresentation.h>
#include <vtkSmartPointer.h>
#include <vtkTextProperty.h>
#include <vtkViewTheme.h>

// --------------------------------------------------------------------------
class voCorrelationGraphViewPrivate
{
public:
  voCorrelationGraphViewPrivate();
  vtkSmartPointer<vtkGraphLayoutView> GraphView;
  QVTKWidget*                         Widget;
};

// --------------------------------------------------------------------------
// voCorrelationGraphViewPrivate methods

// --------------------------------------------------------------------------
voCorrelationGraphViewPrivate::voCorrelationGraphViewPrivate()
{
  this->GraphView = 0;
  this->Widget = 0;
}

// --------------------------------------------------------------------------
// voCorrelationGraphView methods

// --------------------------------------------------------------------------
voCorrelationGraphView::voCorrelationGraphView(QWidget * newParent):
    Superclass(newParent), d_ptr(new voCorrelationGraphViewPrivate)
{
}

// --------------------------------------------------------------------------
voCorrelationGraphView::~voCorrelationGraphView()
{
}

// --------------------------------------------------------------------------
void voCorrelationGraphView::setupUi(QLayout *layout)
{
  Q_D(voCorrelationGraphView);

  d->GraphView = vtkSmartPointer<vtkGraphLayoutView>::New();
  d->Widget = new QVTKWidget();
  d->GraphView->SetInteractor(d->Widget->GetInteractor());
  d->Widget->SetRenderWindow(d->GraphView->GetRenderWindow());
  d->GraphView->DisplayHoverTextOn();
  d->GraphView->SetLayoutStrategyToCircular();
  d->GraphView->SetVertexLabelArrayName("label");
  d->GraphView->VertexLabelVisibilityOn();
  d->GraphView->SetEdgeColorArrayName("Correlation");
  d->GraphView->ColorEdgesOn();
  d->GraphView->SetEdgeLabelArrayName("Correlation");
  d->GraphView->EdgeLabelVisibilityOn();

  vtkSmartPointer<vtkArcParallelEdgeStrategy> arc =
    vtkSmartPointer<vtkArcParallelEdgeStrategy>::New();
  arc->SetNumberOfSubdivisions(50);
  d->GraphView->SetEdgeLayoutStrategy(arc);

  vtkSmartPointer<vtkViewTheme> theme =
    vtkSmartPointer<vtkViewTheme>::New();
  theme->SetBackgroundColor(1.0, 1.0, 1.0);
  theme->SetBackgroundColor2(1.0, 1.0, 1.0);
  theme->SetLineWidth(2);
  vtkSmartPointer<vtkLookupTable> lut =
    vtkSmartPointer<vtkLookupTable>::New();
  lut->SetHueRange(0.65, 0.65);
  lut->SetSaturationRange(1.0, 1.0);
  lut->SetValueRange(0.8, 0.8);
  lut->SetAlphaRange(0.0, 1.0);
  lut->Build();
  theme->SetCellLookupTable(lut);
  theme->GetPointTextProperty()->SetColor(0.0, 0.0, 0.0);
  d->GraphView->ApplyViewTheme(theme);

  vtkRenderedGraphRepresentation* rep =
    vtkRenderedGraphRepresentation::SafeDownCast(d->GraphView->GetRepresentation());
  rep->SetVertexHoverArrayName("name");
  rep->SetEdgeHoverArrayName("Correlation");

  layout->addWidget(d->Widget);
}

// --------------------------------------------------------------------------
void voCorrelationGraphView::setDataObject(voDataObject* dataObject)
{
  Q_D(voCorrelationGraphView);

  if (!dataObject)
    {
    qCritical() << "voCorrelationGraphView - Failed to setDataObject - dataObject is NULL";
    return;
    }

  vtkGraph * graph = vtkGraph::SafeDownCast(dataObject->data());
  if (!graph)
    {
    qCritical() << "voCorrelationGraphView - Failed to setDataObject - vtkGraph data is expected !";
    return;
    }

  d->GraphView->SetRepresentationFromInput(graph);
  d->GraphView->Render();
}

<commit_msg>Change voCorrelationGraphView mouse button bindings to be consistent with other views<commit_after>
// Qt includes
#include <QLayout>
#include <QDebug>

// Visomics includes
#include "voCorrelationGraphView.h"
#include "voDataObject.h"
#include "voInteractorStyleRubberBand2D.h"

// VTK includes
#include <QVTKWidget.h>
#include <vtkArcParallelEdgeStrategy.h>
#include <vtkGraph.h>
#include <vtkGraphLayoutView.h>
#include <vtkLookupTable.h>
#include <vtkRenderedGraphRepresentation.h>
#include <vtkSmartPointer.h>
#include <vtkTextProperty.h>
#include <vtkViewTheme.h>

// --------------------------------------------------------------------------
class voCorrelationGraphViewPrivate
{
public:
  voCorrelationGraphViewPrivate();
  vtkSmartPointer<vtkGraphLayoutView> GraphView;
  QVTKWidget*                         Widget;
};

// --------------------------------------------------------------------------
// voCorrelationGraphViewPrivate methods

// --------------------------------------------------------------------------
voCorrelationGraphViewPrivate::voCorrelationGraphViewPrivate()
{
  this->GraphView = 0;
  this->Widget = 0;
}

// --------------------------------------------------------------------------
// voCorrelationGraphView methods

// --------------------------------------------------------------------------
voCorrelationGraphView::voCorrelationGraphView(QWidget * newParent):
    Superclass(newParent), d_ptr(new voCorrelationGraphViewPrivate)
{
}

// --------------------------------------------------------------------------
voCorrelationGraphView::~voCorrelationGraphView()
{
}

// --------------------------------------------------------------------------
void voCorrelationGraphView::setupUi(QLayout *layout)
{
  Q_D(voCorrelationGraphView);

  d->GraphView = vtkSmartPointer<vtkGraphLayoutView>::New();
  d->Widget = new QVTKWidget();
  d->GraphView->SetInteractor(d->Widget->GetInteractor());
  d->GraphView->SetInteractorStyle(vtkSmartPointer<voInteractorStyleRubberBand2D>::New());
  d->Widget->SetRenderWindow(d->GraphView->GetRenderWindow());
  d->GraphView->DisplayHoverTextOn();
  d->GraphView->SetLayoutStrategyToCircular();
  d->GraphView->SetVertexLabelArrayName("label");
  d->GraphView->VertexLabelVisibilityOn();
  d->GraphView->SetEdgeColorArrayName("Correlation");
  d->GraphView->ColorEdgesOn();
  d->GraphView->SetEdgeLabelArrayName("Correlation");
  d->GraphView->EdgeLabelVisibilityOn();

  vtkSmartPointer<vtkArcParallelEdgeStrategy> arc =
    vtkSmartPointer<vtkArcParallelEdgeStrategy>::New();
  arc->SetNumberOfSubdivisions(50);
  d->GraphView->SetEdgeLayoutStrategy(arc);

  vtkSmartPointer<vtkViewTheme> theme =
    vtkSmartPointer<vtkViewTheme>::New();
  theme->SetBackgroundColor(1.0, 1.0, 1.0);
  theme->SetBackgroundColor2(1.0, 1.0, 1.0);
  theme->SetLineWidth(2);
  vtkSmartPointer<vtkLookupTable> lut =
    vtkSmartPointer<vtkLookupTable>::New();
  lut->SetHueRange(0.65, 0.65);
  lut->SetSaturationRange(1.0, 1.0);
  lut->SetValueRange(0.8, 0.8);
  lut->SetAlphaRange(0.0, 1.0);
  lut->Build();
  theme->SetCellLookupTable(lut);
  theme->GetPointTextProperty()->SetColor(0.0, 0.0, 0.0);
  d->GraphView->ApplyViewTheme(theme);

  vtkRenderedGraphRepresentation* rep =
    vtkRenderedGraphRepresentation::SafeDownCast(d->GraphView->GetRepresentation());
  rep->SetVertexHoverArrayName("name");
  rep->SetEdgeHoverArrayName("Correlation");

  layout->addWidget(d->Widget);
}

// --------------------------------------------------------------------------
void voCorrelationGraphView::setDataObject(voDataObject* dataObject)
{
  Q_D(voCorrelationGraphView);

  if (!dataObject)
    {
    qCritical() << "voCorrelationGraphView - Failed to setDataObject - dataObject is NULL";
    return;
    }

  vtkGraph * graph = vtkGraph::SafeDownCast(dataObject->data());
  if (!graph)
    {
    qCritical() << "voCorrelationGraphView - Failed to setDataObject - vtkGraph data is expected !";
    return;
    }

  d->GraphView->SetRepresentationFromInput(graph);
  d->GraphView->ResetCamera();
  d->GraphView->Render();
}
<|endoftext|>


<commit_before>//
//  ComponentDrivenApp.cpp
//  SpaceStationKeeper
//
//  Created by Sean Dawson on 15/03/2014.
//
//

#include "ComponentDrivenApp.h"

using namespace YAML;
using namespace boost;

ComponentDrivenApp::ComponentDrivenApp() {
  assert(_instance == nullptr);
  _instance = this;
  _bindingManager = BindingManager::Instance();

  // Engine game object runs all the engine critical components such as job/bot
  // managers
  _engineGameObject = make_shared<GameObject>();
  registerGameObject(_engineGameObject);
}

ComponentDrivenApp::~ComponentDrivenApp() {}

ComponentDrivenApp *ComponentDrivenApp::Instance() { return _instance; }

// Get the time in seconds since the last update
float ComponentDrivenApp::getDeltaTime() { return _deltaTime; }

// Sets the asset loader used by this app
void ComponentDrivenApp::setAssetLoader(AssetLoaderBase *assetLoader) {
  _assetLoader = assetLoader;
}
// Gets the asset loader used by this app
AssetLoaderBase *ComponentDrivenApp::getAssetLoader() { return _assetLoader; }

/*! Sets the job manager used by this app. */
void ComponentDrivenApp::setJobManager(JobManagerRef jobManager) {
  if (_jobManager != nullptr) {
    _engineGameObject->removeComponent(
        dynamic_pointer_cast<GameComponent>(_jobManager));
  }
  _jobManager = jobManager;
  _engineGameObject->addComponent(
      dynamic_pointer_cast<GameComponent>(_jobManager));
}

/*! Gets the job manager used by this app. */
JobManagerRef ComponentDrivenApp::getJobManager() { return _jobManager; }

/*! Sets the bot manager used by this app. */
void ComponentDrivenApp::setBotManager(BotManagerRef botManager) {
  if (_botManager != nullptr) {
    _engineGameObject->removeComponent(
        dynamic_pointer_cast<GameComponent>(_botManager));
  }
  _botManager = botManager;
  _engineGameObject->addComponent(
      dynamic_pointer_cast<GameComponent>(_botManager));
}

/*! Gets the bot manager used by this app. */
BotManagerRef ComponentDrivenApp::getBotManager() { return _botManager; }

//! Registers a component to receive app events
void ComponentDrivenApp::registerGameObject(GameObjectRef gameObject) {
  if (_registeredGameObjects.count(gameObject)) {
    throw runtime_error("This gameObject is already registered.");
  }
  _registeredGameObjects.insert(gameObject);
}

void ComponentDrivenApp::destroyGameObject(GameObjectRef gameObject) {
  _registeredGameObjects.erase(gameObject);
}

//! Get a list of currently registered components
set<GameObjectRef> ComponentDrivenApp::getGameObjects() {
  return this->_registeredGameObjects;
}

//! Forwards event to component to perform any application cleanup before
// exiting.
void ComponentDrivenApp::shutdown() {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->shutdown();
  }
}

//! Forwards event to component to perform any once-per-loop computation.
void ComponentDrivenApp::update() {
  if (!isnan(_lastElapsedTime)) {
    _deltaTime = ci::app::getElapsedSeconds() - _lastElapsedTime;
  }
  _lastElapsedTime = ci::app::getElapsedSeconds();

  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->update(_deltaTime);
  }
}
//! Forwards event to component to perform any rendering once-per-loop or in
// response to
// OS-prompted requests for refreshes.
void ComponentDrivenApp::draw() {
  // z-depth sorting // TODO: Make more efficient
  set<GameObjectRef> gameObjects = getRegisteredGameObjectsCopy();

  // Copy set into vector
  std::vector<GameObjectRef> vector =
      std::vector<GameObjectRef>(gameObjects.begin(), gameObjects.end());

  // Depth sort the vector
  sort(std::begin(vector), std::end(vector),
       [](GameObjectRef a, GameObjectRef b) {
    return b->renderer->transform->localPosition.z >
           a->renderer->transform->localPosition.z;
  });

  // Draw in order
  for (auto &comp : vector) {
    comp->draw();
  }
}

//! Forwards event to component to receive mouse-down events.
void ComponentDrivenApp::mouseDown(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseDown(event);
  }
}
//! Forwards event to component to receive mouse-up events.
void ComponentDrivenApp::mouseUp(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseUp(event);
  }
}
//! Forwards event to component to receive mouse-wheel events.
void ComponentDrivenApp::mouseWheel(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseWheel(event);
  }
}
//! Forwards event to component to receive mouse-move events.
void ComponentDrivenApp::mouseMove(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseMove(event);
  }
}
//! Forwards event to component to receive mouse-drag events.
void ComponentDrivenApp::mouseDrag(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseDrag(event);
  }
}

//! Forwards event to component to respond to the beginning of a multitouch
// sequence
void ComponentDrivenApp::touchesBegan(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesBegan(event);
  }
}
//! Forwards event to component to respond to movement (drags) during a
// multitouch sequence
void ComponentDrivenApp::touchesMoved(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesMoved(event);
  }
}
//! Forwards event to component to respond to the end of a multitouch sequence
void ComponentDrivenApp::touchesEnded(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesEnded(event);
  }
}

//! Forwards event to component to receive key-down events.
void ComponentDrivenApp::keyDown(KeyEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->keyDown(event);
  }
}
//! Forwards event to component to receive key-up events.
void ComponentDrivenApp::keyUp(KeyEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->keyUp(event);
  }
}
//! Forwards event to component to receive window resize events.
void ComponentDrivenApp::resize() {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->resize();
  }
}
//! Forwards event to component to receive file-drop events.
void ComponentDrivenApp::fileDrop(FileDropEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->fileDrop(event);
  }
}

set<GameObjectRef> ComponentDrivenApp::getRegisteredGameObjectsCopy() {
  return set<GameObjectRef>(_registeredGameObjects);
}

ComponentDrivenApp *ComponentDrivenApp::_instance = nullptr;
<commit_msg>Fixed issue with nested transforms not z sorting properly causing issues with transparency.<commit_after>//
//  ComponentDrivenApp.cpp
//  SpaceStationKeeper
//
//  Created by Sean Dawson on 15/03/2014.
//
//

#include "ComponentDrivenApp.h"

using namespace YAML;
using namespace boost;

ComponentDrivenApp::ComponentDrivenApp() {
  assert(_instance == nullptr);
  _instance = this;
  _bindingManager = BindingManager::Instance();

  // Engine game object runs all the engine critical components such as job/bot
  // managers
  _engineGameObject = make_shared<GameObject>();
  registerGameObject(_engineGameObject);
}

ComponentDrivenApp::~ComponentDrivenApp() {}

ComponentDrivenApp *ComponentDrivenApp::Instance() { return _instance; }

// Get the time in seconds since the last update
float ComponentDrivenApp::getDeltaTime() { return _deltaTime; }

// Sets the asset loader used by this app
void ComponentDrivenApp::setAssetLoader(AssetLoaderBase *assetLoader) {
  _assetLoader = assetLoader;
}
// Gets the asset loader used by this app
AssetLoaderBase *ComponentDrivenApp::getAssetLoader() { return _assetLoader; }

/*! Sets the job manager used by this app. */
void ComponentDrivenApp::setJobManager(JobManagerRef jobManager) {
  if (_jobManager != nullptr) {
    _engineGameObject->removeComponent(
        dynamic_pointer_cast<GameComponent>(_jobManager));
  }
  _jobManager = jobManager;
  _engineGameObject->addComponent(
      dynamic_pointer_cast<GameComponent>(_jobManager));
}

/*! Gets the job manager used by this app. */
JobManagerRef ComponentDrivenApp::getJobManager() { return _jobManager; }

/*! Sets the bot manager used by this app. */
void ComponentDrivenApp::setBotManager(BotManagerRef botManager) {
  if (_botManager != nullptr) {
    _engineGameObject->removeComponent(
        dynamic_pointer_cast<GameComponent>(_botManager));
  }
  _botManager = botManager;
  _engineGameObject->addComponent(
      dynamic_pointer_cast<GameComponent>(_botManager));
}

/*! Gets the bot manager used by this app. */
BotManagerRef ComponentDrivenApp::getBotManager() { return _botManager; }

//! Registers a component to receive app events
void ComponentDrivenApp::registerGameObject(GameObjectRef gameObject) {
  if (_registeredGameObjects.count(gameObject)) {
    throw runtime_error("This gameObject is already registered.");
  }
  _registeredGameObjects.insert(gameObject);
}

void ComponentDrivenApp::destroyGameObject(GameObjectRef gameObject) {
  _registeredGameObjects.erase(gameObject);
}

//! Get a list of currently registered components
set<GameObjectRef> ComponentDrivenApp::getGameObjects() {
  return this->_registeredGameObjects;
}

//! Forwards event to component to perform any application cleanup before
// exiting.
void ComponentDrivenApp::shutdown() {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->shutdown();
  }
}

//! Forwards event to component to perform any once-per-loop computation.
void ComponentDrivenApp::update() {
  if (!isnan(_lastElapsedTime)) {
    _deltaTime = ci::app::getElapsedSeconds() - _lastElapsedTime;
  }
  _lastElapsedTime = ci::app::getElapsedSeconds();

  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->update(_deltaTime);
  }
}
//! Forwards event to component to perform any rendering once-per-loop or in
// response to
// OS-prompted requests for refreshes.
void ComponentDrivenApp::draw() {
  // z-depth sorting // TODO: Make more efficient
  set<GameObjectRef> gameObjects = getRegisteredGameObjectsCopy();

  // Copy set into vector
  std::vector<GameObjectRef> vector =
      std::vector<GameObjectRef>(gameObjects.begin(), gameObjects.end());

  // Depth sort the vector
  sort(std::begin(vector), std::end(vector),
       [](GameObjectRef a, GameObjectRef b) {
    float z0 =
        a->renderer->transform->getTransformMatrixLocal().getTranslate().z;
    float z1 =
        b->renderer->transform->getTransformMatrixLocal().getTranslate().z;
    return z0 < z1;
  });

  // Draw in order
  for (auto &comp : vector) {
    comp->draw();
  }
}

//! Forwards event to component to receive mouse-down events.
void ComponentDrivenApp::mouseDown(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseDown(event);
  }
}
//! Forwards event to component to receive mouse-up events.
void ComponentDrivenApp::mouseUp(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseUp(event);
  }
}
//! Forwards event to component to receive mouse-wheel events.
void ComponentDrivenApp::mouseWheel(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseWheel(event);
  }
}
//! Forwards event to component to receive mouse-move events.
void ComponentDrivenApp::mouseMove(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseMove(event);
  }
}
//! Forwards event to component to receive mouse-drag events.
void ComponentDrivenApp::mouseDrag(MouseEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->mouseDrag(event);
  }
}

//! Forwards event to component to respond to the beginning of a multitouch
// sequence
void ComponentDrivenApp::touchesBegan(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesBegan(event);
  }
}
//! Forwards event to component to respond to movement (drags) during a
// multitouch sequence
void ComponentDrivenApp::touchesMoved(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesMoved(event);
  }
}
//! Forwards event to component to respond to the end of a multitouch sequence
void ComponentDrivenApp::touchesEnded(TouchEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->touchesEnded(event);
  }
}

//! Forwards event to component to receive key-down events.
void ComponentDrivenApp::keyDown(KeyEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->keyDown(event);
  }
}
//! Forwards event to component to receive key-up events.
void ComponentDrivenApp::keyUp(KeyEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->keyUp(event);
  }
}
//! Forwards event to component to receive window resize events.
void ComponentDrivenApp::resize() {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->resize();
  }
}
//! Forwards event to component to receive file-drop events.
void ComponentDrivenApp::fileDrop(FileDropEvent event) {
  for (auto &comp : getRegisteredGameObjectsCopy()) {
    comp->fileDrop(event);
  }
}

set<GameObjectRef> ComponentDrivenApp::getRegisteredGameObjectsCopy() {
  return set<GameObjectRef>(_registeredGameObjects);
}

ComponentDrivenApp *ComponentDrivenApp::_instance = nullptr;
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/component/animationloop/FreeMotionAnimationLoop.h>
#include <sofa/core/visual/VisualParams.h>

#include <sofa/component/constraintset/LCPConstraintSolver.h>

#include <sofa/core/ObjectFactory.h>
#include <sofa/core/VecId.h>

#include <sofa/helper/AdvancedTimer.h>

#include <sofa/simulation/common/BehaviorUpdatePositionVisitor.h>
#include <sofa/simulation/common/MechanicalOperations.h>
#include <sofa/simulation/common/SolveVisitor.h>
#include <sofa/simulation/common/VectorOperations.h>

namespace sofa
{

namespace component
{

namespace animationloop
{

using namespace core::behavior;

FreeMotionAnimationLoop::FreeMotionAnimationLoop(simulation::Node* gnode)
    : Inherit(gnode)
    , m_solveVelocityConstraintFirst(initData(&m_solveVelocityConstraintFirst , false, "solveVelocityConstraintFirst", "solve separately velocity constraint violations before position constraint violations"))
    , constraintSolver(NULL)
    , defaultSolver(NULL)
{
}

FreeMotionAnimationLoop::~FreeMotionAnimationLoop()
{
    if (defaultSolver != NULL)
        defaultSolver.reset();
}

void FreeMotionAnimationLoop::parse ( sofa::core::objectmodel::BaseObjectDescription* arg )
{
    this->simulation::CollisionAnimationLoop::parse(arg);

    defaultSolver = sofa::core::objectmodel::New<constraintset::LCPConstraintSolver>();
    defaultSolver->parse(arg);
}

void FreeMotionAnimationLoop::init()
{
    getContext()->get(constraintSolver, core::objectmodel::BaseContext::SearchDown);
    if (constraintSolver == NULL && defaultSolver != NULL)
    {
        serr << "No ConstraintSolver found, using default LCPConstraintSolver" << sendl;
        this->getContext()->addObject(defaultSolver);
        constraintSolver = defaultSolver.get();
        defaultSolver = NULL;
    }
    else
    {
        defaultSolver.reset();
    }
}

void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params /* PARAMS FIRST */, double dt)
{
    if (dt == 0)
        dt = this->gnode->getDt();

    sofa::helper::AdvancedTimer::stepBegin("AnimationStep");
    {
        AnimateBeginEvent ev ( dt );
        PropagateEventVisitor act ( params, &ev );
        this->gnode->execute ( act );
    }

    double startTime = this->gnode->getTime();

    simulation::common::VectorOperations vop(params, this->getContext());
    simulation::common::MechanicalOperations mop(params, this->getContext());

    MultiVecCoord pos(&vop, core::VecCoordId::position() );
    MultiVecDeriv vel(&vop, core::VecDerivId::velocity() );
    MultiVecCoord freePos(&vop, core::VecCoordId::freePosition() );
    MultiVecDeriv freeVel(&vop, core::VecDerivId::freeVelocity() );

    // This solver will work in freePosition and freeVelocity vectors.
    // We need to initialize them if it's not already done.
    simulation::MechanicalVInitVisitor< core::V_COORD >(params, core::VecCoordId::freePosition(), core::ConstVecCoordId::position(), true).execute(this->gnode);
    simulation::MechanicalVInitVisitor< core::V_DERIV >(params, core::VecDerivId::freeVelocity(), core::ConstVecDerivId::velocity(), true).execute(this->gnode);

    BehaviorUpdatePositionVisitor beh(params , dt);

    using helper::system::thread::CTime;
    using sofa::helper::AdvancedTimer;

    double time = 0.0;
    double timeTotal = 0.0;
    double timeScale = 1000.0 / (double)CTime::getTicksPerSec();

    if (displayTime.getValue())
    {
        time = (double) CTime::getTime();
        timeTotal = (double) CTime::getTime();
    }

    // Update the BehaviorModels
    // Required to allow the RayPickInteractor interaction
    if (f_printLog.getValue())
        serr << "updatePos called" << sendl;

    AdvancedTimer::stepBegin("UpdatePosition");
    this->gnode->execute(&beh);
    AdvancedTimer::stepEnd("UpdatePosition");

    if (f_printLog.getValue())
        serr << "updatePos performed - beginVisitor called" << sendl;

    simulation::MechanicalBeginIntegrationVisitor beginVisitor(params, dt);
    this->gnode->execute(&beginVisitor);

    if (f_printLog.getValue())
        serr << "beginVisitor performed - SolveVisitor for freeMotion is called" << sendl;

    // Free Motion
    AdvancedTimer::stepBegin("FreeMotion");
    simulation::SolveVisitor freeMotion(params, dt, true);
    this->gnode->execute(&freeMotion);
    AdvancedTimer::stepEnd("FreeMotion");

    mop.propagateXAndV(freePos, freeVel);

    if (f_printLog.getValue())
        serr << " SolveVisitor for freeMotion performed" << sendl;

    if (displayTime.getValue())
    {
        sout << " >>>>> Begin display FreeMotionAnimationLoop time" << sendl;
        sout <<" Free Motion " << ((double)CTime::getTime() - time) * timeScale << " ms" << sendl;

        time = (double)CTime::getTime();
    }

    // Collision detection and response creation
    AdvancedTimer::stepBegin("Collision");
    computeCollision(params);
    AdvancedTimer::stepEnd  ("Collision");

    mop.propagateX(pos);

    if (displayTime.getValue())
    {
        sout << " computeCollision " << ((double) CTime::getTime() - time) * timeScale << " ms" << sendl;
        time = (double)CTime::getTime();
    }

    // Solve constraints
    if (constraintSolver)
    {
        AdvancedTimer::stepBegin("ConstraintSolver");

        if (m_solveVelocityConstraintFirst.getValue())
        {
            core::ConstraintParams cparams(*params);
            cparams.setX(freePos);
            cparams.setV(freeVel);

            cparams.setOrder(core::ConstraintParams::VEL);
            constraintSolver->solveConstraint(&cparams, vel);

            MultiVecDeriv dv(&vop, constraintSolver->getDx());
            mop.propagateDx(dv);

            // xfree += dv * dt
            freePos.eq(freePos, dv, dt);
            mop.propagateX(freePos);

            cparams.setOrder(core::ConstraintParams::POS);
            constraintSolver->solveConstraint(&cparams, pos);

            MultiVecDeriv dx(&vop, constraintSolver->getDx());

            mop.propagateV(vel);
            mop.propagateDx(dx);

            // "mapped" x = xfree + dx
            simulation::MechanicalVOpVisitor(params, pos, freePos, dx, 1.0 ).setOnlyMapped(true).execute(this->gnode);
        }
        else
        {
            core::ConstraintParams cparams(*params);
            cparams.setX(freePos);
            cparams.setV(freeVel);

            constraintSolver->solveConstraint(&cparams, pos, vel);

            mop.propagateV(vel);

            MultiVecDeriv dx(&vop, constraintSolver->getDx());
            mop.propagateDx(dx);

            // "mapped" x = xfree + dx
            simulation::MechanicalVOpVisitor(params, pos, freePos, dx, 1.0 ).setOnlyMapped(true).execute(this->gnode);
        }
    }

    if ( displayTime.getValue() )
    {
        sout << " contactCorrections " << ((double)CTime::getTime() - time) * timeScale << " ms" <<sendl;
        sout << "<<<<<< End display FreeMotionAnimationLoop time." << sendl;
    }

    simulation::MechanicalEndIntegrationVisitor endVisitor(params /* PARAMS FIRST */, dt);
    this->gnode->execute(&endVisitor);

    this->gnode->setTime ( startTime + dt );
    this->gnode->execute<UpdateSimulationContextVisitor>(params);  // propagate time

    {
        AnimateEndEvent ev ( dt );
        PropagateEventVisitor act ( params, &ev );
        this->gnode->execute ( act );
    }

    sofa::helper::AdvancedTimer::stepBegin("UpdateMapping");
    //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping
    this->gnode->execute<UpdateMappingVisitor>(params);
    sofa::helper::AdvancedTimer::step("UpdateMappingEndEvent");
    {
        UpdateMappingEndEvent ev ( dt );
        PropagateEventVisitor act ( params , &ev );
        this->gnode->execute ( act );
    }
    sofa::helper::AdvancedTimer::stepEnd("UpdateMapping");

#ifndef SOFA_NO_UPDATE_BBOX
    sofa::helper::AdvancedTimer::stepBegin("UpdateBBox");
    this->gnode->execute<UpdateBoundingBoxVisitor>(params);
    sofa::helper::AdvancedTimer::stepEnd("UpdateBBox");
#endif
#ifdef SOFA_DUMP_VISITOR_INFO
    simulation::Visitor::printCloseNode(std::string("Step"));
#endif

    sofa::helper::AdvancedTimer::stepEnd("AnimationStep");
}

SOFA_DECL_CLASS(FreeMotionAnimationLoop)

int FreeMotionAnimationLoopClass = core::RegisterObject("Constraint solver")
        .add< FreeMotionAnimationLoop >()
        .addAlias("FreeMotionMasterSolver")
        ;

} // namespace animationloop

} // namespace component

} // namespace sofa
<commit_msg>r11663/sofa-dev : FIX : Animation step did not appear in the AdvancedTimer reports in scenes using the FreeMotionAnimationLoop.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <sofa/component/animationloop/FreeMotionAnimationLoop.h>
#include <sofa/core/visual/VisualParams.h>

#include <sofa/component/constraintset/LCPConstraintSolver.h>

#include <sofa/core/ObjectFactory.h>
#include <sofa/core/VecId.h>

#include <sofa/helper/AdvancedTimer.h>

#include <sofa/simulation/common/BehaviorUpdatePositionVisitor.h>
#include <sofa/simulation/common/MechanicalOperations.h>
#include <sofa/simulation/common/SolveVisitor.h>
#include <sofa/simulation/common/VectorOperations.h>

namespace sofa
{

namespace component
{

namespace animationloop
{

using namespace core::behavior;

FreeMotionAnimationLoop::FreeMotionAnimationLoop(simulation::Node* gnode)
    : Inherit(gnode)
    , m_solveVelocityConstraintFirst(initData(&m_solveVelocityConstraintFirst , false, "solveVelocityConstraintFirst", "solve separately velocity constraint violations before position constraint violations"))
    , constraintSolver(NULL)
    , defaultSolver(NULL)
{
}

FreeMotionAnimationLoop::~FreeMotionAnimationLoop()
{
    if (defaultSolver != NULL)
        defaultSolver.reset();
}

void FreeMotionAnimationLoop::parse ( sofa::core::objectmodel::BaseObjectDescription* arg )
{
    this->simulation::CollisionAnimationLoop::parse(arg);

    defaultSolver = sofa::core::objectmodel::New<constraintset::LCPConstraintSolver>();
    defaultSolver->parse(arg);
}

void FreeMotionAnimationLoop::init()
{
    getContext()->get(constraintSolver, core::objectmodel::BaseContext::SearchDown);
    if (constraintSolver == NULL && defaultSolver != NULL)
    {
        serr << "No ConstraintSolver found, using default LCPConstraintSolver" << sendl;
        this->getContext()->addObject(defaultSolver);
        constraintSolver = defaultSolver.get();
        defaultSolver = NULL;
    }
    else
    {
        defaultSolver.reset();
    }
}

void FreeMotionAnimationLoop::step(const sofa::core::ExecParams* params /* PARAMS FIRST */, double dt)
{
    if (dt == 0)
        dt = this->gnode->getDt();

    sofa::helper::AdvancedTimer::stepBegin("AnimationStep");
    sofa::helper::AdvancedTimer::begin("Animate");
    {
        AnimateBeginEvent ev ( dt );
        PropagateEventVisitor act ( params, &ev );
        this->gnode->execute ( act );
    }

    double startTime = this->gnode->getTime();

    simulation::common::VectorOperations vop(params, this->getContext());
    simulation::common::MechanicalOperations mop(params, this->getContext());

    MultiVecCoord pos(&vop, core::VecCoordId::position() );
    MultiVecDeriv vel(&vop, core::VecDerivId::velocity() );
    MultiVecCoord freePos(&vop, core::VecCoordId::freePosition() );
    MultiVecDeriv freeVel(&vop, core::VecDerivId::freeVelocity() );

    // This solver will work in freePosition and freeVelocity vectors.
    // We need to initialize them if it's not already done.
    simulation::MechanicalVInitVisitor< core::V_COORD >(params, core::VecCoordId::freePosition(), core::ConstVecCoordId::position(), true).execute(this->gnode);
    simulation::MechanicalVInitVisitor< core::V_DERIV >(params, core::VecDerivId::freeVelocity(), core::ConstVecDerivId::velocity(), true).execute(this->gnode);

    BehaviorUpdatePositionVisitor beh(params , dt);

    using helper::system::thread::CTime;
    using sofa::helper::AdvancedTimer;

    double time = 0.0;
    double timeTotal = 0.0;
    double timeScale = 1000.0 / (double)CTime::getTicksPerSec();

    if (displayTime.getValue())
    {
        time = (double) CTime::getTime();
        timeTotal = (double) CTime::getTime();
    }

    // Update the BehaviorModels
    // Required to allow the RayPickInteractor interaction
    if (f_printLog.getValue())
        serr << "updatePos called" << sendl;

    AdvancedTimer::stepBegin("UpdatePosition");
    this->gnode->execute(&beh);
    AdvancedTimer::stepEnd("UpdatePosition");

    if (f_printLog.getValue())
        serr << "updatePos performed - beginVisitor called" << sendl;

    simulation::MechanicalBeginIntegrationVisitor beginVisitor(params, dt);
    this->gnode->execute(&beginVisitor);

    if (f_printLog.getValue())
        serr << "beginVisitor performed - SolveVisitor for freeMotion is called" << sendl;

    // Free Motion
    AdvancedTimer::stepBegin("FreeMotion");
    simulation::SolveVisitor freeMotion(params, dt, true);
    this->gnode->execute(&freeMotion);
    AdvancedTimer::stepEnd("FreeMotion");

    mop.propagateXAndV(freePos, freeVel);

    if (f_printLog.getValue())
        serr << " SolveVisitor for freeMotion performed" << sendl;

    if (displayTime.getValue())
    {
        sout << " >>>>> Begin display FreeMotionAnimationLoop time" << sendl;
        sout <<" Free Motion " << ((double)CTime::getTime() - time) * timeScale << " ms" << sendl;

        time = (double)CTime::getTime();
    }

    // Collision detection and response creation
    AdvancedTimer::stepBegin("Collision");
    computeCollision(params);
    AdvancedTimer::stepEnd  ("Collision");

    mop.propagateX(pos);

    if (displayTime.getValue())
    {
        sout << " computeCollision " << ((double) CTime::getTime() - time) * timeScale << " ms" << sendl;
        time = (double)CTime::getTime();
    }

    // Solve constraints
    if (constraintSolver)
    {
        AdvancedTimer::stepBegin("ConstraintSolver");

        if (m_solveVelocityConstraintFirst.getValue())
        {
            core::ConstraintParams cparams(*params);
            cparams.setX(freePos);
            cparams.setV(freeVel);

            cparams.setOrder(core::ConstraintParams::VEL);
            constraintSolver->solveConstraint(&cparams, vel);

            MultiVecDeriv dv(&vop, constraintSolver->getDx());
            mop.propagateDx(dv);

            // xfree += dv * dt
            freePos.eq(freePos, dv, dt);
            mop.propagateX(freePos);

            cparams.setOrder(core::ConstraintParams::POS);
            constraintSolver->solveConstraint(&cparams, pos);

            MultiVecDeriv dx(&vop, constraintSolver->getDx());

            mop.propagateV(vel);
            mop.propagateDx(dx);

            // "mapped" x = xfree + dx
            simulation::MechanicalVOpVisitor(params, pos, freePos, dx, 1.0 ).setOnlyMapped(true).execute(this->gnode);
        }
        else
        {
            core::ConstraintParams cparams(*params);
            cparams.setX(freePos);
            cparams.setV(freeVel);

            constraintSolver->solveConstraint(&cparams, pos, vel);

            mop.propagateV(vel);

            MultiVecDeriv dx(&vop, constraintSolver->getDx());
            mop.propagateDx(dx);

            // "mapped" x = xfree + dx
            simulation::MechanicalVOpVisitor(params, pos, freePos, dx, 1.0 ).setOnlyMapped(true).execute(this->gnode);
        }
    }

    if ( displayTime.getValue() )
    {
        sout << " contactCorrections " << ((double)CTime::getTime() - time) * timeScale << " ms" <<sendl;
        sout << "<<<<<< End display FreeMotionAnimationLoop time." << sendl;
    }

    simulation::MechanicalEndIntegrationVisitor endVisitor(params /* PARAMS FIRST */, dt);
    this->gnode->execute(&endVisitor);

    this->gnode->setTime ( startTime + dt );
    this->gnode->execute<UpdateSimulationContextVisitor>(params);  // propagate time

    {
        AnimateEndEvent ev ( dt );
        PropagateEventVisitor act ( params, &ev );
        this->gnode->execute ( act );
    }

    sofa::helper::AdvancedTimer::stepBegin("UpdateMapping");
    //Visual Information update: Ray Pick add a MechanicalMapping used as VisualMapping
    this->gnode->execute<UpdateMappingVisitor>(params);
    sofa::helper::AdvancedTimer::step("UpdateMappingEndEvent");
    {
        UpdateMappingEndEvent ev ( dt );
        PropagateEventVisitor act ( params , &ev );
        this->gnode->execute ( act );
    }
    sofa::helper::AdvancedTimer::stepEnd("UpdateMapping");

#ifndef SOFA_NO_UPDATE_BBOX
    sofa::helper::AdvancedTimer::stepBegin("UpdateBBox");
    this->gnode->execute<UpdateBoundingBoxVisitor>(params);
    sofa::helper::AdvancedTimer::stepEnd("UpdateBBox");
#endif
#ifdef SOFA_DUMP_VISITOR_INFO
    simulation::Visitor::printCloseNode(std::string("Step"));
#endif

    sofa::helper::AdvancedTimer::end("Animate");
    sofa::helper::AdvancedTimer::stepEnd("AnimationStep");
}

SOFA_DECL_CLASS(FreeMotionAnimationLoop)

int FreeMotionAnimationLoopClass = core::RegisterObject("Constraint solver")
        .add< FreeMotionAnimationLoop >()
        .addAlias("FreeMotionMasterSolver")
        ;

} // namespace animationloop

} // namespace component

} // namespace sofa
<|endoftext|>


<commit_before>/*
 * MIT License
 * Copyright (c) 2016 Vladislav Tananaev
 */
#include "ComputationalGraph.h"
using std::string;

ComputationalGraph::ComputationalGraph()
{
    grad_input_last_gate = 1; // This is gradient input for the last gate
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a, float &input_b){

    // Connect inputs
    g->input_a.connect( &input_a );
    g->input_b.connect( &input_b );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a, float &input_b){

    // Find previous gate with name input_a
    // Note: throwS if element isn't found
    auto prev_g = gates.at(input_a);

    // Connect inputs
    g->input_a.connect( &(prev_g->output) );
    g->input_b.connect( &input_b );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gate
    prev_g->grad_input.connect( &(g->gradout_a) );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a, string input_b){

    // Find previous gate with name input_b
    // Note: throws if element isn't found
    auto prev_g = gates.at(input_b);

    // Connect inputs
    g->input_a.connect( &input_a );
    g->input_b.connect( &(prev_g->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gate
    prev_g->grad_input.connect( &(g->gradout_b) );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a, string input_b){

    // Find previous gate with name input_a
    // Note: throws if element isn't found
    auto prev_g_a = gates.at(input_a);
    // Find previous gate with name input_b
    auto prev_g_b = gates.at(input_b);

    // Connect inputs
    g->input_a.connect( &(prev_g_a->output) );
    g->input_b.connect( &(prev_g_b->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gates
    prev_g_a->grad_input.connect( &(g->gradout_a) );
    prev_g_b->grad_input.connect( &(g->gradout_b) );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a){

    // Find previous gate with name input_a
    // Note: throws if element isn't found
    auto prev_g_a = gates.at(input_a);

    // Connect inputs
    g->input_a.connect( &(prev_g_a->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gates
    prev_g_a->grad_input.connect( &(g->gradout_a) );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a){

    // Connect inputs
    g->input_a.connect( &input_a );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    gates.emplace(name, g);
    order.emplace_back(name);
}

void ComputationalGraph::forward(){
    // Call gates in topological order
    for (auto it = order.begin(); it!=order.end(); ++it){
        auto g = gates.at(*it);
        g->forward();
        std::cout << "[forward] Gate " << *it << " output is " << g->output << std::endl;
    }
}

void ComputationalGraph::backward(){
    // Call gates in reverse topological order
    for (auto it = order.rbegin(); it!=order.rend(); ++it){
        auto g = gates.at(*it);
        g->backward();

        std::cout << "[backward] Gate " << *it << " gradoutput_a is " << g->gradout_a;
        if(!g->unary){
            std::cout << " gradoutput_b is " << g->gradout_b;
        }
        std::cout << std::endl;

    }
}

ComputationalGraph::~ComputationalGraph(){}
<commit_msg>Emplace with move ctor.<commit_after>/*
 * MIT License
 * Copyright (c) 2016 Vladislav Tananaev
 */
#include "ComputationalGraph.h"
using std::string;

ComputationalGraph::ComputationalGraph()
{
    grad_input_last_gate = 1; // This is gradient input for the last gate
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a, float &input_b){

    // Connect inputs
    g->input_a.connect( &input_a );
    g->input_b.connect( &input_b );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a, float &input_b){

    // Find previous gate with name input_a
    // Note: throwS if element isn't found
    auto prev_g = gates.at(input_a);

    // Connect inputs
    g->input_a.connect( &(prev_g->output) );
    g->input_b.connect( &input_b );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gate
    prev_g->grad_input.connect( &(g->gradout_a) );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a, string input_b){

    // Find previous gate with name input_b
    // Note: throws if element isn't found
    auto prev_g = gates.at(input_b);

    // Connect inputs
    g->input_a.connect( &input_a );
    g->input_b.connect( &(prev_g->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gate
    prev_g->grad_input.connect( &(g->gradout_b) );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a, string input_b){

    // Find previous gate with name input_a
    // Note: throws if element isn't found
    auto prev_g_a = gates.at(input_a);
    // Find previous gate with name input_b
    auto prev_g_b = gates.at(input_b);

    // Connect inputs
    g->input_a.connect( &(prev_g_a->output) );
    g->input_b.connect( &(prev_g_b->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gates
    prev_g_a->grad_input.connect( &(g->gradout_a) );
    prev_g_b->grad_input.connect( &(g->gradout_b) );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, string input_a){

    // Find previous gate with name input_a
    // Note: throws if element isn't found
    auto prev_g_a = gates.at(input_a);

    // Connect inputs
    g->input_a.connect( &(prev_g_a->output) );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    // Connect gradients for previous gates
    prev_g_a->grad_input.connect( &(g->gradout_a) );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::add(string name, Gate::Ptr g, float &input_a){

    // Connect inputs
    g->input_a.connect( &input_a );

    // Default gradient input for this gate
    g->grad_input.connect( &grad_input_last_gate );

    gates.emplace({name, g});
    order.emplace_back(name);
}

void ComputationalGraph::forward(){
    // Call gates in topological order
    for (auto it = order.begin(); it!=order.end(); ++it){
        auto g = gates.at(*it);
        g->forward();
        std::cout << "[forward] Gate " << *it << " output is " << g->output << std::endl;
    }
}

void ComputationalGraph::backward(){
    // Call gates in reverse topological order
    for (auto it = order.rbegin(); it!=order.rend(); ++it){
        auto g = gates.at(*it);
        g->backward();

        std::cout << "[backward] Gate " << *it << " gradoutput_a is " << g->gradout_a;
        if(!g->unary){
            std::cout << " gradoutput_b is " << g->gradout_b;
        }
        std::cout << std::endl;

    }
}

ComputationalGraph::~ComputationalGraph(){}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// planner_test.cpp
//
// Identification: test/planner/planner_test.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "catalog/catalog.h"
#include "common/harness.h"
#include "concurrency/transaction_manager_factory.h"
#include "executor/plan_executor.h"
#include "expression/comparison_expression.h"
#include "expression/operator_expression.h"
#include "expression/parameter_value_expression.h"
#include "expression/tuple_value_expression.h"
#include "expression/expression_util.h"
#include "parser/statements.h"
#include "parser/postgresparser.h"

#include "planner/create_plan.h"
#include "planner/delete_plan.h"
#include "planner/attribute_info.h"
#include "planner/plan_util.h"
#include "planner/project_info.h"
#include "planner/seq_scan_plan.h"
#include "planner/update_plan.h"

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Planner Test
//===--------------------------------------------------------------------===//

class PlannerTest : public PelotonTest {};

TEST_F(PlannerTest, CreateDatabasePlanTest) {

  auto& peloton_parser = parser::PostgresParser::GetInstance();
  auto parse_tree_list = peloton_parser.BuildParseTree("CREATE DATABASE pelotondb;");
  // There should be only one statement in the statement list
  EXPECT_EQ(1, parse_tree_list->GetNumStatements());
  auto &parse_tree = parse_tree_list->GetStatements().at(0);

  std::unique_ptr<planner::CreatePlan> create_DB_plan(
    new planner::CreatePlan((parser::CreateStatement *)parse_tree.get()));
  EXPECT_EQ(0, create_DB_plan->GetDatabaseName().compare("pelotondb"));
  EXPECT_EQ(CreateType::DB, create_DB_plan->GetCreateType());
}

TEST_F(PlannerTest, DeletePlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // DELETE FROM department_table WHERE id = $0

  // id = $0
  txn = txn_manager.BeginTransaction();
  auto *parameter_expr = new expression::ParameterValueExpression(0);
  auto *tuple_expr =
      new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0);
  auto *scan_expr = new expression::ComparisonExpression(
      ExpressionType::COMPARE_EQUAL, tuple_expr, parameter_expr);

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  // Create delete plan
  std::unique_ptr<planner::DeletePlan> delete_plan(
      new planner::DeletePlan(target_table));

  // Create sequential scan plan
  LOG_TRACE("Creating a sequential scan plan");
  std::unique_ptr<planner::SeqScanPlan> seq_scan_node(
      new planner::SeqScanPlan(target_table, scan_expr, {}));
  LOG_INFO("Sequential scan plan created");

  // Add seq scan plan
  delete_plan->AddChild(std::move(seq_scan_node));

  LOG_INFO("Plan created:\n%s",
           planner::PlanUtil::GetInfo(delete_plan.get()).c_str());

  std::vector<type::Value> values;

  // id = 15
  LOG_INFO("Binding values");
  values.push_back(type::ValueFactory::GetIntegerValue(15).Copy());

  // bind values to parameters in plan
  delete_plan->SetParameterValues(&values);

  // free the database just created
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, UpdatePlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // UPDATE department_table SET name = $0 WHERE id = $1
  txn = txn_manager.BeginTransaction();

  auto table_name = std::string("department_table");
  auto database_name = DEFAULT_DB_NAME;
  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      database_name, table_name, txn);
  auto schema = target_table->GetSchema();

  TargetList tlist;
  DirectMapList dmlist;
  oid_t col_id;
  std::vector<oid_t> column_ids;

  col_id = schema->GetColumnID(std::string("name"));
  column_ids.push_back(col_id);
  auto *update_expr = new expression::ParameterValueExpression(0);

  planner::DerivedAttribute attribute(update_expr);
  attribute.attribute_info.type = update_expr->ResultType();
  attribute.attribute_info.name = std::string("name");
  tlist.emplace_back(col_id, attribute);

  auto *parameter_expr = new expression::ParameterValueExpression(1);
  auto *tuple_expr =
      new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0);
  auto *where_expr = new expression::ComparisonExpression(
      ExpressionType::COMPARE_EQUAL, tuple_expr, parameter_expr);

  auto &schema_columns = schema->GetColumns();
  for (uint i = 0; i < schema_columns.size(); i++) {
    bool is_in_target_list = false;
    for (auto col_id : column_ids) {
      if (schema_columns[i].column_name == schema_columns[col_id].column_name) {
        is_in_target_list = true;
        break;
      }
    }
    if (is_in_target_list == false)
      dmlist.emplace_back(i, std::pair<oid_t, oid_t>(0, i));
  }

  column_ids.clear();
  for (uint i = 0; i < schema_columns.size(); i++) {
    column_ids.emplace_back(i);
  }

  std::unique_ptr<const planner::ProjectInfo> project_info(
      new planner::ProjectInfo(std::move(tlist), std::move(dmlist)));

  std::unique_ptr<planner::UpdatePlan> update_plan(
      new planner::UpdatePlan(target_table, std::move(project_info)));

  std::unique_ptr<planner::SeqScanPlan> seq_scan_node(
      new planner::SeqScanPlan(target_table, where_expr, column_ids));
  update_plan->AddChild(std::move(seq_scan_node));

  LOG_INFO("Plan created:\n%s", update_plan->GetInfo().c_str());

  std::vector<type::Value> values;

  // name = CS, id = 1
  LOG_INFO("Binding values");
  values.push_back(type::ValueFactory::GetVarcharValue("CS").Copy());
  values.push_back(type::ValueFactory::GetIntegerValue(1).Copy());

  // bind values to parameters in plan
  update_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, InsertPlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  auto ret = catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  if (ret != ResultType::SUCCESS) LOG_TRACE("create table failed");
  txn_manager.CommitTransaction(txn);

  // INSERT INTO department_table VALUES ($0, $1)
  txn = txn_manager.BeginTransaction();
  std::unique_ptr<parser::InsertStatement> insert_statement(
      new parser::InsertStatement(peloton::InsertType::VALUES));

  std::string name = "department_table";
  auto table_ref = new parser::TableRef(TableReferenceType::NAME);
  table_ref->table_info_ .reset(new parser::TableInfo());
  table_ref->table_info_->table_name = name;
  insert_statement->table_ref_.reset(table_ref);

  // Value val =
  //    type::ValueFactory::GetNullValue();  // The value is not important
  // at  this point
  insert_statement->insert_values.push_back(
      std::vector<std::unique_ptr<peloton::expression::AbstractExpression>>());
  auto& parameter_exprs = insert_statement->insert_values[0];
  auto parameter_expr_1 = new expression::ParameterValueExpression(0);
  auto parameter_expr_2 = new expression::ParameterValueExpression(1);
  parameter_exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_1));
  parameter_exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_2));

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  std::unique_ptr<planner::InsertPlan> insert_plan(new planner::InsertPlan(
      target_table, &insert_statement->columns,
      &insert_statement->insert_values));
  LOG_INFO("Plan created:\n%s", insert_plan->GetInfo().c_str());

  // VALUES(1, "CS")
  LOG_INFO("Binding values");
  std::vector<type::Value> values;
  values.push_back(type::ValueFactory::GetIntegerValue(1).Copy());
  values.push_back(type::ValueFactory::GetVarcharValue(
                        (std::string) "CS",
                        TestingHarness::GetInstance().GetTestingPool()).Copy());
  LOG_INFO("Value 1: %s", values.at(0).GetInfo().c_str());
  LOG_INFO("Value 2: %s", values.at(1).GetInfo().c_str());
  // bind values to parameters in plan
  insert_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, InsertPlanTestParameterColumns) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // INSERT INTO department_table VALUES (1, $1)
  txn = txn_manager.BeginTransaction();
  std::unique_ptr<parser::InsertStatement> insert_statement(
      new parser::InsertStatement(peloton::InsertType::VALUES));

  std::string name = "department_table";
  auto table_ref = new parser::TableRef(TableReferenceType::NAME);
  table_ref->table_info_.reset(new parser::TableInfo());
  table_ref->table_info_->table_name = name;

  std::string id_col = "id", name_col = "name";
  insert_statement->table_ref_.reset(table_ref);
  insert_statement->columns.push_back(id_col);
  insert_statement->columns.push_back(name_col);

  // Value val =
  //    type::ValueFactory::GetNullValue();  // The value is not important
  // at  this point
  auto constant_expr_1 = new expression::ConstantValueExpression(
      type::ValueFactory::GetIntegerValue(1));
  auto parameter_expr_2 = new expression::ParameterValueExpression(1);
  insert_statement->insert_values.push_back(
      std::vector<std::unique_ptr<expression::AbstractExpression>>());
  auto& exprs = insert_statement->insert_values[0];
  exprs.push_back(std::unique_ptr<expression::AbstractExpression>(constant_expr_1));
  exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_2));

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  std::unique_ptr<planner::InsertPlan> insert_plan(new planner::InsertPlan(
      target_table, &insert_statement->columns,
      &insert_statement->insert_values));
  LOG_INFO("Plan created:\n%s", insert_plan->GetInfo().c_str());

  // VALUES(1, "CS")
  LOG_INFO("Binding values");
  std::vector<type::Value> values;
  values.push_back(type::ValueFactory::GetVarcharValue(
                        (std::string) "CS",
                        TestingHarness::GetInstance().GetTestingPool()).Copy());
  LOG_INFO("Value 1: %s", values.at(0).GetInfo().c_str());
  // bind values to parameters in plan
  insert_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

}  // namespace test
}  // namespace peloton
<commit_msg>add drop planner test<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// planner_test.cpp
//
// Identification: test/planner/planner_test.cpp
//
// Copyright (c) 2015-17, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "catalog/catalog.h"
#include "common/harness.h"
#include "concurrency/transaction_manager_factory.h"
#include "executor/plan_executor.h"
#include "expression/comparison_expression.h"
#include "expression/operator_expression.h"
#include "expression/parameter_value_expression.h"
#include "expression/tuple_value_expression.h"
#include "expression/expression_util.h"
#include "parser/statements.h"
#include "parser/postgresparser.h"

#include "planner/create_plan.h"
#include "planner/delete_plan.h"
#include "planner/drop_plan.h"
#include "planner/attribute_info.h"
#include "planner/plan_util.h"
#include "planner/project_info.h"
#include "planner/seq_scan_plan.h"
#include "planner/update_plan.h"

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Planner Test
//===--------------------------------------------------------------------===//

class PlannerTest : public PelotonTest {};

TEST_F(PlannerTest, CreateDatabasePlanTest) {
  auto& peloton_parser = parser::PostgresParser::GetInstance();
  auto parse_tree_list = peloton_parser.BuildParseTree("CREATE DATABASE pelotondb;");
  // There should be only one statement in the statement list
  EXPECT_EQ(1, parse_tree_list->GetNumStatements());
  auto &parse_tree = parse_tree_list->GetStatements().at(0);

  std::unique_ptr<planner::CreatePlan> create_DB_plan(
    new planner::CreatePlan((parser::CreateStatement *)parse_tree.get())
  );
  EXPECT_STREQ("pelotondb", create_DB_plan->GetDatabaseName().c_str());
  EXPECT_EQ(CreateType::DB, create_DB_plan->GetCreateType());
}

TEST_F(PlannerTest, DropDatabasePlanTest) {
  auto& peloton_parser = parser::PostgresParser::GetInstance();
  auto parse_tree_list = peloton_parser.BuildParseTree("DROP DATABASE pelotondb;");
  // There should be only one statement in the statement list
  EXPECT_EQ(1, parse_tree_list->GetNumStatements());
  auto &parse_tree = parse_tree_list->GetStatements().at(0);

  std::unique_ptr<planner::DropPlan> drop_DB_plan(
    new planner::DropPlan((parser::DropStatement *)parse_tree.get())
  );
  EXPECT_STREQ("pelotondb", drop_DB_plan->GetDatabaseName().c_str());
  EXPECT_EQ(DropType::DB, drop_DB_plan->GetDropType());
}

TEST_F(PlannerTest, DeletePlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // DELETE FROM department_table WHERE id = $0

  // id = $0
  txn = txn_manager.BeginTransaction();
  auto *parameter_expr = new expression::ParameterValueExpression(0);
  auto *tuple_expr =
      new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0);
  auto *scan_expr = new expression::ComparisonExpression(
      ExpressionType::COMPARE_EQUAL, tuple_expr, parameter_expr);

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  // Create delete plan
  std::unique_ptr<planner::DeletePlan> delete_plan(
      new planner::DeletePlan(target_table));

  // Create sequential scan plan
  LOG_TRACE("Creating a sequential scan plan");
  std::unique_ptr<planner::SeqScanPlan> seq_scan_node(
      new planner::SeqScanPlan(target_table, scan_expr, {}));
  LOG_INFO("Sequential scan plan created");

  // Add seq scan plan
  delete_plan->AddChild(std::move(seq_scan_node));

  LOG_INFO("Plan created:\n%s",
           planner::PlanUtil::GetInfo(delete_plan.get()).c_str());

  std::vector<type::Value> values;

  // id = 15
  LOG_INFO("Binding values");
  values.push_back(type::ValueFactory::GetIntegerValue(15).Copy());

  // bind values to parameters in plan
  delete_plan->SetParameterValues(&values);

  // free the database just created
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, UpdatePlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // UPDATE department_table SET name = $0 WHERE id = $1
  txn = txn_manager.BeginTransaction();

  auto table_name = std::string("department_table");
  auto database_name = DEFAULT_DB_NAME;
  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      database_name, table_name, txn);
  auto schema = target_table->GetSchema();

  TargetList tlist;
  DirectMapList dmlist;
  oid_t col_id;
  std::vector<oid_t> column_ids;

  col_id = schema->GetColumnID(std::string("name"));
  column_ids.push_back(col_id);
  auto *update_expr = new expression::ParameterValueExpression(0);

  planner::DerivedAttribute attribute(update_expr);
  attribute.attribute_info.type = update_expr->ResultType();
  attribute.attribute_info.name = std::string("name");
  tlist.emplace_back(col_id, attribute);

  auto *parameter_expr = new expression::ParameterValueExpression(1);
  auto *tuple_expr =
      new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0);
  auto *where_expr = new expression::ComparisonExpression(
      ExpressionType::COMPARE_EQUAL, tuple_expr, parameter_expr);

  auto &schema_columns = schema->GetColumns();
  for (uint i = 0; i < schema_columns.size(); i++) {
    bool is_in_target_list = false;
    for (auto col_id : column_ids) {
      if (schema_columns[i].column_name == schema_columns[col_id].column_name) {
        is_in_target_list = true;
        break;
      }
    }
    if (is_in_target_list == false)
      dmlist.emplace_back(i, std::pair<oid_t, oid_t>(0, i));
  }

  column_ids.clear();
  for (uint i = 0; i < schema_columns.size(); i++) {
    column_ids.emplace_back(i);
  }

  std::unique_ptr<const planner::ProjectInfo> project_info(
      new planner::ProjectInfo(std::move(tlist), std::move(dmlist)));

  std::unique_ptr<planner::UpdatePlan> update_plan(
      new planner::UpdatePlan(target_table, std::move(project_info)));

  std::unique_ptr<planner::SeqScanPlan> seq_scan_node(
      new planner::SeqScanPlan(target_table, where_expr, column_ids));
  update_plan->AddChild(std::move(seq_scan_node));

  LOG_INFO("Plan created:\n%s", update_plan->GetInfo().c_str());

  std::vector<type::Value> values;

  // name = CS, id = 1
  LOG_INFO("Binding values");
  values.push_back(type::ValueFactory::GetVarcharValue("CS").Copy());
  values.push_back(type::ValueFactory::GetIntegerValue(1).Copy());

  // bind values to parameters in plan
  update_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, InsertPlanTestParameter) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  auto ret = catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  if (ret != ResultType::SUCCESS) LOG_TRACE("create table failed");
  txn_manager.CommitTransaction(txn);

  // INSERT INTO department_table VALUES ($0, $1)
  txn = txn_manager.BeginTransaction();
  std::unique_ptr<parser::InsertStatement> insert_statement(
      new parser::InsertStatement(peloton::InsertType::VALUES));

  std::string name = "department_table";
  auto table_ref = new parser::TableRef(TableReferenceType::NAME);
  table_ref->table_info_ .reset(new parser::TableInfo());
  table_ref->table_info_->table_name = name;
  insert_statement->table_ref_.reset(table_ref);

  // Value val =
  //    type::ValueFactory::GetNullValue();  // The value is not important
  // at  this point
  insert_statement->insert_values.push_back(
      std::vector<std::unique_ptr<peloton::expression::AbstractExpression>>());
  auto& parameter_exprs = insert_statement->insert_values[0];
  auto parameter_expr_1 = new expression::ParameterValueExpression(0);
  auto parameter_expr_2 = new expression::ParameterValueExpression(1);
  parameter_exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_1));
  parameter_exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_2));

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  std::unique_ptr<planner::InsertPlan> insert_plan(new planner::InsertPlan(
      target_table, &insert_statement->columns,
      &insert_statement->insert_values));
  LOG_INFO("Plan created:\n%s", insert_plan->GetInfo().c_str());

  // VALUES(1, "CS")
  LOG_INFO("Binding values");
  std::vector<type::Value> values;
  values.push_back(type::ValueFactory::GetIntegerValue(1).Copy());
  values.push_back(type::ValueFactory::GetVarcharValue(
                        (std::string) "CS",
                        TestingHarness::GetInstance().GetTestingPool()).Copy());
  LOG_INFO("Value 1: %s", values.at(0).GetInfo().c_str());
  LOG_INFO("Value 2: %s", values.at(1).GetInfo().c_str());
  // bind values to parameters in plan
  insert_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

TEST_F(PlannerTest, InsertPlanTestParameterColumns) {
  // Bootstrapping peloton
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);

  // Create table
  txn = txn_manager.BeginTransaction();
  auto id_column = catalog::Column(
      type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER),
      "id", true);
  auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true);

  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({id_column, name_column}));
  catalog::Catalog::GetInstance()->CreateTable(
      DEFAULT_DB_NAME, "department_table", std::move(table_schema), txn);
  txn_manager.CommitTransaction(txn);

  // INSERT INTO department_table VALUES (1, $1)
  txn = txn_manager.BeginTransaction();
  std::unique_ptr<parser::InsertStatement> insert_statement(
      new parser::InsertStatement(peloton::InsertType::VALUES));

  std::string name = "department_table";
  auto table_ref = new parser::TableRef(TableReferenceType::NAME);
  table_ref->table_info_.reset(new parser::TableInfo());
  table_ref->table_info_->table_name = name;

  std::string id_col = "id", name_col = "name";
  insert_statement->table_ref_.reset(table_ref);
  insert_statement->columns.push_back(id_col);
  insert_statement->columns.push_back(name_col);

  // Value val =
  //    type::ValueFactory::GetNullValue();  // The value is not important
  // at  this point
  auto constant_expr_1 = new expression::ConstantValueExpression(
      type::ValueFactory::GetIntegerValue(1));
  auto parameter_expr_2 = new expression::ParameterValueExpression(1);
  insert_statement->insert_values.push_back(
      std::vector<std::unique_ptr<expression::AbstractExpression>>());
  auto& exprs = insert_statement->insert_values[0];
  exprs.push_back(std::unique_ptr<expression::AbstractExpression>(constant_expr_1));
  exprs.push_back(std::unique_ptr<expression::AbstractExpression>(parameter_expr_2));

  auto target_table = catalog::Catalog::GetInstance()->GetTableWithName(
      DEFAULT_DB_NAME, "department_table", txn);

  std::unique_ptr<planner::InsertPlan> insert_plan(new planner::InsertPlan(
      target_table, &insert_statement->columns,
      &insert_statement->insert_values));
  LOG_INFO("Plan created:\n%s", insert_plan->GetInfo().c_str());

  // VALUES(1, "CS")
  LOG_INFO("Binding values");
  std::vector<type::Value> values;
  values.push_back(type::ValueFactory::GetVarcharValue(
                        (std::string) "CS",
                        TestingHarness::GetInstance().GetTestingPool()).Copy());
  LOG_INFO("Value 1: %s", values.at(0).GetInfo().c_str());
  // bind values to parameters in plan
  insert_plan->SetParameterValues(&values);
  txn_manager.CommitTransaction(txn);

  // free the database just created
  txn = txn_manager.BeginTransaction();
  catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn);
  txn_manager.CommitTransaction(txn);
}

}  // namespace test
}  // namespace peloton
<|endoftext|>