Tarantool development patches archive
 help / color / mirror / Atom feed
From: Nikita Pettik <korablev@tarantool.org>
To: imeevma@tarantool.org
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v4 4/5] sql: change implicit cast for assignment
Date: Mon, 13 Jul 2020 14:42:55 +0000	[thread overview]
Message-ID: <20200713144255.GD15396@tarantool.org> (raw)
In-Reply-To: <965068a9fb4a38da3c64e15ab531df57f879ec14.1594618005.git.imeevma@gmail.com>

On 13 Jul 08:33, imeevma@tarantool.org wrote:
> +
>   * Synopsis: type(r[P1@P2])
>   *
> - * Apply types to a range of P2 registers starting with P1.
> - *
> - * P4 is a string that is P2 characters long. The nth character of the
> - * string indicates the column type that should be used for the nth
> - * memory cell in the range.
> + * Check that types of P2 registers starting from register P1 are
> + * compatible with given field types in P4. If the MEM_type of the
> + * value and the given type are incompatible according to
> + * field_mp_plain_type_is_compatible(), but both are numeric,
> + * this opcode attempts to convert the value to the type.
>   */
>  case OP_ApplyType: {
>  	enum field_type *types = pOp->p4.types;
> @@ -2762,7 +2900,13 @@ case OP_ApplyType: {
>  	while((type = *(types++)) != field_type_MAX) {
>  		assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
>  		assert(memIsValid(pIn1));
> -		if (mem_apply_type(pIn1, type) != 0) {
> +		if (mem_is_type_compatible(pIn1, type)) {
> +			pIn1++;
> +			continue;
> +		}
> +		if (!mp_type_is_numeric(mem_mp_type(pIn1)) ||
> +		    !sql_type_is_numeric(type) ||
> +		    mem_convert_to_numeric(pIn1, type, false) != 0) {

Consider refactoring:

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 863f38f5d..41a4750da 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2900,19 +2900,23 @@ case OP_ApplyType: {
        while((type = *(types++)) != field_type_MAX) {
                assert(pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)]);
                assert(memIsValid(pIn1));
-               if (mem_is_type_compatible(pIn1, type)) {
-                       pIn1++;
-                       continue;
-               }
-               if (!mp_type_is_numeric(mem_mp_type(pIn1)) ||
-                   !sql_type_is_numeric(type) ||
-                   mem_convert_to_numeric(pIn1, type, false) != 0) {
-                       diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
-                                sql_value_to_diag_str(pIn1),
-                                field_type_strs[type]);
-                       goto abort_due_to_error;
+               if (!mem_is_type_compatible(pIn1, type)) {
+                       /* Implicit cast is allowed only to numeric type. */
+                       if (!sql_type_is_numeric(type))
+                               goto type_mismatch;
+                       /* Implicit cast is allowed only from numeric type. */
+                       if (!mp_type_is_numeric(mem_mp_type(pIn1)))
+                               goto type_mismatch;
+                       /* Try to convert numeric-to-numeric. */
+                       if (mem_convert_to_numeric(pIn1, type, false) != 0)
+                               goto type_mismatch;
                }
                pIn1++;
+               continue;
+type_mismatch:
+               diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+                        sql_value_to_diag_str(pIn1), field_type_strs[type]);
+               goto abort_due_to_error;
        }
        break;
 }

Otherwise LGTM

>  			diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
>  				 sql_value_to_diag_str(pIn1),
>  				 field_type_strs[type]);
> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> index 44c27bdb7..ad46ab129 100644
> --- a/src/box/sql/vdbeInt.h
> +++ b/src/box/sql/vdbeInt.h
> @@ -566,6 +566,10 @@ mem_mp_type(struct Mem *mem);
>   */
>  #define mp_type_is_bloblike(X) ((X) == MP_BIN || (X) == MP_ARRAY || (X) == MP_MAP)
>  
> +/** Return TRUE if MP_type of X is numeric, FALSE otherwise. */
> +#define mp_type_is_numeric(X) ((X) == MP_INT || (X) == MP_UINT ||\
> +			       (X) == MP_DOUBLE)

  reply	other threads:[~2020-07-13 14:42 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-13  5:32 [Tarantool-patches] [PATCH v4 0/5] Change " imeevma
2020-07-13  5:32 ` [Tarantool-patches] [PATCH v4 1/5] sql: set field_type in mem_set_*() functions imeevma
2020-07-13 10:36   ` Nikita Pettik
2020-07-13  5:33 ` [Tarantool-patches] [PATCH v4 2/5] sql: move diag setting to sql_func_by_signature() imeevma
2020-07-13 10:58   ` Nikita Pettik
2020-07-13  5:33 ` [Tarantool-patches] [PATCH v4 3/5] sql: check number of arguments in sql_func_by_signature() imeevma
2020-07-13 12:21   ` Nikita Pettik
2020-07-13  5:33 ` [Tarantool-patches] [PATCH v4 4/5] sql: change implicit cast for assignment imeevma
2020-07-13 14:42   ` Nikita Pettik [this message]
2020-07-13  5:33 ` [Tarantool-patches] [PATCH v4 5/5] sql: properly check arguments of functions imeevma
2020-07-13 14:56   ` 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=20200713144255.GD15396@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=imeevma@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v4 4/5] sql: change implicit cast for assignment' \
    /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