From: Nikita Pettik <korablev@tarantool.org> To: imeevma@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: Re: [Tarantool-patches] [PATCH v4 3/5] sql: check number of arguments in sql_func_by_signature() Date: Mon, 13 Jul 2020 12:21:01 +0000 [thread overview] Message-ID: <20200713122100.GC15396@tarantool.org> (raw) In-Reply-To: <c053635aba5b788fef69d1122fb72acd5f14c918.1594618005.git.imeevma@gmail.com> On 13 Jul 08:33, imeevma@tarantool.org wrote: > After this patch, the number of function arguments will always be > checked in the sql_func_by_signature() function. This was not the > case for some of the built-in functions. At least, I'd split patch into two parts: first introduces new members and changes data structures, and the second one - adds new check (if it is necessary at all; see comments below). > Part of #4159 > --- > @@ -2195,11 +2164,28 @@ sql_func_by_signature(const char *name, int argc) > name)); > return NULL; > } It looks strange since other 'by' getters (space, index, collation) dont set diag errors. > - int param_count = base->def->param_count; > - if (param_count != -1 && param_count != argc) { > - const char *err = tt_sprintf("%d", param_count); > - diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, > - base->def->name, err, argc); > + if (base->def->language != FUNC_LANGUAGE_SQL_BUILTIN) { > + int param_count = base->def->param_count; > + if (param_count != -1 && param_count != argc) { > + const char *err = tt_sprintf("%d", param_count); > + diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, > + base->def->name, err, argc); > + return NULL; > + } > + return base; > + } > + struct func_sql_builtin *func = (struct func_sql_builtin *)base; > + uint32_t arg_c = (uint32_t)argc; > + if (func->args.min_count > arg_c || func->args.max_count < arg_c) { > + const char *err; > + uint32_t min = func->args.min_count; > + uint32_t max = func->args.max_count; > + if (min != max) > + err = tt_sprintf("from %d to %d", min, max); > + else > + err = tt_sprintf("%d", min); > + diag_set(ClientError, ER_FUNC_WRONG_ARG_COUNT, base->def->name, > + err, argc); > return NULL; > } > return base; > @@ -2242,12 +2228,16 @@ static struct { > /** Members below are related to struct func_def. */ > bool is_deterministic; > int param_count; > + uint32_t min_count; > + uint32_t max_count; Why not erase param_count? min/max_count of what? Also add comments to these members explaining why do we need them at all. Why can't we use -1 param_count for variadic args and provide check in func's implementation? > enum field_type returns; > enum func_aggregate aggregate; > bool export_to_sql; > } sql_builtins[] = { > {.name = "ABS", > .param_count = 1, > + .min_count = 1, > + .max_count = 1, > .returns = FIELD_TYPE_NUMBER, > .aggregate = FUNC_AGGREGATE_NONE, > .is_deterministic = true, > @@ -2318,6 +2320,8 @@ static struct { > }, { > .name = "COALESCE", > .param_count = -1, > + .min_count = 2, > + .max_count = SQL_MAX_FUNCTION_ARG, Why do you need uint32 if max value fits into uint8? > diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h > index 58a65acc1..6af9d7473 100644 > --- a/src/box/sql/sqlInt.h > +++ b/src/box/sql/sqlInt.h > @@ -4397,11 +4397,24 @@ Expr *sqlExprForVectorField(Parse *, Expr *, int); > */ > extern int sqlSubProgramsRemaining; > > +/** > + * A structure that contains additional information about > + * arguments to built-in SQL functions. > + */ > +struct sql_builtin_func_args { > + /** Min number of arguments. */ > + uint32_t min_count; > + /** Max number of arguments. */ > + uint32_t max_count; > +}; > + > struct func_sql_builtin { > /** Function object base class. */ > struct func base; > /** A bitmask of SQL flags. */ > uint16_t flags; > + /** Information about arguments to built-in functions. */ > + struct sql_builtin_func_args args; Why not simply inline two members (min/max)? > /** > * A VDBE-memory-compatible call method. > * SQL built-ins don't use func base class "call" > diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua > index 3c088920f..1d3ef9e2a 100755 > --- a/test/sql-tap/func.test.lua > +++ b/test/sql-tap/func.test.lua > @@ -428,7 +428,7 @@ test:do_catchsql_test( > SELECT round(a,b,c) FROM t1 > ]], { > -- <func-4.5> > - 1, "Wrong number of arguments is passed to ROUND(): expected 1 or 2, got 3" > + 1, "Wrong number of arguments is passed to ROUND(): expected from 1 to 2, got 3" > -- </func-4.5> > }) > > @@ -488,7 +488,7 @@ test:do_catchsql_test( > SELECT round() FROM t1 ORDER BY a > ]], { > -- <func-4.11> > - 1, "Wrong number of arguments is passed to ROUND(): expected 1 or 2, got 0" > + 1, "Wrong number of arguments is passed to ROUND(): expected from 1 to 2, got 0" > -- </func-4.11> > }) > > @@ -2540,7 +2540,7 @@ test:do_catchsql_test( > SELECT coalesce() > ]], { > -- <func-27.1> > - 1, "Wrong number of arguments is passed to COALESCE(): expected at least two, got 0" > + 1, "Wrong number of arguments is passed to COALESCE(): expected from 2 to 127, got 0" Current error message looks better than new one (127 arguments??).
next prev parent reply other threads:[~2020-07-13 12:21 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-07-13 5:32 [Tarantool-patches] [PATCH v4 0/5] Change implicit cast for assignment imeevma 2020-07-13 5:32 ` [Tarantool-patches] [PATCH v4 1/5] sql: set field_type in mem_set_*() functions imeevma 2020-07-13 10:36 ` Nikita Pettik 2020-07-13 5:33 ` [Tarantool-patches] [PATCH v4 2/5] sql: move diag setting to sql_func_by_signature() imeevma 2020-07-13 10:58 ` Nikita Pettik 2020-07-13 5:33 ` [Tarantool-patches] [PATCH v4 3/5] sql: check number of arguments in sql_func_by_signature() imeevma 2020-07-13 12:21 ` Nikita Pettik [this message] 2020-07-13 5:33 ` [Tarantool-patches] [PATCH v4 4/5] sql: change implicit cast for assignment imeevma 2020-07-13 14:42 ` Nikita Pettik 2020-07-13 5:33 ` [Tarantool-patches] [PATCH v4 5/5] sql: properly check arguments of functions imeevma 2020-07-13 14:56 ` Nikita Pettik
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=20200713122100.GC15396@tarantool.org \ --to=korablev@tarantool.org \ --cc=imeevma@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v4 3/5] sql: check number of arguments in sql_func_by_signature()' \ /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