Changeset: f1b3e33b1168 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f1b3e33b1168 Modified Files: sql/backends/monet5/rel_bin.c sql/include/sql_catalog.h sql/server/rel_schema.c sql/server/sql_parser.y sql/server/sql_partition.c sql/server/sql_tokens.h Branch: literal_features Log Message:
SQL23: introduce UNIQUE NULLS NOT DISTINCT constraint diffs (138 lines): diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -4643,7 +4643,9 @@ insert_check_ukey(backend *be, list *ins stmt_add_column_predicate(be, c->c); col = stmt_col(be, c->c, dels, dels->partition); - if ((k->type == ukey) && stmt_has_null(col)) { + if (k->type == unndkey) + s = stmt_uselect(be, col, cs, cmp_equal, s, 0, 1); + else if ((k->type == ukey) && stmt_has_null(col)) { stmt *nn = stmt_selectnonil(be, col, s); s = stmt_uselect(be, col, cs, cmp_equal, nn, 0, 0); } else { @@ -4668,7 +4670,7 @@ insert_check_ukey(backend *be, list *ins list_append(lje, col); list_append(rje, cs); } - s = releqjoin(be, lje, rje, NULL, 1 /* hash used */, 0, 0); + s = releqjoin(be, lje, rje, NULL, 1 /* hash used */, 0, k->type == unndkey? 1: 0); s = stmt_result(be, s, 0); } s = stmt_binop(be, stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1), stmt_atom_lng(be, 0), NULL, ne); @@ -4732,12 +4734,12 @@ insert_check_ukey(backend *be, list *ins s = stmt_project(be, nn, s); } if (h->nrcols) { - s = stmt_join(be, s, h, 0, cmp_equal, 0, 0, false); + s = stmt_join(be, s, h, 0, cmp_equal, 0, k->type == unndkey? 1: 0, false); /* s should be empty */ s = stmt_result(be, s, 0); s = stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1); } else { - s = stmt_uselect(be, s, h, cmp_equal, NULL, 0, 0); + s = stmt_uselect(be, s, h, cmp_equal, NULL, 0, k->type == unndkey? 1: 0); /* s should be empty */ s = stmt_aggr(be, s, NULL, NULL, cnt, 1, 0, 1); } @@ -4844,7 +4846,7 @@ sql_insert_key(backend *be, list *insert * insert values * insert fkey/pkey index */ - if (k->type == pkey || k->type == ukey) { + if (k->type == pkey || k->type == ukey || k->type == unndkey) { return insert_check_ukey(be, inserts, k, idx_inserts); } else { /* foreign keys */ return insert_check_fkey(be, inserts, k, idx_inserts, pin); diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h --- a/sql/include/sql_catalog.h +++ b/sql/include/sql_catalog.h @@ -524,8 +524,9 @@ typedef struct sql_subfunc { typedef enum key_type { pkey, - ukey, - fkey + ukey, /* default behavior is that NULLS are distinct, e.g. there can be multiple null values in a column with regular UNIQUE constraint */ + fkey, + unndkey /* NULLS are not distinct, i.e. NULLS act as regular values for uniqueness checks */ } key_type; typedef struct sql_kc { diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c --- a/sql/server/rel_schema.c +++ b/sql/server/rel_schema.c @@ -366,8 +366,9 @@ column_constraint_type(mvc *sql, const c } switch (s->token) { case SQL_UNIQUE: + case SQL_UNIQUE_NULLS_NOT_DISTINCT: case SQL_PRIMARY_KEY: { - key_type kt = (s->token == SQL_UNIQUE) ? ukey : pkey; + key_type kt = (s->token == SQL_UNIQUE) ? ukey : (s->token == SQL_UNIQUE_NULLS_NOT_DISTINCT) ? unndkey : pkey; sql_key *k; const char *ns = name; @@ -828,8 +829,9 @@ table_constraint_type(mvc *sql, const ch switch (s->token) { case SQL_UNIQUE: + case SQL_UNIQUE_NULLS_NOT_DISTINCT: case SQL_PRIMARY_KEY: { - key_type kt = (s->token == SQL_PRIMARY_KEY ? pkey : ukey); + key_type kt = (s->token == SQL_PRIMARY_KEY ? pkey : s->token == SQL_UNIQUE ? ukey : unndkey); dnode *nms = s->data.lval->h; sql_key *k; const char *ns = name; diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -2144,6 +2144,7 @@ column_constraint_type: NOT sqlNULL { $$ = _symbol_create( SQL_NOT_NULL, NULL); } | sqlNULL { $$ = _symbol_create( SQL_NULL, NULL); } | UNIQUE { $$ = _symbol_create( SQL_UNIQUE, NULL ); } + | UNIQUE NULLS NOT DISTINCT { $$ = _symbol_create( SQL_UNIQUE_NULLS_NOT_DISTINCT, NULL ); } | PRIMARY KEY { $$ = _symbol_create( SQL_PRIMARY_KEY, NULL ); } | REFERENCES qname opt_column_list opt_match opt_ref_action @@ -2160,6 +2161,8 @@ column_constraint_type: table_constraint_type: UNIQUE column_commalist_parens { $$ = _symbol_create_list( SQL_UNIQUE, $2); } + | UNIQUE NULLS NOT DISTINCT column_commalist_parens + { $$ = _symbol_create_list( SQL_UNIQUE_NULLS_NOT_DISTINCT, $5); } | PRIMARY KEY column_commalist_parens { $$ = _symbol_create_list( SQL_PRIMARY_KEY, $3); } | FOREIGN KEY column_commalist_parens @@ -7246,6 +7249,7 @@ char *token2string(tokens token) SQL(TYPE); SQL(UNION); SQL(UNIQUE); + SQL(UNIQUE_NULLS_NOT_DISTINCT); SQL(UNOP); SQL(UPDATE); SQL(USING); diff --git a/sql/server/sql_partition.c b/sql/server/sql_partition.c --- a/sql/server/sql_partition.c +++ b/sql/server/sql_partition.c @@ -54,7 +54,7 @@ sql_partition_validate_key(mvc *sql, sql { if (k->type != fkey) { const char *keys = (k->type == pkey) ? "primary" : "unique"; - assert(k->type == pkey || k->type == ukey); + assert(k->type == pkey || k->type == ukey || k->type == unndkey); if (isPartitionedByColumnTable(nt)) { assert(nt->part.pcol); diff --git a/sql/server/sql_tokens.h b/sql/server/sql_tokens.h --- a/sql/server/sql_tokens.h +++ b/sql/server/sql_tokens.h @@ -153,6 +153,7 @@ typedef enum tokens { SQL_TYPE, SQL_UNION, SQL_UNIQUE, + SQL_UNIQUE_NULLS_NOT_DISTINCT, SQL_UNOP, SQL_UPDATE, SQL_USING, _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org