Catalog Header File
#define RELCATNAME "relcat" // name of relation catalog
#define ATTRCATNAME "attrcat" // name of attribute catalog
#define INDEXCATNAME "indcat"
#define RELNAME "relname" // name of indexed field in rel/attrcat
#define MAXNAME 32 // length of relName, attrName
#define MAXSTRINGLEN 255 // max. length of string attribute
#define NUMTUPLESFILE 2000 // default statistic = no recs in file
#define NUMPAGESFILE 50 // default statistic = no pages in file
#define DISTINCTKEYS 2000 // default statistic: no of distinct keys
#define INDEXPAGES 10 // default statisitc no of index pages
#define MINSTRINGVAL "A" // default statisitic
#define MAXSTRINGVAL "Z" // default statisitic
#define MINNUMVAL 0 // default statistic
#define MAXNUMVAL 999999999 // default statisitic
// attrData struct for minimum and maximum attribute values
typedef struct {
char strVal[10];
int intVal;
float floatVal ;
} attrData;
// RelDesc struct: schema of relation catalog:
typedef struct {
char relName[MAXNAME]; // relation name
int attrCnt; // number of attributes
int indexCnt; // number of indexed attrs
int numTuples; // number of tuples in the relation
int numPages; // number of pages in the file
} RelDesc;
// attrInfo struct used for creating relations
typedef struct {
char attrName[MAXNAME]; // attribute name
AttrType attrType; // INTEGER, FLOAT, or STRING
int attrLen; // length
} attrInfo;
// AttrDesc struct : schema of attribute catalog:
typedef struct {
char relName[MAXNAME]; // relation name
char attrName[MAXNAME]; // attribute name
int attrOffset; // attribute offset
int attrPos; // attribute position
AttrType attrType; // attribute type
int attrLen; // attribute length
int indexCnt; // number of indexes
attrData minVal; // min max key values
attrData maxVal;
} AttrDesc;
// IndexDesc Struct : schema for index catalog
typedef struct {
char relName[MAXNAME]; // relation name
char attrName[MAXNAME]; // attribute name
IndexType accessType; // access method
TupleOrder order; // order of keys
int clustered; //
int distinctKeys; // no of distinct key values
int indexPages; // no of index pages
} IndexDesc;
class RelCatalog : public HeapFile {
friend Catalog;
friend AttrCatalog;
friend IndexCatalog;
public:
// CONSTRUCTOR
RelCatalog(Status &status);
// GET RELATION DESCRIPTION FOR A RELATION
Status getInfo(char* relation, RelDesc& record);
// DESTRUCTOR
~RelCatalog();
private:
// CREATE A NEW RELATION
Status createRel(char* relation, int attrCnt, attrInfo attrList[]);
// DESTROY A RELATION
Status destroyRel(char* relation);
// ADD AN INDEX TO A RELATION
Status addIndex(char* relation, char* attrname, IndexType accessType, int buckets = 1);
// DROP AN INDEX FROM A RELATION
Status dropIndex(char* relation, char* attrname, IndexType accessType);
// DUMPS A CATALOG TO A DISK FILE (FOR OPTIMIZER)
Status dumpCatalog();
// OUTPUTS A RELATION TO DISK FOR OPTIMIZER
Status dumpRelation(fstream &outFile, RelDesc &relRec, int tupleSize);
// OUTPUTS ATTRIBUTES TO DISK FOR OPTIMIZER
Status dumpRelAttributes (fstream &outFile,AttrDesc *&attrRecs, int attrCnt);
// OUTPUTS ACCESS METHODS TO DISK FOR OPTIMIZER
Status dumpRelIndex(fstream &outFile,IndexDesc *&indexRecs, int indexCnt);
// ADD INFORMATION ON A RELATION TO CATALOG
Status addInfo(RelDesc record);
// REMOVE INFORMATION ON A RELATION FROM CATALOG
Status removeInfo(char *relation);
// Converts RelDesc to tuple.
Status make_tuple(Tuple *tuple, RelDesc record);
Status read_tuple(Tuple *tuple, RelDesc& record);
};
class AttrCatalog : public HeapFile {
friend Catalog;
friend RelCatalog;
friend IndexCatalog;
public:
// OPEN ATTRIBUTE CATALOG
AttrCatalog(Status &status);
// GET ATTRIBUTE DESCRIPTION
Status getInfo(char *relation, char *attrName, AttrDesc &record);
// GET ALL ATTRIBUTES OF A RELATION
Status getRelInfo(char *relation, int &attrCnt, AttrDesc *&attrs);
// RETURNS ATTRTYPE AND STRINGSIZE ARRAYS FOR CONSTRUCTING TUPLES
Status getTupleStructure(char * relation, int &attrCnt, AttrType *&typeArray, short *&sizeArray);
// CLOSE ATTRIBUTE CATALOG
~AttrCatalog();
private:
// ADD ATTRIBUTE ENTRY TO CATALOG
Status addInfo(AttrDesc record);
// REMOVE AN ATTRIBUTE ENTRY FROM CATALOG
Status removeInfo(char *relation, char *attrName);
// REMOVE ALL ATTRIBUTE ENTRIES FOR A RELATION
Status dropRelation(char* relation);
// ADD AN INDEX TO A RELATION
Status addIndex(char* relation, char* attrname, IndexType accessType);
// Converts AttrDesc to tuple.
Status make_tuple(Tuple *tuple, AttrDesc record);
Status read_tuple(Tuple *tuple, AttrDesc& record);
};
class IndexCatalog : public HeapFile {
friend Catalog;
friend RelCatalog;
friend AttrCatalog;
public:
// OPEN INDEX CATALOG
IndexCatalog(Status &status);
// GET ALL INDEXES FOR A RELATION
Status getRelInfo(char* relation, int &indexCnt, IndexDesc *&indexes);
// RETURN INFO ON AN INDEX
Status getInfo(char* relation, char* attrName, IndexType accessType, IndexDesc &record);
// GET ALL INDEXES INLUDING A SPECIFIED ATTRIBUTE
Status IndexCatalog::getAttrIndexes(char* relation, char *attrName, int &indexCnt, IndexDesc *&indexes);
// CREATES A FILE NAME FOR AN INDEX
Status buildIndexName(char* relation, char* attrName, IndexType accessType, char *&indexName);
// DESTRUCTOR
~IndexCatalog();
private:
// ADD INDEX ENTRY TO CATALOG
Status addInfo(IndexDesc record);
// REMOVE INDEX ENTRY FROM CATALOG
Status removeInfo(char* relation, char* attrName, IndexType accessType);
// ADD INDEX TO A RELATION
Status addIndex(char* relation, char* attrName, IndexType accessType, int buckets = 1);
// DROP INDEX FROM A RELATION
Status dropIndex(char* relation, char* attrName, IndexType accessType);
// DROP ALL INDEXES FOR A RELATION
Status IndexCatalog::dropRelation(char *relation);
// Converts IndexDesc to tuple.
Status make_tuple(Tuple *tuple, IndexDesc record);
Status read_tuple(Tuple *tuple, IndexDesc& record);
};
ACCOMPLISHMENTS
The project involved a substantial rewrite of the old minirel catalogs. The changes
involved three factors: changes in the catalog structure to add an index
catalog; changes in heapfile and scans; and changes to accomodate the tuple
class. Additional code was also required to support transaction logic and
the new error protocol.
In retrospect, the decision to alter the structure of the catalogs late in
the project proved to be a larger problem than was anticipated.
The project also involved the creation of utilities to insert records, delete
records, and to load a relation. Each of these utilities is completely new.
An interface to the optimizer, that dumps catalog information to a disk file, was also provided.
TESTING
We wrote a driver named main.C which tested each of the functions
provided in both the catalog classes and the utilities. The program
performed the following functions:
- creating a relation
- creating an index
- loading a relation
- adding a second index
- inserting a record
- deleting a record
- dumping a catalog to disk
- dropping a relation
- destroying a relation
In addition, each of the functions which return information was tested.
RETROSPECTIVE
Originally, modification of the catalogs involved changing the way
in which catalog records were stored and located due to the new
heapfile class. The original structure of the catalogs was retained.
Two things occured later in the project that affected this structure.
First, an index catalog was added in order to eventually support
indexes on multiple attributes. Second, a new Catalog class was
added to in order to provide an external interface to the catalogs
and to wrap catalog services in an atomic transaction.
In the original minirel catalog, operations which affected both the
relation and attribute catalogs (ie add an index) were invoked by
a call to a relation catalog method. This function would in turn
call the necessary attribute catalog functions. This structure was
retained with the introduction of the index catalog.
The Catalog class was introduced later, and now provides the external
interface to catalog services. When multiple catalogs are involved in an
operation (add an index), the Catalog class simply wraps a call to
the original relation catalog method in a transaction. Thus the
relation catalog functions for adding indexes, dropping indexes and
destroying relations invoke the necessary functions of the other catalogs.
A cleaner implementation would be to have the Catalog class invoke
the attribute and index catalog calls for these operations.
This is a relatively minor change, but one we did not have time to make.
APPENDIX
- main.C - test driver
- maincatalog.h
- catalog.h
- utility.h
- maincatalog.C
- catalog.C
- create.C
- build.C
- drop.C
- destroy.C
- utility.C
- load.C
- dump.C