1: # include   <ingres.h>
   2: # include   <aux.h>
   3: # include   <symbol.h>
   4: # include   <tree.h>
   5: # include   "qrymod.h"
   6: # include   <sccs.h>
   7: 
   8: SCCSID(@(#)util.c	8.1	12/31/84)
   9: 
  10: /*
  11: **  TRIMQLEND -- trim QLEND node off of qualification
  12: **
  13: **	The QLEND node, and possible the AND node preceeding it,
  14: **	are trimmed off.  The result of this routine should be
  15: **	a very ordinary tree like you might see in some textbook.
  16: **
  17: **	A fast not on the algorithm: the pointer 't' points to the
  18: **	current node (the one which we are checking for a QLEND).
  19: **	's' points to 't's parent, and 'r' points to 's's parent;
  20: **	'r' is NULL at the top of the tree.
  21: **
  22: **	This routine works correctly on trees with no QLEND in
  23: **	the first place, returning the original tree.
  24: **
  25: **	If there is a QLEND, it must be on the far right branch
  26: **	of the tree, that is, the tree must be INGRES-canonical.
  27: **
  28: **	Parameters:
  29: **		qual -- the qualification to be trimmed.
  30: **
  31: **	Returns:
  32: **		A pointer to the new qualification.
  33: **		NULL if the qualification was null once the
  34: **			QLEND is stripped.
  35: **
  36: **	Side Effects:
  37: **		The tree pointed to by 'qual' may be modified.
  38: **
  39: **	Trace Flags:
  40: **		none
  41: */
  42: 
  43: QTREE *
  44: trimqlend(qual)
  45: QTREE   *qual;
  46: {
  47:     register QTREE  *t;
  48:     register QTREE  *s;
  49:     register QTREE  *r;
  50: 
  51:     t = qual;
  52: 
  53:     /* check for the simple null qualification case */
  54:     if (t == NULL || t->sym.type == QLEND)
  55:         return (NULL);
  56: 
  57:     /* scan tree for QLEND node */
  58:     for (r = NULL, s = t; (t = t->right) != NULL; r = s, s = t)
  59:     {
  60:         if (t->sym.type == QLEND)
  61:         {
  62:             /* trim of QLEND and AND node */
  63:             if (r == NULL)
  64:             {
  65:                 /* only one AND -- return its operand */
  66:                 return (s->left);
  67:             }
  68: 
  69:             r->right = s->left;
  70:             break;
  71:         }
  72:     }
  73: 
  74:     /* return tree with final AND node and QLEND node pruned */
  75:     return (qual);
  76: }
  77: /*
  78: **  APPQUAL -- append qualification to tree
  79: **
  80: **	The qualification is conjoined to the qualificaion of the
  81: **	tree which is passed.
  82: **
  83: **	Parameters:
  84: **		qual -- a pointer to the qualification to be appended.
  85: **		root -- a pointer to the tree to be appended to.
  86: **
  87: **	Returns:
  88: **		none
  89: **
  90: **	Side Effects:
  91: **		Both 'qual' ad 'root' may be modified.  Note that
  92: **			'qual' is linked into 'root', and must be
  93: **			retained.
  94: **
  95: **	Trace Flags:
  96: **		13
  97: */
  98: 
  99: appqual(qual, root)
 100: QTREE   *qual;
 101: QTREE   *root;
 102: {
 103:     register QTREE  *p;
 104:     register QTREE  *r;
 105: 
 106:     r = root;
 107: #	ifdef xQTR3
 108:     if (r == NULL)
 109:         syserr("appqual: NULL root");
 110: #	endif
 111: 
 112:     /*
 113: 	**  Find node before QLEND node
 114: 	**	p points the node we are examining, r points to
 115: 	**	it's parent.
 116: 	*/
 117: 
 118:     while ((p = r->right) != NULL && p->sym.type != QLEND)
 119:     {
 120: #		ifdef xQTR3
 121:         if (p->sym.type != AND)
 122:             syserr("appqual: node %d", p->sym.type);
 123: #		endif
 124:         r = p;
 125:     }
 126: 
 127:     /* link in qualification */
 128:     r->right = qual;
 129: }
 130: /*
 131: **  QMERROR -- issue fatal error message and abort query
 132: **
 133: **	This call is almost exactly like 'error' (which is called),
 134: **	but never returns: the return is done by 'reset'.  Also, the
 135: **	R_up pipe is flushed.
 136: **
 137: **	Parameters:
 138: **		errno -- the error number.
 139: **		qmode -- the query mode to pass as $0, -1 if none.
 140: **		vn -- the varno of the relation name to pass as
 141: **			$1, -1 if none.
 142: **		p1 to p5 -- the parameters $2 through $6
 143: **
 144: **	Returns:
 145: **		non-local (via reset())
 146: **
 147: **	Side Effects:
 148: **		The error message is generated.
 149: **
 150: **	Trace Flags:
 151: **		none
 152: */
 153: 
 154: char *QmdName[] =
 155: {
 156:     "[ERROR]",  /* 0 = mdRETTERM */
 157:     "RETRIEVE", /* 1 = mdRETR */
 158:     "APPEND",   /* 2 = mdAPP */
 159:     "REPLACE",  /* 3 = mdREPL */
 160:     "DELETE",   /* 4 = mdDEL */
 161:     "",     /* 5 = mdCOPY */
 162:     "",     /* 6 = mdCREATE */
 163:     "",     /* 7 = mdDESTROY */
 164:     "",     /* 8 = mdHELP */
 165:     "",     /* 9 = mdINDEX */
 166:     "",     /* 10 = mdMODIFY */
 167:     "",     /* 11 = mdPRINT */
 168:     "",     /* 12 = mdRANGE */
 169:     "",     /* 13 = mdSAVE */
 170:     "DEFINE",   /* 14 = mdDEFINE */
 171:     "RET_UNIQUE",   /* 15 = mdRET_UNI */
 172:     "",     /* 16 = mdVIEW */
 173:     "",     /* 17 = mdUPDATE */
 174:     "",     /* 18 = mdRESETREL */
 175:     "",     /* 19 = mdERIC */
 176:     "",     /* 20 = mdNETQRY */
 177:     "",     /* 21 = mdMOVEREL */
 178:     "",     /* 22 = mdPROT */
 179:     "",     /* 23 = mdINTEG */
 180:     "",     /* 24 = mdDCREATE */
 181: };
 182: 
 183: 
 184: qmerror(errno, qmode, vn, p1, p2, p3, p4, p5, p6)
 185: int errno;
 186: int qmode;
 187: int vn;
 188: char    *p1, *p2, *p3, *p4, *p5, *p6;
 189: {
 190:     register char       *x1;
 191:     register char       *x2;
 192:     char            xbuf[MAXNAME + 1];
 193:     register int        i;
 194:     extern char     *trim_relname();
 195: 
 196:     /* set up qmode and varno parameters */
 197:     x1 = x2 = "";
 198:     i = qmode;
 199:     if (i >= 0)
 200:         x1 = QmdName[i];
 201:     i = vn;
 202:     if (i >= 0)
 203:         smove(trim_relname(Qt.qt_rangev[i].rngvdesc->reldum.relid),
 204:               x2 = xbuf);
 205: 
 206:     /* issue the error message and exit */
 207:     error(errno, x1, x2, p1, p2, p3, p4, p5, p6, 0);
 208:     syserr("qmerror");
 209: }
 210: /*
 211: **  LSETBIT -- set a bit in a domain set
 212: **
 213: **	Parameters:
 214: **		bitno -- the bit number to set (0 -> 127)
 215: **		xset -- the set to set it in.
 216: **
 217: **	Returns:
 218: **		none
 219: **
 220: **	Side Effects:
 221: **		none
 222: */
 223: 
 224: lsetbit(bitno, xset)
 225: int bitno;
 226: int xset[8];
 227: {
 228:     register int    b;
 229:     register int    n;
 230:     register int    *x;
 231: 
 232:     x = xset;
 233: 
 234:     b = bitno;
 235:     n = b >> LOG2WORDSIZE;
 236:     b &= WORDSIZE - 1;
 237: 
 238:     x[n] |= 1 << b;
 239: }
 240: /*
 241: **  MERGEVAR -- merge variable numbers to link terms
 242: **
 243: **	One specified variable gets mapped into another, effectively
 244: **	merging those two variables.  This is used for protection
 245: **	and integrity, since the constraint read from the tree
 246: **	must coincide with one of the variables in the query tree.
 247: **
 248: **	Parameters:
 249: **		va -- the variable which will dissappear.
 250: **		vb -- the variable which 'va' gets mapped into.
 251: **		root -- the root of the tree to map.
 252: **
 253: **	Returns:
 254: **		none
 255: **
 256: **	Side Effects:
 257: **		The tree pointed at by 'root' gets VAR and RESDOM
 258: **			nodes mapped.
 259: **		Range table entry for 'va' is deallocated.
 260: **		The 'Qt.qt_remap' vector gets reset and left in an
 261: **			undefined state.
 262: **
 263: **	Trace Flags:
 264: **		72
 265: */
 266: 
 267: mergevar(a, b, root)
 268: register int    a;
 269: register int    b;
 270: QTREE       *root;
 271: {
 272:     register int    i;
 273: 
 274: #	ifdef xQTR1
 275:     if (tTf(72, 0))
 276:     {
 277:         printf("\nmergevar(%d->%d)", a, b);
 278:         treepr(root, NULL);
 279:     }
 280: #	endif
 281: 
 282:     /*
 283: 	**  Insure that 'a' and 'b' are consistant, that is,
 284: 	**  that they both are in range, are defined, and range over
 285: 	**  the same relation.
 286: 	*/
 287: 
 288:     if (a < 0 || b < 0 || a >= MAXVAR + 1 || b >= MAXVAR + 1)
 289:         syserr("mergevar: range %d %d", a, b);
 290:     if (Qt.qt_rangev[a].rngvdesc == NULL || Qt.qt_rangev[b].rngvdesc == NULL)
 291:         syserr("mergevar: undef %d %d", a, b);
 292:     if (!bequal(Qt.qt_rangev[a].rngvdesc->reldum.relid,
 293:             Qt.qt_rangev[b].rngvdesc->reldum.relid, MAXNAME) ||
 294:         !bequal(Qt.qt_rangev[a].rngvdesc->reldum.relowner,
 295:             Qt.qt_rangev[b].rngvdesc->reldum.relowner, 2))
 296:     {
 297:         syserr("mergevar: incon %.14s %.14s",
 298:             Qt.qt_rangev[a].rngvdesc->reldum.relid,
 299:             Qt.qt_rangev[b].rngvdesc->reldum.relid);
 300:     }
 301: 
 302:     /*
 303: 	**  To do the actual mapping, we will set up 'Qt.qt_remap' and
 304: 	**  call 'mapvars()'.  This is because I am too lazy to
 305: 	**  do it myself.
 306: 	*/
 307: 
 308:     for (i = 0; i < MAXRANGE; i++)
 309:         Qt.qt_remap[i] = i;
 310:     Qt.qt_remap[a] = b;
 311:     mapvars(root);
 312: 
 313:     /* delete a from the range table */
 314:     declare(a, NULL);
 315: }
 316: /*
 317: **  MAKEZERO -- make a node with value 'zero'
 318: **
 319: **	A node is created with value representing the zero value
 320: **	for the specified type, that is, 0 for integers, 0.0 for
 321: **	floats, and the blank string for chars.
 322: **
 323: **	Parameters:
 324: **		typ -- the node type.
 325: **
 326: **	Returns:
 327: **		a pointer to the zero node.
 328: **
 329: **	Side Effects:
 330: **		space is grabbed from Qbuf
 331: */
 332: 
 333: QTREE *
 334: makezero(typ)
 335: int typ;
 336: {
 337:     register int        l;
 338:     register QTREE      *s;
 339:     int         symbuf[(sizeof *s) / sizeof l]; /*word aligned*/
 340:     extern char     *need();
 341: 
 342:     s = (QTREE *) symbuf;
 343:     s->sym.type = typ;
 344: 
 345:     switch (typ)
 346:     {
 347:       case INT:
 348:         s->sym.len = l = 2;
 349:         s->sym.value.sym_data.i2type = 0;
 350:         break;
 351: 
 352:       case FLOAT:
 353:         s->sym.len = l = 4;
 354:         s->sym.value.sym_data.f4type = 0.0;
 355:         break;
 356: 
 357:       case CHAR:
 358:         s->sym.len = l = 2;
 359:         s->sym.value.sym_data.i2type = '  ';    /* (two spaces) */
 360:         break;
 361: 
 362:       default:
 363:         syserr("makezero: typ %d", typ);
 364:     }
 365: 
 366:     /* duplicate the node into Qbuf */
 367:     l += 2 + 2 * QT_HDR_SIZ;    /* size of type + len + left + right */
 368:     s = (QTREE *) need(Qbuf, l);
 369:     bmove(symbuf, s, l);
 370:     return (s);
 371: }
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1326
Valid CSS Valid XHTML 1.0 Strict