Skip to content
This repository was archived by the owner on Sep 27, 2019. It is now read-only.

Commit 39f6832

Browse files
committed
Initial checkin with the sequence code (without temporary tables) from #1345
Checking in the testing files from #1345 These should be the last files that we need from from #1345 This compiles and passes all the tests except for the sequence test (obviously)
1 parent 2676275 commit 39f6832

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1670
-54
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Peloton
4+
//
5+
// SequenceTest.java
6+
//
7+
// Identification: script/testing/junit/SequenceTest.java
8+
//
9+
// Copyright (c) 2015-2018, Carnegie Mellon University Database Group
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import java.sql.*;
14+
import org.junit.*;
15+
import org.postgresql.util.PSQLException;
16+
import static org.junit.Assert.assertEquals;
17+
import static org.junit.Assert.assertTrue;
18+
import static junit.framework.TestCase.fail;
19+
20+
public class SequenceTest extends PLTestBase {
21+
private Connection conn1;
22+
private Connection conn2;
23+
24+
private static final String SQL_DROP_SEQ =
25+
"DROP SEQUENCE seq;";
26+
27+
private static final String SQL_CREATE_SEQ =
28+
"CREATE SEQUENCE seq;";
29+
30+
private static final String SQL_NEXTVAL =
31+
"SELECT NEXTVAL('seq')";
32+
33+
private static final String SQL_CURRVAL =
34+
"SELECT CURRVAL('seq')";
35+
36+
/**
37+
* Test sequence functions for single-statment transactions
38+
*/
39+
@Test
40+
public void test_SingleStmtTxn() throws SQLException {
41+
conn1 = makeDefaultConnection();
42+
conn1.setAutoCommit(true);
43+
Statement stmt1 = conn1.createStatement();
44+
45+
conn2 = makeDefaultConnection();
46+
conn2.setAutoCommit(true);
47+
Statement stmt2 = conn2.createStatement();
48+
49+
// Create a sequence
50+
stmt1.execute(SQL_CREATE_SEQ);
51+
52+
// Check the sequence is visible by others
53+
try {
54+
stmt2.execute(SQL_CREATE_SEQ);
55+
fail();
56+
} catch (PSQLException e) { }
57+
58+
// Check currval cannot be called before nextval
59+
try {
60+
stmt1.execute(SQL_CURRVAL);
61+
fail();
62+
} catch (PSQLException e) { }
63+
64+
// Check functionality with conn1
65+
stmt1.execute(SQL_NEXTVAL);
66+
ResultSet res1 = stmt1.executeQuery(SQL_CURRVAL);
67+
res1.next();
68+
assertEquals(1, res1.getInt(1));
69+
assertNoMoreRows(res1);
70+
71+
// Update should be visible to conn2
72+
stmt2.execute(SQL_NEXTVAL);
73+
ResultSet res2 = stmt2.executeQuery(SQL_CURRVAL);
74+
res2.next();
75+
assertEquals(2, res2.getInt(1));
76+
assertNoMoreRows(res2);
77+
78+
// Currval should be session consistent
79+
res1 = stmt1.executeQuery(SQL_CURRVAL);
80+
res1.next();
81+
assertEquals(1, res1.getInt(1));
82+
assertNoMoreRows(res1);
83+
84+
// Clean up
85+
stmt1.close();
86+
conn1.close();
87+
stmt2.close();
88+
conn2.close();
89+
}
90+
91+
/**
92+
* Test sequence functions for multi-statment transactions
93+
*/
94+
@Test
95+
public void test_MultiStmtTxn() throws SQLException {
96+
conn1 = makeDefaultConnection();
97+
conn1.setAutoCommit(false);
98+
Statement stmt1 = conn1.createStatement();
99+
100+
conn2 = makeDefaultConnection();
101+
conn2.setAutoCommit(false);
102+
Statement stmt2 = conn2.createStatement();
103+
104+
// Check functionality with conn1
105+
stmt1.execute(SQL_NEXTVAL);
106+
ResultSet res1 = stmt1.executeQuery(SQL_CURRVAL);
107+
res1.next();
108+
assertEquals(3, res1.getInt(1));
109+
assertNoMoreRows(res1);
110+
111+
// Update should be visible to conn2
112+
stmt2.execute(SQL_NEXTVAL);
113+
ResultSet res2 = stmt2.executeQuery(SQL_CURRVAL);
114+
res2.next();
115+
assertEquals(4, res2.getInt(1));
116+
assertNoMoreRows(res2);
117+
118+
// Rollback transactions
119+
conn1.rollback();
120+
conn2.rollback();
121+
122+
// Check sequence incremental will not rollback
123+
conn1.setAutoCommit(true);
124+
stmt1.execute(SQL_NEXTVAL);
125+
res1 = stmt1.executeQuery(SQL_CURRVAL);
126+
res1.next();
127+
assertEquals(5, res1.getInt(1));
128+
assertNoMoreRows(res1);
129+
130+
// Clean up
131+
stmt1.close();
132+
conn1.close();
133+
stmt2.close();
134+
conn2.close();
135+
}
136+
137+
/**
138+
* Test dropping sequence
139+
*/
140+
@Test
141+
public void test_Drop_Seq() throws SQLException {
142+
conn1 = makeDefaultConnection();
143+
conn1.setAutoCommit(true);
144+
Statement stmt1 = conn1.createStatement();
145+
146+
conn2 = makeDefaultConnection();
147+
conn2.setAutoCommit(true);
148+
Statement stmt2 = conn2.createStatement();
149+
150+
// Drop the sequence
151+
stmt1.execute(SQL_DROP_SEQ);
152+
153+
// Check the sequence is invisible to all conns
154+
try {
155+
stmt1.execute(SQL_CURRVAL);
156+
fail();
157+
} catch (PSQLException e) { }
158+
try {
159+
stmt2.execute(SQL_CURRVAL);
160+
fail();
161+
} catch (PSQLException e) { }
162+
163+
// Check the same sequence can be created w/o exception
164+
stmt2.execute(SQL_CREATE_SEQ);
165+
166+
// Clean up
167+
stmt1.close();
168+
conn1.close();
169+
stmt2.close();
170+
conn2.close();
171+
}
172+
}

