LCOV - code coverage report
Current view: top level - sql/backends/monet5 - rel_predicates.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 59 71.2 %
Date: 2021-10-13 02:24:04 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : 
      11             : #include "rel_predicates.h"
      12             : #include "rel_rel.h"
      13             : #include "rel_exp.h"
      14             : #include "mal_backend.h"
      15             : 
      16             : static sql_column *
      17         585 : bt_find_column( sql_rel *rel, char *tname, char *name)
      18             : {
      19         585 :         if (!rel || !rel->exps || !rel->l)
      20             :                 return NULL;
      21             :         sql_exp *ne = NULL;
      22             :         sql_table *t = rel->l;
      23         585 :         if ((ne = exps_bind_column2(rel->exps, tname, name, NULL)) != NULL)
      24         585 :                 return find_sql_column(t, ne->r);
      25             :         return NULL;
      26             : }
      27             : 
      28             : static sql_column *
      29         591 : exp_find_column( sql_rel *rel, sql_exp *exp)
      30             : {
      31         820 :         if (exp->type == e_column)
      32         585 :                 return bt_find_column(is_basetable(rel->op)?rel:rel->l, exp->l, exp->r);
      33         235 :         if (exp->type == e_convert)
      34         229 :                 return exp_find_column( rel, exp->l);
      35             :         return NULL;
      36             : }
      37             : 
      38             : static sql_rel *
      39       26492 : rel_find_predicates(visitor *v, sql_rel *rel)
      40             : {
      41             :         bool needall = false;
      42             : 
      43       26492 :         if (is_basetable(rel->op)) {
      44        3322 :                 sql_table *t = rel->l;
      45             : 
      46        3322 :                 if (!t || !rel->exps || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
      47             :                         return rel;
      48        1813 :                 sql_rel *parent = v->parent;
      49             : 
      50             :                 /* select with basetable */
      51        1813 :                 if (is_select(parent->op)) {
      52             :                         /* add predicates */
      53        1356 :                         for (node *n = parent->exps->h; n && !needall; n = n->next) {
      54         764 :                                 sql_exp *e = n->data, *r = e->r, *r2 = e->f;
      55             :                                 sql_column *c = NULL;
      56             : 
      57         764 :                                 if (!is_compare(e->type) || !is_theta_exp(e->flag) || r->type != e_atom || !r->l || (r2 && (r2->type != e_atom || !r2->l)) || is_symmetric(e) || !(c = exp_find_column(rel, e->l))) {
      58             :                                         needall = true;
      59         585 :                                 } else if (isNew(c)) {
      60           0 :                                         continue;
      61             :                                 } else {
      62         585 :                                         atom *e1 = r && r->l ? atom_dup(NULL, r->l) : NULL, *e2 = r2 && r2->l ? atom_dup(NULL, r2->l) : NULL;
      63             : 
      64         585 :                                         if ((r && r->l && !e1) || (r2 && r2->l && !e2)) {
      65           0 :                                                 if (e1) {
      66           0 :                                                         VALclear(&e1->data);
      67           0 :                                                         _DELETE(e1);
      68             :                                                 }
      69           0 :                                                 if (e2) {
      70           0 :                                                         VALclear(&e2->data);
      71           0 :                                                         _DELETE(e2);
      72             :                                                 }
      73           0 :                                                 return sql_error(v->sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      74             :                                         }
      75             : 
      76         585 :                                         if (sql_trans_add_predicate(v->sql->session->tr, c, e->flag, e1, e2, is_anti(e), is_semantics(e)) != LOG_OK) {
      77           0 :                                                 if (e1) {
      78           0 :                                                         VALclear(&e1->data);
      79           0 :                                                         _DELETE(e1);
      80             :                                                 }
      81           0 :                                                 if (e2) {
      82           0 :                                                         VALclear(&e2->data);
      83           0 :                                                         _DELETE(e2);
      84             :                                                 }
      85           0 :                                                 return sql_error(v->sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      86             :                                         }
      87         585 :                                         v->changes++;
      88             :                                 }
      89             :                         }
      90             :                 }
      91             : 
      92        1813 :                 if (!is_select(parent->op) || needall) {
      93             :                         /* any other case, add all predicates */
      94        1400 :                         sql_table *t = rel->l;
      95             : 
      96        1400 :                         if (!t || !rel->exps || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
      97             :                                 return rel;
      98        6111 :                         for (node *n = rel->exps->h; n; n = n->next) {
      99        4711 :                                 sql_exp *e = n->data;
     100             : 
     101        4711 :                                 if (!is_intern(e)) {
     102        3357 :                                         sql_column *c = find_sql_column(t, e->r);
     103             : 
     104        3357 :                                         assert(c);
     105        3357 :                                         if (isNew(c))
     106           0 :                                                 continue;
     107        3357 :                                         if (sql_trans_add_predicate(v->sql->session->tr, c, 0, NULL, NULL, false, false) != LOG_OK)
     108           0 :                                                 return sql_error(v->sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     109        3357 :                                         v->changes++;
     110             :                                 }
     111             :                         }
     112             :                 }
     113             :         }
     114             :         return rel;
     115             : }
     116             : 
     117             : sql_rel *
     118       70140 : rel_predicates(backend *be, sql_rel *rel)
     119             : {
     120       70140 :         if (be->mvc->session->level < tr_serializable)
     121             :                 return rel;
     122        8259 :         visitor v = { .sql = be->mvc };
     123        8259 :         rel = rel_visitor_topdown(&v, rel, &rel_find_predicates);
     124        8259 :         return rel;
     125             : }
     126             : 
     127             : int
     128       28046 : add_column_predicate(backend *be, sql_column *c)
     129             : {
     130       28046 :         if (be->mvc->session->level < tr_serializable || isNew(c) || !isGlobal(c->t) || isGlobalTemp(c->t))
     131             :                 return LOG_OK;
     132         989 :         return sql_trans_add_predicate(be->mvc->session->tr, c, 0, NULL, NULL, false, false);
     133             : }

Generated by: LCOV version 1.14