Tarantool development patches archive
 help / color / mirror / Atom feed
From: Nikita Pettik <korablev@tarantool.org>
To: tarantool-patches@freelists.org
Cc: v.shpilevoy@tarantool.org, Nikita Pettik <korablev@tarantool.org>
Subject: [tarantool-patches] [PATCH 1/2] space: add method to fetch next rowid
Date: Mon, 29 Oct 2018 22:02:05 +0300	[thread overview]
Message-ID: <11f65a415a9b1101fa4ba816be237df524de9b47.1540838910.git.korablev@tarantool.org> (raw)
In-Reply-To: <cover.1540838910.git.korablev@tarantool.org>
In-Reply-To: <cover.1540838910.git.korablev@tarantool.org>

Ephemeral space are extensively used in SQL to store intermediate
results of query processing. To keep things simple, they feature only
one unique index (primary) which covers all fields. However, ephemeral
space can be used to store non-unique entries. In this case, one
additional field added to the end if stored data:

[field1, ... fieldn, rowid]

Note that it can't be added to the beginning of tuple since data in
ephemeral space may be kept as sorted. Previously, to generate proper
rowid index_max() was used. However, it is obviously wrong way to do it.
Hence, lets add simple integer counter to memtx space (ephemeral spaces
are valid only for memtx engine) and introduce method in vtab to fetch
next rowid value.

Needed for #3297
---
 src/box/blackhole.c    |  1 +
 src/box/errcode.h      |  2 ++
 src/box/memtx_space.c  | 17 +++++++++++++++++
 src/box/memtx_space.h  |  7 +++++++
 src/box/space.c        |  9 +++++++++
 src/box/space.h        |  3 +++
 src/box/sysview.c      |  1 +
 src/box/vinyl.c        |  1 +
 src/errinj.h           |  1 +
 test/box/errinj.result |  2 ++
 test/box/misc.result   |  1 +
 11 files changed, 45 insertions(+)

