BadgerDB
Static Public Member Functions
PxxInterp Class Reference

#include <SqlInterp.h>

List of all members.

Static Public Member Functions

static void eval (PxxPnode *ptree)
static void quit (void)
static void createTable (PxxPnode *ptree)
static void deleteTable (PxxDrop *ptree)
static void insertIntoTable (PxxPnode *ptree)
static void processQuery (PxxPnode *ptree)
static void createIndex (PxxCreateIndex *pIdxCreate)
static void deleteIndex (PxxDropIndex *pIdxCreate)

Detailed Description

Class for Interpreting SQL Parse Tree.

Id:
SqlInterp.h,v 1.2 2001/10/15 21:50:12 jignesh Exp

Definition at line 29 of file SqlInterp.h.


Member Function Documentation

void PxxInterp::createIndex ( PxxCreateIndex ptree) [static]

createIndex: create an index

Definition at line 176 of file SqlInterp.cpp.

{
   // Call the catalog create index
   relCat->addIndex(ptree->RelName(), ptree->AttrName());
}
void PxxInterp::createTable ( PxxPnode ptree) [static]

createTable() - query tree creates the data - inserts the data into the catalogs

Definition at line 140 of file SqlInterp.cpp.

{   
   // make a list of ATTR_DESCRS suitable for sending to Create
   nattrs = mk_attr_descrs(((PxxCreate*)ptree)->AttrList(), attr_descrs);
   if (nattrs < 0) 
   {
      print_error("Corrupt attribute list", E_CORRUPTSQL);
      return;
   }
   
   for(int acnt = 0; acnt < nattrs; acnt++) {
      strcpy(attrList[acnt].relName, ((PxxCreate*)ptree) -> RelName());
      strcpy(attrList[acnt].attrName, attr_descrs[acnt].attrName);
      attrList[acnt].attrType = attr_descrs[acnt].attrType;
      attrList[acnt].attrLen = attr_descrs[acnt].attrLen;
      attrList[acnt].attrValue = NULL;
   }
   
   // make the call to Create
   relCat->createRel(((PxxCreate*)ptree)->RelName(), nattrs, attrList);
   
   return;
}
void PxxInterp::deleteIndex ( PxxDropIndex ptree) [static]

deleteIndex: delete an index

Definition at line 185 of file SqlInterp.cpp.

{
   relCat->dropIndex(ptree->RelName(), ptree->AttrName());
}
void PxxInterp::deleteTable ( PxxDrop ptree) [static]

deleteTable: delete a table

Definition at line 167 of file SqlInterp.cpp.

{
   // Make a call to Drop.
   relCat->destroyRel(ptree->RelName());
}
void PxxInterp::insertIntoTable ( PxxPnode ptree) [static]

insertIntoTable() - query tree inserts the data into the table already created

Definition at line 194 of file SqlInterp.cpp.

{
   if(((PxxInsert*)ptree)->ValList() != NULL)
   { 
      // make attribute and value list to be passed to Updates::Insert
      nattrs = mk_ins_attrs(ptree, ins_attrs);
      if (nattrs < 0) 
      {
         print_error("Invalid attribute list", E_CORRUPTSQL);
         return;
      }
      
      PxxInsert* pinsert = (PxxInsert*)ptree;
      
      // make the call to Updates::Insert
      int acnt;
      for(acnt = 0; acnt < nattrs; acnt++) 
      {
         strcpy(attrList[acnt].relName, pinsert->RelName());
         
         strcpy(attrList[acnt].attrName, ins_attrs[acnt].attrName);
         attrList[acnt].attrType = (Datatype)ins_attrs[acnt].valType;
         attrList[acnt].attrLen = -1;
         attrList[acnt].attrValue = ins_attrs[acnt].value;
      }
      
      Updates::Insert(pinsert->RelName(),nattrs,attrList);
      
      // for (acnt = 0; acnt < nattrs; acnt++)
      //  delete [] (char*)attrList[acnt].attrValue; // Winter 00
      
      return;
   }   
   else
   {
      /* Doing a load from a file */
      Utilities::Load(((PxxInsert*)ptree)->RelName(), ((PxxInsert*)ptree)->FileName());
   }
}
void PxxInterp::processQuery ( PxxPnode ptree) [static]

processQuery() - query tree processes the query tree

Definition at line 239 of file SqlInterp.cpp.

