From 1fb46b161a5b81b619235192a7b12baeac2817d8 Mon Sep 17 00:00:00 2001 From: Mergen Imeev <imeevma@gmail.com> Date: Tue, 27 Apr 2021 15:12:33 +0300 Subject: [PATCH] sql: make mem_is_bin() to check only for VARBINARY After this patch, the mem_is_bin() function will return 'true' only if the value that the MEM contains is of type VARBINARY. This patch also adds the mem_is_bin_ext() function, which is used to check if a MEM contains value of type VARBINARY or value of types that are currently considered VARBINARY extensions - MAP and ARRAY. Part of #4906 --- src/box/sql/func.c | 11 +++++++---- src/box/sql/mem.h | 2 +- src/box/sql/vdbe.c | 5 +++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 94302cc56b..90e8e152fb 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -553,7 +553,7 @@ roundFunc(sql_context * context, int argc, sql_value ** argv) } if (mem_is_null(argv[0])) return; - if (mem_is_bin(argv[0])) { + if (!mem_is_num(argv[0]) && !mem_is_str(argv[0])) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(argv[0]), "numeric"); context->is_aborted = true; @@ -613,7 +613,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \ const char *z2; \ int n; \ UNUSED_PARAMETER(argc); \ - if (mem_is_bin(argv[0])) { \ + if (mem_is_bin(argv[0]) || mem_is_map(argv[0]) || \ + mem_is_array(argv[0])) { \ diag_set(ClientError, ER_INCONSISTENT_TYPES, "text", \ "varbinary"); \ context->is_aborted = true; \ @@ -694,7 +695,8 @@ randomBlob(sql_context * context, int argc, sql_value ** argv) unsigned char *p; assert(argc == 1); UNUSED_PARAMETER(argc); - if (mem_is_bin(argv[0])) { + if (mem_is_bin(argv[0]) || mem_is_map(argv[0]) || + mem_is_array(argv[0])) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(argv[0]), "numeric"); context->is_aborted = true; @@ -1584,7 +1586,8 @@ soundexFunc(sql_context * context, int argc, sql_value ** argv) 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, }; assert(argc == 1); - if (mem_is_bin(argv[0])) { + if (mem_is_bin(argv[0]) || mem_is_map(argv[0]) || + mem_is_array(argv[0])) { diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(argv[0]), "text"); context->is_aborted = true; diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h index 1db7f4debe..526b6bf3e7 100644 --- a/src/box/sql/mem.h +++ b/src/box/sql/mem.h @@ -184,7 +184,7 @@ mem_is_bool(const struct Mem *mem) static inline bool mem_is_bin(const struct Mem *mem) { - return (mem->flags & MEM_Blob) != 0; + return (mem->flags & MEM_Blob) != 0 && (mem->flags & MEM_Subtype) == 0; } static inline bool diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c index 2308587e75..12ec703a22 100644 --- a/src/box/sql/vdbe.c +++ b/src/box/sql/vdbe.c @@ -1643,6 +1643,11 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ "varbinary"); goto abort_due_to_error; } + } else if (mem_is_map(pIn3) || mem_is_map(pIn1) || mem_is_array(pIn3) || + mem_is_array(pIn1)) { + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, + mem_type_to_str(pIn3), mem_type_to_str(pIn1)); + goto abort_due_to_error; } else if (type == FIELD_TYPE_STRING) { if (mem_cmp_str(pIn3, pIn1, &res, pOp->p4.pColl) != 0) { const char *str = -- GitLab