Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladimir Davydov <vdavydov.dev@gmail.com>
To: kostja@tarantool.org
Cc: tarantool-patches@freelists.org
Subject: [PATCH v2 7/8] vinyl: factor out vy_check_is_unique_secondary
Date: Sun, 27 May 2018 22:05:55 +0300	[thread overview]
Message-ID: <089a67b8077d0fa67da66c4868e0755f3aa01973.1527446023.git.vdavydov.dev@gmail.com> (raw)
In-Reply-To: <cover.1527446023.git.vdavydov.dev@gmail.com>
In-Reply-To: <cover.1527446023.git.vdavydov.dev@gmail.com>

We need to check unique constraint when building a new index. So let's
factor out this helper function and pass space_name, index_name, and
read view to it explicitly (because index_name_by_id isn't going to work
for an index that is under construction and there's no tx when we are
building a new index). Suggested by @Gerold103.

Needed for #1653
---
 src/box/vinyl.c | 81 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 56 insertions(+), 25 deletions(-)

diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index 4d670328..41ffa42c 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -1353,7 +1353,9 @@ vy_lsm_get(struct vy_lsm *lsm, struct vy_tx *tx,
  * a duplicate key error in the diagnostics area.
  * @param env        Vinyl environment.
  * @param tx         Current transaction.
- * @param space      Target space.
+ * @param rv         Read view.
+ * @param space_name Space name.
+ * @param index_name Index name.
  * @param lsm        LSM tree in which to search.
  * @param key        Key statement.
  *
@@ -1361,7 +1363,9 @@ vy_lsm_get(struct vy_lsm *lsm, struct vy_tx *tx,
  * @retval -1 Memory error or the key is found.
  */
 static inline int
-vy_check_is_unique(struct vy_env *env, struct vy_tx *tx, struct space *space,
+vy_check_is_unique(struct vy_env *env, struct vy_tx *tx,
+		   const struct vy_read_view **rv,
+		   const char *space_name, const char *index_name,
 		   struct vy_lsm *lsm, struct tuple *key)
 {
 	struct tuple *found;
@@ -1371,20 +1375,57 @@ vy_check_is_unique(struct vy_env *env, struct vy_tx *tx, struct space *space,
 	 */
 	if (env->status != VINYL_ONLINE)
 		return 0;
-	if (vy_lsm_get(lsm, tx, vy_tx_read_view(tx), key, &found))
+	if (vy_lsm_get(lsm, tx, rv, key, &found))
 		return -1;
 
 	if (found) {
 		tuple_unref(found);
 		diag_set(ClientError, ER_TUPLE_FOUND,
-			 index_name_by_id(space, lsm->index_id),
-			 space_name(space));
+			 index_name, space_name);
 		return -1;
 	}
 	return 0;
 }
 
 /**
+ * Check if insertion of a new tuple violates unique constraint
+ * of a secondary index.
+ * @param env        Vinyl environment.
+ * @param tx         Current transaction.
+ * @param rv         Read view.
+ * @param space_name Space name.
+ * @param index_name Index name.
+ * @param lsm        LSM tree corresponding to the index.
+ * @param stmt       New tuple.
+ *
+ * @retval  0 Success, unique constraint is satisfied.
+ * @retval -1 Duplicate is found or read error occurred.
+ */
+static int
+vy_check_is_unique_secondary(struct vy_env *env, struct vy_tx *tx,
+			     const struct vy_read_view **rv,
+			     const char *space_name, const char *index_name,
+			     struct vy_lsm *lsm, const struct tuple *stmt)
+{
+	assert(lsm->index_id > 0);
+	struct key_def *def = lsm->key_def;
+	if (lsm->check_is_unique &&
+	    !key_update_can_be_skipped(def->column_mask,
+				       vy_stmt_column_mask(stmt)) &&
+	    (!def->is_nullable || !vy_tuple_key_contains_null(stmt, def))) {
+		struct tuple *key = vy_stmt_extract_key(stmt, def,
+							lsm->env->key_format);
+		if (key == NULL)
+			return -1;
+		int rc = vy_check_is_unique(env, tx, rv, space_name,
+					    index_name, lsm, key);
+		tuple_unref(key);
+		return rc;
+	}
+	return 0;
+}
+
+/**
  * Insert a tuple in a primary index LSM tree.
  * @param env   Vinyl environment.
  * @param tx    Current transaction.
@@ -1407,7 +1448,9 @@ vy_insert_primary(struct vy_env *env, struct vy_tx *tx, struct space *space,
 	 * conflict with existing tuples.
 	 */
 	if (pk->check_is_unique &&
-	    vy_check_is_unique(env, tx, space, pk, stmt) != 0)
+	    vy_check_is_unique(env, tx, vy_tx_read_view(tx), space_name(space),
+			       index_name_by_id(space, pk->index_id),
+			       pk, stmt) != 0)
 		return -1;
 	return vy_tx_set(tx, pk, stmt);
 }
@@ -1431,25 +1474,13 @@ vy_insert_secondary(struct vy_env *env, struct vy_tx *tx, struct space *space,
 	       vy_stmt_type(stmt) == IPROTO_REPLACE);
 	assert(tx != NULL && tx->state == VINYL_TX_READY);
 	assert(lsm->index_id > 0);
-	/*
-	 * If the index is unique then the new tuple must not
-	 * conflict with existing tuples. If the index is not
-	 * unique a conflict is impossible.
-	 */
-	if (lsm->check_is_unique &&
-	    !key_update_can_be_skipped(lsm->key_def->column_mask,
-				       vy_stmt_column_mask(stmt)) &&
-	    (!lsm->key_def->is_nullable ||
-	     !vy_tuple_key_contains_null(stmt, lsm->key_def))) {
-		struct tuple *key = vy_stmt_extract_key(stmt, lsm->key_def,
-							lsm->env->key_format);
-		if (key == NULL)
-			return -1;
-		int rc = vy_check_is_unique(env, tx, space, lsm, key);
-		tuple_unref(key);
-		if (rc != 0)
-			return -1;
-	}
+
+	if (vy_check_is_unique_secondary(env, tx, vy_tx_read_view(tx),
+					 space_name(space),
+					 index_name_by_id(space, lsm->index_id),
+					 lsm, stmt) != 0)
+		return -1;
+
 	/*
 	 * We must always append the statement to transaction write set
 	 * of each LSM tree, even if operation itself does not update
-- 
2.11.0

  parent reply	other threads:[~2018-05-27 19:05 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-27 19:05 [PATCH v2 0/8] Allow to build indexes for vinyl spaces Vladimir Davydov
2018-05-27 19:05 ` [PATCH v2 1/8] vinyl: allocate key parts in vy_recovery_do_create_lsm Vladimir Davydov
2018-05-30 11:51   ` Konstantin Osipov
2018-05-27 19:05 ` [PATCH v2 2/8] vinyl: update recovery context with records written during recovery Vladimir Davydov
2018-05-30 11:51   ` Konstantin Osipov
2018-05-27 19:05 ` [PATCH v2 3/8] vinyl: log new index before WAL write on DDL Vladimir Davydov
2018-06-06 18:01   ` Konstantin Osipov
2018-05-27 19:05 ` [PATCH v2 4/8] vinyl: bump mem version after committing statement Vladimir Davydov
2018-06-07  5:41   ` Konstantin Osipov
2018-05-27 19:05 ` [PATCH v2 5/8] vinyl: allow to commit statements to mem in arbitrary order Vladimir Davydov
2018-06-07  5:41   ` Konstantin Osipov
2018-05-27 19:05 ` [PATCH v2 6/8] vinyl: relax limitation imposed on run min/max lsn Vladimir Davydov
2018-05-27 19:05 ` Vladimir Davydov [this message]
2018-05-27 19:05 ` [PATCH v2 8/8] vinyl: allow to build secondary index for non-empty space Vladimir Davydov

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=089a67b8077d0fa67da66c4868e0755f3aa01973.1527446023.git.vdavydov.dev@gmail.com \
    --to=vdavydov.dev@gmail.com \
    --cc=kostja@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [PATCH v2 7/8] vinyl: factor out vy_check_is_unique_secondary' \
    /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