Tarantool development patches archive
 help / color / mirror / Atom feed
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??).

  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