Changeset: 43a0834f3796 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/43a0834f3796
Modified Files:
sql/server/rel_select.c
Branch: literal_features
Log Message:
factor out code and check multiple unique keys
diffs (115 lines):
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1226,6 +1226,59 @@ sql_rel* find_union(visitor *v, sql_rel
return rel;
}
+static inline
+bool group_by_pk_project_uk_cond(mvc* sql, sql_rel* inner, sql_exp* exp,const
char* sname, const char* tname) {
+ sql_table* t = find_table_or_view_on_scope(sql, NULL, sname, tname,
"SELECT", false);
+ bool allow = false;
+ if (t) {
+ sql_idx* pki = NULL;
+ list *ukil = sa_list(sql->sa);
+
+ for (node * n = ol_first_node(t->idxs); n; n = n->next) {
+ sql_idx *i = n->data;
+ switch (i->key->type) {
+ case pkey:
+ pki = i;
+ continue;
+ case ukey:
+ case unndkey:
+ list_append(ukil, i);
+ continue;
+ default:
+ continue;
+ }
+ }
+ if (pki && pki->columns->cnt == 1 && ((list*) inner->r)->cnt
== 1) {
+ /* for now only check simple case where primary key and
group by expression is a single column*/
+ sql_exp* gbe = ((list*) inner->r)->h->data;
+ assert(gbe->type == e_column);
+ sql_column* pkc = ((sql_kc *)pki->columns->h->data)->c;
+ if (strcmp(gbe->alias.name, pkc->base.name) == 0) {
+ node *n;
+ for (n = ukil->h; n; n = n->next){
+ sql_idx* uki = n->data;
+ if (uki->columns->cnt == 1) {
+ /* for now only check simple
case where unique key is a single column*/
+ sql_column* ukc = ((sql_kc
*)uki->columns->h->data)->c;
+ if (strcmp(exp->alias.name,
ukc->base.name) == 0)
+ allow = true;
+ }
+ }
+ }
+ }
+
+ /* sufficiency condition: abort if relation contains union
subrelation
+ * because it may break functional dependency between pk and uk
*/
+ visitor v = {.sql=sql};
+ rel_visitor_topdown(&v, inner, &find_union);
+ if (v.data)
+ allow = false;
+ }
+
+ return allow;
+
+}
+
static sql_exp *
rel_column_ref(sql_query *query, sql_rel **rel, symbol *column_r, int f)
{
@@ -1422,48 +1475,9 @@ rel_column_ref(sql_query *query, sql_rel
}
if (!exp) {
if (inner && !is_sql_aggr(f) && is_groupby(inner->op)
&& inner->l && (exp = rel_bind_column3(sql, inner->l, sname, tname, cname, f)))
{
- sql_table* t = find_table_or_view_on_scope(sql,
NULL, sname, tname, "SELECT", false);
- bool check_pk_with_uk = false;
- if (t) {
- sql_idx* pki = NULL;
- sql_idx* uki = NULL;
- for (node * n = ol_first_node(t->idxs);
n; n = n->next) {
- sql_idx *i = n->data;
-
- switch (i->key->type) {
- case pkey:
- pki = i;
- continue;
- case ukey:
- case unndkey:
- uki = i;
- continue;
- default:
- continue;
- }
- }
-
- if (uki && pki) {
- if (pki->columns->cnt == 1 &&
uki->columns->cnt == 1 && ((list*) inner->r)->cnt == 1) {
- sql_column* pkc =
((sql_kc *)pki->columns->h->data)->c;
- sql_column* ukc =
((sql_kc *)uki->columns->h->data)->c;
- (void) pkc;
- (void) ukc;
- sql_exp* gbe = ((list*)
inner->r)->h->data;
- assert(gbe->type ==
e_column);
- if
(strcmp(gbe->alias.name, pkc->base.name) == 0 && strcmp(exp->alias.name,
ukc->base.name) == 0)
-
check_pk_with_uk = true;
- }
- }
- if (check_pk_with_uk) {
- visitor v = {.sql=sql};
- rel_visitor_topdown(&v, inner,
&find_union);
- if (v.data)
- check_pk_with_uk =
false;
- }
- }
-
- if (check_pk_with_uk) {
+ if (group_by_pk_project_uk_cond(sql, inner,
exp, sname, tname)) {
+ /* SQL23 feature: very special case
where primary key is used in GROUP BY expression and
+ * unique key is in the project list or
ORDER BY clause */
sql->session->status = 0;
sql->errstr[0] = 0;
exp->card = CARD_AGGR;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]