Tarantool development patches archive
 help / color / mirror / Atom feed
From: olegrok@tarantool.org
To: tarantool-patches@dev.tarantool.org, v.shpilevoy@tarantool.org,
	korablev@tarantool.org
Cc: Oleg Babin <babinoleg@mail.ru>
Subject: [Tarantool-patches] [PATCH 1/2] box: introduce internal sequence error
Date: Fri,  6 Mar 2020 14:46:42 +0300	[thread overview]
Message-ID: <e360f3fecca045fd6bb21d238b9e2fcabf429377.1583494653.git.babinoleg@mail.ru> (raw)
In-Reply-To: <cover.1583494653.git.babinoleg@mail.ru>

From: Oleg Babin <babinoleg@mail.ru>

This patch introduces SequenceError. It is thrown
in case when we try to get current value of sequence
before it was initialized ("next" was called at least once)

Need for #4752
---
Issue: https://github.com/tarantool/tarantool/issues/4752
Branch: https://github.com/tarantool/tarantool/tree/olegrok/4752-sequence-current
 src/box/sequence.c        | 12 ++++++++----
 src/box/sequence.h        |  7 ++++---
 src/box/sql/vdbe.c        |  5 ++++-
 src/lib/core/diag.h       |  2 ++
 src/lib/core/exception.cc | 25 +++++++++++++++++++++++++
 src/lib/core/exception.h  |  6 ++++++
 6 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/src/box/sequence.c b/src/box/sequence.c
index 5ebfa2747..617b7ca38 100644
--- a/src/box/sequence.c
+++ b/src/box/sequence.c
@@ -367,14 +367,18 @@ sequence_data_iterator_create(void)
 	return &iter->base;
 }
 
-int64_t
-sequence_get_value(struct sequence *seq)
+int
+sequence_get_value(struct sequence *seq, int64_t *result)
 {
 	uint32_t key = seq->def->id;
 	uint32_t hash = sequence_hash(key);
 	uint32_t pos = light_sequence_find_key(&sequence_data_index, hash, key);
-	assert(pos != light_sequence_end);
+	if (pos == light_sequence_end) {
+		diag_set(SequenceError, "Sequence is not initialized yet");
+		return -1;
+	}
 	struct sequence_data data = light_sequence_get(&sequence_data_index,
 						       pos);
-	return data.value;
+	*result = data.value;
+	return 0;
 }
diff --git a/src/box/sequence.h b/src/box/sequence.h
index a164da9af..8c442872a 100644
--- a/src/box/sequence.h
+++ b/src/box/sequence.h
@@ -171,10 +171,11 @@ sequence_data_iterator_create(void);
  * Get last element of given sequence.
  *
  * @param seq sequence to get value from.
- * @retval last element of sequence.
+ * @result value of sequence.
+ * Return 0 on success, -1 if sequence is not initialized.
  */
-int64_t
-sequence_get_value(struct sequence *seq);
+int
+sequence_get_value(struct sequence *seq, int64_t *result);
 
 #if defined(__cplusplus)
 } /* extern "C" */
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 912a10153..0de07ca1d 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -4328,7 +4328,10 @@ case OP_IdxInsert: {
 		p->nChange++;
 	if (pOp->p3 > 0 && ((aMem[pOp->p3].flags) & MEM_Null) != 0) {
 		assert(space->sequence != NULL);
-		int64_t value = sequence_get_value(space->sequence);
+		int64_t value;
+		if (sequence_get_value(space->sequence, &value) != 0) {
+			goto abort_due_to_error;
+		}
 		if (vdbe_add_new_autoinc_id(p, value) != 0)
 			goto abort_due_to_error;
 	}
diff --git a/src/lib/core/diag.h b/src/lib/core/diag.h
index f763957c2..e19b6b824 100644
--- a/src/lib/core/diag.h
+++ b/src/lib/core/diag.h
@@ -259,6 +259,8 @@ struct error *
 BuildSwimError(const char *file, unsigned line, const char *format, ...);
 struct error *
 BuildCryptoError(const char *file, unsigned line, const char *format, ...);
+struct error *
+BuildSequenceError(const char *file, unsigned line, const char *format, ...);
 
 struct index_def;
 
diff --git a/src/lib/core/exception.cc b/src/lib/core/exception.cc
index 76dcea553..53b86291f 100644
--- a/src/lib/core/exception.cc
+++ b/src/lib/core/exception.cc
@@ -287,6 +287,19 @@ CryptoError::CryptoError(const char *file, unsigned line,
 	va_end(ap);
 }
 
+const struct type_info type_SequenceError =
+		make_type("SequenceError", &type_Exception);
+
+SequenceError::SequenceError(const char *file, unsigned line,
+						 const char *format, ...)
+		: Exception(&type_SequenceError, file, line)
+{
+	va_list ap;
+	va_start(ap, format);
+	error_vformat_msg(this, format, ap);
+	va_end(ap);
+}
+
 #define BuildAlloc(type)				\
 	void *p = malloc(sizeof(type));			\
 	if (p == NULL)					\
@@ -390,6 +403,18 @@ BuildCryptoError(const char *file, unsigned line, const char *format, ...)
 	return e;
 }
 
+struct error *
+BuildSequenceError(const char *file, unsigned line, const char *format, ...)
+{
+	BuildAlloc(CryptoError);
+	SequenceError *e =  new (p) SequenceError(file, line, "");
+	va_list ap;
+	va_start(ap, format);
+	error_vformat_msg(e, format, ap);
+	va_end(ap);
+	return e;
+}
+
 struct error *
 BuildSocketError(const char *file, unsigned line, const char *socketname,
 		 const char *format, ...)
diff --git a/src/lib/core/exception.h b/src/lib/core/exception.h
index d6154eb32..d9c4542da 100644
--- a/src/lib/core/exception.h
+++ b/src/lib/core/exception.h
@@ -168,6 +168,12 @@ public:
 	virtual void raise() { throw this; }
 };
 
+class SequenceError: public Exception {
+public:
+	SequenceError(const char *file, unsigned line, const char *format, ...);
+	virtual void raise() { throw this; }
+};
+
 /**
  * Initialize the exception subsystem.
  */
-- 
2.23.0

  reply	other threads:[~2020-03-06 11:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06 11:46 [Tarantool-patches] [PATCH 0/2] Introcude sequence.current olegrok
2020-03-06 11:46 ` olegrok [this message]
2020-03-06 12:55   ` [Tarantool-patches] [PATCH 1/2] box: introduce internal sequence error Nikita Pettik
2020-03-06 16:37     ` Oleg Babin
2020-03-06 11:46 ` [Tarantool-patches] [PATCH 2/2] box: introduce "current" for sequence olegrok
2020-03-06 13:00   ` Nikita Pettik

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=e360f3fecca045fd6bb21d238b9e2fcabf429377.1583494653.git.babinoleg@mail.ru \
    --to=olegrok@tarantool.org \
    --cc=babinoleg@mail.ru \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH 1/2] box: introduce internal sequence error' \
    /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