{
   PxxQuery* pquery = (PxxQuery*)ptree;
   PxxList* projnames = pquery->Projs();
   PxxList  starList; 
   PxxList* fromnames = pquery->Froms();
   // PxxList* fromlist = fromnames; 
   PxxPredTree* predicates = pquery->Preds();
   PxxPredicate* singlepred = 0;
   PxxLiteral* literal = 0; 
   //unsigned int usingtemp = 0; //This is a flag to let us know when we are reading into a temp
   int numberoftables;  
   int attrCnt;
   
   // First, check to see how many tables we are reading from.
   // If it is more than one, then the query is a join query
   // Check if the table definition exists in the catalog. 
   ListNode* table = fromnames->Init();  
   for(numberoftables = 0; table != NULL; table = table->Next())
   {
      PxxRelName* relname = (PxxRelName*)(table->Data()); 
      RelDesc relDesc;

      relCat->getInfo(relname->RelName(), relDesc);

      // Add attrnames to the starlist.
      AttrDesc* attrDescs;
      int numAttrs;

      attrCat->getRelInfo(relname->RelName(), numAttrs, attrDescs);

      // Add all the attributes of this relations to the starList. 
      for (int j=0; j<numAttrs; j++)
      {
         PxxAttrName *aname = new PxxAttrName(attrDescs[j].attrName, 
                                              attrDescs[j].relName,
                                              true);
         starList.Add(aname);
      }

      delete [] attrDescs;

      numberoftables++;
   } 
   
   // process * ops in the projection list
   if (projnames->Cardinality() == 1 &&  
       ((PxxAttrName*)(projnames->First()->Data()))->Star())
   {
      projnames = &starList; 
   }

   // Check to see if an "INTO" was specified, else just write into a default
   PxxRelName insert_relname = pquery->RelName();
   
   RelDesc relDesc;
   if(insert_relname.RelName() == NULL)
   {
      // If we are using a temp relation then the number of 
      // attributes will just be the number of projected ones 
      //usingtemp = 1;
      resultName = "TMP_BDB";
      unsigned i;
      attrCnt = projnames->Cardinality();
      
      try
      {
        relCat->getInfo(resultName, relDesc);
        std::cerr << "TMP_RES_EXISTS : Database corrupted!" << std::endl;
        return;
      }
      catch(RelationNotFoundException &e)
      {
      }

      // Create the temp result relation
      attrInfo *createAttrInfo = new attrInfo[attrCnt];
           
      ListNode *projdata = projnames->Init();
      PxxAttrName* projattr;
      
      // for each element of the list...
      for(i = 0; projdata != NULL && i < MAXATTRS; ++i, projdata = projdata->Next()) 
      {     
         projattr = (PxxAttrName*)(projdata->Data());
         
         // Step through each projection attribute.
         AttrDesc attrDesc;
         attrCat->getInfo(projattr->RelName(), projattr->AttrName(), attrDesc); 
         
         strcpy(createAttrInfo[i].relName, resultName.c_str());
         
         // Create a unique attribute name
         ostringstream newAttrName;
         newAttrName << projattr->AttrName() << '.' << i << endl;
         strcpy(createAttrInfo[i].attrName, newAttrName.str().c_str());
 
         createAttrInfo[i].attrType = attrDesc.attrType;
         createAttrInfo[i].attrLen = attrDesc.attrLen;
      }
      
      if (i != projnames->Cardinality())
      {
         print_error("Corrupt SELECT clause", E_CORRUPTSQL);
         return;
      }

      // Create the temp relation. 
      relCat->createRel(resultName, attrCnt, createAttrInfo);
      delete [] createAttrInfo;
   } 
   else
   { 
      resultName = insert_relname.RelName();
      relCat->getInfo(resultName, relDesc);
      // if (status != OK && status != RELNOTFOUND)

      AttrDesc* resAttrDesc;
      attrCat->getRelInfo(resultName, attrCnt, resAttrDesc); 

      if (attrCnt != relDesc.attrCnt)
      {
         print_error("Incompatible projection list", E_CORRUPTSQL);
         return; 
      }

      // Type check the projection list and the target relation schema
      ListNode *temp = projnames->Init();
      PxxAttrName *attr;

      int iter;
      AttrDesc attrDesc;
      // for each qualified attribute in the list...
      for(iter = 0; temp != NULL; iter++, temp = temp->Next()) 
      {
         attr = (PxxAttrName*)(temp->Data());
         char* aName = attr->AttrName();
         char* rName = attr->RelName();

         attrCat->getInfo(rName, aName, attrDesc);

         if (resAttrDesc[iter].attrType != attrDesc.attrType || resAttrDesc[iter].attrLen  != attrDesc.attrLen)
         {
             print_error("Corrupt projection list", E_CORRUPTSQL);
             delete [] resAttrDesc;
             return; 
         }
      }

      if (iter != relDesc.attrCnt)
      {
         print_error("Incompatible projection list", E_CORRUPTSQL);
         delete [] resAttrDesc;
         return; 
      }

      delete [] resAttrDesc;
   }
   
   // See if we are doing a join or calling select
   if(numberoftables == 1)
   {
      // Now take care of the projected names and
      // make a list of attribute names suitable for passing to select
      char *rName = 0;
      nattrs = mk_attrnames(projnames, names, rName);
      if (nattrs < 0) 
      {
         print_error("Select Clause", E_CORRUPTSQL);
         return; 
      }
      
      for(int acnt = 0; acnt < nattrs; acnt++) 
      {
         strcpy(attrList[acnt].relName, names[nattrs]);
         strcpy(attrList[acnt].attrName, names[acnt]);
         attrList[acnt].attrType = -1;
         attrList[acnt].attrLen = -1;
         attrList[acnt].attrValue = NULL;
      }
      
      if(predicates != NULL)
      {
         // cout << "Predicate Node Type: " << predicates->MyType() << endl;
         if (predicates->MyType() == PxxPnode::Predicate)
         {
            singlepred = (PxxPredicate*) predicates;
            // cout << *singlepred << endl;
            // At this point single pred is the predicate to evaluate. Assume 
            // that a query never has more than one predicate ... 
            
            strcpy(attr1.relName, (*singlepred)[0].AttrName()->RelName());
            strcpy(attr1.attrName, (*singlepred)[0].AttrName()->AttrName());
            attr1.attrLen = -1; 
            literal = ((*singlepred)[1]).Lit(); 
            attr1.attrType = literal->Type();
            switch(attr1.attrType)
            {
            case PxxAttrType::STRING:
               attr1.attrValue = (void*)(literal->Char());
               break; 
            case PxxAttrType::INTEGER:
               attr1.attrValue = (void*)(literal->Int());
               break; 
            case PxxAttrType::DOUBLE: 
               attr1.attrValue = (void*)(literal->Double());
               break;
            }
         } 
         else
         {
            assert (!"multiple predicates not supported");
         }
         
      }
      
      // make different calls to Operators::Select depending upon whether 
      // there is a predicate or not
      if(predicates == NULL)
      {
         Operators::Select(resultName, nattrs, attrList, NULL, NOTSET, NULL);
      }
      else
      {
         void* filter = 0;
         switch(attr1.attrType)
         { 
         case PxxAttrType::STRING:
            filter = literal->Char();
            break; 
         case PxxAttrType::INTEGER:
            filter = literal->Int();
            break; 
         case PxxAttrType::DOUBLE: 
            filter = literal->Double();
            break; 
         }
         // cerr << "Calling select with a predicate" << endl;
         Operator selectop = singlepred->Oper();
         Operators::Select(resultName, nattrs,
            attrList, &attr1,
            selectop,
            filter);
      }
  }
  
  // JOIN Query: If we are joining then don't actually select, just call join
  else 
  {
     PxxPredicate* singlepred = (PxxPredicate*) predicates;
     PxxAttrName* first_attr = (*singlepred)[0].AttrName();
     PxxAttrName* second_attr = (*singlepred)[1].AttrName();   
     
     // make an attribute list suitable for passing to join
     nattrs = mk_qual_attrs(projnames,
                            qual_attrs,
                            first_attr->RelName(),
                            second_attr->RelName());
     if (nattrs < 0) 
     {
        print_error("Invalid attribute list", E_CORRUPTSQL);
     }
     
     // set up the joined attributes to be passed to Join
     qual_attrs[nattrs].relName = first_attr->RelName();
     qual_attrs[nattrs].attrName = first_attr->AttrName();
     qual_attrs[nattrs + 1].relName = second_attr->RelName(); 
     qual_attrs[nattrs + 1].attrName = second_attr->AttrName();
     
     for(int acnt = 0; acnt < nattrs; acnt++) 
     {
        strcpy(attrList[acnt].relName, qual_attrs[acnt].relName);
        strcpy(attrList[acnt].attrName, qual_attrs[acnt].attrName);
        attrList[acnt].attrType = -1;
        attrList[acnt].attrLen = -1;
        attrList[acnt].attrValue = NULL;
     }
     
     strcpy(attr1.relName, qual_attrs[nattrs].relName);
     strcpy(attr1.attrName, qual_attrs[nattrs].attrName);
     attr1.attrType = -1;
     attr1.attrLen = -1;
     attr1.attrValue = NULL;
     
     strcpy(attr2.relName, qual_attrs[nattrs+1].relName);
     strcpy(attr2.attrName, qual_attrs[nattrs+1].attrName);
     attr2.attrType = -1;
     attr2.attrLen = -1;
     attr2.attrValue = NULL;
          
     // make the call to Operators::Join
     
     Operators::Join(resultName, nattrs, attrList, &attr1, (Operator)(singlepred->Oper()), &attr2);
  }
  
  if (resultName == string( "TMP_BDB"))
  {
     // Print the contents of the result relation and destroy it
     Utilities::Print(resultName);
     
     relCat->destroyRel(resultName);
  }
  
  
  return; 
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends