After this patch, DECIMAL values can be bound like any other supported by SQL values. Closes #4717 --- https://github.com/tarantool/tarantool/issues/4717 https://github.com/tarantool/tarantool/tree/imeevma/gh-4717-binding-for-decimal .../unreleased/gh-4717-binding-for-decimal.md | 4 ++++ src/box/bind.c | 6 +++-- src/box/bind.h | 2 ++ src/box/lua/execute.c | 4 ++++ src/box/sql/mem.c | 2 +- src/box/sql/mem.h | 2 +- src/box/sql/sqlInt.h | 4 ++++ src/box/sql/vdbeapi.c | 10 ++++++++ test/sql-tap/decimal.test.lua | 23 ++++++++++++++++++- 9 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/gh-4717-binding-for-decimal.md diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md new file mode 100644 index 000000000..9ffd64272 --- /dev/null +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md @@ -0,0 +1,4 @@ +## feature/sql + +* Now DECIMAL values can be binded in SQL (gh-4717). + diff --git a/src/box/bind.c b/src/box/bind.c index 734f65186..58fff0b98 100644 --- a/src/box/bind.c +++ b/src/box/bind.c @@ -192,8 +192,10 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p, return sql_bind_blob64(stmt, pos, (const void *) p->s, p->bytes, SQL_STATIC); case MP_EXT: - assert(p->ext_type == MP_UUID); - return sql_bind_uuid(stmt, pos, &p->uuid); + assert(p->ext_type == MP_UUID || p->ext_type == MP_DECIMAL); + if (p->ext_type == MP_UUID) + return sql_bind_uuid(stmt, pos, &p->uuid); + return sql_bind_dec(stmt, pos, &p->dec); default: unreachable(); } diff --git a/src/box/bind.h b/src/box/bind.h index 143f010ce..a88cc105b 100644 --- a/src/box/bind.h +++ b/src/box/bind.h @@ -40,6 +40,7 @@ extern "C" { #include <stdlib.h> #include "msgpuck.h" +#include "lua/decimal.h" #include "uuid/tt_uuid.h" #include "mp_extension_types.h" @@ -72,6 +73,7 @@ struct sql_bind { /** For string or blob. */ const char *s; struct tt_uuid uuid; + decimal_t dec; }; }; diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index 62ccaf3f1..777db82cb 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -375,6 +375,10 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) bind->uuid = *field.uuidval; break; } + if (field.ext_type == MP_DECIMAL) { + bind->dec = *field.decval; + break; + } diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA", sql_bind_name(bind)); return -1; diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 0aca76112..2bf78e625 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -293,7 +293,7 @@ mem_set_double(struct Mem *mem, double value) } void -mem_set_dec(struct Mem *mem, decimal_t *d) +mem_set_dec(struct Mem *mem, const decimal_t *d) { mem_clear(mem); mem->u.d = *d; diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h index 543944b80..0da45b8af 100644 --- a/src/box/sql/mem.h +++ b/src/box/sql/mem.h @@ -312,7 +312,7 @@ mem_set_uuid(struct Mem *mem, const struct tt_uuid *uuid); /** Clear MEM and set it to DECIMAL. */ void -mem_set_dec(struct Mem *mem, decimal_t *dec); +mem_set_dec(struct Mem *mem, const decimal_t *dec); /** Clear MEM and set it to STRING. The string belongs to another object. */ void diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index d78076868..5d622bfad 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -75,6 +75,7 @@ #include "box/sql.h" #include "box/txn.h" #include "trivia/util.h" +#include "lua/decimal.h" /* * These #defines should enable >2GB file support on POSIX if the @@ -639,6 +640,9 @@ sql_bind_zeroblob64(sql_stmt *, int, int sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid); +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec); + /** * Return the number of wildcards that should be bound to. */ diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 8031ee0dc..77df0e4cc 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -850,6 +850,16 @@ sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid) return 0; } +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec) +{ + struct Vdbe *p = (struct Vdbe *)stmt; + if (vdbeUnbind(p, i) != 0 || sql_bind_type(p, i, "decimal") != 0) + return -1; + mem_set_dec(&p->aVar[i - 1], dec); + return 0; +} + int sql_bind_parameter_count(const struct sql_stmt *stmt) { diff --git a/test/sql-tap/decimal.test.lua b/test/sql-tap/decimal.test.lua index 69288d696..2455bab61 100755 --- a/test/sql-tap/decimal.test.lua +++ b/test/sql-tap/decimal.test.lua @@ -3,7 +3,7 @@ local build_path = os.getenv("BUILDDIR") package.cpath = build_path..'/test/sql-tap/?.so;'..build_path..'/test/sql-tap/?.dylib;'..package.cpath local test = require("sqltester") -test:plan(101) +test:plan(104) local dec = require("decimal") local dec1 = dec.new("111") @@ -938,6 +938,27 @@ test:do_catchsql_test( 1, "Inconsistent types: expected string or varbinary got decimal(111)" }) +-- Make sure that DECIMAL value can be binded. +test:do_test( + "dec-16-1", + function() + return box.execute([[SELECT ?;]], {dec1}).rows[1][1] + end, + dec1) +test:do_test( + "dec-16-2", + function() + return box.execute([[SELECT $2;]], {123, dec2}).rows[1][1] + end, + dec2) + +test:do_test( + "dec-16-3", + function() + return box.execute([[SELECT :two;]], {{[":two"] = dec3}}).rows[1][1] + end, + dec3) + test:execsql([[ DROP TRIGGER t; DROP VIEW v; -- 2.25.1
Thanks for the patch! See 3 comments below. > diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md > new file mode 100644 > index 000000000..9ffd64272 > --- /dev/null > +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md > @@ -0,0 +1,4 @@ > +## feature/sql > + > +* Now DECIMAL values can be binded in SQL (gh-4717). 1. binded -> bound. > diff --git a/src/box/bind.h b/src/box/bind.h > index 143f010ce..a88cc105b 100644 > --- a/src/box/bind.h > +++ b/src/box/bind.h > @@ -40,6 +40,7 @@ extern "C" { > #include <stdlib.h> > > #include "msgpuck.h" > +#include "lua/decimal.h" 2. Why do you need Lua in the non-Lua folder? > #include "uuid/tt_uuid.h" > #include "mp_extension_types.h" > > diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h > index d78076868..5d622bfad 100644 > --- a/src/box/sql/sqlInt.h > +++ b/src/box/sql/sqlInt.h > @@ -75,6 +75,7 @@ > #include "box/sql.h" > #include "box/txn.h" > #include "trivia/util.h" > +#include "lua/decimal.h" 3. Ditto.
Thank you for the review! My answers, diff and new patch below. On Thu, Aug 26, 2021 at 10:51:07PM +0200, Vladislav Shpilevoy wrote: > Thanks for the patch! > > See 3 comments below. > > > diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md > > new file mode 100644 > > index 000000000..9ffd64272 > > --- /dev/null > > +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md > > @@ -0,0 +1,4 @@ > > +## feature/sql > > + > > +* Now DECIMAL values can be binded in SQL (gh-4717). > > 1. binded -> bound. > Fixed. > > diff --git a/src/box/bind.h b/src/box/bind.h > > index 143f010ce..a88cc105b 100644 > > --- a/src/box/bind.h > > +++ b/src/box/bind.h > > @@ -40,6 +40,7 @@ extern "C" { > > #include <stdlib.h> > > > > #include "msgpuck.h" > > +#include "lua/decimal.h" > > 2. Why do you need Lua in the non-Lua folder? > Replaced by "decimal.h". > > #include "uuid/tt_uuid.h" > > #include "mp_extension_types.h" > > > > diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h > > index d78076868..5d622bfad 100644 > > --- a/src/box/sql/sqlInt.h > > +++ b/src/box/sql/sqlInt.h > > @@ -75,6 +75,7 @@ > > #include "box/sql.h" > > #include "box/txn.h" > > #include "trivia/util.h" > > +#include "lua/decimal.h" > > 3. Ditto. Same. Diff: diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md index 9ffd64272..3612e287d 100644 --- a/changelogs/unreleased/gh-4717-binding-for-decimal.md +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md @@ -1,4 +1,3 @@ ## feature/sql -* Now DECIMAL values can be binded in SQL (gh-4717). - +* Now DECIMAL values can be bound in SQL (gh-4717). diff --git a/src/box/bind.h b/src/box/bind.h index a88cc105b..1ab8ea72d 100644 --- a/src/box/bind.h +++ b/src/box/bind.h @@ -40,7 +40,7 @@ extern "C" { #include <stdlib.h> #include "msgpuck.h" -#include "lua/decimal.h" +#include "decimal.h" #include "uuid/tt_uuid.h" #include "mp_extension_types.h" diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index 5d622bfad..2e250dc29 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -75,7 +75,8 @@ #include "box/sql.h" #include "box/txn.h" #include "trivia/util.h" -#include "lua/decimal.h" + +#include "decimal.h" /* * These #defines should enable >2GB file support on POSIX if the diff --git a/test/sql-tap/decimal.test.lua b/test/sql-tap/decimal.test.lua index 2455bab61..d422533d6 100755 --- a/test/sql-tap/decimal.test.lua +++ b/test/sql-tap/decimal.test.lua @@ -938,7 +938,7 @@ test:do_catchsql_test( 1, "Inconsistent types: expected string or varbinary got decimal(111)" }) --- Make sure that DECIMAL value can be binded. +-- Make sure that DECIMAL value can be bound. test:do_test( "dec-16-1", function() New patch: commit 2ec28c37f9431e3fb2fbb2a8772e4eac26c1ace9 Author: Mergen Imeev <imeevma@gmail.com> Date: Thu Aug 26 15:52:13 2021 +0300 sql: allow to bind DECIMAL values After this patch, DECIMAL values can be bound like any other supported by SQL values. Closes #4717 diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md new file mode 100644 index 000000000..3612e287d --- /dev/null +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md @@ -0,0 +1,3 @@ +## feature/sql + +* Now DECIMAL values can be bound in SQL (gh-4717). diff --git a/src/box/bind.c b/src/box/bind.c index 734f65186..58fff0b98 100644 --- a/src/box/bind.c +++ b/src/box/bind.c @@ -192,8 +192,10 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p, return sql_bind_blob64(stmt, pos, (const void *) p->s, p->bytes, SQL_STATIC); case MP_EXT: - assert(p->ext_type == MP_UUID); - return sql_bind_uuid(stmt, pos, &p->uuid); + assert(p->ext_type == MP_UUID || p->ext_type == MP_DECIMAL); + if (p->ext_type == MP_UUID) + return sql_bind_uuid(stmt, pos, &p->uuid); + return sql_bind_dec(stmt, pos, &p->dec); default: unreachable(); } diff --git a/src/box/bind.h b/src/box/bind.h index 143f010ce..1ab8ea72d 100644 --- a/src/box/bind.h +++ b/src/box/bind.h @@ -40,6 +40,7 @@ extern "C" { #include <stdlib.h> #include "msgpuck.h" +#include "decimal.h" #include "uuid/tt_uuid.h" #include "mp_extension_types.h" @@ -72,6 +73,7 @@ struct sql_bind { /** For string or blob. */ const char *s; struct tt_uuid uuid; + decimal_t dec; }; }; diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index 62ccaf3f1..777db82cb 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -375,6 +375,10 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) bind->uuid = *field.uuidval; break; } + if (field.ext_type == MP_DECIMAL) { + bind->dec = *field.decval; + break; + } diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA", sql_bind_name(bind)); return -1; diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 0aca76112..2bf78e625 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -293,7 +293,7 @@ mem_set_double(struct Mem *mem, double value) } void -mem_set_dec(struct Mem *mem, decimal_t *d) +mem_set_dec(struct Mem *mem, const decimal_t *d) { mem_clear(mem); mem->u.d = *d; diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h index 543944b80..0da45b8af 100644 --- a/src/box/sql/mem.h +++ b/src/box/sql/mem.h @@ -312,7 +312,7 @@ mem_set_uuid(struct Mem *mem, const struct tt_uuid *uuid); /** Clear MEM and set it to DECIMAL. */ void -mem_set_dec(struct Mem *mem, decimal_t *dec); +mem_set_dec(struct Mem *mem, const decimal_t *dec); /** Clear MEM and set it to STRING. The string belongs to another object. */ void diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index d78076868..2e250dc29 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -76,6 +76,8 @@ #include "box/txn.h" #include "trivia/util.h" +#include "decimal.h" + /* * These #defines should enable >2GB file support on POSIX if the * underlying operating system supports it. If the OS lacks @@ -639,6 +641,9 @@ sql_bind_zeroblob64(sql_stmt *, int, int sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid); +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec); + /** * Return the number of wildcards that should be bound to. */ diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 8031ee0dc..77df0e4cc 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -850,6 +850,16 @@ sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid) return 0; } +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec) +{ + struct Vdbe *p = (struct Vdbe *)stmt; + if (vdbeUnbind(p, i) != 0 || sql_bind_type(p, i, "decimal") != 0) + return -1; + mem_set_dec(&p->aVar[i - 1], dec); + return 0; +} + int sql_bind_parameter_count(const struct sql_stmt *stmt) { diff --git a/test/sql-tap/decimal.test.lua b/test/sql-tap/decimal.test.lua index 69288d696..d422533d6 100755 --- a/test/sql-tap/decimal.test.lua +++ b/test/sql-tap/decimal.test.lua @@ -3,7 +3,7 @@ local build_path = os.getenv("BUILDDIR") package.cpath = build_path..'/test/sql-tap/?.so;'..build_path..'/test/sql-tap/?.dylib;'..package.cpath local test = require("sqltester") -test:plan(101) +test:plan(104) local dec = require("decimal") local dec1 = dec.new("111") @@ -938,6 +938,27 @@ test:do_catchsql_test( 1, "Inconsistent types: expected string or varbinary got decimal(111)" }) +-- Make sure that DECIMAL value can be bound. +test:do_test( + "dec-16-1", + function() + return box.execute([[SELECT ?;]], {dec1}).rows[1][1] + end, + dec1) +test:do_test( + "dec-16-2", + function() + return box.execute([[SELECT $2;]], {123, dec2}).rows[1][1] + end, + dec2) + +test:do_test( + "dec-16-3", + function() + return box.execute([[SELECT :two;]], {{[":two"] = dec3}}).rows[1][1] + end, + dec3) + test:execsql([[ DROP TRIGGER t; DROP VIEW v;
You didn't push the new version.
On Fri, Aug 27, 2021 at 11:32:19PM +0200, Vladislav Shpilevoy wrote:
> You didn't push the new version.
Hi! Sorry, fixed.
Hi! Thanks for the fixes! LGTM.
After this patch, DECIMAL values can be bound like any other supported by SQL values. Closes #4717 --- https://github.com/tarantool/tarantool/issues/4717 https://github.com/tarantool/tarantool/tree/imeevma/gh-4717-binding-for-decimal .../unreleased/gh-4717-binding-for-decimal.md | 3 +++ src/box/bind.c | 6 +++-- src/box/bind.h | 2 ++ src/box/lua/execute.c | 4 ++++ src/box/sql/mem.c | 2 +- src/box/sql/mem.h | 2 +- src/box/sql/sqlInt.h | 5 ++++ src/box/sql/vdbeapi.c | 10 ++++++++ test/sql-tap/decimal.test.lua | 23 ++++++++++++++++++- 9 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/gh-4717-binding-for-decimal.md diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md b/changelogs/unreleased/gh-4717-binding-for-decimal.md new file mode 100644 index 000000000..3612e287d --- /dev/null +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md @@ -0,0 +1,3 @@ +## feature/sql + +* Now DECIMAL values can be bound in SQL (gh-4717). diff --git a/src/box/bind.c b/src/box/bind.c index 734f65186..58fff0b98 100644 --- a/src/box/bind.c +++ b/src/box/bind.c @@ -192,8 +192,10 @@ sql_bind_column(struct sql_stmt *stmt, const struct sql_bind *p, return sql_bind_blob64(stmt, pos, (const void *) p->s, p->bytes, SQL_STATIC); case MP_EXT: - assert(p->ext_type == MP_UUID); - return sql_bind_uuid(stmt, pos, &p->uuid); + assert(p->ext_type == MP_UUID || p->ext_type == MP_DECIMAL); + if (p->ext_type == MP_UUID) + return sql_bind_uuid(stmt, pos, &p->uuid); + return sql_bind_dec(stmt, pos, &p->dec); default: unreachable(); } diff --git a/src/box/bind.h b/src/box/bind.h index 143f010ce..1ab8ea72d 100644 --- a/src/box/bind.h +++ b/src/box/bind.h @@ -40,6 +40,7 @@ extern "C" { #include <stdlib.h> #include "msgpuck.h" +#include "decimal.h" #include "uuid/tt_uuid.h" #include "mp_extension_types.h" @@ -72,6 +73,7 @@ struct sql_bind { /** For string or blob. */ const char *s; struct tt_uuid uuid; + decimal_t dec; }; }; diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c index 62ccaf3f1..777db82cb 100644 --- a/src/box/lua/execute.c +++ b/src/box/lua/execute.c @@ -375,6 +375,10 @@ lua_sql_bind_decode(struct lua_State *L, struct sql_bind *bind, int idx, int i) bind->uuid = *field.uuidval; break; } + if (field.ext_type == MP_DECIMAL) { + bind->dec = *field.decval; + break; + } diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA", sql_bind_name(bind)); return -1; diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 4c40f15dc..24de26548 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -293,7 +293,7 @@ mem_set_double(struct Mem *mem, double value) } void -mem_set_dec(struct Mem *mem, decimal_t *d) +mem_set_dec(struct Mem *mem, const decimal_t *d) { mem_clear(mem); mem->u.d = *d; diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h index 543944b80..0da45b8af 100644 --- a/src/box/sql/mem.h +++ b/src/box/sql/mem.h @@ -312,7 +312,7 @@ mem_set_uuid(struct Mem *mem, const struct tt_uuid *uuid); /** Clear MEM and set it to DECIMAL. */ void -mem_set_dec(struct Mem *mem, decimal_t *dec); +mem_set_dec(struct Mem *mem, const decimal_t *dec); /** Clear MEM and set it to STRING. The string belongs to another object. */ void diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index d78076868..2e250dc29 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -76,6 +76,8 @@ #include "box/txn.h" #include "trivia/util.h" +#include "decimal.h" + /* * These #defines should enable >2GB file support on POSIX if the * underlying operating system supports it. If the OS lacks @@ -639,6 +641,9 @@ sql_bind_zeroblob64(sql_stmt *, int, int sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid); +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec); + /** * Return the number of wildcards that should be bound to. */ diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c index 8031ee0dc..77df0e4cc 100644 --- a/src/box/sql/vdbeapi.c +++ b/src/box/sql/vdbeapi.c @@ -850,6 +850,16 @@ sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid *uuid) return 0; } +int +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec) +{ + struct Vdbe *p = (struct Vdbe *)stmt; + if (vdbeUnbind(p, i) != 0 || sql_bind_type(p, i, "decimal") != 0) + return -1; + mem_set_dec(&p->aVar[i - 1], dec); + return 0; +} + int sql_bind_parameter_count(const struct sql_stmt *stmt) { diff --git a/test/sql-tap/decimal.test.lua b/test/sql-tap/decimal.test.lua index 69288d696..d422533d6 100755 --- a/test/sql-tap/decimal.test.lua +++ b/test/sql-tap/decimal.test.lua @@ -3,7 +3,7 @@ local build_path = os.getenv("BUILDDIR") package.cpath = build_path..'/test/sql-tap/?.so;'..build_path..'/test/sql-tap/?.dylib;'..package.cpath local test = require("sqltester") -test:plan(101) +test:plan(104) local dec = require("decimal") local dec1 = dec.new("111") @@ -938,6 +938,27 @@ test:do_catchsql_test( 1, "Inconsistent types: expected string or varbinary got decimal(111)" }) +-- Make sure that DECIMAL value can be bound. +test:do_test( + "dec-16-1", + function() + return box.execute([[SELECT ?;]], {dec1}).rows[1][1] + end, + dec1) +test:do_test( + "dec-16-2", + function() + return box.execute([[SELECT $2;]], {123, dec2}).rows[1][1] + end, + dec2) + +test:do_test( + "dec-16-3", + function() + return box.execute([[SELECT :two;]], {{[":two"] = dec3}}).rows[1][1] + end, + dec3) + test:execsql([[ DROP TRIGGER t; DROP VIEW v; -- 2.25.1
LGTM, thanks!
Timur
> -----Original Message-----
> From: imeevma@tarantool.org <imeevma@tarantool.org>
> Sent: Tuesday, August 31, 2021 11:25 AM
> To: tsafin@tarantool.org
> Cc: tarantool-patches@dev.tarantool.org
> Subject: [PATCH v1 1/1] sql: allow to bind DECIMAL values
>
> After this patch, DECIMAL values can be bound like any other
> supported
> by SQL values.
>
> Closes #4717
> ---
> https://github.com/tarantool/tarantool/issues/4717
> https://github.com/tarantool/tarantool/tree/imeevma/gh-4717-binding-
> for-decimal
>
> .../unreleased/gh-4717-binding-for-decimal.md | 3 +++
> src/box/bind.c | 6 +++--
> src/box/bind.h | 2 ++
> src/box/lua/execute.c | 4 ++++
> src/box/sql/mem.c | 2 +-
> src/box/sql/mem.h | 2 +-
> src/box/sql/sqlInt.h | 5 ++++
> src/box/sql/vdbeapi.c | 10 ++++++++
> test/sql-tap/decimal.test.lua | 23
> ++++++++++++++++++-
> 9 files changed, 52 insertions(+), 5 deletions(-)
> create mode 100644 changelogs/unreleased/gh-4717-binding-for-
> decimal.md
>
> diff --git a/changelogs/unreleased/gh-4717-binding-for-decimal.md
> b/changelogs/unreleased/gh-4717-binding-for-decimal.md
> new file mode 100644
> index 000000000..3612e287d
> --- /dev/null
> +++ b/changelogs/unreleased/gh-4717-binding-for-decimal.md
> @@ -0,0 +1,3 @@
> +## feature/sql
> +
> +* Now DECIMAL values can be bound in SQL (gh-4717).
> diff --git a/src/box/bind.c b/src/box/bind.c
> index 734f65186..58fff0b98 100644
> --- a/src/box/bind.c
> +++ b/src/box/bind.c
> @@ -192,8 +192,10 @@ sql_bind_column(struct sql_stmt *stmt, const
> struct sql_bind *p,
> return sql_bind_blob64(stmt, pos, (const void *) p->s, p-
> >bytes,
> SQL_STATIC);
> case MP_EXT:
> - assert(p->ext_type == MP_UUID);
> - return sql_bind_uuid(stmt, pos, &p->uuid);
> + assert(p->ext_type == MP_UUID || p->ext_type ==
> MP_DECIMAL);
> + if (p->ext_type == MP_UUID)
> + return sql_bind_uuid(stmt, pos, &p->uuid);
> + return sql_bind_dec(stmt, pos, &p->dec);
> default:
> unreachable();
> }
> diff --git a/src/box/bind.h b/src/box/bind.h
> index 143f010ce..1ab8ea72d 100644
> --- a/src/box/bind.h
> +++ b/src/box/bind.h
> @@ -40,6 +40,7 @@ extern "C" {
> #include <stdlib.h>
>
> #include "msgpuck.h"
> +#include "decimal.h"
> #include "uuid/tt_uuid.h"
> #include "mp_extension_types.h"
>
> @@ -72,6 +73,7 @@ struct sql_bind {
> /** For string or blob. */
> const char *s;
> struct tt_uuid uuid;
> + decimal_t dec;
> };
> };
>
> diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
> index 62ccaf3f1..777db82cb 100644
> --- a/src/box/lua/execute.c
> +++ b/src/box/lua/execute.c
> @@ -375,6 +375,10 @@ lua_sql_bind_decode(struct lua_State *L, struct
> sql_bind *bind, int idx, int i)
> bind->uuid = *field.uuidval;
> break;
> }
> + if (field.ext_type == MP_DECIMAL) {
> + bind->dec = *field.decval;
> + break;
> + }
> diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA",
> sql_bind_name(bind));
> return -1;
> diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
> index 4c40f15dc..24de26548 100644
> --- a/src/box/sql/mem.c
> +++ b/src/box/sql/mem.c
> @@ -293,7 +293,7 @@ mem_set_double(struct Mem *mem, double value)
> }
>
> void
> -mem_set_dec(struct Mem *mem, decimal_t *d)
> +mem_set_dec(struct Mem *mem, const decimal_t *d)
> {
> mem_clear(mem);
> mem->u.d = *d;
> diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h
> index 543944b80..0da45b8af 100644
> --- a/src/box/sql/mem.h
> +++ b/src/box/sql/mem.h
> @@ -312,7 +312,7 @@ mem_set_uuid(struct Mem *mem, const struct
> tt_uuid *uuid);
>
> /** Clear MEM and set it to DECIMAL. */
> void
> -mem_set_dec(struct Mem *mem, decimal_t *dec);
> +mem_set_dec(struct Mem *mem, const decimal_t *dec);
>
> /** Clear MEM and set it to STRING. The string belongs to another
> object. */
> void
> diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
> index d78076868..2e250dc29 100644
> --- a/src/box/sql/sqlInt.h
> +++ b/src/box/sql/sqlInt.h
> @@ -76,6 +76,8 @@
> #include "box/txn.h"
> #include "trivia/util.h"
>
> +#include "decimal.h"
> +
> /*
> * These #defines should enable >2GB file support on POSIX if the
> * underlying operating system supports it. If the OS lacks
> @@ -639,6 +641,9 @@ sql_bind_zeroblob64(sql_stmt *, int,
> int
> sql_bind_uuid(struct sql_stmt *stmt, int i, const struct tt_uuid
> *uuid);
>
> +int
> +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec);
> +
> /**
> * Return the number of wildcards that should be bound to.
> */
> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
> index 8031ee0dc..77df0e4cc 100644
> --- a/src/box/sql/vdbeapi.c
> +++ b/src/box/sql/vdbeapi.c
> @@ -850,6 +850,16 @@ sql_bind_uuid(struct sql_stmt *stmt, int i,
> const struct tt_uuid *uuid)
> return 0;
> }
>
> +int
> +sql_bind_dec(struct sql_stmt *stmt, int i, const decimal_t *dec)
> +{
> + struct Vdbe *p = (struct Vdbe *)stmt;
> + if (vdbeUnbind(p, i) != 0 || sql_bind_type(p, i, "decimal") !=
> 0)
> + return -1;
> + mem_set_dec(&p->aVar[i - 1], dec);
> + return 0;
> +}
> +
> int
> sql_bind_parameter_count(const struct sql_stmt *stmt)
> {
> diff --git a/test/sql-tap/decimal.test.lua b/test/sql-
> tap/decimal.test.lua
> index 69288d696..d422533d6 100755
> --- a/test/sql-tap/decimal.test.lua
> +++ b/test/sql-tap/decimal.test.lua
> @@ -3,7 +3,7 @@ local build_path = os.getenv("BUILDDIR")
> package.cpath = build_path..'/test/sql-
> tap/?.so;'..build_path..'/test/sql-tap/?.dylib;'..package.cpath
>
> local test = require("sqltester")
> -test:plan(101)
> +test:plan(104)
>
> local dec = require("decimal")
> local dec1 = dec.new("111")
> @@ -938,6 +938,27 @@ test:do_catchsql_test(
> 1, "Inconsistent types: expected string or varbinary got
> decimal(111)"
> })
>
> +-- Make sure that DECIMAL value can be bound.
> +test:do_test(
> + "dec-16-1",
> + function()
> + return box.execute([[SELECT ?;]], {dec1}).rows[1][1]
> + end,
> + dec1)
> +test:do_test(
> + "dec-16-2",
> + function()
> + return box.execute([[SELECT $2;]], {123, dec2}).rows[1][1]
> + end,
> + dec2)
> +
> +test:do_test(
> + "dec-16-3",
> + function()
> + return box.execute([[SELECT :two;]], {{[":two"] =
> dec3}}).rows[1][1]
> + end,
> + dec3)
> +
> test:execsql([[
> DROP TRIGGER t;
> DROP VIEW v;
> --
> 2.25.1
Hello,
On 31 авг 11:24, Mergen Imeev via Tarantool-patches wrote:
> After this patch, DECIMAL values can be bound like any other supported
> by SQL values.
>
> Closes #4717
> ---
> https://github.com/tarantool/tarantool/issues/4717
> https://github.com/tarantool/tarantool/tree/imeevma/gh-4717-binding-for-decimal
LGTM.
I've checked your patch into master.
--
Regards, Kirill Yukhin