From: imeevma@tarantool.org To: v.shpilevoy@tarantool.org, tsafin@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: [Tarantool-patches] [PATCH v2 06/10] sql: add overloaded versions of the functions Date: Fri, 14 Aug 2020 18:05:02 +0300 [thread overview] Message-ID: <34e3d319f2955e21f9fc1d358b778128cea9ed79.1597417321.git.imeevma@gmail.com> (raw) In-Reply-To: <cover.1597417321.git.imeevma@gmail.com> This patch adds overload function definitions for the length(), substr(), trim(), and position() functions. Part of #4159 --- src/box/sql/analyze.c | 6 ++--- src/box/sql/expr.c | 29 ++++++++++++++++++++--- src/box/sql/func.c | 54 ++++++++++++++++++++++++++++++++++++++++--- src/box/sql/sqlInt.h | 5 ++-- src/box/sql/vdbemem.c | 2 +- 5 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index f74f9b358..d304b266e 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -716,7 +716,7 @@ callStatGet(Vdbe * v, int regStat4, int iParam, int regOut) { assert(regOut != regStat4 && regOut != regStat4 + 1); sqlVdbeAddOp2(v, OP_Integer, iParam, regStat4 + 1); - struct func *func = sql_func_by_signature("_sql_stat_get", 2); + struct func *func = sql_func_by_signature("_sql_stat_get", false, 2); assert(func != NULL); sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, regStat4, regOut, (char *)func, P4_FUNC); @@ -856,7 +856,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space) sqlVdbeAddOp2(v, OP_Integer, part_count, stat4_reg + 1); sqlVdbeAddOp2(v, OP_Integer, part_count, stat4_reg + 2); struct func *init_func = - sql_func_by_signature("_sql_stat_init", 3); + sql_func_by_signature("_sql_stat_init", false, 3); assert(init_func != NULL); sqlVdbeAddOp4(v, OP_BuiltinFunction0, 0, stat4_reg + 1, stat4_reg, (char *)init_func, P4_FUNC); @@ -957,7 +957,7 @@ vdbe_emit_analyze_space(struct Parse *parse, struct space *space) pk_part_count, key_reg); assert(chng_reg == (stat4_reg + 1)); struct func *push_func = - sql_func_by_signature("_sql_stat_push", 3); + sql_func_by_signature("_sql_stat_push", false, 3); assert(push_func != NULL); sqlVdbeAddOp4(v, OP_BuiltinFunction0, 1, stat4_reg, tmp_reg, (char *)push_func, P4_FUNC); diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c index bc2182446..99ca91bba 100644 --- a/src/box/sql/expr.c +++ b/src/box/sql/expr.c @@ -328,8 +328,15 @@ sql_expr_coll(Parse *parse, Expr *p, bool *is_explicit_coll, uint32_t *coll_id, if (op == TK_FUNCTION) { uint32_t arg_count = p->x.pList == NULL ? 0 : p->x.pList->nExpr; + bool has_blob_arg = false; + if (arg_count > 0) { + enum field_type type = + sql_expr_type(p->x.pList->a[0].pExpr); + has_blob_arg = type == FIELD_TYPE_VARBINARY; + } struct func *func = - sql_func_by_signature(p->u.zToken, arg_count); + sql_func_by_signature(p->u.zToken, has_blob_arg, + arg_count); if (func == NULL) break; if (sql_func_flag_is_set(func, SQL_FUNC_DERIVEDCOLL) && @@ -3975,8 +3982,15 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target) } nFarg = pFarg ? pFarg->nExpr : 0; assert(!ExprHasProperty(pExpr, EP_IntValue)); + bool has_blob_arg = false; + if (nFarg > 0) { + enum field_type type = + sql_expr_type(pExpr->x.pList->a[0].pExpr); + has_blob_arg = type == FIELD_TYPE_VARBINARY; + } zId = pExpr->u.zToken; - struct func *func = sql_func_by_signature(zId, nFarg); + struct func *func = + sql_func_by_signature(zId, has_blob_arg, nFarg); if (func == NULL) { diag_set(ClientError, ER_NO_SUCH_FUNCTION, zId); @@ -5448,9 +5462,18 @@ analyzeAggregate(Walker * pWalker, Expr * pExpr) uint32_t argc = pExpr->x.pList != NULL ? pExpr->x.pList->nExpr : 0; + bool has_blob_arg = false; + if (argc > 0) { + enum field_type type = + sql_expr_type(pExpr->x.pList->a[0].pExpr); + has_blob_arg = + type == FIELD_TYPE_VARBINARY; + } pItem->func = sql_func_by_signature( - name, argc); + name, + has_blob_arg, + argc); assert(pItem->func != NULL); assert(pItem->func->def-> language == diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 1afee4924..ae1842824 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -2169,19 +2169,27 @@ sql_is_like_func(struct Expr *expr) expr->x.pList->nExpr != 2) return 0; assert(!ExprHasProperty(expr, EP_xIsSelect)); - struct func *func = sql_func_by_signature(expr->u.zToken, 2); + struct func *func = sql_func_by_signature(expr->u.zToken, false, 2); if (func == NULL || !sql_func_flag_is_set(func, SQL_FUNC_LIKE)) return 0; return 1; } struct func * -sql_func_by_signature(const char *name, int argc) +sql_func_by_signature(const char *name, bool has_blob_arg, int argc) { struct func *base = func_by_name(name, strlen(name)); - if (base == NULL || !base->def->exports.sql) + if (base == NULL || !base->def->exports.sql || + base->def->opts.is_overloaded) return NULL; + if (has_blob_arg && base->def->opts.has_overload) { + const char *overload_name = tt_sprintf("%s_VARBINARY", name); + base = func_by_name(overload_name, strlen(overload_name)); + assert(base != NULL && base->def->exports.sql); + assert(base->def->opts.is_overloaded); + } + if (!base->def->opts.has_vararg && base->def->param_count != argc) return NULL; return base; @@ -2497,6 +2505,16 @@ static struct { .call = lengthFunc, .finalize = NULL, .export_to_sql = true, + }, { + .name = "LENGTH_VARBINARY", + .param_count = 1, + .returns = FIELD_TYPE_INTEGER, + .aggregate = FUNC_AGGREGATE_NONE, + .is_deterministic = true, + .flags = SQL_FUNC_LENGTH, + .call = lengthFunc, + .finalize = NULL, + .export_to_sql = true, }, { .name = "LESSER", .call = sql_builtin_stub, @@ -2617,6 +2635,16 @@ static struct { .call = position_func, .finalize = NULL, .export_to_sql = true, + }, { + .name = "POSITION_VARBINARY", + .param_count = 2, + .returns = FIELD_TYPE_INTEGER, + .aggregate = FUNC_AGGREGATE_NONE, + .is_deterministic = true, + .flags = 0, + .call = position_func, + .finalize = NULL, + .export_to_sql = true, }, { .name = "POWER", .call = sql_builtin_stub, @@ -2747,6 +2775,16 @@ static struct { .call = substrFunc, .finalize = NULL, .export_to_sql = true, + }, { + .name = "SUBSTR_VARBINARY", + .param_count = -1, + .returns = FIELD_TYPE_STRING, + .aggregate = FUNC_AGGREGATE_NONE, + .is_deterministic = true, + .flags = SQL_FUNC_DERIVEDCOLL, + .call = substrFunc, + .finalize = NULL, + .export_to_sql = true, }, { .name = "SUM", .param_count = 1, @@ -2787,6 +2825,16 @@ static struct { .call = trim_func, .finalize = NULL, .export_to_sql = true, + }, { + .name = "TRIM_VARBINARY", + .param_count = -1, + .returns = FIELD_TYPE_STRING, + .aggregate = FUNC_AGGREGATE_NONE, + .is_deterministic = true, + .flags = SQL_FUNC_DERIVEDCOLL, + .call = trim_func, + .finalize = NULL, + .export_to_sql = true, }, { .name = "TYPEOF", .param_count = 1, diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h index adf90d824..9ff1dd3ff 100644 --- a/src/box/sql/sqlInt.h +++ b/src/box/sql/sqlInt.h @@ -4441,13 +4441,14 @@ sql_func_flag_is_set(struct func *func, uint16_t flag) * A SQL method to find a function in a hash by its name and * count of arguments. Only functions that have 'SQL' engine * export field set true and have exactly the same signature - * are returned. + * are returned. If has_blob_arg is set to true, the varbinary + * version of the function is returned is the functions has one. * * Returns not NULL function pointer when a valid and exported * to SQL engine function is found and NULL otherwise. */ struct func * -sql_func_by_signature(const char *name, int argc); +sql_func_by_signature(const char *name, bool has_blob_arg, int argc); /** * Generate VDBE code to halt execution with correct error if diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c index 8e9ebf7ab..3af96c37c 100644 --- a/src/box/sql/vdbemem.c +++ b/src/box/sql/vdbemem.c @@ -1327,7 +1327,7 @@ valueFromFunction(sql * db, /* The database connection */ pList = p->x.pList; if (pList) nVal = pList->nExpr; - struct func *func = sql_func_by_signature(p->u.zToken, nVal); + struct func *func = sql_func_by_signature(p->u.zToken, false, nVal); if (func == NULL || func->def->language != FUNC_LANGUAGE_SQL_BUILTIN || !func->def->is_deterministic || sql_func_flag_is_set(func, SQL_FUNC_NEEDCOLL)) -- 2.25.1
next prev parent reply other threads:[~2020-08-14 15:05 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-08-14 15:04 [Tarantool-patches] [PATCH v2 00/10] sql: properly check arguments types of built-in functions imeevma 2020-08-14 15:04 ` [Tarantool-patches] [PATCH v2 01/10] sql: do not return UNSIGNED in " imeevma 2020-08-22 14:23 ` Vladislav Shpilevoy 2020-08-14 15:04 ` [Tarantool-patches] [PATCH v2 02/10] sql: fix functions return types imeevma 2020-08-22 14:24 ` Vladislav Shpilevoy 2020-08-14 15:04 ` [Tarantool-patches] [PATCH v2 03/10] sql: change signature of trim() imeevma 2020-08-22 14:26 ` Vladislav Shpilevoy 2020-08-14 15:04 ` [Tarantool-patches] [PATCH v2 04/10] box: add new options for functions imeevma 2020-08-22 14:28 ` Vladislav Shpilevoy 2020-08-14 15:05 ` [Tarantool-patches] [PATCH v2 05/10] sql: use has_vararg for built-in functions imeevma 2020-08-14 15:05 ` imeevma [this message] 2020-08-22 14:29 ` [Tarantool-patches] [PATCH v2 06/10] sql: add overloaded versions of the functions Vladislav Shpilevoy 2020-08-14 15:05 ` [Tarantool-patches] [PATCH v2 07/10] sql: move built-in function definitions in _func imeevma 2020-08-22 14:30 ` Vladislav Shpilevoy 2020-08-14 15:05 ` [Tarantool-patches] [PATCH v2 08/10] box: add param_list to 'struct func' imeevma 2020-08-22 14:30 ` Vladislav Shpilevoy 2020-08-14 15:05 ` [Tarantool-patches] [PATCH v2 09/10] sql: check built-in functions argument types imeevma 2020-08-14 15:05 ` [Tarantool-patches] [PATCH v2 10/10] sql: refactor sql/func.c imeevma 2020-08-22 14:31 ` Vladislav Shpilevoy 2020-08-22 14:25 ` [Tarantool-patches] [PATCH v2 00/10] sql: properly check arguments types of built-in functions Vladislav Shpilevoy
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=34e3d319f2955e21f9fc1d358b778128cea9ed79.1597417321.git.imeevma@gmail.com \ --to=imeevma@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=tsafin@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 06/10] sql: add overloaded versions of the functions' \ /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