From 86a42f4529586282ab2baeebc8757edcbce0c990 Mon Sep 17 00:00:00 2001
From: Dmitry Simonenko <pmwkaa@gmail.com>
Date: Thu, 21 Aug 2014 18:12:50 +0400
Subject: [PATCH] Fix gh-436: No error when creating temporary sophia space.

---
 src/box/alter.cc         |  8 ++++++++
 src/box/engine.h         |  8 ++++++++
 src/box/engine_memtx.cc  |  3 ++-
 src/box/key_def.cc       |  8 ++++++++
 test/box/sophia.result   | 33 +++++++++++++++++++++++++++++++++
 test/box/sophia.test.lua |  7 +++++++
 6 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index 9cd4f59aa7..8a25866464 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -507,6 +507,14 @@ ModifySpace::prepare(struct alter_space *alter)
 			  (unsigned) def.id,
 			  "can not change field count on a non-empty space");
 	}
+
+	EngineFactory * factory =
+		alter->old_space->engine->factory;
+	if (def.temporary && !engine_can_be_temporary(factory->id)) {
+		tnt_raise(ClientError, ER_ALTER_SPACE,
+			  (unsigned) def.id,
+			  "space does not support temporary flag");
+	}
 	if (def.temporary != alter->old_space->def.temporary &&
 	    recovery->state != READY_NO_KEYS &&
 	    space_size(alter->old_space) > 0) {
diff --git a/src/box/engine.h b/src/box/engine.h
index 26140d59e3..24d2ef3786 100644
--- a/src/box/engine.h
+++ b/src/box/engine.h
@@ -37,6 +37,7 @@ struct tuple;
 enum engine_flags {
 	ENGINE_TRANSACTIONAL = 1,
 	ENGINE_NO_YIELD = 2,
+	ENGINE_CAN_BE_TEMPORARY = 4
 };
 
 extern uint32_t engine_flags[BOX_ENGINE_MAX];
@@ -189,6 +190,13 @@ engine_no_yield(uint32_t id)
 	return engine_flags[id] & ENGINE_NO_YIELD;
 }
 
+static inline bool
+engine_can_be_temporary(uint32_t id)
+{
+	assert(id);
+	return engine_flags[id] & ENGINE_CAN_BE_TEMPORARY;
+}
+
 static inline uint32_t
 engine_id(Engine *engine)
 {
diff --git a/src/box/engine_memtx.cc b/src/box/engine_memtx.cc
index 23a74253c0..ade14477d2 100644
--- a/src/box/engine_memtx.cc
+++ b/src/box/engine_memtx.cc
@@ -74,7 +74,8 @@ memtx_recovery_prepare(struct engine_recovery *r)
 MemtxFactory::MemtxFactory()
 	:EngineFactory("memtx")
 {
-	flags = ENGINE_TRANSACTIONAL | ENGINE_NO_YIELD;
+	flags = ENGINE_TRANSACTIONAL | ENGINE_NO_YIELD |
+	        ENGINE_CAN_BE_TEMPORARY;
 	memtx_recovery_prepare(&recovery);
 }
 
diff --git a/src/box/key_def.cc b/src/box/key_def.cc
index 66f4fd4f3c..42283d80ae 100644
--- a/src/box/key_def.cc
+++ b/src/box/key_def.cc
@@ -224,6 +224,14 @@ space_def_check(struct space_def *def, uint32_t namelen, uint32_t engine_namelen
 			  "space engine name is too long");
 	}
 	identifier_check(def->engine_name);
+
+	if (def->temporary) {
+		EngineFactory *factory = engine_find(def->engine_name);
+		if (! engine_can_be_temporary(factory->id))
+			tnt_raise(ClientError, ER_ALTER_SPACE,
+			         (unsigned) def->id,
+			         "space does not support temporary flag");
+	}
 }
 
 bool
diff --git a/test/box/sophia.result b/test/box/sophia.result
index 7bb5dc44aa..f0e70014b0 100644
--- a/test/box/sophia.result
+++ b/test/box/sophia.result
@@ -213,6 +213,39 @@ s:select{10000}
 s:drop()
 ---
 ...
+---
+--- gh-456: Sophia: index size() is unsupported
+---
+box.cfg{}
+---
+...
+s = box.schema.create_space('tester',{engine='sophia'})
+---
+...
+s:create_index('sophia_index', {})
+---
+...
+s.index[0]:len() -- exception
+---
+- 4294967295
+...
+box.error()
+---
+- error: SophiaIndex does not support size operation
+...
+s:drop()
+---
+...
+---
+--- gh-436: No error when creating temporary sophia space
+---
+box.cfg{}
+---
+...
+s = box.schema.create_space('tester',{engine='sophia', temporary=true})
+---
+- error: 'Can''t modify space 512: space does not support temporary flag'
+...
 os.execute("rm -rf sophia")
 ---
 - 0
diff --git a/test/box/sophia.test.lua b/test/box/sophia.test.lua
index c57ef7f913..517e8a7cb2 100644
--- a/test/box/sophia.test.lua
+++ b/test/box/sophia.test.lua
@@ -83,4 +83,11 @@ s.index[0]:len() -- exception
 box.error()
 s:drop()
 
+---
+--- gh-436: No error when creating temporary sophia space
+---
+
+box.cfg{}
+s = box.schema.create_space('tester',{engine='sophia', temporary=true})
+
 os.execute("rm -rf sophia")
-- 
GitLab