<commit_before>/*-------------------------------------------------------------------------
 *
 * dll.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /n-store/src/bridge/ddl.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"
#include "c.h"

#include "bridge/bridge.h"
#include "nodes/parsenodes.h"
#include "parser/parse_utilcmd.h"
#include "parser/parse_type.h"
#include "access/htup_details.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
#include "catalog/pg_type.h"

#include "backend/bridge/ddl.h"
#include "backend/catalog/catalog.h"
#include "backend/catalog/schema.h"
#include "backend/common/logger.h"
#include "backend/common/types.h"
#include "backend/index/index.h"
#include "backend/index/index_factory.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/table_factory.h"

#include <cassert>
#include <iostream>

namespace peloton {
namespace bridge {

static std::vector<IndexInfo> index_infos;

/**
 * @brief Process utility statement.
 * @param parsetree Parse tree
 */
void DDL::ProcessUtility(Node *parsetree,
                         const char *queryString){
  assert(parsetree != nullptr);
  assert(queryString != nullptr);

  // Process depending on type of utility statement
  switch (nodeTag(parsetree))
  {
    case T_CreateStmt:
    case T_CreateForeignTableStmt:
    {
      List     *stmts;
      ListCell   *l;

      assert(CurrentResourceOwner != NULL);

      /* Run parse analysis ... */
      stmts = transformCreateStmt((CreateStmt *) parsetree,
                                  queryString);

      /* ... and do it */
      foreach(l, stmts)
      {
        Node     *stmt = (Node *) lfirst(l);
        if (IsA(stmt, CreateStmt))
        {
          CreateStmt* Cstmt = (CreateStmt*)stmt;
          List* schema = (List*)(Cstmt->tableElts);

          char* relation_name = Cstmt->relation->relname;
          std::vector<peloton::catalog::ColumnInfo> column_infos;
          std::vector<std::string> reference_table_names;

          bool status;

          // Construct DDL_ColumnInfo with schema
          if( schema != NULL ){
            column_infos = peloton::bridge::DDL::ConstructColumnInfoByParsingCreateStmt( Cstmt, reference_table_names );
            status = peloton::bridge::DDL::CreateTable( relation_name, column_infos );
          }
          else {
            // Create Table without column info
            status = peloton::bridge::DDL::CreateTable( relation_name, column_infos );
          }

          fprintf(stderr, "DDL_CreateTable(%s) :: %d \n", relation_name, status);

          // TODO :: Change location or 
          // Foreign keys
          for( auto reference_table_name : reference_table_names ){
               oid_t database_oid = GetCurrentDatabaseOid();
               assert( database_oid );
               storage::DataTable* current_table = (storage::DataTable*) catalog::Manager::GetInstance().GetLocation(database_oid, relation_name);
               storage::DataTable* reference_table = (storage::DataTable*) catalog::Manager::GetInstance().GetLocation(database_oid, reference_table_name);

               current_table->AddReferenceTable(reference_table);
          }
           
          { // DEBUGGING CREATE TABLE
            oid_t database_oid = GetCurrentDatabaseOid();
            auto table = peloton::catalog::Manager::GetInstance().GetLocation(database_oid, relation_name);
            peloton::storage::DataTable* data_table = (peloton::storage::DataTable*) table;
            auto tuple_schema = data_table->GetSchema();
            
            std::cout << "Relation Name : " << relation_name << "\n" <<  *tuple_schema << std::endl;

            if( data_table->ishasPrimaryKey()  ){
              printf("print primary key index \n");
              std::cout<< *(data_table->GetPrimaryIndex()) << std::endl;
            }
            if ( data_table->ishasUnique()){
              printf("print unique index \n");
              for( int i =0 ; i<  data_table->GetUniqueIndexCount(); i++){
                std::cout << *(data_table->GetUniqueIndex(i)) << std::endl;
              }
            }
            if ( data_table->GetIndexCount() > 0 ){
              printf("print index \n");
              for( int i =0 ; i<  data_table->GetIndexCount(); i++){
                std::cout << *(data_table->GetIndex(i)) << std::endl;
              }
            }
            if ( data_table->ishasReferenceTable() ){
              printf("print foreign tables \n");
              for( int i =0 ; i<  data_table->GetReferenceTableCount(); i++){
                peloton::storage::DataTable *temp_table = data_table->GetReferenceTable(i);
                const peloton::catalog::Schema* temp_our_schema = temp_table->GetSchema();
                std::cout << "table name : " << temp_table->GetName() << " " << *temp_our_schema << std::endl;
              }
            }
          } // DEBUGGING CREATE TABLE
        }
      }
    }

    
    break;

    case T_IndexStmt:  /* CREATE INDEX */
    {
      bool status;
      IndexStmt  *Istmt = (IndexStmt *) parsetree;

      // Construct IndexInfo 
      IndexInfo* index_info = ConstructIndexInfoByParsingIndexStmt( Istmt );

      // If this index is either unique or primary key, store the index information and skip
      // the rest part since the table has not been created yet.
      if( Istmt->isconstraint ){
         index_infos.push_back(*index_info);
         break;
      }

      status = peloton::bridge::DDL::CreateIndex( index_info->GetIndexName(),
                                                  index_info->GetTableName(),
                                                  index_info->GetMethodType(), 
                                                  index_info->GetType(),
                                                  index_info->IsUnique(),
                                                  index_info->GetKeyColumnNames());

      fprintf(stderr, "DDLCreateIndex %s :: %d \n", index_info->GetIndexName().c_str(), status);

    }
    break;

    case T_DropStmt:
    {
      DropStmt* drop = (DropStmt*) parsetree;
      bool status;

      ListCell  *cell;
      foreach(cell, drop->objects){
        if (drop->removeType == OBJECT_TABLE ){
          List* names = ((List *) lfirst(cell));

          char* table_name = strVal(linitial(names));
          Oid table_oid = GetRelationOid(table_name);

          status = peloton::bridge::DDL::DropTable( table_oid );
          fprintf(stderr, "DDLDropTable :: %d \n", ret);
        }
      }
    }
    break;<commit_msg>Minor fix<commit_after>/*-------------------------------------------------------------------------
 *
 * dll.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /n-store/src/bridge/ddl.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"
#include "c.h"

#include "bridge/bridge.h"
#include "nodes/parsenodes.h"
#include "parser/parse_utilcmd.h"
#include "parser/parse_type.h"
#include "access/htup_details.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
#include "catalog/pg_type.h"

#include "backend/bridge/ddl.h"
#include "backend/catalog/catalog.h"
#include "backend/catalog/schema.h"
#include "backend/common/logger.h"
#include "backend/common/types.h"
#include "backend/index/index.h"
#include "backend/index/index_factory.h"
#include "backend/storage/backend_vm.h"
#include "backend/storage/table_factory.h"

#include <cassert>
#include <iostream>

namespace peloton {
namespace bridge {

static std::vector<IndexInfo> index_infos;

/**
 * @brief Process utility statement.
 * @param parsetree Parse tree
 */
void DDL::ProcessUtility(Node *parsetree,
                         const char *queryString){
  assert(parsetree != nullptr);
  assert(queryString != nullptr);

  // Process depending on type of utility statement
  switch (nodeTag(parsetree))
  {
    case T_CreateStmt:
    case T_CreateForeignTableStmt:
    {
      List     *stmts;
      ListCell   *l;

      assert(CurrentResourceOwner != NULL);

      /* Run parse analysis ... */
      stmts = transformCreateStmt((CreateStmt *) parsetree,
                                  queryString);

      /* ... and do it */
      foreach(l, stmts)
      {
        Node     *stmt = (Node *) lfirst(l);
        if (IsA(stmt, CreateStmt))
        {
          CreateStmt* Cstmt = (CreateStmt*)stmt;
          List* schema = (List*)(Cstmt->tableElts);

          char* relation_name = Cstmt->relation->relname;
          std::vector<peloton::catalog::ColumnInfo> column_infos;
          std::vector<std::string> reference_table_names;

          bool status;

          // Construct DDL_ColumnInfo with schema
          if( schema != NULL ){
            column_infos = peloton::bridge::DDL::ConstructColumnInfoByParsingCreateStmt( Cstmt, reference_table_names );
            status = peloton::bridge::DDL::CreateTable( relation_name, column_infos );
          }
          else {
            // Create Table without column info
            status = peloton::bridge::DDL::CreateTable( relation_name, column_infos );
          }

          fprintf(stderr, "DDL_CreateTable(%s) :: %d \n", relation_name, status);

          // TODO :: Change location or 
          // Foreign keys
          for( auto reference_table_name : reference_table_names ){
               oid_t database_oid = GetCurrentDatabaseOid();
               assert( database_oid );
               storage::DataTable* current_table = (storage::DataTable*) catalog::Manager::GetInstance().GetLocation(database_oid, relation_name);
               storage::DataTable* reference_table = (storage::DataTable*) catalog::Manager::GetInstance().GetLocation(database_oid, reference_table_name);

               current_table->AddReferenceTable(reference_table);
          }
           
          { // DEBUGGING CREATE TABLE
            oid_t database_oid = GetCurrentDatabaseOid();
            auto table = peloton::catalog::Manager::GetInstance().GetLocation(database_oid, relation_name);
            peloton::storage::DataTable* data_table = (peloton::storage::DataTable*) table;
            auto tuple_schema = data_table->GetSchema();
            
            std::cout << "Relation Name : " << relation_name << "\n" <<  *tuple_schema << std::endl;

            if( data_table->ishasPrimaryKey()  ){
              printf("print primary key index \n");
              std::cout<< *(data_table->GetPrimaryIndex()) << std::endl;
            }
            if ( data_table->ishasUnique()){
              printf("print unique index \n");
              for( int i =0 ; i<  data_table->GetUniqueIndexCount(); i++){
                std::cout << *(data_table->GetUniqueIndex(i)) << std::endl;
              }
            }
            if ( data_table->GetIndexCount() > 0 ){
              printf("print index \n");
              for( int i =0 ; i<  data_table->GetIndexCount(); i++){
                std::cout << *(data_table->GetIndex(i)) << std::endl;
              }
            }
            if ( data_table->ishasReferenceTable() ){
              printf("print foreign tables \n");
              for( int i =0 ; i<  data_table->GetReferenceTableCount(); i++){
                peloton::storage::DataTable *temp_table = data_table->GetReferenceTable(i);
                const peloton::catalog::Schema* temp_our_schema = temp_table->GetSchema();
                std::cout << "table name : " << temp_table->GetName() << " " << *temp_our_schema << std::endl;
              }
            }
          } // DEBUGGING CREATE TABLE
        }
      }
    }

    
    break;

    case T_IndexStmt:  /* CREATE INDEX */
    {
      bool status;
      IndexStmt  *Istmt = (IndexStmt *) parsetree;

      // Construct IndexInfo 
      IndexInfo* index_info = ConstructIndexInfoByParsingIndexStmt( Istmt );

      // If this index is either unique or primary key, store the index information and skip
      // the rest part since the table has not been created yet.
      if( Istmt->isconstraint ){
         index_infos.push_back(*index_info);
         break;
      }

      status = peloton::bridge::DDL::CreateIndex( index_info->GetIndexName(),
                                                  index_info->GetTableName(),
                                                  index_info->GetMethodType(), 
                                                  index_info->GetType(),
                                                  index_info->IsUnique(),
                                                  index_info->GetKeyColumnNames());

      fprintf(stderr, "DDLCreateIndex %s :: %d \n", index_info->GetIndexName().c_str(), status);

    }
    break;

    case T_DropStmt:
    {
      DropStmt* drop = (DropStmt*) parsetree;
      bool status;

      ListCell  *cell;
      foreach(cell, drop->objects){
        if (drop->removeType == OBJECT_TABLE ){
          List* names = ((List *) lfirst(cell));

          char* table_name = strVal(linitial(names));
          Oid table_oid = GetRelationOid(table_name);

          status = peloton::bridge::DDL::DropTable( table_oid );
          fprintf(stderr, "DDLDropTable :: %d \n", status);
        }
      }
    }
    break;
{'fraction_non_alphanumeric': 0.14613935969868172, 'fraction_numerical': 0.0012052730696798493, 'mean_word_length': 2.0009041591320074, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2614440', 'n_tokens_mistral': 3689, 'n_tokens_neox': 3645, 'n_words': 754}