diff --git a/src/box/blackhole.c b/src/box/blackhole.c
index aafbfbf65..e34a2dc4a 100644
--- a/src/box/blackhole.c
+++ b/src/box/blackhole.c
@@ -118,6 +118,7 @@ static const struct space_vtab blackhole_space_vtab = {
 	/* .execute_upsert = */ blackhole_space_execute_upsert,
 	/* .ephemeral_replace = */ generic_space_ephemeral_replace,
 	/* .ephemeral_delete = */ generic_space_ephemeral_delete,
+	/* .ephemeral_rowid_next = */ generic_space_ephemeral_rowid_next,
 	/* .init_system_space = */ generic_init_system_space,
 	/* .init_ephemeral_space = */ generic_init_ephemeral_space,
 	/* .check_index_def = */ generic_space_check_index_def,
diff --git a/src/box/errcode.h b/src/box/errcode.h
index 04f4f34ee..fab8b6617 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -223,6 +223,8 @@ struct errcode_record {
 	/*168 */_(ER_DROP_FK_CONSTRAINT,	"Failed to drop foreign key constraint '%s': %s") \
 	/*169 */_(ER_NO_SUCH_CONSTRAINT,	"Constraint %s does not exist") \
 	/*170 */_(ER_CONSTRAINT_EXISTS,		"Constraint %s already exists") \
+	/*171 */_(ER_ROWID_OVERFLOW,		"Rowid is overflowed: too many entries in ephemeral space") \
+
 
 /*
  * !IMPORTANT! Please follow instructions at start of the file
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index 8cf2e6b94..075b86f9d 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -601,6 +601,21 @@ memtx_space_ephemeral_delete(struct space *space, const char *key)
 	return 0;
 }
 
+static int
+memtx_space_ephemeral_rowid_next(struct space *space, uint64_t *rowid)
+{
+	assert(rowid != NULL);
+	struct memtx_space *memtx_space = (struct memtx_space *)space;
+	ERROR_INJECT(ERRINJ_ROWID_OVERFLOW,
+		     { memtx_space->rowid = UINT64_MAX; });
+	if (unlikely(memtx_space->rowid == UINT64_MAX)) {
+		diag_set(ClientError, ER_ROWID_OVERFLOW);
+		return -1;
+	}
+	*rowid = memtx_space->rowid++;
+	return 0;
+}
+
 /* }}} DML */
 
 /* {{{ DDL */
@@ -941,6 +956,7 @@ static const struct space_vtab memtx_space_vtab = {
 	/* .execute_upsert = */ memtx_space_execute_upsert,
 	/* .ephemeral_replace = */ memtx_space_ephemeral_replace,
 	/* .ephemeral_delete = */ memtx_space_ephemeral_delete,
+	/* .ephemeral_rowid_next = */ memtx_space_ephemeral_rowid_next,
 	/* .init_system_space = */ memtx_init_system_space,
 	/* .init_ephemeral_space = */ memtx_init_ephemeral_space,
 	/* .check_index_def = */ memtx_space_check_index_def,
@@ -1002,6 +1018,7 @@ memtx_space_new(struct memtx_engine *memtx,
 	tuple_format_unref(format);
 
 	memtx_space->bsize = 0;
+	memtx_space->rowid = 0;
 	memtx_space->replace = memtx_space_replace_no_keys;
 	return (struct space *)memtx_space;
 }
diff --git a/src/box/memtx_space.h b/src/box/memtx_space.h
index 7dc341079..532538312 100644
--- a/src/box/memtx_space.h
+++ b/src/box/memtx_space.h
@@ -42,6 +42,13 @@ struct memtx_space {
 	struct space base;
 	/* Number of bytes used in memory by tuples in the space. */
 	size_t bsize;
+	/**
+	 * This counter is used to generate unique ids for
+	 * ephemeral spaces. Mostly used by SQL: values of this
+	 * var are stored as separate field to hold non-unique
+	 * tuples within one unique primary key.
+	 */
+	uint64_t rowid;
 	/**
 	 * A pointer to replace function, set to different values
 	 * at different stages of recovery.
diff --git a/src/box/space.c b/src/box/space.c
index 548f66787..4d174f7ec 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -568,6 +568,15 @@ generic_space_ephemeral_delete(struct space *space, const char *key)
 	return -1;
 }
 
+int
+generic_space_ephemeral_rowid_next(struct space *space, uint64_t *rowid)
+{
+	(void)space;
+	(void)rowid;
+	unreachable();
+	return 0;
+}
+
 void
 generic_init_system_space(struct space *space)
 {
diff --git a/src/box/space.h b/src/box/space.h
index f3e9e1e21..7eb7ae292 100644
--- a/src/box/space.h
+++ b/src/box/space.h
@@ -71,6 +71,8 @@ struct space_vtab {
 
 	int (*ephemeral_delete)(struct space *, const char *);
 
+	int (*ephemeral_rowid_next)(struct space *, uint64_t *);
+
 	void (*init_system_space)(struct space *);
 	/**
 	 * Initialize an ephemeral space instance.
@@ -457,6 +459,7 @@ size_t generic_space_bsize(struct space *);
 int generic_space_apply_initial_join_row(struct space *, struct request *);
 int generic_space_ephemeral_replace(struct space *, const char *, const char *);
 int generic_space_ephemeral_delete(struct space *, const char *);
+int generic_space_ephemeral_rowid_next(struct space *, uint64_t *);
 void generic_init_system_space(struct space *);
 void generic_init_ephemeral_space(struct space *);
 int generic_space_check_index_def(struct space *, struct index_def *);
diff --git a/src/box/sysview.c b/src/box/sysview.c
index ed5bca38e..29de43093 100644
--- a/src/box/sysview.c
+++ b/src/box/sysview.c
@@ -484,6 +484,7 @@ static const struct space_vtab sysview_space_vtab = {
 	/* .execute_upsert = */ sysview_space_execute_upsert,
 	/* .ephemeral_replace = */ generic_space_ephemeral_replace,
 	/* .ephemeral_delete = */ generic_space_ephemeral_delete,
+	/* .ephemeral_rowid_next = */ generic_space_ephemeral_rowid_next,
 	/* .init_system_space = */ generic_init_system_space,
 	/* .init_ephemeral_space = */ generic_init_ephemeral_space,
 	/* .check_index_def = */ generic_space_check_index_def,
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index 09b665598..8ff52b466 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -4470,6 +4470,7 @@ static const struct space_vtab vinyl_space_vtab = {
 	/* .execute_upsert = */ vinyl_space_execute_upsert,
 	/* .ephemeral_replace = */ generic_space_ephemeral_replace,
 	/* .ephemeral_delete = */ generic_space_ephemeral_delete,
+	/* .ephemeral_rowid_next = */ generic_space_ephemeral_rowid_next,
 	/* .init_system_space = */ generic_init_system_space,
 	/* .init_ephemeral_space = */ generic_init_ephemeral_space,
 	/* .check_index_def = */ vinyl_space_check_index_def,
diff --git a/src/errinj.h b/src/errinj.h
index 84a1fbb5e..58aa5864a 100644
--- a/src/errinj.h
+++ b/src/errinj.h
@@ -121,6 +121,7 @@ struct errinj {
 	_(ERRINJ_RELAY_BREAK_LSN, ERRINJ_INT, {.iparam = -1}) \
 	_(ERRINJ_WAL_BREAK_LSN, ERRINJ_INT, {.iparam = -1}) \
 	_(ERRINJ_VY_COMPACTION_DELAY, ERRINJ_BOOL, {.bparam = false}) \
+	_(ERRINJ_ROWID_OVERFLOW, ERRINJ_BOOL, {.bparam = false}) \
 
 ENUM0(errinj_id, ERRINJ_LIST);
 extern struct errinj errinjs[];
diff --git a/test/box/errinj.result b/test/box/errinj.result
index c4a1326cd..191e16911 100644
--- a/test/box/errinj.result
+++ b/test/box/errinj.result
@@ -54,6 +54,8 @@ errinj.info()
     state: false
   ERRINJ_RELAY_REPORT_INTERVAL:
     state: 0
+  ERRINJ_ROWID_OVERFLOW:
+    state: false
   ERRINJ_VY_READ_PAGE_TIMEOUT:
     state: 0
   ERRINJ_XLOG_META:
diff --git a/test/box/misc.result b/test/box/misc.result
index 3d7317caf..e3d3d3c3b 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -497,6 +497,7 @@ t;
   168: box.error.DROP_FK_CONSTRAINT
   169: box.error.NO_SUCH_CONSTRAINT
   170: box.error.CONSTRAINT_EXISTS
+  171: box.error.ROWID_OVERFLOW
 ...
 test_run:cmd("setopt delimiter ''");
 ---
-- 
2.15.1

  reply	other threads:[~2018-10-29 19:02 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-29 19:02 [tarantool-patches] [PATCH 0/2] Re-implement rowid generation for ephemeral spaces Nikita Pettik
2018-10-29 19:02 ` Nikita Pettik [this message]
2018-10-30  8:45   ` [tarantool-patches] [PATCH 1/2] space: add method to fetch next rowid Vladimir Davydov
2018-10-30 10:32     ` n.pettik
2018-11-09  9:25   ` [tarantool-patches] " Vladislav Shpilevoy
2018-11-11 23:16     ` n.pettik
2018-11-11 23:22       ` Vladislav Shpilevoy
2018-11-14 23:11         ` n.pettik
2018-11-21 18:58       ` Konstantin Osipov
2018-10-29 19:02 ` [tarantool-patches] [PATCH 2/2] sql: use vtab::rowid_next() instead of index_max() Nikita Pettik
2018-11-09  9:25   ` [tarantool-patches] " Vladislav Shpilevoy
2018-11-15  4:54 ` [tarantool-patches] Re: [PATCH 0/2] Re-implement rowid generation for ephemeral spaces Kirill Yukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11f65a415a9b1101fa4ba816be237df524de9b47.1540838910.git.korablev@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [tarantool-patches] [PATCH 1/2] space: add method to fetch next rowid' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox