Tarantool development patches archive
 help / color / mirror / Atom feed
From: Nikita Pettik <korablev@tarantool.org>
To: tarantool-patches@freelists.org
Cc: roman.habibov@tarantool.org
Subject: [tarantool-patches] Re: [PATCH] sql: add check for <WITH> absence in <CREATE VIEW>
Date: Wed, 11 Sep 2019 16:32:06 +0300	[thread overview]
Message-ID: <20190911133203.GA49615@tarantool.org> (raw)
In-Reply-To: <0FDC0655-79B5-479F-8FAA-5E9A2E93F1CF@tarantool.org>

On Wed, Sep 04, 2019 at 05:14:10PM +0300, Roman Khabibov wrote:
> 
> commit 4f78ff7cf8b4a3f496d72388235f773ae51d6efc
> Author: Roman Khabibov <roman.habibov@tarantool.org>
> Date:   Mon Jul 29 18:00:34 2019 +0300
> 
>     sql: allow to create view as <WITH> clause
>     
>     Allow views to use CTEs in <WITH> clauses, 

Nit: all CTEs start from WITH clause; so your statement is a bit confusing.

>     which can be in any
>     (nested) select after <AS>. Before this patch, during view
>     creation all referenced spaces were fetched by name from SELECT
>     and their reference counters were incremented to avoid dangling
>     references. It occurred in update_view_references(). Obviously, CTE
>     tables weren't held in space cache, ergo error "space doesn’t
>     exist" was raised. Add check if a space from FROM is CTE. If it is,
>     don't increment its reference counter and don't raise the error.
>     
>     Closes #4149
> 
> diff --git a/src/box/alter.cc b/src/box/alter.cc
> index 4f2e34bf0..a625d8c39 100644
> --- a/src/box/alter.cc
> +++ b/src/box/alter.cc
> @@ -1759,6 +1759,13 @@ update_view_references(struct Select *select, int update_value,
>  		const char *space_name = sql_src_list_entry_name(list, i);
>  		if (space_name == NULL)
>  			continue;
> +		/*
> +		 * CTE tables isn't held in space cache and we

Nit: tables aren't held ...

> +		 * don't need to increment reference counter for
> +		 * CTEs.

I'd rephrase a bit:

Views are allowed to contain CTEs. CTE is a temporary object, created
and destroyed at SQL runtime (it is represented by an ephemeral table).
So, it is absent in space cache and as a consequence we can't increment
its reference counter. Skip iteration.

> +		 */
> +		if (sql_select_has_cte_with_name(select, space_name))
> +			continue;
>  		struct space *space = space_by_name(space_name);
>  		if (space == NULL) {
>  			if (! suppress_error) {
> diff --git a/src/box/sql.h b/src/box/sql.h
> index 7644051b4..422c8dfc2 100644
> --- a/src/box/sql.h
> +++ b/src/box/sql.h
> @@ -323,6 +323,17 @@ sql_select_delete(struct sql *db, struct Select *select);
>  struct SrcList *
>  sql_select_expand_from_tables(struct Select *select);
>  
> +/**
> + * Check if @a name matches with at least one of CTE names typed
> + * in <WITH> clauses within @a select.
> + *
> + * @param select Select which may contain CTE.

Nit: you forgot to describe name argument.

> + * @retval true Has CTE with @a name.
> + * @retval false Hasn't CTE with @a name.
> +*/
> +bool
> +sql_select_has_cte_with_name(struct Select *select, const char *name);

sql_select_contains_cte() is enough, I guess.

> +
>  /**
>   * Temporary getter in order to avoid including sqlInt.h
>   * in alter.cc.
> diff --git a/src/box/sql/select.c b/src/box/sql/select.c
> index ddb5de87e..d7dab35cd 100644
> --- a/src/box/sql/select.c
> +++ b/src/box/sql/select.c
> @@ -332,6 +332,29 @@ sql_select_expand_from_tables(struct Select *select)
>  	return walker.u.pSrcList;
>  }
>  
> +bool
> +sql_select_has_cte_with_name(struct Select *select, const char *name)
> +{
> +	assert(select != NULL && name != NULL);
> +	struct With *with = select->pWith;
> +	if (with != NULL) {
> +		for (int i = 0; i < with->nCte; i++) {
> +			const struct Cte *cte = &with->a[i];
> +			if (memcmp(name, cte->zName, strlen(name)) == 0)
> +				return true;
> +		}
> +	}

Please explain why we don't use recursion here (cte->pSelect->pWith).
I'd attach schema of SELECT for the sake of the clarity.

> +	struct SrcList *list = select->pSrc;
> +	int item_count = sql_src_list_entry_count(list);
> +	for (int i = 0; i < item_count; ++i) {
> +		if (list->a[i].pSelect != NULL)
> +			if (sql_select_has_cte_with_name(list->a[i].pSelect,
> +							 name))
> +				return true;
> +	

Nit: in case 'if' body contains more than one string it is enclosed in
brackets.

  reply	other threads:[~2019-09-11 13:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-02 12:52 [tarantool-patches] " Roman Khabibov
2019-08-09 15:15 ` [tarantool-patches] " n.pettik
2019-08-13 12:42   ` Roman Khabibov
2019-08-13 22:10     ` n.pettik
2019-08-16 19:09       ` Roman Khabibov
2019-08-19 15:39         ` Roman Khabibov
2019-08-20 19:41         ` n.pettik
2019-08-28 12:17           ` Roman Khabibov
2019-08-29 17:59             ` Nikita Pettik
2019-09-04 14:14               ` Roman Khabibov
2019-09-11 13:32                 ` Nikita Pettik [this message]
2019-09-13 14:57                   ` Roman Khabibov

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=20190911133203.GA49615@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=roman.habibov@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --subject='[tarantool-patches] Re: [PATCH] sql: add check for <WITH> absence in <CREATE VIEW>' \
    /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