LCOV - code coverage report
Current view: top level - sql/backends/monet5 - rel_predicates.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 49 68 72.1 %
Date: 2024-10-03 20:03:20 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : 
      15             : #include "rel_predicates.h"
      16             : #include "rel_rel.h"
      17             : #include "rel_exp.h"
      18             : #include "mal_backend.h"
      19             : 
      20             : static sql_column *
      21        4084 : bt_find_column( sql_rel *rel, char *tname, char *name)
      22             : {
      23        4084 :         if (!rel || list_empty(rel->exps) || !rel->l)
      24           0 :                 return NULL;
      25        4084 :         sql_exp *ne = NULL;
      26        4084 :         sql_table *t = rel->l;
      27        4084 :         if ((ne = exps_bind_column2(rel->exps, tname, name, NULL)) != NULL)
      28        4084 :                 return find_sql_column(t, ne->r);
      29             :         return NULL;
      30             : }
      31             : 
      32             : static sql_column *
      33        4097 : exp_find_column( sql_rel *rel, sql_exp *exp)
      34             : {
      35        4099 :         if (exp->type == e_column)
      36        4084 :                 return bt_find_column(is_basetable(rel->op)?rel:rel->l, exp->l, exp->r);
      37          15 :         if (exp->type == e_convert)
      38           2 :                 return exp_find_column( rel, exp->l);
      39             :         return NULL;
      40             : }
      41             : 
      42             : static sql_rel *
      43      135787 : rel_find_predicates(visitor *v, sql_rel *rel)
      44             : {
      45      135787 :         bool needall = false;
      46             : 
      47      135787 :         if (is_basetable(rel->op)) {
      48        8696 :                 sql_table *t = rel->l;
      49             : 
      50        8696 :                 if (!t || list_empty(rel->exps) || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
      51        2264 :                         return rel;
      52        6432 :                 sql_rel *parent = v->parent;
      53             : 
      54             :                 /* select with basetable */
      55        6432 :                 if (is_select(parent->op)) {
      56             :                         /* add predicates */
      57        2273 :                         if (list_empty(parent->exps)) {
      58             :                                 needall = true;
      59             :                         } else {
      60        5016 :                                 for (node *n = parent->exps->h; n && !needall; n = n->next) {
      61        2743 :                                         sql_exp *e = n->data, *r = e->r, *r2 = e->f;
      62        2743 :                                         sql_column *c = NULL;
      63             : 
      64        2743 :                                         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)))
      65             :                                                 needall = true;
      66             :                                 }
      67        2273 :                                 if (!needall) {
      68        3614 :                                         for (node *n = parent->exps->h; n; n = n->next) {
      69        1895 :                                                 sql_exp *e = n->data, *r = e->r, *r2 = e->f;
      70        1895 :                                                 sql_column *c = exp_find_column(rel, e->l);
      71             : 
      72        1895 :                                                 if (isNew(c))
      73           0 :                                                         continue;
      74        1895 :                                                 atom *e1 = r && r->l ? atom_copy(NULL, r->l) : NULL, *e2 = r2 && r2->l ? atom_copy(NULL, r2->l) : NULL;
      75             : 
      76        1895 :                                                 if ((r && r->l && !e1) || (r2 && r2->l && !e2)) {
      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, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      86             :                                                 }
      87             : 
      88        1895 :                                                 if (sql_trans_add_predicate(v->sql->session->tr, c, e->flag, e1, e2, is_anti(e), is_semantics(e)) != LOG_OK) {
      89           0 :                                                         if (e1) {
      90           0 :                                                                 VALclear(&e1->data);
      91           0 :                                                                 _DELETE(e1);
      92             :                                                         }
      93           0 :                                                         if (e2) {
      94           0 :                                                                 VALclear(&e2->data);
      95           0 :                                                                 _DELETE(e2);
      96             :                                                         }
      97           0 :                                                         return sql_error(v->sql, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      98             :                                                 }
      99        1895 :                                                 v->changes++;
     100             :                                         }
     101             :                                 }
     102             :                         }
     103             :                 }
     104             : 
     105        6432 :                 if (!is_select(parent->op) || needall) {
     106             :                         /* any other case, add all predicates */
     107        4713 :                         sql_table *t = rel->l;
     108             : 
     109        4713 :                         if (!t || list_empty(rel->exps) || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
     110           0 :                                 return rel;
     111       22633 :                         for (node *n = rel->exps->h; n; n = n->next) {
     112       17920 :                                 sql_exp *e = n->data;
     113             : 
     114       17920 :                                 if (!is_intern(e)) {
     115       13682 :                                         sql_column *c = find_sql_column(t, e->r);
     116             : 
     117       13682 :                                         assert(c);
     118       13682 :                                         if (isNew(c))
     119           0 :                                                 continue;
     120       13682 :                                         if (sql_trans_add_predicate(v->sql->session->tr, c, 0, NULL, NULL, false, false) != LOG_OK)
     121           0 :                                                 return sql_error(v->sql, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     122       13682 :                                         v->changes++;
     123             :                                 }
     124             :                         }
     125             :                 }
     126             :         }
     127             :         return rel;
     128             : }
     129             : 
     130             : sql_rel *
     131       98498 : rel_predicates(backend *be, sql_rel *rel)
     132             : {
     133       98498 :         if ((be->mvc->session->level & tr_snapshot) == tr_snapshot)
     134             :                 return rel;
     135       98498 :         visitor v = { .sql = be->mvc };
     136       98498 :         rel = rel_visitor_topdown(&v, rel, &rel_find_predicates);
     137       98498 :         return rel;
     138             : }

Generated by: LCOV version 1.14