Commit 580e0055 authored by Abuhujair Javed's avatar Abuhujair Javed

Final Commit for to implement Functional Dependency in PostgreSQL

parent cd0de49f
......@@ -25,3 +25,14 @@ instructions.
The latest version of this software may be obtained at
https://www.postgresql.org/download/. For more information look at our
web site located at https://www.postgresql.org/.
Following Files have been ammended to include functional dependency in PostgreSQL.
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtsearch.c
src/backend/access/nbtree/nbtutils.c
src/backend/catalog/index.c
src/backend/tcop/postgres.c
src/include/access/nbtree.h
install/data/gdata.h
/* CS631 Start */
/*
* gdata.h
*
* Created on: 28-Nov-2022
* Author: abuhujair
*/
extern int fd_flag;
int check_fd(int id_num);
#ifndef INSTALL_DATA_GDATA_H_
#define INSTALL_DATA_GDATA_H_
#endif /* INSTALL_DATA_GDATA_H_ */
/* CS631 End */
32789
40981
40982
40986
40987
40991
49176
49183
49184
......@@ -26,6 +26,8 @@
#include "storage/smgr.h"
/* CS631 Start */
/* The file at /install/data/gdata.h/
* */
#include "/home/abuhujair/git/postgresql/install/data/gdata.h"
/* CS631 End */
......@@ -111,9 +113,10 @@ _bt_doinsert(Relation rel, IndexTuple itup,
bool checkingunique = (checkUnique != UNIQUE_CHECK_NO);
/* CS631 Start */
// Oid special = 32788;
/* We are creating a flag to implement FD functionality.
* FD implementation is being done in line with what postgres implements to do uniqueness check.
* */
bool checkingfd = false;
// if ( rel->rd_index->indexrelid == special )
if ( check_fd( (int)rel->rd_index->indexrelid ) )
checkingfd = true;
/* CS631 End */
......@@ -212,6 +215,9 @@ search:
*/
/* CS631 Start */
/* We will enter the _bt_check_unique function in case
* while checking for FD as well as to check uniqueness.
* */
if (checkingunique || checkingfd)
/* CS631 End */
{
......@@ -436,9 +442,10 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
int curposti = 0;
/* CS631 Start */
// Oid special = 32788;
/* We are again checking if the given index defines any FD constraints.
* and raising the flag.
* */
bool checkfd = false;
//if ( rel->rd_index->indexrelid == special )
if ( check_fd((int)rel->rd_index->indexrelid) )
checkfd = true;
/* CS631 End */
......@@ -679,6 +686,8 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
insertstate->bounds_valid = false;
/* CS631 Start */
/* depending on whether the checkUnique flag was turned on,
* or checkfd we will decide which error message to be displayed */
if ( checkUnique )
{
Datum values[INDEX_MAX_KEYS];
......
......@@ -756,7 +756,14 @@ _bt_compare(Relation rel,
}
/* CS631 Start */
// if (rel->rd_index->indexrelid == special)
/* The _bt_compare function implements tiebreaker in case of primary/unique key
* as non-pivot search, which imply it will return the offset the first index tuple
* it matches with, while for non-primary key it returns the offset of one more
* than last tuple which is equal to key.
* For checking FD constraint, we need to verify with first element in the tree.
* So instead of breaking tie using some other factor in case of FD index,
* we return 0, indicating we found a match.
* */
if ( check_fd((int)rel->rd_index->indexrelid) )
return 0;
/* CS631 End */
......@@ -2514,14 +2521,19 @@ _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir)
/* CS631 Start */
/*----------
* _bt_compare_fd() -- Compare insertion-type scankey to tuple on a page.
* _bt_compare_fd() -- Compare the inserting tuple with that of tuple in the tree.
*
* page/offnum: location of btree item to be compared to.
*
* This routine returns:
* <0 if scankey < tuple at offnum;
* 0 if scankey == tuple at offnum;
* >0 if scankey > tuple at offnum.
*
* For A->B FD constraints this routine returns:
* A B Return Value
* Equal Equal 1
* Unequal Equal 1
* Equal Unequal 0
* Unequal Unequal 1
*
* Here A is represented by key of the index, and B is the Covering attribute of the index.
*
* NULLs in the keys are treated as sortable values. Therefore
* "equality" does not necessarily mean that the item should be returned
......@@ -2550,13 +2562,10 @@ _bt_compare_fd(Relation rel,
TupleDesc itupdesc = RelationGetDescr(rel);
BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
IndexTuple itup;
// ItemPointer heapTid;
ScanKey scankey;
int ncmpkey;
int ntupatts;
int32 result;
// BTScanInsert nonkey;
// ScanKey scannonkey;
Assert(_bt_check_natts(rel, key->heapkeyspace, page, offnum));
Assert(key->keysz <= IndexRelationGetNumberOfKeyAttributes(rel));
......@@ -2584,6 +2593,10 @@ _bt_compare_fd(Relation rel,
* _bt_first).
*/
/* Here we are only checking the key attributes of the index,
* which is similar to the one in _bt_compare. Here we have ommitted, tie breakers
* we are just checking for equality.
* */
ncmpkey = Min(ntupatts, key->keysz);
Assert(key->heapkeyspace || ncmpkey == key->keysz);
Assert(!BTreeTupleIsPosting(itup) || key->allequalimage);
......@@ -2615,8 +2628,12 @@ _bt_compare_fd(Relation rel,
scankey++;
}
// nonkey = _bt_mkscankey_nonkey(rel, itup_);
// scannonkey = nonkey->scankeys;
/* This part check for inequality in B and is checked only if A is unequal.
* We are essentially comparing all the attributes of covering index
* using the sk_func of the first attribute of A. Hence, this became our
* constraints while implementing FD. All the attributes of B, need to be of same
* datatype as first attribute of A.
* */
scankey = key->scankeys;
for (int i = ncmpkey+1; i <= ntupatts; i++)
{
......@@ -2637,7 +2654,6 @@ _bt_compare_fd(Relation rel,
result = 0;
return result;
}
scankey++;
}
if (result == 0){
......@@ -2647,4 +2663,3 @@ _bt_compare_fd(Relation rel,
}
/* CS631 End */
......@@ -2752,33 +2752,14 @@ _bt_allequalimage(Relation rel, bool debugmessage)
/* CS631 Start */
/*
* _bt_mkscankey
* Build an insertion scan key that contains comparison data from itup
* as well as comparator routines appropriate to the key datatypes.
*
* When itup is a non-pivot tuple, the returned insertion scan key is
* suitable for finding a place for it to go on the leaf level. Pivot
* tuples can be used to re-find leaf page with matching high key, but
* then caller needs to set scan key's pivotsearch field to true. This
* allows caller to search for a leaf page with a matching high key,
* which is usually to the left of the first leaf page a non-pivot match
* might appear on.
*
* The result is intended for use with _bt_compare() and _bt_truncate().
* Callers that don't need to fill out the insertion scankey arguments
* (e.g. they use an ad-hoc comparison routine, or only need a scankey
* for _bt_truncate()) can pass a NULL index tuple. The scankey will
* be initialized as if an "all truncated" pivot tuple was passed
* instead.
*
* Note that we may occasionally have to share lock the metapage to
* determine whether or not the keys in the index are expected to be
* unique (i.e. if this is a "heapkeyspace" index). We assume a
* heapkeyspace index when caller passes a NULL tuple, allowing index
* build callers to avoid accessing the non-existent metapage. We
* also assume that the index is _not_ allequalimage when a NULL tuple
* is passed; CREATE INDEX callers call _bt_allequalimage() to set the
* field themselves.
* _bt_mkscankey_nonkey
* Build a scan key that contains comparison data from itup
* as well as comparator routines appropriate to the datatypes.
*
* The result is intended for use with _bt_compare_fd(). But did, not workout,
* as index relation data does not store information about comparator routines
* for nonkey attributes. Hence the function is not being used. Other functionality
* of the function is similar to the _bt_mkscankey.
*/
BTScanInsert
_bt_mkscankey_nonkey(Relation rel, IndexTuple itup)
......@@ -2822,7 +2803,6 @@ _bt_mkscankey_nonkey(Relation rel, IndexTuple itup)
skey = key->scankeys;
for (i = indnkeyatts; i < tupnatts; i++)
{
// FmgrInfo *procinfo;
RegProcedure procedure;
Datum arg;
bool null;
......@@ -2832,7 +2812,6 @@ _bt_mkscankey_nonkey(Relation rel, IndexTuple itup)
* We can use the cached (default) support procs since no cross-type
* comparison can be needed.
*/
// procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
procedure = index_getprocid(rel, i + 1, BTORDER_PROC);
......
......@@ -86,13 +86,11 @@
#include "utils/tuplesort.h"
/* CS631 Start */
# include <string.h>
# include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
// #include "../../../install/data/gdata.h"
#include "/home/abuhujair/git/postgresql/install/data/gdata.h"
/* CS631 End */
......@@ -537,6 +535,9 @@ AppendAttributeTuples(Relation indexRelation, Datum *attopts)
}
/* CS631 Start */
/* This function adds an entry of relation id of the index to the file inx_inf.txt if
* user wants to implements index as an FD
* */
int add_entry(char *idxid)
{
......@@ -682,6 +683,8 @@ UpdateIndexRelation(Oid indexoid,
heap_freetuple(tuple);
/* CS631 Start */
/* If the given index is created successfully, and if the index is created
* to implement FD constraints we will add it.*/
if(fd_flag)
{
char idxid[20];
......
......@@ -946,6 +946,9 @@ pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions,
}
/* CS631 Start */
/* We have not ammended the parser to parse the SQL query to create FD, instead
* just changing the "FD" to "INDEX" and "determines" to "include" we are creating FD.
* */
char* replaceWord(const char* s, const char* oldW,
const char* newW)
{
......@@ -974,8 +977,14 @@ char* replaceWord(const char* s, const char* oldW,
}
#include "../../../install/data/gdata.h"
/* This flag is being used to indicate whether the query is create FD.*/
int fd_flag=0;
/* This function is being called whenver we want to check if the given index relation
* ID is an FD.
* Since we have saved the index which implements the FD constraints in file, this just
* searches the index in the file.
* */
int check_fd(int id_num)
{
FILE * fp;
......@@ -1014,6 +1023,8 @@ exec_simple_query(const char *query_string)
char msec_str[32];
/* CS631 Start */
/* If the given SQL query is to create FD, this will create and equivalent query to create the index
* and raise the fd_flag*/
fd_flag=0;
if (strstr(query_string, "FD") && strstr(query_string, "determines")) {
const char old[]="FD";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment