-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrdb-join.cpp
134 lines (123 loc) · 3.97 KB
/
rdb-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
131
132
133
134
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <tuple>
#include <algorithm>
#include "rdb-basics.cpp"
Relation *naturaljoin(Relation *_R1, Relation *_R2, list<string> joinattr) //
{
Relation *res;
Relation *R1 = new Relation(*_R1);
Relation *R2 = new Relation(*_R2);
// find common attributes and their indices in respective relations
map<string, int> R1_index;
map<string, int> R2_index;
map<string, int> R1_cnt;
map<string, int> R2_cnt;
vector<string> common_attributes;
for(int i = 0; i < R1->natttr; ++i)
{
R1_index[R1->mapped_schema[i]] = i;
R1_cnt[R1->mapped_schema[i]]++;
}
for(int i = 0; i < R2->natttr; ++i)
{
R2_index[R2->mapped_schema[i]] = i;
R2_cnt[R2->mapped_schema[i]]++;
}
for(auto it = R2->attrnames.begin(); it != R2->attrnames.end(); ++it)
{
if(R1_cnt[*it] != 0)
{
common_attributes.push_back(*it);
reverse(it->begin(), it->end());
}
}
// construct DNFformula and filter res accordingly
DNFformula *f = new DNFformula;
res = cartesian_product(R1, R2);
for(auto it1 : R1->recs)
{
for(auto it2 : R2->recs)
{
list<tuple<string, char, Attr *>> temp;
bool x1 = true;
for(auto i : common_attributes)
{
if(*it1->attrptr[R1_index[i]] == *it2->attrptr[R2_index[i]])
{
temp.push_back(make_tuple(i, '=', it1->attrptr[R1_index[i]]));
string s = i;
reverse(s.begin(), s.end());
temp.push_back(make_tuple(s, '=', it1->attrptr[R1_index[i]]));
}
else{
x1 = false;
break;
}
}
if(x1)
{
f->ops.push_back(temp);
}
}
}
res = res->Union(f);
// remove the reversed colomn
list<string> selection;
for(auto it : res->attrnames)
{
bool x = true;
for(auto it2 : common_attributes)
{
string s = it2;
reverse(s.begin(), s.end());
if (it == s)
{
x = false;
break;
}
}
if(x)
{
selection.push_back(it);
}
}
res = res->projection(selection);
return res;
}
using namespace std;
// int main()
// {
// vector<string> _attrnames1 = {"Name", "EmpId", "DeptName"};
// vector<int> _attrinds1 = {1, 2, 3};
// list<Record *> l1;
// vector<Attr *> v1 = {new stringAttribute("Harry"), new integerAttribute(3415), new stringAttribute("Finance")};
// l1.push_back(new Record(v1));
// v1 = {new stringAttribute("Sally"), new integerAttribute(2241), new stringAttribute("Sales")};
// l1.push_back(new Record(v1));
// v1 = {new stringAttribute("George"), new integerAttribute(3401), new stringAttribute("Finance")};
// l1.push_back(new Record(v1));
// v1 = {new stringAttribute("Harriet"), new integerAttribute(2202), new stringAttribute("Sales")};
// l1.push_back(new Record(v1));
// Relation R1(3, 4, _attrnames1, _attrinds1, l1);
// //R1.disp();
// vector<string> _attrnames2 = {"DeptName", "Manager"};
// vector<int> _attrinds2 = {1, 2};
// list<Record *> l2;
// vector<Attr *> v2 = {new stringAttribute("Finance"), new stringAttribute("George")};
// l2.push_back(new Record(v2));
// v2 = {new stringAttribute("Sales"), new stringAttribute("Harriet")};
// l2.push_back(new Record(v2));
// v2 = {new stringAttribute("Productions"), new stringAttribute("Charles")};
// l2.push_back(new Record(v2));
// Relation R2(2, 3, _attrnames2, _attrinds2, l2);
// //R2.disp();
// list<string> joinattr;
// Relation *R3 = naturaljoin(&R1, &R2, joinattr);
// //R3->delete_copies();
// R3->disp();
// return 0;
// }