souffle  2.0.2-371-g6315b36
interpreter_relation_test.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2019, The Souffle Developers. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file interpreter_relation_test.cpp
12  *
13  * Tests RelInterface
14  *
15  ***********************************************************************/
16 
17 #include "tests/test.h"
18 
20 #include "interpreter/Relation.h"
21 #include "ram/analysis/Index.h"
23 #include "souffle/SymbolTable.h"
24 #include <iosfwd>
25 #include <string>
26 #include <utility>
27 
29 
30 using ::souffle::ram::analysis::MinIndexSelection;
31 
32 TEST(Relation0, Construction) {
33  // create a nullary relation
34  SymbolTable symbolTable;
35  MinIndexSelection order{};
36  order.insertDefaultTotalIndex(0);
37  Relation<0, interpreter::Btree> rel(0, "test", order);
38 
40  // add some values
41  EXPECT_EQ(0, rel.size());
42  rel.insert(tuple);
43  EXPECT_EQ(1, rel.size());
44  rel.insert(tuple);
45  EXPECT_EQ(1, rel.size());
46 }
47 
48 TEST(Relation0, Iteration) {
49  // create a nullary relation
50  SymbolTable symbolTable;
51  MinIndexSelection order{};
52  order.insertDefaultTotalIndex(0);
53  Relation<0, interpreter::Btree> rel(0, "test", order);
54  RelationWrapper* wrapper = &rel;
55 
57 
58  // empty relation
59  EXPECT_EQ(wrapper->begin() == wrapper->end(), true);
60 
61  // add some values
62  rel.insert(tuple);
63 
64  EXPECT_EQ(wrapper->begin() == wrapper->end(), false);
65 }
66 
67 TEST(Relation1, Construction) {
68  // create a single attribute relation
69  SymbolTable symbolTable;
70  MinIndexSelection order{};
71  order.insertDefaultTotalIndex(1);
72  Relation<1, interpreter::Btree> rel(0, "test", order);
73  RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
74 
75  tuple d1(&relInt, {1});
76  // add some values
77  EXPECT_EQ(0, rel.size());
78  relInt.insert(d1);
79  EXPECT_EQ(1, rel.size());
80  relInt.insert(tuple(&relInt, {2}));
81  EXPECT_EQ(2, rel.size());
82  relInt.insert(tuple(&relInt, {3}));
83  EXPECT_EQ(3, rel.size());
84  relInt.insert(tuple(&relInt, {4}));
85  EXPECT_EQ(4, rel.size());
86 }
87 
88 TEST(Basic, Iteration) {
89  // create a relation
90  SymbolTable symbolTable;
91  MinIndexSelection order{};
92  order.insertDefaultTotalIndex(1);
93  Relation<1, interpreter::Btree> rel(0, "test", order);
94  RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
95 
96  // add some values
97  relInt.insert(tuple(&relInt, {1}));
98  relInt.insert(tuple(&relInt, {2}));
99  relInt.insert(tuple(&relInt, {3}));
100  relInt.insert(tuple(&relInt, {4}));
101 
102  // Iterate
103  souffle::Relation::iterator it = relInt.begin();
104  std::size_t count = 0;
105  while (it != relInt.end()) {
106  // Check the 'deref' doesn't crash
107  auto value = (*it)[0];
108  (void)value;
109  ++it;
110  ++count;
111  }
112  EXPECT_EQ(4, count);
113 }
114 
115 TEST(Independence, Iteration) {
116  // create a table
117  SymbolTable symbolTable;
118  MinIndexSelection order{};
119  order.insertDefaultTotalIndex(1);
120  Relation<1, interpreter::Btree> rel(0, "test", order);
121  RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
122 
123  // add a value
124  relInt.insert(tuple(&relInt, {1}));
125 
126  // Test a iterator returns the correct value
127  souffle::Relation::iterator it = relInt.begin();
128  EXPECT_EQ(1, (*it)[0]);
129 
130  // Copy the iterator and modify the copy
131  {
133  EXPECT_EQ(1, (*it2)[0]);
134  ++it2;
135  }
136  EXPECT_EQ(1, (*it)[0]);
137 
138  // Test that a new iterator is also valid
139  souffle::Relation::iterator it3 = relInt.begin();
140  EXPECT_EQ(1, (*it3)[0]);
141 }
142 
143 TEST(IndependentMoving, Iteration) {
144  // create a table
145  SymbolTable symbolTable;
146  MinIndexSelection order{};
147  order.insertDefaultTotalIndex(1);
148  Relation<1, interpreter::Btree> rel(0, "test", order);
149  RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
150 
151  // add a value
152  relInt.insert(tuple(&relInt, {1}));
153 
154  souffle::Relation::iterator it = relInt.begin();
155  EXPECT_EQ(1, (*it)[0]);
156 
157  // Make a new iterator, move it to the first iterator, then let the new iterator go out of scope
158  {
159  souffle::Relation::iterator it2(relInt.begin());
160  EXPECT_EQ(1, (*it2)[0]);
161  it = std::move(it2);
162  }
163  EXPECT_EQ(1, (*it)[0]);
164 }
165 
166 TEST(IndependentCopying, Iteration) {
167  // create a table
168  SymbolTable symbolTable;
169  MinIndexSelection order{};
170  order.insertDefaultTotalIndex(1);
171  Relation<1, interpreter::Btree> rel(0, "test", order);
172  RelInterface relInt(rel, symbolTable, "test", {"i"}, {"i"}, 0);
173 
174  // add a value
175  relInt.insert(tuple(&relInt, {1}));
176 
177  souffle::Relation::iterator it = relInt.begin();
178  EXPECT_EQ(1, (*it)[0]);
179 
180  // Make a new iterator, copy it to the first iterator, then let the new iterator go out of scope
181  {
182  souffle::Relation::iterator it2(relInt.begin());
183  EXPECT_EQ(1, (*it2)[0]);
184  it = it2;
185  }
186  EXPECT_EQ(1, (*it)[0]);
187 }
188 
189 TEST(Reordering, Iteration) {
190  // create a relation, with a non-default ordering.
191  SymbolTable symbolTable;
192 
193  // create an index of order {0, 2, 1}
194  MinIndexSelection order{};
199  order.addSearch(cols);
200  order.solve();
201 
202  Relation<3, interpreter::Btree> rel(0, "test", order);
204  rel.insert(tuple);
205 
206  // Scan should give undecoded tuple.
207  {
208  const auto& t = *(rel.scan().begin());
210  }
211 
212  // For-each should give decoded tuple.
213  {
214  auto t = rel.begin();
215  EXPECT_EQ(0, (*t)[0]);
216  EXPECT_EQ(1, (*t)[1]);
217  EXPECT_EQ(2, (*t)[2]);
218  }
219 
220  RelInterface relInt(rel, symbolTable, "test", {"i", "i", "i"}, {"i", "i", "i"}, 3);
221 
222  // ProgInterface should give decoded tuple.
223  {
224  const auto it = relInt.begin();
225  EXPECT_EQ(0, (*it)[0]);
226  EXPECT_EQ(1, (*it)[1]);
227  EXPECT_EQ(2, (*it)[2]);
228  }
229 }
230 
231 } // namespace souffle::interpreter::test
souffle::ram::analysis::SearchSignature
search signature of a RAM operation; each bit represents an attribute of a relation.
Definition: Index.h:52
souffle::Relation::iterator
Wrapper class for abstract iterator.
Definition: SouffleInterface.h:158
souffle::interpreter::RelationWrapper::end
virtual Iterator end() const =0
Index.h
Relation.h
SymbolTable.h
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: test.h:191
ProgInterface.h
souffle::ram::analysis::AttributeConstraint::None
@ None
souffle::Relation
Object-oriented wrapper class for Souffle's templatized relations.
Definition: SouffleInterface.h:49
souffle::interpreter::test
Definition: interpreter_relation_test.cpp:28
souffle::ram::Relation
An abstract class for performing indexed operations.
Definition: Relation.h:40
souffle::ram::analysis::MinIndexSelection
Definition: Index.h:208
souffle::interpreter::RelationWrapper::begin
virtual Iterator begin() const =0
souffle::SymbolTable
Definition: SymbolTable.h:48
souffle::test::count
int count(const C &c)
Definition: table_test.cpp:40
test.h
souffle::Tuple
std::array< A, N > Tuple
Definition: RamTypes.h:36
souffle::ram::analysis::AttributeConstraint::Equal
@ Equal
souffle::ram::analysis::MinIndexSelection::insertDefaultTotalIndex
void insertDefaultTotalIndex(size_t arity)
@Brief insert a total order index
Definition: Index.h:287
souffle::interpreter::RelInterface
Wrapper class for interpreter relations.
Definition: ProgInterface.h:53
souffle::interpreter::RelationWrapper
Wrapper for InterpreterRelation.
Definition: Relation.h:48
souffle::interpreter::RelInterface::insert
void insert(const tuple &t) override
Insert tuple.
Definition: ProgInterface.h:68
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
souffle::tuple
Defines a tuple for the OO interface such that relations with varying columns can be accessed.
Definition: SouffleInterface.h:443
SouffleInterface.h
souffle::interpreter::test::TEST
TEST(Relation0, Construction)
Definition: interpreter_relation_test.cpp:38