# 2.11BSD#431 - /usr/ingres/source/qrymod/util.c

##### Functions

    appqual           X
    ferror            X
    lsetbit           X
    makezero          X
    mergevar          X
    trimqlend         X
    xerror            X

##### Variables

    Qmdname           X

       1: # include   "../ingres.h"
       2: # include   "../aux.h"
       3: # include   "../symbol.h"
       4: # include   "../tree.h"
       5: # include   "../pipes.h"
       6: # include   "qrymod.h"
       7:
       8: /*
       9: **  UTIL.C -- qrymod support routines
      10: **
      11: **	This module contains a set of support routines for use
      12: **	by the query modification routines.
      13: **
      14: **	Defined Constants:
      15: **		none
      16: **
      17: **	Defines:
      18: **		trimqlend() -- trim QLEND node off of qualification.
      19: **		appqual() -- append qualification to tree.
      20: **		ferror() -- issue fatal error
      21: **		lsetbit() -- set bit in large set.
      22: **		mergevar() -- merge variables to link terms
      23: **		makezero() -- make a zero node
      24: **
      25: **	Required By:
      26: **		almost all
      27: **
      28: **	Trace Flags:
      29: **		00 -> 19
      30: **
      31: **	History:
      32: **		2/14/79 -- version 6.2/0 release.
      33: */
      34: /*
      35: **  TRIMQLEND -- trim QLEND node off of qualification
      36: **
      37: **	The QLEND node, and possible the AND node preceeding it,
      38: **	are trimmed off.  The result of this routine should be
      39: **	a very ordinary tree like you might see in some textbook.
      40: **
      41: **	A fast not on the algorithm: the pointer 't' points to the
      42: **	current node (the one which we are checking for a QLEND).
      43: **	's' points to 't's parent, and 'r' points to 's's parent;
      44: **	'r' is NULL at the top of the tree.
      45: **
      46: **	This routine works correctly on trees with no QLEND in
      47: **	the first place, returning the original tree.
      48: **
      49: **	If there is a QLEND, it must be on the far right branch
      50: **	of the tree, that is, the tree must be INGRES-canonical.
      51: **
      52: **	Parameters:
      53: **		qual -- the qualification to be trimmed.
      54: **
      55: **	Returns:
      56: **		A pointer to the new qualification.
      57: **		NULL if the qualification was null once the
      58: **			QLEND is stripped.
      59: **
      60: **	Side Effects:
      61: **		The tree pointed to by 'qual' may be modified.
      62: **
      63: **	Called By:
      64: **		protect()
      65: **		appqual()
      66: **		maybe others.
      67: **
      68: **	Trace Flags:
      69: **		none
      70: **
      71: **	Syserrs:
      72: **		none
      73: */
      74:
      75: QTREE *
      76: trimqlend(qual)
      77: QTREE   *qual;
      78: {
      79:     register QTREE  *t;
      80:     register QTREE  *s;
      81:     register QTREE  *r;
      82:
      83:     t = qual;
      84:
      85:     /* check for the simple null qualification case */
      86:     if (t == NULL || t->sym.type == QLEND)
      87:         return (NULL);
      88:
      89:     /* scan tree for QLEND node */
      90:     for (r = NULL, s = t; (t = t->right) != NULL; r = s, s = t)
      91:     {
      92:         if (t->sym.type == QLEND)
      93:         {
      94:             /* trim of QLEND and AND node */
      95:             if (r == NULL)
      96:             {
      97:                 /* only one AND -- return its operand */
      98:                 return (s->left);
      99:             }
     100:
     101:             r->right = s->left;
     102:             break;
     103:         }
     104:     }
     105:
     106:     /* return tree with final AND node and QLEND node pruned */
     107:     return (qual);
     108: }
     109: /*
     110: **  APPQUAL -- append qualification to tree
     111: **
     112: **	The qualification is conjoined to the qualificaion of the
     113: **	tree which is passed.
     114: **
     115: **	Parameters:
     116: **		qual -- a pointer to the qualification to be appended.
     117: **		root -- a pointer to the tree to be appended to.
     118: **
     119: **	Returns:
     120: **		none
     121: **
     122: **	Side Effects:
     123: **		Both 'qual' ad 'root' may be modified.  Note that
     124: **			'qual' is linked into 'root', and must be
     125: **			retained.
     126: **
     127: **	Requires:
     128: **		tree() -- to create a new AND node.
     129: **
     130: **	Called By:
     131: **		view
     132: **		protect
     133: **		integrity
     134: **
     135: **	Trace Flags:
     136: **		13
     137: */
     138:
     139: appqual(qual, root)
     140: QTREE   *qual;
     141: QTREE   *root;
     142: {
     143:     register QTREE  *p;
     144:     register QTREE  *r;
     145:
     146:     r = root;
     147: #	ifdef xQTR3
     148:     if (r == NULL)
     149:         syserr("appqual: NULL root");
     150: #	endif
     151:
     152:     /*
     153: 	**  Find node before QLEND node
     154: 	**	p points the node we are examining, r points to
     155: 	**	it's parent.
     156: 	*/
     157:
     158:     while ((p = r->right) != NULL && p->sym.type != QLEND)
     159:     {
     160: #		ifdef xQTR3
     161:         if (p->sym.type != AND)
     162:             syserr("appqual: node %d", p->sym.type);
     163: #		endif
     164:         r = p;
     165:     }
     166:
     167:     /* link in qualification */
     168:     r->right = qual;
     169: }
     170: /*
     171: **  FERROR -- issue fatal error message and abort query
     172: **
     173: **	This call is almost exactly like 'error' (which is called),
     174: **	but never returns: the return is done by 'reset'.  Also, the
     175: **	R_up pipe is flushed.
     176: **
     177: **	Parameters:
     178: **		errno -- the error number.
     179: **		qmode -- the query mode to pass as $0, -1 if none.
     180: **		vn -- the varno of the relation name to pass as
     181: **			$1, -1 if none.
     182: **		p1 to p5 -- the parameters $2 through $6
     183: **
     184: **	Returns:
     185: **		non-local (via reset())
     186: **
     187: **	Side Effects:
     188: **		The error message is generated.
     189: **
     190: **	Defines:
     191: **		ferror
     192: **		Qmdname -- the names of the various Qmodes.
     193: **
     194: **	Requires:
     195: **		error
     196: **		reset
     197: **		Pipe
     198: **		rdpipe
     199: **		wrpipe
     200: **		Nullsync -- send null query on error -- defined
     201: **			in main.c
     202: **		nullsync -- routine to do same -- defined in
     203: **			issue.c.
     204: **
     205: **	Called By:
     206: **		MANY
     207: **
     208: **	Trace Flags:
     209: **		none
     210: **
     211: **	Diagnostics:
     212: **		none of it's own.
     213: **
     214: **	Syserrs:
     215: **		none
     216: */
     217:
     218: extern struct pipfrmt   Pipe;
     219: char    *Qmdname[] =
     220: {
     221:     "[ERROR]",  /* 0 = mdRETTERM */
     222:     "RETRIEVE", /* 1 = mdRETR */
     223:     "APPEND",   /* 2 = mdAPP */
     224:     "REPLACE",  /* 3 = mdREPL */
     225:     "DELETE",   /* 4 = mdDEL */
     226:     "",     /* 5 = mdCOPY */
     227:     "",     /* 6 = mdCREATE */
     228:     "",     /* 7 = mdDESTROY */
     229:     "",     /* 8 = mdHELP */
     230:     "",     /* 9 = mdINDEX */
     231:     "",     /* 10 = mdMODIFY */
     232:     "",     /* 11 = mdPRINT */
     233:     "",     /* 12 = mdRANGE */
     234:     "",     /* 13 = mdSAVE */
     235:     "DEFINE",   /* 14 = mdDEFINE */
     236:     "RET_UNIQUE",   /* 15 = mdRET_UNI */
     237:     "",     /* 16 = mdVIEW */
     238:     "",     /* 17 = mdUPDATE */
     239:     "",     /* 18 = mdRESETREL */
     240:     "",     /* 19 = mdERIC */
     241:     "",     /* 20 = mdNETQRY */
     242:     "",     /* 21 = mdMOVEREL */
     243:     "",     /* 22 = mdPROT */
     244:     "",     /* 23 = mdINTEG */
     245:     "",     /* 24 = mdDCREATE */
     246: };
     247:
     248:
     249: ferror(errno, qmode, vn, p1, p2, p3, p4, p5, p6)
     250: int errno;
     251: int qmode;
     252: int vn;
     253: char    *p1, *p2, *p3, *p4, *p5, *p6;
     254: {
     255:     register char   *x1;
     256:     register char   *x2;
     257:     char        xbuf[MAXNAME + 1];
     258:     register int    i;
     259:     extern char *trim_relname();
     260:     extern int  Nullsync;
     261:     struct retcode  *rc, *nullsync();
     262:
     263:     /* flush the upward read pipe */
     264:     rdpipe(P_SYNC, &Pipe, R_up);
     265:
     266:     /* set up qmode and varno parameters */
     267:     x1 = x2 = "";
     268:     i = qmode;
     269:     if (i >= 0)
     270:         x1 = Qmdname[i];
     271:     i = vn;
     272:     if (i >= 0)
     273:         smove(trim_relname(Rangev[i].relid), x2 = xbuf);
     274:
     275:     /* issue the error message */
     276:     error(errno, x1, x2, p1, p2, p3, p4, p5, p6, 0);
     277:
     278:     /* issue null query if running Equel */
     279:     if (Nullsync)
     280:         rc = nullsync();
     281:     else
     282:         rc = NULL;
     283:
     284:     /* sync to above */
     285:     wrpipe(P_PRIME, &Pipe, 0, 0, 0);
     286:     if (rc != NULL)
     287:         wrpipe(P_NORM, &Pipe, W_up, rc, sizeof *rc);
     288:     wrpipe(P_END, &Pipe, W_up);
     289:
     290:     /* return to main loop for next query */
     291:     reset();
     292: }
     293: /*
     294: **  XERROR -- interface from need() to ferror()
     295: **
     296: **	Parameters:
     297: **		err -- the error number.
     298: **
     299: **	Returns:
     300: **		never
     301: **
     302: **	Side Effects:
     303: **		see ferror
     304: */
     305:
     306: xerror(err)
     307: int err;
     308: {
     309:     ferror(err, -1, -1, 0);
     310: }
     311: /*
     312: **  LSETBIT -- set a bit in a domain set
     313: **
     314: **	Parameters:
     315: **		bitno -- the bit number to set (0 -> 127)
     316: **		xset -- the set to set it in.
     317: **
     318: **	Returns:
     319: **		none
     320: **
     321: **	Side Effects:
     322: **		none
     323: **
     324: **	Called By:
     325: **		makedset()
     326: **
     327: **	History:
     328: **		8/21/78 (eric) -- written.
     329: */
     330:
     331: lsetbit(bitno, xset)
     332: int bitno;
     333: int xset[8];
     334: {
     335:     register int    b;
     336:     register int    n;
     337:     register int    *x;
     338:
     339:     x = xset;
     340:
     341:     b = bitno;
     342:     n = b >> LOG2WORDSIZE;
     343:     b &= WORDSIZE - 1;
     344:
     345:     x[n] |= 1 << b;
     346: }
     347: /*
     348: **  MERGEVAR -- merge variable numbers to link terms
     349: **
     350: **	One specified variable gets mapped into another, effectively
     351: **	merging those two variables.  This is used for protection
     352: **	and integrity, since the constraint read from the tree
     353: **	must coincide with one of the variables in the query tree.
     354: **
     355: **	Parameters:
     356: **		va -- the variable which will dissappear.
     357: **		vb -- the variable which 'va' gets mapped into.
     358: **		root -- the root of the tree to map.
     359: **
     360: **	Returns:
     361: **		none
     362: **
     363: **	Side Effects:
     364: **		The tree pointed at by 'root' gets VAR and RESDOM
     365: **			nodes mapped.
     366: **		Range table entry for 'va' is deallocated.
     367: **		The 'Remap' vector gets reset and left in an
     368: **			undefined state.
     369: **
     370: **	Requires:
     371: **		clrrange -- to clear the 'Remap' vector (called with
     372: **			a FALSE parameter, so 'Rangev' is not cleared).
     373: **		mapvars -- to do the actual mapping.
     374: **		Remap -- to define the mapping for mapvars().
     375: **		Rangev -- to check consistency and to clear the entry
     376: **			for variable 'va'.
     377: **
     378: **	Called By:
     379: **		protect.c
     380: **		integrity.c
     381: **
     382: **	Trace Flags:
     383: **		16
     384: **
     385: **	Diagnostics:
     386: **		none
     387: **
     388: **	Syserrs:
     389: **		mergevar: range %d %d
     390: **			Either 'va' or 'vb' was out of range.
     391: **		mergevar: incon %s %s
     392: **			The variables for 'va' and 'vb' must range
     393: **			over the same relation.  The strings are the
     394: **			relation names if this does not hold.
     395: **		mergevar: undef %d %d
     396: **			The variables 'va' and 'vb' must both
     397: **			be defined.
     398: */
     399:
     400: mergevar(va, vb, root)
     401: int va;
     402: int vb;
     403: QTREE   *root;
     404: {
     405:     register int    a;
     406:     register int    b;
     407:
     408:     a = va;
     409:     b = vb;
     410:
     411: #	ifdef xQTR1
     412:     if (tTf(16, 0))
     413:     {
     414:         printf("\nmergevar(%d->%d)", a, b);
     415:         treepr(root, NULL);
     416:     }
     417: #	endif
     418:
     419:     /*
     420: 	**  Insure that 'va' and 'vb' are consistant, that is,
     421: 	**  that they both are in range, are defined, and range over
     422: 	**  the same relation.
     423: 	*/
     424:
     425:     if (a < 0 || b < 0 || a >= MAXVAR + 1 || b >= MAXVAR + 1)
     426:         syserr("mergevar: range %d %d", a, b);
     427:     if (!Rangev[a].rused || !Rangev[b].rused)
     428:         syserr("mergevar: undef %d %d", a, b);
     429:     if (!bequal(Rangev[a].relid, Rangev[b].relid, MAXNAME) ||
     430:         !bequal(Rangev[a].rowner, Rangev[b].rowner, 2))
     431:         syserr("mergevar: incon %.14s %.14s", Rangev[a].relid,
     432:             Rangev[b].relid);
     433:
     434:     /*
     435: 	**  To do the actual mapping, we will set up 'Remap' and
     436: 	**  call 'mapvars()'.  This is because I am too lazy to
     437: 	**  do it myself.
     438: 	*/
     439:
     440:     clrrange(FALSE);
     441:     Remap[a] = b;
     442:     mapvars(root);
     443:
     444:     /* delete a from the range table */
     445:     Rangev[a].rused = FALSE;
     446: }
     447: /*
     448: **  MAKEZERO -- make a node with value 'zero'
     449: **
     450: **	A node is created with value representing the zero value
     451: **	for the specified type, that is, 0 for integers, 0.0 for
     452: **	floats, and the blank string for chars.
     453: **
     454: **	Parameters:
     455: **		typ -- the node type.
     456: **
     457: **	Returns:
     458: **		a pointer to the zero node.
     459: **
     460: **	Side Effects:
     461: **		space is grabbed from Qbuf
     462: **
     463: **	Requires:
     464: **		Qbuf -- for space.
     465: **		need() -- to get that space.
     466: **
     467: **	History:
     468: **		11/21/78 (eric) -- written.
     469: */
     470:
     471: QTREE *
     472: makezero(typ)
     473: int typ;
     474: {
     475:     register int        l;
     476:     register struct symbol  *s;
     477:     int         symbuf[(sizeof *s + 4) / sizeof l];
     478:     char            *need();
     479:
     480:     s = (struct symbol *) &symbuf;
     481:     s->type = typ;
     482:
     483:     switch (typ)
     484:     {
     485:       case INT:
     486:         s->len = l = 2;
     487:         i2deref(s->value) = 0;
     488:         break;
     489:
     490:       case FLOAT:
     491:         s->len = l = 4;
     492:         f4deref(s->value) = 0.0;
     493:         break;
     494:
     495:       case CHAR:
     496:         s->len = l = 2;
     497:         i2deref(s->value) = 0x2020; /* (two spaces) */
     498:         break;
     499:
     500:       default:
     501:         syserr("makezero: typ %d", typ);
     502:     }
     503:
     504:     /* duplicate the node into Qbuf */
     505:     l += sizeof *s;
     506:     s = (struct symbol *) need(Qbuf, l);
     507:     bmove(&symbuf, s, l);
     508:     return ((QTREE *) s);
     509: }

