Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: imeevma@tarantool.org
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v1 1/1] sql: introduce literals for DECIMAL
Date: Sat, 9 Oct 2021 00:32:37 +0200	[thread overview]
Message-ID: <6d07c477-7d5c-1031-33e3-5d09b978b8f4@tarantool.org> (raw)
In-Reply-To: <7ac4a555ec1237159e423fec7fd6d4df6ac65d3b.1633354455.git.imeevma@gmail.com>

Thanks for the patch!

See 5 comments below.

> diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
> index ee21c1ede..2b156284c 100644
> --- a/src/box/sql/expr.c
> +++ b/src/box/sql/expr.c
> @@ -3286,6 +3286,27 @@ codeReal(Vdbe * v, const char *z, int negateFlag, int iMem)
>  	}
>  }
>  
> +static void
> +expr_code_dec(struct Parse *parser, struct Expr *expr, bool is_neg, int reg)
> +{
> +	const char *str = expr->u.zToken;
> +	assert(str != NULL);
> +	decimal_t dec;
> +	if (is_neg)
> +		str = tt_sprintf("-%s", str);
> +	if (decimal_from_string(&dec, str) == NULL) {
> +		parser->is_aborted = true;
> +		return;
> +	}
> +	char *value = sqlDbMallocRawNN(sql_get(), sizeof(dec));
> +	if (value == NULL) {
> +		parser->is_aborted = true;
> +		return;
> +	}
> +	memcpy(value, &dec, sizeof(dec));
> +	sqlVdbeAddOp4(parser->pVdbe, OP_Decimal, 0, reg, 0, value, P4_DEC);

1. memcpy() is not needed. For the positive case for sure. For the
negative too, but I didn't bench what is faster - tt_sprintf() or
decimal_minus().

====================
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 2b156284c..cce0e5030 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -3291,20 +3291,22 @@ expr_code_dec(struct Parse *parser, struct Expr *expr, bool is_neg, int reg)
 {
 	const char *str = expr->u.zToken;
 	assert(str != NULL);
-	decimal_t dec;
-	if (is_neg)
-		str = tt_sprintf("-%s", str);
-	if (decimal_from_string(&dec, str) == NULL) {
-		parser->is_aborted = true;
-		return;
-	}
-	char *value = sqlDbMallocRawNN(sql_get(), sizeof(dec));
-	if (value == NULL) {
-		parser->is_aborted = true;
-		return;
+	decimal_t *value = sqlDbMallocRawNN(sql_get(), sizeof(*value));
+	if (value == NULL)
+		goto error;
+	if (is_neg) {
+		decimal_t dec;
+		if (decimal_from_string(&dec, str) == NULL)
+			goto error;
+		decimal_minus(value, &dec);
+	} else if (decimal_from_string(value, str) == NULL) {
+		goto error;
 	}
-	memcpy(value, &dec, sizeof(dec));
 	sqlVdbeAddOp4(parser->pVdbe, OP_Decimal, 0, reg, 0, value, P4_DEC);
+	return;
+error:
+	sqlDbFree(sql_get(), value);
+	parser->is_aborted = true;
 }
====================

> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 44533fb3e..747fb608b 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -804,6 +804,17 @@ case OP_Real: {            /* same as TK_FLOAT, out2 */
>  	break;
>  }
>  
> +/* Opcode: Decimal * P2 * P4 *
> + * Synopsis: r[P2]=P4
> + *
> + * P4 is a pointer to a DECIMAL value. Write that value into register P2.
> + */
> +case OP_Decimal: {            /* same as TK_DECIMAL, out2 */

2. Lets stick to our code style when write comments:
start them with /** out of functions, and not write them
on the same line as code.

> +	pOut = vdbe_prepare_null_out(p, pOp->p2);
> +	mem_set_dec(pOut, pOp->p4.dec);
> +	break;
> +}
> +
>  /* Opcode: String8 * P2 * P4 *
>   * Synopsis: r[P2]='P4'
>   *
> diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
> index e40a1a0b3..121b86029 100644
> --- a/src/box/sql/vdbe.h
> +++ b/src/box/sql/vdbe.h
> @@ -97,6 +97,8 @@ struct VdbeOp {
>  		 * Information about ephemeral space field types and key parts.
>  		 */

3. Not related to the patch, but wtf P4_REAL is stored by a
pointer? 'double' is 8 bytes, it fits perfectly into this
union. But instead it is copied onto the heap?! Could you
please file a ticket to fix that and store it by value?

>  		struct sql_space_info *space_info;
> +		/** P4 contains address of decimal. */
> +		decimal_t *dec;
>  	} p4;
> diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
> index 68d2ae585..5f8e885ce 100755
> --- a/test/sql-tap/cast.test.lua
> +++ b/test/sql-tap/cast.test.lua
> @@ -962,7 +962,7 @@ test:do_catchsql_test(
>  test:do_catchsql_test(
>      "cast-6.2.3",
>      [[
> -        SELECT CAST(1.5 AS BOOLEAN);
> +        SELECT CAST(15e-1 AS BOOLEAN);

4. It might be more readable to use e0 ending everywhere.
The numbers otherwise become unreadable.

5. Please, add some tests for so large numbers that only
DECIMAL would fit them. To prove that VDBE really uses
decimal for them.

Also need to ensure typeof() returns correct types depending
on the literal.

  reply	other threads:[~2021-10-08 22:32 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-04 13:35 Mergen Imeev via Tarantool-patches
2021-10-08 22:32 ` Vladislav Shpilevoy via Tarantool-patches [this message]
2021-10-19  8:49   ` Mergen Imeev via Tarantool-patches
2021-10-24 15:50     ` Vladislav Shpilevoy via Tarantool-patches
2021-10-26 10:27 Mergen Imeev via Tarantool-patches
2021-11-03  9:55 ` Kirill Yukhin via Tarantool-patches

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=6d07c477-7d5c-1031-33e3-5d09b978b8f4@tarantool.org \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=imeevma@tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v1 1/1] sql: introduce literals for DECIMAL' \
    /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