src/catalog/catalog.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "function/date_functions.h"
3333
#include "function/numeric_functions.h"
3434
#include "function/old_engine_string_functions.h"
35+
#include "function/string_functions.h"
36+
#include "function/sequence_functions.h"
3537
#include "function/timestamp_functions.h"
3638
#include "index/index_factory.h"
3739
#include "settings/settings_manager.h"
@@ -1308,6 +1310,20 @@ void Catalog::InitializeFunctions() {
13081310
function::BuiltInFuncType{OperatorId::Like,
13091311
function::OldEngineStringFunctions::Like},
13101312
txn);
1313+
// Sequence
1314+
AddBuiltinFunction(
1315+
"nextval", {type::TypeId::VARCHAR}, type::TypeId::INTEGER,
1316+
internal_lang, "Nextval",
1317+
function::BuiltInFuncType{OperatorId::Nextval,
1318+
function::SequenceFunctions::_Nextval},
1319+
txn);
1320+
AddBuiltinFunction(
1321+
"currval", {type::TypeId::VARCHAR}, type::TypeId::INTEGER,
1322+
internal_lang, "Currval",
1323+
function::BuiltInFuncType{OperatorId::Currval,
1324+
function::SequenceFunctions::_Currval},
1325+
txn);
1326+
13111327

13121328
/**
13131329
* decimal functions

src/catalog/catalog_cache.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "catalog/catalog_cache.h"
1616

1717
#include "catalog/database_catalog.h"
18+
#include "catalog/sequence_catalog.h"
1819
#include "common/logger.h"
1920

2021
namespace peloton {
@@ -111,6 +112,14 @@ std::shared_ptr<DatabaseCatalogObject> CatalogCache::GetDatabaseObject(
111112
return it->second;
112113
}
113114

115+
std::vector<std::shared_ptr<DatabaseCatalogObject>> CatalogCache::GetAllDatabaseObjects() {
116+
std::vector<std::shared_ptr<DatabaseCatalogObject>> databases;
117+
for (auto it : database_objects_cache) {
118+
databases.push_back(it.second);
119+
}
120+
return (databases);
121+
}
122+
114123
/*@brief search table catalog object from all cached database objects
115124
* @param table_oid
116125
* @return table catalog object; if not found return null
@@ -152,5 +161,79 @@ std::shared_ptr<IndexCatalogObject> CatalogCache::GetCachedIndexObject(
152161
return nullptr;
153162
}
154163

164+
/*@brief insert sequence catalog object into cache
165+
* @param sequence_object
166+
* @return false only if sequence already exists in cache or invalid
167+
*/
168+
bool CatalogCache::InsertSequenceObject(
169+
std::shared_ptr<SequenceCatalogObject> sequence_object) {
170+
if (!sequence_object || sequence_object->seq_oid == INVALID_OID) {
171+
return false; // invalid object
172+
}
173+
174+
std::size_t hash_key = GetHashKey(sequence_object->seq_name,
175+
sequence_object->db_oid);
176+
177+
// check if already in cache
178+
if (sequence_objects_cache.find(hash_key) !=
179+
sequence_objects_cache.end()) {
180+
LOG_DEBUG("Sequence %s already exists in cache!",
181+
sequence_object->seq_name.c_str());
182+
return false;
183+
}
184+
185+
sequence_objects_cache.insert(
186+
std::make_pair(hash_key, sequence_object));
187+
return true;
188+
}
189+
190+
/*@brief evict sequence catalog object from cache
191+
* @param sequence_name
192+
* @param database_oid
193+
* @return true if specified sequence is found and evicted;
194+
* false if not found
195+
*/
196+
bool CatalogCache::EvictSequenceObject(const std::string & sequence_name,
197+
oid_t database_oid) {
198+
std::size_t hash_key = GetHashKey(sequence_name, database_oid);
199+
200+
auto it = sequence_objects_cache.find(hash_key);
201+
if (it == sequence_objects_cache.end()) {
202+
return false; // sequence not found in cache
203+
}
204+
205+
auto sequence_object = it->second;
206+
PELOTON_ASSERT(sequence_object);
207+
sequence_objects_cache.erase(it);
208+
return true;
209+
}
210+
211+
/*@brief get sequence catalog object from cache
212+
* @param sequence_name
213+
* @param database_oid
214+
* @return sequence catalog object; if not found return object with invalid oid
215+
*/
216+
std::shared_ptr<SequenceCatalogObject> CatalogCache::GetSequenceObject(
217+
const std::string & sequence_name, oid_t database_oid) {
218+
std::size_t hash_key = GetHashKey(sequence_name, database_oid);
219+
auto it = sequence_objects_cache.find(hash_key);
220+
if (it == sequence_objects_cache.end()) {
221+
return nullptr;
222+
}
223+
return it->second;
224+
}
225+
226+
/*@brief get the hash key given the sequence information
227+
* @param sequence_name
228+
* @param database_oid
229+
* @return hash key
230+
*/
231+
std::size_t CatalogCache::GetHashKey(const std::string sequence_name,
232+
oid_t database_oid) {
233+
std::tuple<std::string, size_t> key(sequence_name, database_oid);
234+
boost::hash<std::tuple<std::string, size_t>> key_hash;
235+
return key_hash(key);
236+
}
237+
155238
} // namespace catalog
156239
} // namespace peloton

src/catalog/database_catalog.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ bool DatabaseCatalog::DeleteDatabase(oid_t database_oid,
314314
values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy());
315315

316316
// evict cache
317-
txn->catalog_cache.EvictDatabaseObject(database_oid);
317+
txn->GetCatalogCache()->EvictDatabaseObject(database_oid);
318318

319319
return DeleteWithIndexScan(index_offset, values, txn);
320320
}
@@ -325,7 +325,7 @@ std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject(
325325
throw CatalogException("Transaction is invalid!");
326326
}
327327
// try get from cache
328-
auto database_object = txn->catalog_cache.GetDatabaseObject(database_oid);
328+
auto database_object = txn->GetCatalogCache()->GetDatabaseObject(database_oid);
329329
if (database_object) return database_object;
330330

331331
// cache miss, get from pg_database
@@ -341,7 +341,7 @@ std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject(
341341
auto database_object =
342342
std::make_shared<DatabaseCatalogObject>((*result_tiles)[0].get(), txn);
343343
// insert into cache
344-
bool success = txn->catalog_cache.InsertDatabaseObject(database_object);
344+
bool success = txn->GetCatalogCache()->InsertDatabaseObject(database_object);
345345
PELOTON_ASSERT(success == true);
346346
(void)success;
347347
return database_object;
@@ -364,7 +364,7 @@ std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject(
364364
throw CatalogException("Transaction is invalid!");
365365
}
366366
// try get from cache
367-
auto database_object = txn->catalog_cache.GetDatabaseObject(database_name);
367+
auto database_object = txn->GetCatalogCache()->GetDatabaseObject(database_name);
368368
if (database_object) return database_object;
369369

370370
// cache miss, get from pg_database
@@ -382,7 +382,7 @@ std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject(
382382
std::make_shared<DatabaseCatalogObject>((*result_tiles)[0].get(), txn);
383383
if (database_object) {
384384
// insert into cache
385-
bool success = txn->catalog_cache.InsertDatabaseObject(database_object);
385+
bool success = txn->GetCatalogCache()->InsertDatabaseObject(database_object);
386386
PELOTON_ASSERT(success == true);
387387
(void)success;
388388
}

src/catalog/index_catalog.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ bool IndexCatalog::DeleteIndex(oid_t database_oid, oid_t index_oid,
174174
values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy());
175175

176176
auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid,
177-
index_oid);
177+
index_oid);
178178
if (index_object) {
179179
auto table_object =
180180
txn->catalog_cache.GetCachedTableObject(database_oid,
181-
index_object->GetTableOid());
181+
index_object->GetTableOid());
182182
table_object->EvictAllIndexObjects();
183183
}
184184

@@ -192,7 +192,7 @@ std::shared_ptr<IndexCatalogObject> IndexCatalog::GetIndexObject(
192192
}
193193
// try get from cache
194194
auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid,
195-
index_oid);
195+
index_oid);
196196
if (index_object) {
197197
return index_object;
198198
}
@@ -235,7 +235,7 @@ std::shared_ptr<IndexCatalogObject> IndexCatalog::GetIndexObject(
235235
// try get from cache
236236
auto index_object =
237237
txn->catalog_cache.GetCachedIndexObject(database_name, index_name,
238-
schema_name);
238+
schema_name);
239239
if (index_object) {
240240
return index_object;
241241
}

0 commit comments

Comments
 (0)