#### Defined functions

appqual defined in line 139; used 4 times

- in /usr/ingres/source/qrymod/integrity.c line 171, 188
- in /usr/ingres/source/qrymod/protect.c line 584
- in /usr/ingres/source/qrymod/view.c line 303

ferror defined in line 249; used 24 times

- in line 309
- in /usr/ingres/source/qrymod/d_integ.c line 96, 110, 116-120(2), 136
- in /usr/ingres/source/qrymod/d_prot.c line 135-140(2), 190
- in /usr/ingres/source/qrymod/fillprotup.c line 81, 107, 142, 151
- in /usr/ingres/source/qrymod/protect.c line 570
- in /usr/ingres/source/qrymod/range.c line 170
- in /usr/ingres/source/qrymod/readtree.c line 126
- in /usr/ingres/source/qrymod/trscan.c line 392
- in /usr/ingres/source/qrymod/view.c line 289, 300, 437, 449, 470-474(2), 481

lsetbit defined in line 331; used 5 times

- in /usr/ingres/source/qrymod/d_integ.c line 210
- in /usr/ingres/source/qrymod/d_prot.c line 164
- in /usr/ingres/source/qrymod/integrity.c line 107
- in /usr/ingres/source/qrymod/protect.c line 716, 741

makezero defined in line 471; used 2 times

- in /usr/ingres/source/qrymod/trscan.c line 343, 402

mergevar defined in line 400; used 2 times

- in /usr/ingres/source/qrymod/integrity.c line 162
- in /usr/ingres/source/qrymod/protect.c line 539

trimqlend defined in line 75; used 7 times

- in /usr/ingres/source/qrymod/integrity.c line 193
- in /usr/ingres/source/qrymod/issue.c line 127, 138
- in /usr/ingres/source/qrymod/protect.c line 360, 528, 587
- in /usr/ingres/source/qrymod/view.c line 317

xerror defined in line 306; used 2 times

- in /usr/ingres/source/qrymod/readtree.c line 67, 78

#### Defined variables

Qmdname defined in line 219; used 2 times

- in line 270
- in /usr/ingres/source/qrymod/treepr.c line 96

Last modified: 1995-02-19 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1341 |