Tarantool development patches archive
 help / color / mirror / Atom feed
From: Konstantin Osipov <kostja@tarantool.org>
To: "n.pettik" <korablev@tarantool.org>
Cc: tarantool-patches@freelists.org,
	Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Subject: [tarantool-patches] Re: [PATCH 2/6] sql: rework ALTER TABLE grammar
Date: Fri, 18 Jan 2019 04:42:27 +0300	[thread overview]
Message-ID: <20190118014227.GS28204@chai> (raw)
In-Reply-To: <C8EB016B-A539-4598-94B4-5863A6D6A3B1@tarantool.org>

* n.pettik <korablev@tarantool.org> [19/01/17 20:20]:

Looks good to me.

> 
> 
> > On 17 Jan 2019, at 14:51, Konstantin Osipov <kostja@tarantool.org> wrote:
> > 
> > * Nikita Pettik <korablev@tarantool.org> [19/01/09 15:17]:
> >> +alter_table_start ::= ALTER TABLE fullname(Z) . {
> >> +  pParse->constraint->table_name = Z;
> >> +  pParse->constraint->name.n = 0;
> >> +}
> > 
> > It's bikeshed at this point, but in future you will have other
> > ALTER TABLE clauses: add/drop column, add/drop index,
> 
> Indexes out of scope: they are part of constraint routines.
> 
> > add/drop
> > constraint. It's unclear why you initialize a specific parsing
> > context (constraint definition) right in alter_table_start rule.
> > OK for now.
> 
> We must save name of table before any other processing.
> So, at the moment of parsing table’s name we don’t have
> any notion about next actions yet.
> 
> We can use the way you suggested in previous letter:
> introduce some hierarchical structures.
> For instance ALTER can be implemented in the next way:
> 
> diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
> index e38e0da08..f1a5e1974 100644
> --- a/src/box/sql/sqliteInt.h
> +++ b/src/box/sql/sqliteInt.h
> @@ -2707,6 +2707,105 @@ struct constraint_parse {
>         struct ExprList *cols;
>  };
>  
> +enum entity_type {
> +       ENTITY_TYPE_TABLE = 0,
> +       ENTITY_TYPE_INDEX,
> +       ENTITY_TYPE_TRIGGER,
> +       ENTITY_TYPE_CONSTRAINT,
> +       ENTITY_TYPE_COLUMN
> +};
> +
> +/***
> + * Hierarchy is following:
> + *
> + * Base structure is ALTER.
> + * ALTER is omitted only for CREATE TABLE.
> + *
> + * DROP is general for all existing objects and includes
> + * name of object itself, name of parent object (table),
> + * IF EXISTS clause and may contain on-drop behaviour.
> + * Hence, it terms of grammar - it is terminal symbol.
> + *
> + * RENAME can be applied only to table, so it is also
> + * terminal symbol.
> + *
> + * CREATE in turn can be expanded to nonterminal symbol
> + * CREATE CONSTRAINT or to terminal CREATE TABLE/INDEX/TRIGGER.
> + * CREATE CONSTRAINT unfolds to FOREIGN KEY or UNIQUE/PRIMARY KEY.
> + *
> + * For instance, ALTER TABLE t ADD CONSTRAINT c FOREIGN KEY
> + *                  REFERENCES t2(id);
> + * ALTER *TABLE* -> CREATE ENTITY -> CREATE CONSTRAINT -> CREATE FK
> + *
> + * CREATE TRIGGER tr1 ...
> + * ALTER *TABLE* -> CREATE ENTITY -> CREATE TRIGGER
> + */
> +struct alter_entity_def {
> +       enum entity_type entity_type;
> +       struct SrcList *entity_name;
> +};
> +
> +struct rename_entity_def {
> +       struct alter_entity_def *base;
> +       struct Token new_name;
> +};
> +
> +struct create_entity_def {
> +       struct alter_entity_def *base;
> +       /** Statement comes with IF NOT EXISTS clause. */
> +       bool if_not_exist;
> +       struct Token *name;
> +};
> +
> +struct drop_entity_def {
> +       struct alter_entity_def *base;
> +       /** Statement comes with IF EXISTS clause. */
> +       bool if_exist;
> +       struct Token entity_name;
> +       /** One of CASCADE, RESTRICT */
> +       int drop_behaviour;
> +};
> +
> +struct create_trigger_def {
> +       struct create_entity_def *base;
> +       /** One of TK_BEFORE, TK_AFTER, TK_INSTEAD. */
> +       int tr_tm;
> +       /** One of TK_INSERT, TK_UPDATE, TK_DELETE. */
> +       int op;
> +       /** Column list if this is an UPDATE OF trigger. */
> +       struct IdList *columns;
> +       /** When clause. */
> +       struct Expr *when;
> +       bool if_not_exist;
> +
> +};
> +struct create_table_def {
> +       struct create_entity_def *base;
> +       struct space_def *table_def;
> +       struct Select *select;
> +};
> +
> +struct create_index_def {
> +       struct create_entity_def *base;
> +       enum sort_order sort_order;
> +       enum sql_index_type idx_type;
> +       struct ExprList *col_list;
> +};
> +
> +struct create_constraint_def {
> +       struct create_entity_def *base;
> +       /** One of DEFERRED, IMMEDIATE. */
> +       int check_time;
> +};
> +
> +struct create_fk_def {
> +       struct create_constraint_def *base;
> +       struct ExprList *child_cols;
> +       struct ExprList *parent_cols;
> +       struct Token *parent_name;
> +       enum fkey_action action;
> +};
> +
> diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
> index de5429498..84597bb91 100644
> --- a/src/box/sql/parse.y
> +++ b/src/box/sql/parse.y
> @@ -1452,8 +1452,11 @@ cmd ::= alter_table_start alter_table_action .
>   * the separate rule.
>   */
>  alter_table_start ::= ALTER TABLE fullname(Z) . {
> -  pParse->constraint.table = Z;
> -  pParse->constraint.name.n = 0;
> +  pParse->alter_entity_def =
> +    region_alloc(pParse->region, sizeof(struct alter_entity_def));
> +  pParse->alter_entity_def->entity_type = ENTITY_TYPE_TABLE;
> +  pParse->alter_entity_def->parent_name = Z;
> +  pParse->alter_entity_def->entity_name.n = 0;
>  }
>  
>  alter_table_action ::= add_constraint_def.
> @@ -1461,25 +1464,44 @@ alter_table_action ::= drop_constraint_def.
>  alter_table_action ::= rename.
>  
>  rename ::= RENAME TO nm(Z). {
> -  sql_alter_table_rename(pParse, &Z);
> +  struct alter_entity_rename *entity_rename =
> +    region_alloc(pParse->region, sizeof(struct rename_entity_def));
> +  entity_rename->base = pParse->alter_entity_def;
> +  entity_rename->new_name = Z;
> +  pParse->alter_entity_def = (struct alter_entity_def *) entity_rename;
> +  sql_alter_table_rename(pParse);
>  }
>  
>  add_constraint_def ::= add_constraint_start constraint_def.
>  
>  add_constraint_start ::= ADD CONSTRAINT nm(Z). {
> -  pParse->constraint.name = Z;
> +  struct create_entity_def *entity_create =
> +    region_alloc(pParse->region, sizeof(struct create_entity_def));
> +  entity_create->base = pParse->alter_entity_def;
> +  entity_create->name = Z;
> +  entity_create->if_not_exist = false;
> +  pParse->alter_entity_def = (struct alter_entity_def *)entity_create;
>  }
>  
>  constraint_def ::= foreign_key_def.
>  
>  foreign_key_def ::= FOREIGN KEY LP eidlist(FA) RP REFERENCES nm(T)
>                      eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
> -  pParse->constraint.cols = FA;
> -  sql_create_foreign_key(pParse, &T, TA, D, R);
> +  struct create_fk_def *fk_def =
> +    region_alloc(pParse->region, sizeof(struct create_fk_def));
> +  fk_def->child_cols = FA;
> +  fk_def->parent_cols = TA;
> +  fk_def->action = R;
> +  fk_def->parent_name = T;
> +  sql_create_foreign_key(pParse);
>  }
>  
>  drop_constraint_def ::= DROP CONSTRAINT nm(Z). {
> -  sql_drop_foreign_key(pParse, &Z);
> +    struct drop_entity_rename *entity_drop =
> +      region_alloc(pParse->region, sizeof(struct drop_entity_def));
> +    entity_drop->base = pParse->alter_entity_def;
> +    entity_drop->new_name = Z;
> +  sql_drop_foreign_key(pParse);
>  }
> 
> It is easy to fix other create/drop statements to use
> these structures. If it is OK to you and Vlad, I can
> rework whole patch.
> 
> >> +
> >> +alter_table_action ::= add_constraint_def.
> >> +alter_table_action ::= drop_constraint_def.
> > 
> > Why use the same data structure for create and drop?
> 
> For the sake of simplicity.
> 
> > When I drop a
> > constraint I specify its name and (perhaps) table name, none of
> > other properties.
> 
> Not quite: drop constraint clause also may include drop behaviour:
> one of CASCADE or RESTRICT.
> In our implementation it is always RESTRICT.
> 
> > To capture drop context one could use:
> > 
> > struct drop_object_def {
> >    enum object_type object_type;
> >    const char *object_name;
> >    const char *parent_object_name;
> > };
> > 
> > rename of an object could be captured in a similar data structure.
> 
> Rename and drop are the easiest cases.
> 
> 

