1: # include   "../ingres.h"
   2: # include   "../symbol.h"
   3: # include   "../tree.h"
   4: # include   "qrymod.h"
   5: 
   6: /*
   7: **  TRSCAN -- scan trees for various conditions
   8: **
   9: **	These are basically utility routines which do tree scans for
  10: **	one thing or another.  Really, there is nothing exciting at
  11: **	all in this module.
  12: **
  13: **	Defines:
  14: **		aggcheck -- scan tree for aggregates
  15: **		vfind -- find definition for VAR in a view tree
  16: **		qscan -- scan qualification for a variable
  17: **
  18: **	Requires:
  19: **		-
  20: **
  21: **	Required By:
  22: **		MANY
  23: **
  24: **	Compilation Flags:
  25: **		14
  26: **
  27: **	Trace Flags:
  28: **		14
  29: **
  30: **	History:
  31: **		2/14/79 -- version 6.2/0 release.
  32: **		3/22/78 (eric) -- written
  33: */
  34: /*
  35: **  AGGCHECK -- check for any aggregate in subtree.
  36: **
  37: **	This routine checks to insure that the view algorithm can
  38: **	proceed safely by checking for aggregates in the view tree.
  39: **
  40: **	Parameters:
  41: **		root -- the root of the tree to check.
  42: **
  43: **	Returns:
  44: **		TRUE -- an aggregate found.
  45: **		FALSE -- no aggregates in tree.
  46: **
  47: **	Side Effects:
  48: **		none
  49: **
  50: **	Called By:
  51: **		view
  52: **
  53: **	Trace Flags:
  54: **		14
  55: */
  56: 
  57: aggcheck(root)
  58: QTREE   *root;
  59: {
  60:     register QTREE  *t;
  61: 
  62:     t = root;
  63: 
  64:     /* check for no pointer */
  65:     while (t != NULL)
  66:     {
  67:         /* check for this node an AGHEAD */
  68:         if (t->sym.type == AGHEAD)
  69:             return (TRUE);
  70: 
  71:         /* check left subtree recursively */
  72:         if (aggcheck(t->left))
  73:             return (TRUE);
  74: 
  75:         /* check right subtree iteratively */
  76:         t = t->right;
  77:     }
  78: 
  79:     return (FALSE);
  80: }
  81: /*
  82: **  VFIND -- find definition for attribute in view tree
  83: **
  84: **	The view tree is scanned for a specified RESDOM; a pointer
  85: **	to the value is returned.
  86: **
  87: **	Parameters:
  88: **		vn -- the variable number to dig out.
  89: **		vtree -- a pointer to the target list of the
  90: **			view definition tree.
  91: **
  92: **	Returns:
  93: **		a pointer to the substitution value for the specified
  94: **			'vn'.
  95: **		NULL -- if not found.
  96: **
  97: **	Side Effects:
  98: **		none
  99: **
 100: **	Requires:
 101: **
 102: **	Called By:
 103: **		subsvars
 104: **		vrscan
 105: **
 106: **	Trace Flags:
 107: **		14
 108: **
 109: **	Diagnostics:
 110: **		none
 111: **
 112: **	Syserrs:
 113: **		vfind: bad RESDOM %d -- a node was found which was not
 114: **			a RESDOM node, nor a TREE node, in 'vtree'.
 115: */
 116: 
 117: QTREE *
 118: vfind(vn, vtree)
 119: int vn;
 120: QTREE   *vtree;
 121: {
 122:     register int    n;
 123:     register QTREE  *v;
 124: 
 125:     n = vn;
 126: 
 127:     for (v = vtree; v->sym.type == RESDOM; v = v->left)
 128:     {
 129:         if (((struct qt_res *)v)->resno != n)
 130:             continue;
 131: 
 132:         /* found the correct replacement */
 133:         return (v->right);
 134:     }
 135: 
 136:     if (v->sym.type != TREE)
 137:         syserr("vfind: bad RESDOM node %d", v->sym.type);
 138:     return (NULL);
 139: }
 140: /*
 141: **  QSCAN -- find specified VAR node in subtree
 142: **
 143: **	Intended for finding a variable in a qualification, this
 144: **	routine just scans a tree recursively looking for a node
 145: **	with the specified VAR (varno.attno) node.
 146: **
 147: **	Parameters:
 148: **		root -- the root of the tree to scan.
 149: **		vn -- the varno to scan for.
 150: **		an -- the attno to scan for.
 151: **
 152: **	Returns:
 153: **		A pointer to the first found VAR node which matches.
 154: **			Scan is prefix.
 155: **		NULL if not found at all.
 156: **
 157: **	Side Effects:
 158: **		none
 159: **
 160: **	Requires:
 161: **		none
 162: **
 163: **	Called By:
 164: **		vrscan
 165: **
 166: **	Trace Flags:
 167: **		15
 168: **
 169: **	Diagnostics:
 170: **		none
 171: **
 172: **	Syserrs:
 173: **		none
 174: */
 175: 
 176: QTREE *
 177: qscan(root, vn, an)
 178: QTREE   *root;
 179: int vn;
 180: int an;
 181: {
 182:     register QTREE  *t;
 183:     register QTREE  *u;
 184: 
 185:     t = root;
 186: 
 187:     /* check for null node */
 188:     if (t == NULL)
 189:         return (t);
 190: 
 191:     /* check to see if this node qualifies */
 192:     if (t->sym.type == VAR && ((struct qt_var *)t)->varno == vn && ((struct qt_var *)t)->attno == an)
 193:         return (t);
 194: 
 195:     /* check other nodes */
 196:     if ((u = qscan(t->left, vn, an)) != NULL)
 197:         return (u);
 198:     return (qscan(t->right, vn, an));
 199: }
 200: /*
 201: **  VARSET -- scan tree and set a bit vector of variables
 202: **
 203: **	The return value is a bit vector representing the set of
 204: **	variables used in that subtree.
 205: **
 206: **	Parameters:
 207: **		root -- the root of the tree to check.
 208: **
 209: **	Returns:
 210: **		A bit vector, such that bit zero (on the low order,
 211: **			right-hand end) means var zero.
 212: **
 213: **	Side Effects:
 214: **		none
 215: **
 216: **	Requires:
 217: **		none
 218: **
 219: **	Called By:
 220: **		vrscan
 221: **
 222: **	Trace Flags:
 223: **		none
 224: **
 225: **	Diagnostics:
 226: **		none
 227: **
 228: **	Syserrs:
 229: **		none
 230: */
 231: 
 232: varset(root)
 233: QTREE   *root;
 234: {
 235:     register QTREE  *t;
 236:     register int    s;
 237: 
 238:     t = root;
 239: 
 240:     if (t == NULL)
 241:         return (0);
 242: 
 243:     /* scan left and right branches */
 244:     s = varset(t->left);
 245:     s |= varset(t->right);
 246: 
 247:     /* check out this node */
 248:     if (t->sym.type == VAR)
 249:     {
 250:         /* or in bit corresponding to this varno */
 251:         s |= 1 << ((struct qt_var *)t)->varno;
 252:     }
 253: 
 254:     return (s);
 255: }
 256: /*
 257: **  SUBSVARS -- scan query tree and replace VAR nodes
 258: **
 259: **	Scans a tree and finds all VAR nodes for this variable.
 260: **	These nodes are looked up in the translation tree and
 261: **	replaced by the value found there.  If this is for a
 262: **	view, the corresponding node must exist in the translation
 263: **	tree, otherwise, a 'zero' node (of a type appropriate based
 264: **	on the context) is created and inserted.
 265: **
 266: **	This routine is one half of the guts of the whole view
 267: **	algorithm.
 268: **
 269: **	VAR nodes are detached and replaced with the replacement
 270: **	as defined by the view.  Note that there can never be any
 271: **	problems here, since VAR nodes are only used in retrieve
 272: **	contexts.
 273: **
 274: **	It does some extra processing with RESDOM nodes with
 275: **	resno = 0.  These nodes specify a 'tid' domain, and are
 276: **	included by the parser on REPLACE and DELETE commands
 277: **	(for some reason decomp wants them).  Subsvars will allow
 278: **	this construct iff the right hand pointer is a VAR node
 279: **	with attno = 0.  In this case it just changes the varno
 280: **	of the VAR node to be the Resultvar number.  This is be-
 281: **	cause the Resultvar is the variable number of the one and
 282: **	only underlying base relation of the view on an update
 283: **	(which is presumably the only case where this can come
 284: **	up).  Vrscan has already insured that there can only be
 285: **	a single base relation in this case.
 286: **
 287: **	This whole messy thing is only done with view substitutions.
 288: **
 289: **	Parameters:
 290: **		proot -- a pointer to the pointer to the root of the
 291: **			tree to be updated.
 292: **		vn -- the varno of the view variable.  This is the
 293: **			varno which will be scanned for.
 294: **		transtree -- a pointer to the left branch (target list)
 295: **			of the translation tree.
 296: **		vmode -- mdVIEW if called from view processor, mdAPP
 297: **			if called from the integrity processor with
 298: **			an APPEND command, else something else.
 299: **			Mostly, changes the handling of TID type
 300: **			nodes, and forces an error on a view if the
 301: **			VAR node in the scanned tree does not exist
 302: **			in the vtree.
 303: **
 304: **	Returns:
 305: **		none
 306: **		(non-local on error).
 307: **
 308: **	Side Effects:
 309: **		The tree pointed to by *proot is updated in possibly
 310: **			very exciting ways.
 311: **
 312: **	Requires:
 313: **		Newresvar -- in the view case, the new result variable
 314: **			number of the query.
 315: **		treedup -- to dup the tree from vfind.
 316: **		makezero -- to make a zero node when vmode == mdAPP.
 317: **
 318: **	Called By:
 319: **		view
 320: **
 321: **	Trace Flags:
 322: **		32
 323: **
 324: **	Diagnostics:
 325: **		3340: views do not have tids -- the user has tried to
 326: **			reference 'v.tid', where v is the range variable
 327: **			for the view.  This can be determined un-
 328: **			ambiguously if the view ranges over only one
 329: **			relation, but is impossible otherwise; for the
 330: **			time being it is impossible to reference the
 331: **			'tid' field at all.
 332: */
 333: 
 334: subsvars(proot, vn, transtree, vmode)
 335: QTREE   **proot;
 336: int vn;
 337: QTREE   *transtree;
 338: int vmode;
 339: {
 340:     register QTREE  *t;
 341:     register QTREE  *v;
 342:     register int    i;
 343:     extern QTREE    *vfind(), *makezero(), *treedup();
 344:     extern int  Newresvar;  /* defined in view.c */
 345: 
 346:     t = *proot;
 347:     v = transtree;
 348: 
 349: #	ifdef xQTR3
 350:     if (tTf(32, 0))
 351:         printf("subsvars: vn %d root %u transtree %u\n", vn, t, v);
 352: #	endif
 353: 
 354:     if (t == NULL)
 355:         return;
 356: 
 357:     /* check left branch of the tree */
 358:     subsvars(&t->left, vn, v, vmode);
 359: 
 360:     /* check for special 'tid' RESDOM (used by DEL and REPL) */
 361:     if (t->sym.type == RESDOM && ((struct qt_res *)t)->resno == 0)
 362:     {
 363:         /* test for not Resultvar, in which case we ignore leaf */
 364:         if (vn != Resultvar)
 365:             return;
 366: 
 367:         /* t->right better be VAR node, attno 0 */
 368:         t = t->right;
 369:         if (t->sym.type != VAR || ((struct qt_var *)t)->attno != 0 || ((struct qt_var *)t)->varno != vn)
 370:             syserr("subsvars: RESDOM 0 not VAR 0 %d, %d, %d",
 371:                 vn, ((struct qt_var *)t)->attno, t->sym.type);
 372: 
 373:         /* change varno to new Newresvar (set by vrscan) */
 374: #		ifdef xQTR3
 375:         if (tTf(32, 1))
 376:             printf("RESDOM 0: Newresvar %d\n", Newresvar);
 377: #		endif
 378:         ((struct qt_var *)t)->varno = Newresvar;
 379:         return;
 380:     }
 381: 
 382:     /* scan right branch */
 383:     subsvars(&t->right, vn, v, vmode);
 384: 
 385:     /* check for interesting node */
 386:     if (t->sym.type != VAR || ((struct qt_var *)t)->varno != vn)
 387:         return;
 388: 
 389:     /* test for special 'tid' attribute case */
 390:     if (((struct qt_var *)t)->attno == 0 && vmode == mdVIEW)
 391:     {
 392:         ferror(3340, Qmode, vn, 0); /* views do not have tids */
 393:     }
 394: 
 395:     /* find var in vtree */
 396:     v = vfind(((struct qt_var *)t)->attno, v);
 397:     if (v == NULL)
 398:     {
 399:         if (vmode == mdVIEW)
 400:             syserr("subsvars: attno %d", ((struct qt_var *)t)->attno);
 401:         else if (vmode == mdAPP)
 402:             v = makezero();
 403:     }
 404:     else
 405:         v = treedup(v);
 406: 
 407:     /* replace VAR node */
 408:     if (v != NULL)
 409:         *proot = v;
 410: }

Defined functions

aggcheck defined in line 57; used 3 times
qscan defined in line 176; used 4 times
subsvars defined in line 334; used 4 times
varset defined in line 232; used 4 times
vfind defined in line 117; used 4 times
Last modified: 1995-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3110
Valid CSS Valid XHTML 1.0 Strict