BadgerDB
|
#include <SqlInterp.h>
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) |
Class for Interpreting SQL Parse Tree.
Definition at line 29 of file SqlInterp.h.
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; }