Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: imeevma@tarantool.org, tarantool-patches@freelists.org
Subject: [tarantool-patches] Re: [PATCH v4 1/1] sql: return all generated ids via IPROTO
Date: Thu, 20 Sep 2018 18:36:22 +0200	[thread overview]
Message-ID: <b255ff22-f157-903c-8a79-325f68f839f3@tarantool.org> (raw)
In-Reply-To: <4041f49f7a62d12d9a6c8a9a452ed4cac267b1e3.1537204943.git.imeevma@gmail.com>

Hi! Thanks for the patch! See 10 comments below.

On 17/09/2018 19:23, imeevma@tarantool.org wrote:
> According to documentation some JDBC functions have an ability to
> return all ids that were generated in executed INSERT statement.
> This patch gives a way to implements such functinality.

1. Typos: 'way to implements', 'functinality'.

> 
> Closes #2618
> ---
> Branch: https://github.com/tarantool/tarantool/tree/imeevma/gh-2618-return-all-generated-ids
> Issue: https://github.com/tarantool/tarantool/issues/2618
> 
>   src/box/execute.c        |  17 ++++-
>   src/box/execute.h        |   1 +
>   src/box/lua/net_box.c    |  16 ++++-
>   src/box/sequence.c       |  37 ++++++++++
>   src/box/sql/sqliteInt.h  |   4 ++
>   src/box/sql/vdbeaux.c    |  29 ++++++++
>   src/box/txn.c            |   5 ++
>   src/box/txn.h            |   6 ++
>   test/sql/errinj.result   |   3 +-
>   test/sql/iproto.result   | 171 ++++++++++++++++++++++++++++++++++++++---------
>   test/sql/iproto.test.lua |  15 +++++
>   11 files changed, 266 insertions(+), 38 deletions(-)
> 
> diff --git a/src/box/execute.c b/src/box/execute.c
> index 24459b4..8e4bc80 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
> @@ -641,14 +641,27 @@ err:
>   			goto err;
>   		int changes = sqlite3_changes(db);
>   		int size = mp_sizeof_uint(SQL_INFO_ROW_COUNT) +
> -			   mp_sizeof_uint(changes);
> +			   mp_sizeof_uint(changes) +
> +			   mp_sizeof_uint(SQL_INFO_GENERATED_IDS) +
> +			   mp_sizeof_array(db->generated_ids_count);

2. When you use '<noun>_count', the noun should be in the singular.

> +		for (uint64_t i = 0; i < db->generated_ids_count; ++i) {
> +			size += db->generated_ids_array[i] >= 0 ?

3. Type can be omitted in a variable name (no <name>_array, but <name>s).

> +				mp_sizeof_uint(db->generated_ids_array[i]) :
> +				mp_sizeof_int(db->generated_ids_array[i]);
> +		}
>   		char *buf = obuf_alloc(out, size);
>   		if (buf == NULL) {
>   			diag_set(OutOfMemory, size, "obuf_alloc", "buf");
> -			goto err;

4. Why?

>   		}
>   		buf = mp_encode_uint(buf, SQL_INFO_ROW_COUNT);
>   		buf = mp_encode_uint(buf, changes);
> +		buf = mp_encode_uint(buf, SQL_INFO_GENERATED_IDS);

5. I do not think we should send empty array. Maybe it is better to
omit the key in such a case?

