LCOV - code coverage report
Current view: top level - sql/server - rel_basetable.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 263 315 83.5 %
Date: 2021-10-13 02:24:04 Functions: 21 24 87.5 %

          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             : #include "rel_rel.h"
      11             : #include "rel_exp.h"
      12             : #include "rel_prop.h"
      13             : #include "rel_basetable.h"
      14             : #include "rel_remote.h"
      15             : #include "sql_privileges.h"
      16             : 
      17             : #define USED_LEN(nr) ((nr+31)/32)
      18             : #define rel_base_set_used(b,nr) b->used[(nr)/32] |= (1<<((nr)%32))
      19             : #define rel_base_is_used(b,nr) ((b->used[(nr)/32]&(1<<((nr)%32))) != 0)
      20             : 
      21             : typedef struct rel_base_t {
      22             :         sql_table *mt;
      23             :         char *name;
      24             :         int disallowed; /* ie check per column */
      25             :         int used[FLEXIBLE_ARRAY_MEMBER];
      26             : } rel_base_t;
      27             : 
      28             : void
      29          66 : rel_base_disallow(sql_rel *r)
      30             : {
      31          66 :         rel_base_t *ba = r->r;
      32          66 :         ba->disallowed = 1;
      33          66 : }
      34             : 
      35             : char *
      36       91325 : rel_base_name(sql_rel *r)
      37             : {
      38       91325 :         sql_table *t = r->l;
      39       91325 :         rel_base_t *ba = r->r;
      40       91325 :         if (ba->name)
      41             :                 return ba->name;
      42       89933 :         return t->base.name;
      43             : }
      44             : 
      45             : char *
      46           0 : rel_base_rename(sql_rel *r, char *name)
      47             : {
      48           0 :         rel_base_t *ba = r->r;
      49           0 :         ba->name = name;
      50           0 :         return name;
      51             : }
      52             : 
      53             : int
      54     1480484 : rel_base_use( mvc *sql, sql_rel *rt, int nr)
      55             : {
      56     1480484 :         assert(is_basetable(rt->op));
      57     1480484 :         sql_table *t = rt->l;
      58     1480484 :         rel_base_t *ba = rt->r;
      59             : 
      60     1480484 :         if (ba->disallowed && nr < ol_length(t->columns)) {
      61          25 :                 sql_column *c = ol_fetch(t->columns, nr);
      62          25 :                 if (!column_privs(sql, c, PRIV_SELECT))
      63             :                         return -1;
      64             :         }
      65     1480474 :         rel_base_set_used(ba, nr);
      66     1480474 :         return 0;
      67             : }
      68             : 
      69             : void
      70        6389 : rel_base_use_tid( mvc *sql, sql_rel *rt)
      71             : {
      72        6389 :         sql_table *t = rt->l;
      73        6389 :         rel_base_use(sql, rt, ol_length(t->columns));
      74        6389 : }
      75             : 
      76             : void
      77      424497 : rel_base_use_all( mvc *sql, sql_rel *rel)
      78             : {
      79      424497 :         sql_table *t = rel->l;
      80      424497 :         rel_base_t *ba = rel->r;
      81             : 
      82      424497 :         if (ba->disallowed) {
      83             :                 int i = 0;
      84          15 :                 for (node *cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
      85          11 :                         sql_column *c = cn->data;
      86          11 :                         if (!column_privs(sql, c, PRIV_SELECT))
      87           6 :                                 continue;
      88           5 :                         rel_base_set_used(ba, i);
      89             :                 }
      90             :         } else {
      91      424493 :                 int len = USED_LEN(ol_length(t->columns) + 1 + ol_length(t->idxs));
      92      858461 :                 for (int i = 0; i < len; i++)
      93      433968 :                         ba->used[i] = ~0;
      94             :         }
      95      424497 : }
      96             : 
      97             : sql_rel *
      98      482604 : rel_basetable(mvc *sql, sql_table *t, const char *atname)
      99             : {
     100      482604 :         sql_allocator *sa = sql->sa;
     101      482604 :         sql_rel *rel = rel_create(sa);
     102      482604 :         int nrcols = ol_length(t->columns), end = nrcols + 1 + ol_length(t->idxs);
     103      482604 :         rel_base_t *ba = (rel_base_t*)sa_zalloc(sa, sizeof(rel_base_t) + sizeof(int)*USED_LEN(end));
     104             : 
     105      482604 :         if(!rel || !ba)
     106             :                 return NULL;
     107             : 
     108      482604 :         assert(atname);
     109      482604 :         if (strcmp(atname, t->base.name) != 0)
     110      235070 :                 ba->name = sa_strdup(sa, atname);
     111     1114869 :         for(int i = nrcols; i<end; i++)
     112      632265 :                 rel_base_set_used(ba, i);
     113      482604 :         rel->l = t;
     114      482604 :         rel->r = ba;
     115      482604 :         rel->op = op_basetable;
     116      482604 :         rel->card = CARD_MULTI;
     117      482604 :         rel->nrcols = nrcols;
     118      482604 :         return rel;
     119             : }
     120             : 
     121             : void
     122          29 : rel_base_copy(mvc *sql, sql_rel *in, sql_rel *out)
     123             : {
     124          29 :         sql_allocator *sa = sql->sa;
     125          29 :         sql_table *t = in->l;
     126          29 :         rel_base_t *ba = in->r;
     127             : 
     128          29 :         assert(is_basetable(in->op) && is_basetable(out->op));
     129          29 :         int nrcols = ol_length(t->columns), end = nrcols + 1 + ol_length(t->idxs);
     130          29 :         size_t bsize = sizeof(rel_base_t) + sizeof(int)*USED_LEN(end);
     131          29 :         rel_base_t *nba = (rel_base_t*)sa_alloc(sa, bsize);
     132             : 
     133          29 :         memcpy(nba, ba, bsize);
     134          29 :         if (ba->name)
     135           0 :                 nba->name = sa_strdup(sa, ba->name);
     136             : 
     137          29 :         out->l = t;
     138          29 :         out->r = nba;
     139          29 : }
     140             : 
     141             : sql_rel *
     142           0 : rel_base_bind_column_( sql_rel *rel, const char *cname)
     143             : {
     144           0 :         sql_table *t = rel->l;
     145           0 :         node *n = ol_find_name(t->columns, cname);
     146           0 :         if (n)
     147           0 :                 return rel;
     148             :         return NULL;
     149             : }
     150             : 
     151             : static sql_exp *
     152     1980525 : bind_col_exp(mvc *sql, char *name, sql_column *c)
     153             : {
     154             :         prop *p = NULL;
     155     1980525 :         sql_exp *e = exp_column(sql->sa, name, c->base.name, &c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
     156             : 
     157     1980525 :         if (c->t->pkey && ((sql_kc*)c->t->pkey->k.columns->h->data)->c == c) {
     158       91513 :                 p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
     159       91513 :                 p->value = c->t->pkey;
     160     1889012 :         } else if (c->unique == 2) {
     161       26309 :                 p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
     162       26309 :                 p->value = NULL;
     163             :         }
     164     1980525 :         set_basecol(e);
     165     1980525 :         return e;
     166             : }
     167             : 
     168             : static sql_exp *
     169     1405026 : bind_col(mvc *sql, sql_rel *rel, char *name, sql_column *c )
     170             : {
     171     1405026 :         if (rel_base_use(sql, rel, c->colnr)) {
     172             :                 /* error */
     173             :                 return NULL;
     174             :         }
     175     1405016 :         return bind_col_exp(sql, name, c);
     176             : }
     177             : 
     178             : sql_exp *
     179         218 : rel_base_bind_colnr( mvc *sql, sql_rel *rel, int nr)
     180             : {
     181         218 :         sql_table *t = rel->l;
     182         218 :         rel_base_t *ba = rel->r;
     183         218 :         return bind_col(sql, rel, ba->name?ba->name:t->base.name, ol_fetch(t->columns, nr));
     184             : }
     185             : 
     186             : sql_exp *
     187     3941299 : rel_base_bind_column( mvc *sql, sql_rel *rel, const char *cname, int no_tname)
     188             : {
     189     3941299 :         sql_table *t = rel->l;
     190     3941299 :         rel_base_t *ba = rel->r;
     191             :         (void)no_tname;
     192     3941299 :         node *n = ol_find_name(t->columns, cname);
     193     3941299 :         if (!n)
     194             :                 return NULL;
     195      711089 :         return bind_col(sql, rel, ba->name?ba->name:t->base.name, n->data);
     196             : }
     197             : 
     198             : sql_rel *
     199     1835261 : rel_base_bind_column2_( sql_rel *rel, const char *tname, const char *cname)
     200             : {
     201     1835261 :         sql_table *t = rel->l;
     202     1835261 :         rel_base_t *ba = rel->r;
     203             : 
     204     1835261 :         assert(ba);
     205     1835261 :         if ((ba->name && strcmp(ba->name, tname) != 0) || (!ba->name && strcmp(t->base.name, tname) != 0))
     206             :                 return NULL;
     207      360546 :         node *n = ol_find_name(t->columns, cname);
     208      360546 :         if (!n)
     209           0 :                 return NULL;
     210             :         return rel;
     211             : }
     212             : 
     213             : sql_exp *
     214     1229739 : rel_base_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname)
     215             : {
     216     1229739 :         sql_table *t = rel->l;
     217     1229739 :         rel_base_t *ba = rel->r;
     218             : 
     219     1229739 :         assert(ba);
     220     1229739 :         if ((ba->name && strcmp(ba->name, tname) != 0) || (!ba->name && strcmp(t->base.name, tname) != 0))
     221             :                 return NULL;
     222      575558 :         node *n = ol_find_name(t->columns, cname);
     223      575558 :         if (!n)
     224             :                 return NULL;
     225      575553 :         sql_column *c = n->data;
     226      575553 :         return bind_col(sql, rel, ba->name?ba->name:t->base.name, c);
     227             : }
     228             : 
     229             : list *
     230       90620 : rel_base_projection( mvc *sql, sql_rel *rel, int intern)
     231             : {
     232             :         int i = 0;
     233       90620 :         sql_table *t = rel->l;
     234       90620 :         rel_base_t *ba = rel->r;
     235       90620 :         char *name = ba->name?ba->name:t->base.name;
     236       90620 :         list *exps = new_exp_list(sql->sa);
     237             :         prop *p;
     238             : 
     239      666135 :         for (node *cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
     240      575515 :                 if (rel_base_is_used(ba, i))
     241      575509 :                         append(exps, bind_col_exp(sql, name, cn->data));
     242             :         }
     243       90620 :         if ((intern && rel_base_is_used(ba, i)) || list_empty(exps)) /* Add TID column if no column is used */
     244       84922 :                 append(exps, exp_column(sql->sa, name, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
     245       90620 :         i++;
     246       90620 :         if (intern) {
     247      126825 :                 for (node *in = ol_first_node(t->idxs); in; in = in->next, i++) {
     248       41903 :                         if (rel_base_is_used(ba, i)) {
     249       41903 :                                 sql_idx *i = in->data;
     250       41903 :                                 sql_subtype *t = sql_bind_localtype("lng"); /* hash "lng" */
     251             :                                 int has_nils = 0, unique;
     252             : 
     253       41903 :                                 if ((hash_index(i->type) && list_length(i->columns) <= 1) || !idx_has_column(i->type))
     254       41011 :                                         continue;
     255             : 
     256         892 :                                 if (i->type == join_idx)
     257         765 :                                         t = sql_bind_localtype("oid");
     258             : 
     259         892 :                                 char *iname = sa_strconcat( sql->sa, "%", i->base.name);
     260        1915 :                                 for (node *n = i->columns->h ; n && !has_nils; n = n->next) { /* check for NULL values */
     261        1023 :                                         sql_kc *kc = n->data;
     262             : 
     263        1023 :                                         if (kc->c->null)
     264             :                                                 has_nils = 1;
     265             :                                 }
     266         892 :                                 unique = list_length(i->columns) == 1 && is_column_unique(((sql_kc*)i->columns->h->data)->c);
     267         892 :                                 sql_exp *e = exp_column(sql->sa, name, iname, t, CARD_MULTI, has_nils, unique, 1);
     268         892 :                                 if (hash_index(i->type)) {
     269         127 :                                         p = e->p = prop_create(sql->sa, PROP_HASHIDX, e->p);
     270         127 :                                         p->value = i;
     271             :                                 }
     272         892 :                                 if (i->type == join_idx) {
     273         765 :                                         p = e->p = prop_create(sql->sa, PROP_JOINIDX, e->p);
     274         765 :                                         p->value = i;
     275             :                                 }
     276         892 :                                 append(exps, e);
     277             :                         }
     278             :                 }
     279             :         }
     280       90620 :         return exps;
     281             : }
     282             : 
     283             : list *
     284       11922 : rel_base_project_all( mvc *sql, sql_rel *rel, char *tname)
     285             : {
     286       11922 :         sql_table *t = rel->l;
     287       11922 :         rel_base_t *ba = rel->r;
     288       11922 :         char *name = ba->name?ba->name:t->base.name;
     289       11922 :         list *exps = new_exp_list(sql->sa);
     290             : 
     291       11922 :         if (!exps || strcmp(name, tname) != 0)
     292             :                 return NULL;
     293             : 
     294      130076 :         for (node *cn = ol_first_node(t->columns); cn; cn = cn->next)
     295      118166 :                 append(exps, bind_col( sql, rel, name, cn->data));
     296             :         return exps;
     297             : }
     298             : 
     299             : sql_rel *
     300         427 : rel_base_add_columns( mvc *sql, sql_rel *r)
     301             : {
     302         427 :         sql_table *t = r->l;
     303         427 :         rel_base_t *ba = r->r;
     304             : 
     305         427 :         r->exps = new_exp_list(sql->sa);
     306         427 :         if(!r->exps) {
     307           0 :                 rel_destroy(r);
     308           0 :                 return NULL;
     309             :         }
     310             : 
     311             :         int i = 0;
     312             :         prop *p = NULL;
     313             :         node *cn;
     314         427 :         const char *tname = t->base.name;
     315         427 :         const char *atname = ba->name?ba->name:tname;
     316             : 
     317        1278 :         for (cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
     318         851 :                 sql_column *c = cn->data;
     319         851 :                 sql_exp *e = exp_alias(sql->sa, atname, c->base.name, tname, c->base.name, &c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
     320             : 
     321         851 :                 if (e == NULL) {
     322           0 :                         rel_destroy(r);
     323           0 :                         return NULL;
     324             :                 }
     325         851 :                 if (c->t->pkey && ((sql_kc*)c->t->pkey->k.columns->h->data)->c == c) {
     326           0 :                         p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
     327           0 :                         p->value = c->t->pkey;
     328         851 :                 } else if (c->unique == 2) {
     329           0 :                         p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
     330           0 :                         p->value = NULL;
     331             :                 }
     332         851 :                 set_basecol(e);
     333         851 :                 append(r->exps, e);
     334             :         }
     335             :         return r;
     336             : }
     337             : 
     338             : sql_rel *
     339     3631674 : rewrite_basetable(mvc *sql, sql_rel *rel)
     340             : {
     341     3631674 :         if (is_basetable(rel->op) && !rel->exps) {
     342      430499 :                 sql_allocator *sa = sql->sa;
     343      430499 :                 sql_table *t = rel->l;
     344      430499 :                 rel_base_t *ba = rel->r;
     345             : 
     346      430499 :                 rel->exps = new_exp_list(sa);
     347      430499 :                 if(!rel->exps) {
     348           0 :                         rel_destroy(rel);
     349           0 :                         return NULL;
     350             :                 }
     351             : 
     352             :                 int i = 0;
     353             :                 prop *p = NULL;
     354             :                 node *cn;
     355      430499 :                 const char *tname = t->base.name;
     356      430499 :                 const char *atname = ba->name?ba->name:tname;
     357             : 
     358      430499 :                 if (isRemote(t))
     359         175 :                         tname = mapiuri_table(t->query, sql->sa, tname);
     360     3174876 :                 for (cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
     361     2744377 :                         if (!rel_base_is_used(ba, i))
     362      778906 :                                 continue;
     363             : 
     364     1965471 :                         sql_column *c = cn->data;
     365     1965471 :                         sql_exp *e = exp_alias(sa, atname, c->base.name, tname, c->base.name, &c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
     366             : 
     367     1965471 :                         if (e == NULL) {
     368           0 :                                 rel_destroy(rel);
     369           0 :                                 return NULL;
     370             :                         }
     371     1965471 :                         if (c->t->pkey && ((sql_kc*)c->t->pkey->k.columns->h->data)->c == c) {
     372       66866 :                                 p = e->p = prop_create(sa, PROP_HASHCOL, e->p);
     373       66866 :                                 p->value = c->t->pkey;
     374     1898605 :                         } else if (c->unique == 2) {
     375       21438 :                                 p = e->p = prop_create(sa, PROP_HASHCOL, e->p);
     376       21438 :                                 p->value = NULL;
     377             :                         }
     378     1965471 :                         set_basecol(e);
     379     1965471 :                         append(rel->exps, e);
     380             :                 }
     381      430499 :                 if (rel_base_is_used(ba, i) || list_empty(rel->exps)) /* Add TID column if no column is used */
     382      430499 :                         append(rel->exps, exp_alias(sa, atname, TID, tname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
     383      430499 :                 i++;
     384             : 
     385      569765 :                 for (cn = ol_first_node(t->idxs); cn; cn = cn->next, i++) {
     386      139266 :                         if (!rel_base_is_used(ba, i))
     387           0 :                                 continue;
     388             : 
     389             :                         sql_exp *e;
     390      139266 :                         sql_idx *i = cn->data;
     391             :                         sql_subtype *t;
     392             :                         char *iname = NULL;
     393             :                         int has_nils = 0, unique;
     394             : 
     395             :                         /* do not include empty indices in the plan */
     396      139266 :                         if ((hash_index(i->type) && list_length(i->columns) <= 1) || !idx_has_column(i->type))
     397      120993 :                                 continue;
     398             : 
     399       18273 :                         t = (i->type == join_idx) ? sql_bind_localtype("oid") : sql_bind_localtype("lng");
     400       18273 :                         iname = sa_strconcat( sa, "%", i->base.name);
     401       40240 :                         for (node *n = i->columns->h ; n && !has_nils; n = n->next) { /* check for NULL values */
     402       21967 :                                 sql_kc *kc = n->data;
     403             : 
     404       21967 :                                 if (kc->c->null)
     405             :                                         has_nils = 1;
     406             :                         }
     407       18273 :                         unique = list_length(i->columns) == 1 && is_column_unique(((sql_kc*)i->columns->h->data)->c);
     408       18273 :                         e = exp_alias(sa, atname, iname, tname, iname, t, CARD_MULTI, has_nils, unique, 1);
     409             :                         /* index names are prefixed, to make them independent */
     410       18273 :                         if (hash_index(i->type)) {
     411       10007 :                                 p = e->p = prop_create(sa, PROP_HASHIDX, e->p);
     412       10007 :                                 p->value = i;
     413             :                         }
     414       18273 :                         if (i->type == join_idx) {
     415        8266 :                                 p = e->p = prop_create(sa, PROP_JOINIDX, e->p);
     416        8266 :                                 p->value = i;
     417             :                         }
     418       18273 :                         append(rel->exps, e);
     419             :                 }
     420             :         }
     421             :         return rel;
     422             : }
     423             : 
     424             : sql_rel *
     425         406 : rel_rename_part(mvc *sql, sql_rel *p, sql_rel *mt_rel, const char *mtalias)
     426             : {
     427         406 :         sql_table *mt = rel_base_table(mt_rel), *t = rel_base_table(p);
     428             : 
     429         406 :         assert(!p->exps);
     430         406 :         p->exps = sa_list(sql->sa);
     431         406 :         const char *pname = t->base.name;
     432         406 :         if (isRemote(t))
     433          25 :                 pname = mapiuri_table(t->query, sql->sa, pname);
     434        1165 :         for (node *n = mt_rel->exps->h; n; n = n->next) {
     435         759 :                 sql_exp *e = n->data;
     436             :                 node *cn = NULL, *ci = NULL;
     437         759 :                 const char *nname = exp_name(e);
     438             : 
     439         759 :                 if (nname[0] == '%' && strcmp(nname, TID) == 0) {
     440          41 :                         list_append(p->exps, exp_alias(sql->sa, mtalias, TID, pname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
     441          41 :                         rel_base_use_tid(sql, p);
     442        1434 :                 } else if (nname[0] != '%' && (cn = ol_find_name(mt->columns, nname))) {
     443         716 :                         sql_column *c = cn->data, *rc = ol_fetch(t->columns, c->colnr);
     444             : 
     445             :                         /* with name find column in merge table, with colnr find column in member */
     446         716 :                         sql_exp *ne = exp_alias(sql->sa, mtalias, c->base.name, pname, rc->base.name, &rc->type, CARD_MULTI, rc->null, is_column_unique(rc), 0);
     447         716 :                         if (rc->t->pkey && ((sql_kc*)rc->t->pkey->k.columns->h->data)->c == rc) {
     448          22 :                                 prop *p = ne->p = prop_create(sql->sa, PROP_HASHCOL, ne->p);
     449          22 :                                 p->value = rc->t->pkey;
     450         694 :                         } else if (rc->unique == 2) {
     451           0 :                                 prop *p = ne->p = prop_create(sql->sa, PROP_HASHCOL, ne->p);
     452           0 :                                 p->value = NULL;
     453             :                         }
     454         716 :                         set_basecol(ne);
     455         716 :                         rel_base_use(sql, p, rc->colnr);
     456         716 :                         list_append(p->exps, ne);
     457           2 :                 } else if (nname[0] == '%' && ol_length(mt->idxs) && (ci = ol_find_name(mt->idxs, nname + 1))) {
     458           2 :                         sql_idx *i = ci->data, *ri = NULL;
     459             : 
     460             :                         /* indexes don't have a number field like 'colnr', so get the index the old way */
     461           4 :                         for (node *nn = mt->idxs->l->h, *mm = t->idxs->l->h; nn && mm ; nn = nn->next, mm = mm->next) {
     462           4 :                                 sql_idx *ii = nn->data;
     463             : 
     464           4 :                                 if (ii->base.id == i->base.id) {
     465           2 :                                         ri = mm->data;
     466           2 :                                         break;
     467             :                                 }
     468             :                         }
     469             : 
     470           2 :                         assert((!hash_index(ri->type) || list_length(ri->columns) > 1) && idx_has_column(ri->type));
     471           2 :                         sql_subtype *t = (ri->type == join_idx) ? sql_bind_localtype("oid") : sql_bind_localtype("lng");
     472           2 :                         char *iname1 = sa_strconcat(sql->sa, "%", i->base.name), *iname2 = sa_strconcat(sql->sa, "%", ri->base.name);
     473             : 
     474           2 :                         sql_exp *ne = exp_alias(sql->sa, mtalias, iname1, pname, iname2, t, CARD_MULTI, has_nil(e), is_unique(e), 1);
     475             :                         /* index names are prefixed, to make them independent */
     476           2 :                         if (hash_index(ri->type)) {
     477           0 :                                 prop *p = ne->p = prop_create(sql->sa, PROP_HASHIDX, ne->p);
     478           0 :                                 p->value = ri;
     479           2 :                         } else if (ri->type == join_idx) {
     480           2 :                                 prop *p = ne->p = prop_create(sql->sa, PROP_JOINIDX, ne->p);
     481           2 :                                 p->value = ri;
     482             :                         }
     483           2 :                         list_append(p->exps, ne);
     484             :                 }
     485             :         }
     486         406 :         rel_base_set_mergetable(p, mt);
     487         406 :         return p;
     488             : }
     489             : 
     490             : void
     491           0 : rel_base_dump_exps( stream *fout, sql_rel *rel)
     492             : {
     493             :         int i = 0, comma = 0;
     494           0 :         sql_table *t = rel->l;
     495           0 :         rel_base_t *ba = rel->r;
     496           0 :         assert(ba);
     497           0 :         mnstr_printf(fout, "[ ");
     498           0 :         for (node *cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
     499           0 :                 if (rel_base_is_used(ba, i)) {
     500           0 :                         sql_column *c = cn->data;
     501           0 :                         mnstr_printf(fout, "%s\"%s\".\"%s\"", comma?", ":"", t->base.name, c->base.name);
     502           0 :                         if (ba->name)
     503           0 :                                 mnstr_printf(fout, " as \"%s\".\"%s\"", ba->name, c->base.name);
     504             :                         comma = 1;
     505             :                 }
     506             :         }
     507           0 :         if (rel_base_is_used(ba, i)) {
     508           0 :                 mnstr_printf(fout, "%s\"%s\".\"%%TID\"", comma?", ":"", t->base.name);
     509           0 :                 if (ba->name)
     510           0 :                         mnstr_printf(fout, " as \"%s\".\"%%TID\"", ba->name);
     511             :                 comma = 1;
     512             :         }
     513           0 :         i++;
     514           0 :         for (node *in = ol_first_node(t->idxs); in; in = in->next, i++) {
     515           0 :                 if (rel_base_is_used(ba, i)) {
     516           0 :                         sql_idx *i = in->data;
     517           0 :                         mnstr_printf(fout, "%s\"%s\".\"%s\"", comma?", ":"", t->base.name, i->base.name);
     518           0 :                         if (ba->name)
     519           0 :                                 mnstr_printf(fout, " as \"%s\".\"%s\"", ba->name, i->base.name);
     520             :                         comma = 1;
     521             :                 }
     522             :         }
     523           0 :         mnstr_printf(fout, " ]\n");
     524           0 : }
     525             : 
     526             : int
     527          66 : rel_base_has_column_privileges(mvc *sql, sql_rel *rel)
     528             : {
     529          66 :         sql_table *t = rel->l;
     530             :         int has = 0;
     531             : 
     532         225 :         for (node *m = ol_first_node(t->columns); m && !has; m = m->next) {
     533         159 :                 sql_column *c = m->data;
     534             : 
     535         159 :                 if (column_privs(sql, c, PRIV_SELECT))
     536             :                         has = 1;
     537             :         }
     538          66 :         return has;
     539             : }
     540             : 
     541             : void
     542         406 : rel_base_set_mergetable(sql_rel *rel, sql_table *mt)
     543             : {
     544         406 :         rel_base_t *ba = rel->r;
     545             : 
     546         406 :         if (ba)
     547         406 :                 ba->mt = mt;
     548         406 : }
     549             : 
     550             : sql_table *
     551      402593 : rel_base_get_mergetable(sql_rel *rel)
     552             : {
     553      402593 :         rel_base_t *ba = rel->r;
     554             : 
     555      402593 :         return ba ? ba->mt : NULL;
     556             : }

Generated by: LCOV version 1.14