/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA. */

/***********************************************************************
 *   $Id: dmlpkg.cpp 9210 2013-01-21 14:10:42Z rdempsey $
 *
 *
 ***********************************************************************/
#include "dmlpkg.h"

namespace dmlpackage
{
using namespace std;

/** SqlStatementList
 */
ostream& operator<<(ostream& os, const SqlStatementList& ssl)
{
  vector<SqlStatement*>::const_iterator itr;

  for (itr = ssl.fList.begin(); itr != ssl.fList.end(); ++itr)
  {
    SqlStatement& stmt = **itr;
    os << stmt;
  }

  return os;
}

void SqlStatementList::push_back(SqlStatement* v)
{
  fList.push_back(v);
}

SqlStatementList::~SqlStatementList()
{
  vector<SqlStatement*>::iterator itr;

  for (itr = fList.begin(); itr != fList.end(); ++itr)
  {
    delete *itr;
  }
}

/** SqlStatement
 */
SqlStatement::SqlStatement() : fNamePtr(0)
{
}

SqlStatement::~SqlStatement()
{
  if (0 != fNamePtr)
    delete fNamePtr;
}

ostream& operator<<(ostream& os, const SqlStatement& stmt)
{
  return stmt.put(os);
}

std::string SqlStatement::getSchemaName() const
{
  std::string schema_name;

  if (0 != fNamePtr)
    schema_name = fNamePtr->fSchema;

  return schema_name;
}

std::string SqlStatement::getTableName() const
{
  std::string table_name;

  if (0 != fNamePtr)
    table_name = fNamePtr->fName;

  return table_name;
}

/** InsertSqlStatement
 */
InsertSqlStatement::InsertSqlStatement() : fValuesOrQueryPtr(0)
{
}

InsertSqlStatement::InsertSqlStatement(TableName* tableNamePtr, ValuesOrQuery* valsOrQueryPtr)
 : fValuesOrQueryPtr(valsOrQueryPtr)
{
  fNamePtr = tableNamePtr;
}

InsertSqlStatement::InsertSqlStatement(TableName* tableNamePtr, ColumnNameList* columnNamesPtr,
                                       ValuesOrQuery* valsOrQueryPtr)
 : fValuesOrQueryPtr(valsOrQueryPtr)
{
  fNamePtr = tableNamePtr;
  fColumnList = *columnNamesPtr;
  delete columnNamesPtr;
}

InsertSqlStatement::~InsertSqlStatement()
{
  if (0 != fValuesOrQueryPtr)
    delete fValuesOrQueryPtr;
}

ostream& InsertSqlStatement::put(ostream& os) const
{
  os << "Insert " << endl;

  if (0 != fNamePtr)
  {
    fNamePtr->put(os);
  }

  ColumnNameList::const_iterator itr;

  for (itr = fColumnList.begin(); itr != fColumnList.end(); ++itr)
  {
    os << *itr << endl;
  }

  if (0 != fValuesOrQueryPtr)
  {
    fValuesOrQueryPtr->put(os);
  }

  return os;
}

string InsertSqlStatement::getQueryString() const
{
  std::string query_string;

  if (0 != fValuesOrQueryPtr)
  {
    query_string = fValuesOrQueryPtr->getQueryString();
  }

  return query_string;
}

/** UpdateSqlStatement
 */
UpdateSqlStatement::UpdateSqlStatement() : fColAssignmentListPtr(0), fWhereClausePtr(0)
{
}

UpdateSqlStatement::UpdateSqlStatement(TableName* tableNamePtr, ColumnAssignmentList* colAssignmentListPtr,
                                       WhereClause* whereClausePtr /*=0*/)
 : fColAssignmentListPtr(colAssignmentListPtr), fWhereClausePtr(whereClausePtr)
{
  fNamePtr = tableNamePtr;
}

UpdateSqlStatement::~UpdateSqlStatement()
{
  if (0 != fColAssignmentListPtr)
  {
    ColumnAssignmentList::iterator iter = fColAssignmentListPtr->begin();

    while (iter != fColAssignmentListPtr->end())
    {
      delete *iter;
      ++iter;
    }

    fColAssignmentListPtr->clear();
    delete fColAssignmentListPtr;
  }

  if (0 != fWhereClausePtr)
  {
    delete fWhereClausePtr;
  }
}

ostream& UpdateSqlStatement::put(ostream& os) const
{
  os << "Update " << endl;

  if (0 != fNamePtr)
  {
    fNamePtr->put(os);
  }

  if (0 != fColAssignmentListPtr)
  {
    os << "SET " << endl;
    ColumnAssignmentList::const_iterator iter = fColAssignmentListPtr->begin();

    while (iter != fColAssignmentListPtr->end())
    {
      ColumnAssignment* cola = *iter;
      cola->put(os);
      ++iter;
    }
  }

  if (0 != fWhereClausePtr)
  {
    fWhereClausePtr->put(os);
  }

  return os;
}

string UpdateSqlStatement::getQueryString() const
{
  std::string query_string;

  if (0 != fColAssignmentListPtr)
  {
    query_string += "SET ";
    ColumnAssignmentList::const_iterator iter = fColAssignmentListPtr->begin();

    while (iter != fColAssignmentListPtr->end())
    {
      ColumnAssignment* cola = *iter;
      query_string += cola->getColumnAssignmentString();

      ++iter;

      if (iter != fColAssignmentListPtr->end())
        query_string += ",";
    }
  }

  if (0 != fWhereClausePtr)
  {
    query_string += " ";
    query_string += fWhereClausePtr->getWhereClauseString();
  }

  return query_string;
}

/** DeleteSqlStatement
 */
DeleteSqlStatement::DeleteSqlStatement() : fWhereClausePtr(0)
{
}

DeleteSqlStatement::DeleteSqlStatement(TableName* tableNamePtr, WhereClause* whereClausePtr /*=0*/)
 : fWhereClausePtr(whereClausePtr)
{
  fNamePtr = tableNamePtr;
}

DeleteSqlStatement::~DeleteSqlStatement()
{
  if (0 != fWhereClausePtr)
  {
    delete fWhereClausePtr;
  }
}

ostream& DeleteSqlStatement::put(ostream& os) const
{
  os << "Delete " << endl;

  if (0 != fNamePtr)
  {
    fNamePtr->put(os);
  }

  if (0 != fWhereClausePtr)
  {
    fWhereClausePtr->put(os);
  }

  return os;
}

string DeleteSqlStatement::getQueryString() const
{
  std::string query_string;

  if (0 != fWhereClausePtr)
  {
    query_string += fWhereClausePtr->getWhereClauseString();
  }

  return query_string;
}

/** CommandSqlStatement
 */
CommandSqlStatement::CommandSqlStatement(std::string command) : fCommandText(command)
{
}

ostream& CommandSqlStatement::put(ostream& os) const
{
  os << fCommandText << endl;

  return os;
}

string CommandSqlStatement::getQueryString() const
{
  return fCommandText;
}

/** TableName
 */
TableName::TableName()
{
}

TableName::TableName(char* name)
{
  fName = name;
}

TableName::TableName(char* schema, char* name)
{
  fSchema = schema;
  fName = name;
}

ostream& TableName::put(ostream& os) const
{
  if (fSchema != "")
    os << fSchema << ".";

  os << fName << endl;
  return os;
}

/** ColumnAssignment
 */
ostream& ColumnAssignment::put(ostream& os) const
{
  os << fColumn << endl;
  os << fOperator << endl;
  os << fScalarExpression << endl;
  return os;
}

string ColumnAssignment::getColumnAssignmentString() const
{
  std::string column_assignment = fColumn;
  column_assignment += " ";
  column_assignment += fOperator;
  column_assignment += " ";
  column_assignment += fScalarExpression;

  return column_assignment;
}

/** ValuesOrQuery
 */
ValuesOrQuery::ValuesOrQuery() : fQuerySpecPtr(0)
{
}

ValuesOrQuery::ValuesOrQuery(ValuesList* valuesPtr) : fQuerySpecPtr(0)
{
  fValuesList = *valuesPtr;
  delete valuesPtr;
}

ValuesOrQuery::ValuesOrQuery(QuerySpec* querySpecPtr)
{
  fQuerySpecPtr = querySpecPtr;
}

ValuesOrQuery::~ValuesOrQuery()
{
  if (0 != fQuerySpecPtr)
    delete fQuerySpecPtr;
}

ostream& ValuesOrQuery::put(ostream& os) const
{
  ValuesList::const_iterator iter = fValuesList.begin();

  while (iter != fValuesList.end())
  {
    os << *iter << endl;
    ++iter;
  }

  if (0 != fQuerySpecPtr)
  {
    fQuerySpecPtr->put(os);
  }

  return os;
}

string ValuesOrQuery::getQueryString() const
{
  std::string query_string;

  if (0 != fQuerySpecPtr)
  {
    query_string = fQuerySpecPtr->getQueryString();
  }

  return query_string;
}

/** QuerySpec
 */
QuerySpec::QuerySpec() : fSelectFilterPtr(0), fTableExpressionPtr(0)
{
}

QuerySpec::QuerySpec(SelectFilter* selectFilter, TableExpression* tableExpression)
 : fSelectFilterPtr(selectFilter), fTableExpressionPtr(tableExpression)
{
}

QuerySpec::QuerySpec(SelectFilter* selectFilter, TableExpression* tableExpression, char* allOrDistinct)
 : fSelectFilterPtr(selectFilter), fTableExpressionPtr(tableExpression)
{
  fOptionAllOrDistinct = allOrDistinct;
}

QuerySpec::~QuerySpec()
{
  if (0 != fSelectFilterPtr)
    delete fSelectFilterPtr;

  if (0 != fTableExpressionPtr)
    delete fTableExpressionPtr;
}

ostream& QuerySpec::put(ostream& os) const
{
  if (0 != fSelectFilterPtr)
  {
    fSelectFilterPtr->put(os);
  }

  if (0 != fTableExpressionPtr)
  {
    fTableExpressionPtr->put(os);
  }

  if (fOptionAllOrDistinct != "")
  {
    os << fOptionAllOrDistinct << endl;
  }

  return os;
}

string QuerySpec::getQueryString() const
{
  std::string query_string;

  if (0 != fSelectFilterPtr)
  {
    query_string += fSelectFilterPtr->getSelectString();
  }

  if (0 != fTableExpressionPtr)
  {
    query_string += " ";
    query_string += fTableExpressionPtr->getTableExpressionString();
  }

  if (fOptionAllOrDistinct != "")
  {
    query_string += " ";
    query_string += fOptionAllOrDistinct;
  }

  return query_string;
}

/** SelectFilter
 */
SelectFilter::SelectFilter() : fColumnList(0)
{
}

SelectFilter::SelectFilter(ColumnNameList* columnListPtr)
{
  fColumnList = *columnListPtr;

  delete columnListPtr;
}

SelectFilter::~SelectFilter()
{
}

ostream& SelectFilter::put(ostream& os) const
{
  os << "SELECT" << endl;
  ColumnNameList::const_iterator iter = fColumnList.begin();

  while (iter != fColumnList.end())
  {
    os << *iter << endl;
    ++iter;
  }

  if (0 == fColumnList.size())
    os << "*" << endl;

  return os;
}

string SelectFilter::getSelectString() const
{
  std::string select_filter = "SELECT ";
  ColumnNameList::const_iterator iter = fColumnList.begin();

  while (iter != fColumnList.end())
  {
    select_filter += *iter;
    ++iter;

    if (iter != fColumnList.end())
      select_filter += ",";
  }

  if (0 == fColumnList.size())
    select_filter += "*";

  return select_filter;
}

/** TableExpression
 */
TableExpression::TableExpression() : fFromClausePtr(0), fWhereClausePtr(0), fGroupByPtr(0), fHavingPtr(0)
{
}

TableExpression::TableExpression(FromClause* fromClausePtr, WhereClause* whereClausePtr,
                                 GroupByClause* groupByPtr, HavingClause* havingPtr)
 : fFromClausePtr(fromClausePtr)
 , fWhereClausePtr(whereClausePtr)
 , fGroupByPtr(groupByPtr)
 , fHavingPtr(havingPtr)
{
}

TableExpression::~TableExpression()
{
  if (0 != fFromClausePtr)
    delete fFromClausePtr;

  if (0 != fWhereClausePtr)
    delete fWhereClausePtr;

  if (0 != fGroupByPtr)
    delete fGroupByPtr;

  if (0 != fHavingPtr)
    delete fHavingPtr;
}

ostream& TableExpression::put(ostream& os) const
{
  if (0 != fFromClausePtr)
  {
    fFromClausePtr->put(os);
  }

  if (0 != fWhereClausePtr)
  {
    fWhereClausePtr->put(os);
  }

  if (0 != fGroupByPtr)
  {
    fGroupByPtr->put(os);
  }

  if (0 != fHavingPtr)
  {
    fHavingPtr->put(os);
  }

  return os;
}

string TableExpression::getTableExpressionString() const
{
  std::string table_expression;

  if (0 != fFromClausePtr)
  {
    table_expression += fFromClausePtr->getFromClauseString();
  }

  if (0 != fWhereClausePtr)
  {
    table_expression += " ";
    table_expression += fWhereClausePtr->getWhereClauseString();
  }

  if (0 != fGroupByPtr)
  {
    table_expression += " ";
    table_expression += fGroupByPtr->getGroupByClauseString();
  }

  if (0 != fHavingPtr)
  {
    table_expression += " ";
    table_expression += fHavingPtr->getHavingClauseString();
  }

  return table_expression;
}

/** FromClause
 */
FromClause::FromClause() : fTableListPtr(0)
{
}

FromClause::FromClause(TableNameList* tableNameList)
{
  fTableListPtr = tableNameList;
}

FromClause::~FromClause()
{
  if (0 != fTableListPtr)
  {
    TableNameList::iterator iter = fTableListPtr->begin();

    while (iter != fTableListPtr->end())
    {
      TableName* tableNamePtr = *iter;
      delete tableNamePtr;
      ++iter;
    }

    fTableListPtr->clear();
    delete fTableListPtr;
  }
}

ostream& FromClause::put(ostream& os) const
{
  os << "FROM" << endl;

  if (0 != fTableListPtr)
  {
    TableNameList::const_iterator iter = fTableListPtr->begin();

    while (iter != fTableListPtr->end())
    {
      TableName* tableNamePtr = *iter;
      tableNamePtr->put(os);
      ++iter;
    }
  }

  return os;
}

string FromClause::getFromClauseString() const
{
  std::string from_clause = "FROM ";

  if (0 != fTableListPtr)
  {
    TableNameList::const_iterator iter = fTableListPtr->begin();

    while (iter != fTableListPtr->end())
    {
      TableName* tableNamePtr = *iter;

      if (tableNamePtr->fSchema != "")
      {
        from_clause += tableNamePtr->fSchema;
        from_clause += ".";
      }

      from_clause += tableNamePtr->fName;

      ++iter;

      if (iter != fTableListPtr->end())
        from_clause += ",";
    }
  }

  return from_clause;
}

/** WhereClause
 */
WhereClause::WhereClause() : fSearchConditionPtr(0)
{
}

WhereClause::~WhereClause()
{
  if (0 != fSearchConditionPtr)
  {
    delete fSearchConditionPtr;
  }
}

ostream& WhereClause::put(ostream& os) const
{
  os << "WHERE" << endl;

  if (0 != fSearchConditionPtr)
  {
    fSearchConditionPtr->put(os);
  }

  return os;
}

string WhereClause::getWhereClauseString() const
{
  std::string where_clause = "WHERE";

  if (0 != fSearchConditionPtr)
  {
    where_clause += " ";
    where_clause += fSearchConditionPtr->getSearchConditionString();
  }

  return where_clause;
}

/** HavingClause
 */
HavingClause::HavingClause() : fSearchConditionPtr(0)
{
}

HavingClause::~HavingClause()
{
  if (fSearchConditionPtr != 0)
  {
    delete fSearchConditionPtr;
  }
}

ostream& HavingClause::put(ostream& os) const
{
  os << "HAVING" << endl;

  if (0 != fSearchConditionPtr)
  {
    fSearchConditionPtr->put(os);
  }

  return os;
}

string HavingClause::getHavingClauseString() const
{
  std::string having_clause = "HAVING";

  if (0 != fSearchConditionPtr)
  {
    having_clause += " ";
    having_clause += fSearchConditionPtr->getSearchConditionString();
  }

  return having_clause;
}

/** GroupByClause
 */
GroupByClause::GroupByClause() : fColumnNamesListPtr(0)
{
}

GroupByClause::~GroupByClause()
{
  if (0 != fColumnNamesListPtr)
  {
    fColumnNamesListPtr->clear();
    delete fColumnNamesListPtr;
  }
}

ostream& GroupByClause::put(ostream& os) const
{
  os << "GROUP BY" << endl;

  if (0 != fColumnNamesListPtr)
  {
    ColumnNameList::const_iterator iter = fColumnNamesListPtr->begin();

    if (iter != fColumnNamesListPtr->end())
    {
      os << *iter << endl;
      ++iter;
    }
  }

  return os;
}

string GroupByClause::getGroupByClauseString() const
{
  std::string group_by_clause = "GROUP BY ";

  if (0 != fColumnNamesListPtr)
  {
    ColumnNameList::const_iterator iter = fColumnNamesListPtr->begin();

    if (iter != fColumnNamesListPtr->end())
    {
      group_by_clause += *iter;
      ++iter;

      if (iter != fColumnNamesListPtr->end())
        group_by_clause += ",";
    }
  }

  return group_by_clause;
}

/** Escape
 */
ostream& Escape::put(ostream& os) const
{
  os << "ESCAPE" << endl;

  os << fEscapeChar << endl;
  return os;
}

/** SearchCondition
 */
SearchCondition::SearchCondition() : fPredicatePtr(0), fLHSearchConditionPtr(0), fRHSearchConditionPtr(0)
{
}

SearchCondition::~SearchCondition()
{
  if (0 != fPredicatePtr)
  {
    delete fPredicatePtr;
  }

  if (0 != fLHSearchConditionPtr)
  {
    delete fLHSearchConditionPtr;
  }

  if (0 != fRHSearchConditionPtr)
  {
    delete fRHSearchConditionPtr;
  }
}

ostream& SearchCondition::put(ostream& os) const
{
  if (0 != fPredicatePtr)
  {
    fPredicatePtr->put(os);
  }

  if (0 != fLHSearchConditionPtr)
  {
    fLHSearchConditionPtr->put(os);
  }

  if (0 != fRHSearchConditionPtr)
  {
    os << fOperator << endl;
    fRHSearchConditionPtr->put(os);
  }

  return os;
}

string SearchCondition::getSearchConditionString() const
{
  std::string search_condition;

  if (0 != fPredicatePtr)
  {
    search_condition += fPredicatePtr->getPredicateString();
  }

  if (0 != fLHSearchConditionPtr)
  {
    search_condition += fLHSearchConditionPtr->getSearchConditionString();
    search_condition += " ";
  }

  if (0 != fRHSearchConditionPtr)
  {
    search_condition += fOperator;
    search_condition += " ";
    search_condition += fRHSearchConditionPtr->getSearchConditionString();
  }

  return search_condition;
}

/** ExistanceTestPredicate
 */
ExistanceTestPredicate::ExistanceTestPredicate() : Predicate(EXIST_PREDICATE), fSubQuerySpecPtr(0)
{
}

ExistanceTestPredicate::~ExistanceTestPredicate()
{
  if (0 != fSubQuerySpecPtr)
  {
    delete fSubQuerySpecPtr;
  }
}

ostream& ExistanceTestPredicate::put(ostream& os) const
{
  // cout << "EXISTS" << endl;
  // cout << "("  << endl;
  if (0 != fSubQuerySpecPtr)
  {
    fSubQuerySpecPtr->put(os);
  }

  // cout << ")" << endl;
  return os;
}

string ExistanceTestPredicate::getPredicateString() const
{
  std::string exists_predicate = "EXISTS";
  exists_predicate += "(";

  if (0 != fSubQuerySpecPtr)
  {
    exists_predicate += " ";
    exists_predicate += fSubQuerySpecPtr->getQueryString();
  }

  exists_predicate += ")";
  return exists_predicate;
}

/** AllOrAnyPredicate
 */
AllOrAnyPredicate::AllOrAnyPredicate() : Predicate(ALLORANY_PREDICATE), fSubQuerySpecPtr(0)
{
}

AllOrAnyPredicate::~AllOrAnyPredicate()
{
  if (0 != fSubQuerySpecPtr)
  {
    delete fSubQuerySpecPtr;
  }
}

ostream& AllOrAnyPredicate::put(ostream& os) const
{
  os << fScalarExpression << endl;
  os << fOperator;
  os << fAnyAllSome;

  if (0 != fSubQuerySpecPtr)
  {
    fSubQuerySpecPtr->put(os);
  }

  return os;
}

string AllOrAnyPredicate::getPredicateString() const
{
  std::string all_or_any = fScalarExpression;
  all_or_any += " ";
  all_or_any += fOperator;
  all_or_any += " ";
  all_or_any += fAnyAllSome;

  if (0 != fSubQuerySpecPtr)
  {
    all_or_any += fSubQuerySpecPtr->getQueryString();
  }

  return all_or_any;
}

/** InPredicate
 */
InPredicate::InPredicate() : Predicate(IN_PREDICATE), fSubQuerySpecPtr(0)
{
}

InPredicate::~InPredicate()
{
  if (0 != fSubQuerySpecPtr)
  {
    delete fSubQuerySpecPtr;
  }
}

ostream& InPredicate::put(ostream& os) const
{
  os << fScalarExpression << endl;
  os << fOperator << endl;

  os << "(" << endl;
  AtomList::const_iterator iter = fAtomList.begin();

  while (iter != fAtomList.end())
  {
    os << *iter << endl;
    ++iter;
  }

  if (0 != fSubQuerySpecPtr)
  {
    fSubQuerySpecPtr->put(os);
  }

  os << ")" << endl;

  return os;
}

string InPredicate::getPredicateString() const
{
  std::string in_predicate = fScalarExpression;
  in_predicate += " ";
  in_predicate += fOperator;
  in_predicate += " ";
  in_predicate += "(";

  AtomList::const_iterator iter = fAtomList.begin();

  while (iter != fAtomList.end())
  {
    in_predicate += *iter;
    ++iter;

    if (iter != fAtomList.end())
      in_predicate += ",";
  }

  if (0 != fSubQuerySpecPtr)
  {
    in_predicate += fSubQuerySpecPtr->getQueryString();
  }

  in_predicate += ")";

  return in_predicate;
}

/** NullTestPredicate
 */
NullTestPredicate::NullTestPredicate() : Predicate(NULLTEST_PREDICATE)
{
}

NullTestPredicate::~NullTestPredicate()
{
}

ostream& NullTestPredicate::put(ostream& os) const
{
  os << fColumnRef;
  os << fOperator;

  return os;
}

string NullTestPredicate::getPredicateString() const
{
  std::string null_test_predicate = fColumnRef;
  null_test_predicate += " ";
  null_test_predicate += fOperator;

  return null_test_predicate;
}

/** LikePredicate
 */
LikePredicate::LikePredicate() : Predicate(LIKE_PREDICATE), fOptionalEscapePtr(0)
{
}

LikePredicate::~LikePredicate()
{
  if (0 != fOptionalEscapePtr)
    delete fOptionalEscapePtr;
}

ostream& LikePredicate::put(ostream& os) const
{
  os << fLHScalarExpression << endl;
  os << fAtom << endl;

  if (0 != fOptionalEscapePtr)
    fOptionalEscapePtr->put(os);

  return os;
}

string LikePredicate::getPredicateString() const
{
  std::string like_predicate = fLHScalarExpression;
  like_predicate += " ";
  like_predicate += fAtom;

  if (0 != fOptionalEscapePtr)
  {
    like_predicate += " ";
    like_predicate += fOptionalEscapePtr->fEscapeChar;
  }

  return like_predicate;
}

/** BetweenPredicate
 */
BetweenPredicate::BetweenPredicate() : Predicate(BETWEEN_PREDICATE)
{
}

BetweenPredicate::~BetweenPredicate()
{
}

ostream& BetweenPredicate::put(ostream& os) const
{
  os << fLHScalarExpression << endl;
  os << fOperator1 << endl;
  os << fRH1ScalarExpression << endl;
  os << fOperator2 << endl;
  os << fRH2ScalarExpression << endl;

  return os;
}

string BetweenPredicate::getPredicateString() const
{
  std::string between_predicate = fLHScalarExpression;
  between_predicate += " ";
  between_predicate += fOperator1;
  between_predicate += " ";
  between_predicate += fRH1ScalarExpression;
  between_predicate += " ";
  between_predicate += fOperator2;
  between_predicate += " ";
  between_predicate += fRH2ScalarExpression;

  return between_predicate;
}

/** ComparisonPredicate
 */
ComparisonPredicate::ComparisonPredicate() : Predicate(COMPARE_PREDICATE), fSubQuerySpec(0)
{
}

ComparisonPredicate::~ComparisonPredicate()
{
  if (0 != fSubQuerySpec)
    delete fSubQuerySpec;
}

ostream& ComparisonPredicate::put(ostream& os) const
{
  os << fLHScalarExpression << endl;
  os << fOperator << endl;
  os << fRHScalarExpression << endl;

  if (0 != fSubQuerySpec)
    fSubQuerySpec->put(os);

  return os;
}

string ComparisonPredicate::getPredicateString() const
{
  std::string comparison_predicate = fLHScalarExpression;
  comparison_predicate += " ";
  comparison_predicate += fOperator;
  comparison_predicate += " ";
  comparison_predicate += fRHScalarExpression;

  if (0 != fSubQuerySpec)
  {
    comparison_predicate += " ";
    comparison_predicate += fSubQuerySpec->getQueryString();
  }

  return comparison_predicate;
}

/** Predicate
 */
Predicate::Predicate() : fPredicateType(INVALID_PREDICATE)
{
}

Predicate::Predicate(PREDICATE_TYPE predicateType) : fPredicateType(predicateType)
{
}

Predicate::~Predicate()
{
}

ostream& Predicate::put(ostream& os) const
{
  return os;
}

string Predicate::getPredicateString() const
{
  std::string predicate;

  return predicate;
}

}  // namespace dmlpackage