> +		buf = mp_encode_array(buf, db->generated_ids_count);
> +		for (uint64_t i = 0; i < db->generated_ids_count; ++i) {
> +			buf = db->generated_ids_array[i] < 0 ?
> +			      mp_encode_int(buf, db->generated_ids_array[i]) :
> +			      mp_encode_uint(buf, db->generated_ids_array[i]);
> +		}
>   	}
>   	iproto_reply_sql(out, &header_svp, response->sync, schema_version,
>   			 keys);
> diff --git a/src/box/sequence.c b/src/box/sequence.c
> index 35b7605..234509c 100644
> --- a/src/box/sequence.c
> +++ b/src/box/sequence.c
> @@ -178,6 +180,37 @@ sequence_update(struct sequence *seq, int64_t value)
>   	return 0;
>   }
>   
> +/*
> + * Save generated value into txn.
> + *
> + * \param value value to save.
> + * \retval 0 Success.
> + * \retval -1 Error.
> + */
> +static inline int
> +save_value(int64_t value)
> +{
> +	struct txn *txn = in_txn();
> +	if (txn == NULL)
> +		return 0;
> +	if (txn->generated_ids.size == txn->generated_ids.capacity) {

6. Why do you store generated ids in box txn instead of vdbe? As I know,
after commit/rollback txn object is freed so it does not matter where do
you store ids array - on the heap or on a region - txn.generated_ids
attribute will be invalid after commit/rollback. What is more, we do not
need ids from non-SQL requests - they are never used.

Last time we discussed that you should store result of sequence_next from
OP_NextAutoincValue. And at the same place you can save the result into
Vdbe generated ids array. This will work the same way as your current
implementation, but will not slow down non-SQL requests.

> +		txn->generated_ids.capacity = txn->generated_ids.capacity > 0 ?
> +					      txn->generated_ids.capacity * 2 :
> +					      SEQUENCE_GENERATED_IDS_MIN_LEN;
> +		uint64_t capacity = txn->generated_ids.capacity *
> +				    sizeof(*txn->generated_ids.array);
> +		txn->generated_ids.array = realloc(txn->generated_ids.array,
> +						   capacity);
> +		if (txn->generated_ids.array == NULL) {
> +			diag_set(OutOfMemory, txn->generated_ids.capacity,
> +				 "realloc", "txn->generated_ids.array");
> +			return -1;
> +		}
> +	}
> +	txn->generated_ids.array[txn->generated_ids.size++] = value;
> +	return 0;
> +}
> +
>   int
>   sequence_next(struct sequence *seq, int64_t *result)
>   {
> diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
> index 1d32c9a..7d41ece 100644
> --- a/src/box/sql/sqliteInt.h
> +++ b/src/box/sql/sqliteInt.h
> @@ -1525,6 +1525,10 @@ struct sqlite3 {
>   	u8 mTrace;		/* zero or more SQLITE_TRACE flags */
>   	u32 magic;		/* Magic number for detect library misuse */
>   	int nChange;		/* Value returned by sqlite3_changes() */
> +	/* Number of generated ids. */
> +	uint64_t generated_ids_count;
> +	/* Array of generated ids. */
> +	int64_t *generated_ids_array;

7. Do not store ids in multiple places, and moreover in sqlite3 that will be
removed in future. Use struct Vdbe. Ids array is per-request attribute.

>   	int nTotalChange;	/* Value returned by sqlite3_total_changes() */
>   	int aLimit[SQLITE_N_LIMIT];	/* Limits */
>   	int nMaxSorterMmap;	/* Maximum size of regions mapped by sorter */
> diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
> index 3b0c90c..7b5d6b9 100644
> --- a/src/box/sql/vdbeaux.c
> +++ b/src/box/sql/vdbeaux.c
> @@ -2303,6 +2303,29 @@ sql_savepoint(Vdbe *p, const char *zName)
>   }
>   
>   /*
> + * Move array of generated ids into db.
> + *
> + * \param db db to save array to.
> + * \retval 0 Success.
> + * \retval -1 Error.

8. Use @, not \.

9. You should not have this function. Ids must be stored in Vdbe.

> + */
> +static inline int
> +move_generated_ids_in_db(sqlite3 *db)
> +{
> +	struct txn *txn = in_txn();
> +	if (txn == NULL)
> +		return 0;
> +	uint64_t size = txn->generated_ids.size *
> +			sizeof(*txn->generated_ids.array);
> +	db->generated_ids_count = txn->generated_ids.size;
> +	db->generated_ids_array = malloc(size);
> +	if (db->generated_ids_array == NULL)
> +		return -1;
> +	memcpy(db->generated_ids_array, txn->generated_ids.array, size);
> +	return 0;
> +}
> +
> +/*
>    * This routine is called the when a VDBE tries to halt.  If the VDBE
>    * has made changes and is in autocommit mode, then commit those
>    * changes.  If a rollback is needed, then do the rollback.
10. I still think that we should not realloc a huge monolith array of ids.
My proposal is to use a list of small arrays. When a last chunk in the list
becomes full, we allocate a new chunk, append it to the list and use it for
next ids. But you can discuss it with Kirill if you do not agree.

  reply	other threads:[~2018-09-20 16:36 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-17 17:23 [tarantool-patches] " imeevma
2018-09-20 16:36 ` Vladislav Shpilevoy [this message]
2018-09-26 16:08   ` [tarantool-patches] " Imeev Mergen

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=b255ff22-f157-903c-8a79-325f68f839f3@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=imeevma@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='[tarantool-patches] Re: [PATCH v4 1/1] sql: return all generated ids via IPROTO' \
    /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