-
Notifications
You must be signed in to change notification settings - Fork 0
/
join.cpp
executable file
·130 lines (105 loc) · 3.48 KB
/
join.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "catalog.h"
#include "query.h"
#include "sort.h"
#include "index.h"
#include <cmath>
#include <cstring>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define DOUBLEERROR 1e-07
/*
* Joins two relations
*
* Returns:
* OK on success
* an error code otherwise
*/
Status Operators::Join(const string& result, // Name of the output relation
const int projCnt, // Number of attributes in the projection
const attrInfo projNames[], // List of projection attributes
const attrInfo* attr1, // Left attr in the join predicate
const Operator op, // Predicate operator
const attrInfo* attr2) // Right attr in the join predicate
{
/* Your solution goes here */
Status temp;
AttrDesc Rattr;
AttrDesc Rattr1;
AttrDesc Rattr2;
int tempLength=0;
AttrDesc TempProjNames[projCnt];
// get the length
for (int i = 0; i < projCnt; i++)
{
temp=attrCat->getInfo(projNames[i].relName, projNames[i].attrName, Rattr);
if (temp != OK)
{
return temp;
}
TempProjNames[i]=Rattr;
tempLength+=Rattr.attrLen;
}
temp=attrCat->getInfo(attr1->relName, attr1->attrName, Rattr1);
if (temp != OK)
{
return temp;
}
temp=attrCat->getInfo(attr2->relName, attr2->attrName, Rattr2);
if (temp != OK)
{
return temp;
}
// check self join
if (strcmp(Rattr1.relName, Rattr2.relName) == 0)
{
return NOTUSED1;
}
if(op == EQ)
{
// op=EQ, and index exist in at least one predicate attribute
if (Rattr1.indexed||Rattr2.indexed)
{
return INL(result, projCnt, TempProjNames, Rattr1, op, Rattr2, tempLength);
}
// op=EQ, but there is no index on either predicate attribute
else
{
return SMJ(result, projCnt, TempProjNames, Rattr1, op, Rattr2, tempLength);
}
}
else
{
// op!=EQ
return SNL(result, projCnt, TempProjNames, Rattr1, op, Rattr2, tempLength);
}
return OK;
}
// Function to compare two record based on the predicate. Returns 0 if the two attributes
// are equal, a negative number if the left (attrDesc1) attribute is less that the right
// attribute, otherwise this function returns a positive number.
double Operators::matchRec(const Record& outerRec, // Left record
const Record& innerRec, // Right record
const AttrDesc& attrDesc1, // Left attribute in the predicate
const AttrDesc& attrDesc2) // Right attribute in the predicate
{
int tmpInt1, tmpInt2;
double tmpFloat1, tmpFloat2, floatDiff;
// Compare the attribute values using memcpy to avoid byte alignment issues
switch(attrDesc1.attrType)
{
case INTEGER:
memcpy(&tmpInt1, (char *) outerRec.data + attrDesc1.attrOffset, sizeof(int));
memcpy(&tmpInt2, (char *) innerRec.data + attrDesc2.attrOffset, sizeof(int));
return tmpInt1 - tmpInt2;
case DOUBLE:
memcpy(&tmpFloat1, (char *) outerRec.data + attrDesc1.attrOffset, sizeof(double));
memcpy(&tmpFloat2, (char *) innerRec.data + attrDesc2.attrOffset, sizeof(double));
floatDiff = tmpFloat1 - tmpFloat2;
return (fabs(floatDiff) < DOUBLEERROR) ? 0 : floatDiff;
case STRING:
return strncmp(
(char *) outerRec.data + attrDesc1.attrOffset,
(char *) innerRec.data + attrDesc2.attrOffset,
MAX(attrDesc1.attrLen, attrDesc2.attrLen));
}
return 0;
}