-- 
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
http://tarantool.io - www.twitter.com/kostja_osipov

  reply	other threads:[~2019-01-18  1:42 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-09 12:13 [tarantool-patches] [PATCH 0/6] Introduce ALTER TABLE ADD CONSTRAINT UNIQUE/PK Nikita Pettik
2019-01-09 12:13 ` [tarantool-patches] [PATCH 1/6] sql: move constraint name to struct contraint_parse Nikita Pettik
2019-01-14 14:04   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 20:06     ` n.pettik
2019-01-16 20:54       ` Vladislav Shpilevoy
2019-01-17 10:56       ` Konstantin Osipov
2019-01-17 17:14         ` n.pettik
2019-01-09 12:13 ` [tarantool-patches] [PATCH 2/6] sql: rework ALTER TABLE grammar Nikita Pettik
2019-01-14 14:05   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 20:06     ` n.pettik
2019-01-16 20:54       ` Vladislav Shpilevoy
2019-01-17 11:51   ` Konstantin Osipov
2019-01-17 17:14     ` n.pettik
2019-01-18  1:42       ` Konstantin Osipov [this message]
2019-01-09 12:13 ` [tarantool-patches] [PATCH 3/6] sql: remove start token from sql_create_index args Nikita Pettik
2019-01-09 12:13 ` [tarantool-patches] [PATCH 4/6] sql: refactor getNewIid() function Nikita Pettik
2019-01-14 14:05   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-09 12:13 ` [tarantool-patches] [PATCH 5/6] sql: fix error message for improperly created index Nikita Pettik
2019-01-14 14:06   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 20:06     ` n.pettik
2019-01-09 12:13 ` [tarantool-patches] [PATCH 6/6] sql: introduce ALTER TABLE ADD CONSTRAINT UNIQUE/PRIMARY KEY Nikita Pettik
2019-01-14 14:06   ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-16 20:06     ` n.pettik
2019-01-16 20:54       ` 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=20190118014227.GS28204@chai \
    --to=kostja@tarantool.org \
    --cc=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='[tarantool-patches] Re: [PATCH 2/6] sql: rework ALTER TABLE grammar' \
    /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