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-12-20 21:24:02 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             : #include "sql_storage.h"
      20             : 
      21             : static sql_column *
      22        4934 : bt_find_column( sql_rel *rel, char *tname, char *name)
      23             : {
      24        4934 :         if (!rel || list_empty(rel->exps) || !rel->l)
      25           0 :                 return NULL;
      26        4934 :         sql_exp *ne = NULL;
      27        4934 :         sql_table *t = rel->l;
      28        4934 :         if ((ne = exps_bind_column2(rel->exps, tname, name, NULL)) != NULL)
      29        4934 :                 return find_sql_column(t, ne->r);
      30             :         return NULL;
      31             : }
      32             : 
      33             : static sql_column *
      34        4947 : exp_find_column( sql_rel *rel, sql_exp *exp)
      35             : {
      36        4949 :         if (exp->type == e_column)
      37        4934 :                 return bt_find_column(is_basetable(rel->op)?rel:rel->l, exp->l, exp->r);
      38          15 :         if (exp->type == e_convert)
      39           2 :                 return exp_find_column( rel, exp->l);
      40             :         return NULL;
      41             : }
      42             : 
      43             : static sql_rel *
      44      147800 : rel_find_predicates(visitor *v, sql_rel *rel)
      45             : {
      46      147800 :         bool needall = false;
      47             : 
      48      147800 :         if (is_basetable(rel->op)) {
      49        9165 :                 sql_table *t = rel->l;
      50             : 
      51        9165 :                 if (!t || list_empty(rel->exps) || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
      52        2264 :                         return rel;
      53        6901 :                 sql_rel *parent = v->parent;
      54             : 
      55             :                 /* select with basetable */
      56        6901 :                 if (is_select(parent->op)) {
      57             :                         /* add predicates */
      58        2627 :                         if (list_empty(parent->exps)) {
      59             :                                 needall = true;
      60             :                         } else {
      61        5996 :                                 for (node *n = parent->exps->h; n && !needall; n = n->next) {
      62        3369 :                                         sql_exp *e = n->data, *r = e->r, *r2 = e->f;
      63        3369 :                                         sql_column *c = NULL;
      64             : 
      65        3369 :                                         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)))
      66             :                                                 needall = true;
      67             :                                 }
      68        2627 :                                 if (!needall) {
      69        4192 :                                         for (node *n = parent->exps->h; n; n = n->next) {
      70        2232 :                                                 sql_exp *e = n->data, *r = e->r, *r2 = e->f;
      71        2232 :                                                 sql_column *c = exp_find_column(rel, e->l);
      72             : 
      73        2232 :                                                 if (isNew(c))
      74           0 :                                                         continue;
      75        2232 :                                                 atom *e1 = r && r->l ? atom_copy(NULL, r->l) : NULL, *e2 = r2 && r2->l ? atom_copy(NULL, r2->l) : NULL;
      76             : 
      77        2232 :                                                 if ((r && r->l && !e1) || (r2 && r2->l && !e2)) {
      78           0 :                                                         if (e1) {
      79           0 :                                                                 VALclear(&e1->data);
      80           0 :                                                                 _DELETE(e1);
      81             :                                                         }
      82           0 :                                                         if (e2) {
      83           0 :                                                                 VALclear(&e2->data);
      84           0 :                                                                 _DELETE(e2);
      85             :                                                         }
      86           0 :                                                         return sql_error(v->sql, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      87             :                                                 }
      88             : 
      89        2232 :                                                 if (sql_trans_add_predicate(v->sql->session->tr, c, e->flag, e1, e2, is_anti(e), is_semantics(e)) != LOG_OK) {
      90           0 :                                                         if (e1) {
      91           0 :                                                                 VALclear(&e1->data);
      92           0 :                                                                 _DELETE(e1);
      93             :                                                         }
      94           0 :                                                         if (e2) {
      95           0 :                                                                 VALclear(&e2->data);
      96           0 :                                                                 _DELETE(e2);
      97             :                                                         }
      98           0 :                                                         return sql_error(v->sql, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
      99             :                                                 }
     100        2232 :                                                 v->changes++;
     101             :                                         }
     102             :                                 }
     103             :                         }
     104             :                 }
     105             : 
     106        6901 :                 if (!is_select(parent->op) || needall) {
     107             :                         /* any other case, add all predicates */
     108        4941 :                         sql_table *t = rel->l;
     109             : 
     110        4941 :                         if (!t || list_empty(rel->exps) || isNew(t) || !isGlobal(t) || isGlobalTemp(t))
     111           0 :                                 return rel;
     112       24642 :                         for (node *n = rel->exps->h; n; n = n->next) {
     113       19701 :                                 sql_exp *e = n->data;
     114             : 
     115       19701 :                                 if (!is_intern(e)) {
     116       15320 :                                         sql_column *c = find_sql_column(t, e->r);
     117             : 
     118       15320 :                                         assert(c);
     119       15320 :                                         if (isNew(c))
     120           0 :                                                 continue;
     121       15320 :                                         if (sql_trans_add_predicate(v->sql->session->tr, c, 0, NULL, NULL, false, false) != LOG_OK)
     122           0 :                                                 return sql_error(v->sql, 10, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     123       15320 :                                         v->changes++;
     124             :                                 }
     125             :                         }
     126             :                 }
     127             :         }
     128             :         return rel;
     129             : }
     130             : 
     131             : sql_rel *
     132      109187 : rel_predicates(backend *be, sql_rel *rel)
     133             : {
     134      109187 :         if ((be->mvc->session->level & tr_snapshot) == tr_snapshot)
     135             :                 return rel;
     136      109252 :         visitor v = { .sql = be->mvc };
     137      109252 :         rel = rel_visitor_topdown(&v, rel, &rel_find_predicates);
     138      109252 :         return rel;
     139             : }

Generated by: LCOV version 1.14