|
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;
}
1.7.6.1