From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng1.m.smailru.net (smtpng1.m.smailru.net [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 436D343040A for ; Fri, 14 Aug 2020 18:05:03 +0300 (MSK) From: imeevma@tarantool.org Date: Fri, 14 Aug 2020 18:05:02 +0300 Message-Id: <34e3d319f2955e21f9fc1d358b778128cea9ed79.1597417321.git.imeevma@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH v2 06/10] sql: add overloaded versions of the functions List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: v.shpilevoy@tarantool.org, tsafin@tarantool.org Cc: tarantool-patches@dev.tarantool.org 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