|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <tree.h>
4: # include <symbol.h>
5: # include <range.h>
6: # include "parser.h"
7: # include <sccs.h>
8: # include <errors.h>
9:
10: SCCSID(@(#)range_fcn.c 8.3 2/8/85)
11:
12: /*
13: ** Range table variables
14: */
15:
16: PARRNG Parrng[MAXRANGE]; /* table for keeping track of atts */
17: /* and allocation of range vars */
18: int Resrng; /* result reln slot */
19:
20: PARRNG *Rngfront; /* the front of Rnga */
21: PARRNG *Rngback; /* the back of Qt.qt_rangev */
22:
23:
24: /*
25: ** RANGE_FCN.C -- functions for manipulating the range table
26: **
27: ** Trace Flags:
28: ** RANGE_FCN.C ~~ 66, 67
29: */
30:
31: ctlmod_decl(slot)
32: int slot;
33: {
34: extern PARRNG Parrng[];
35:
36: Qt.qt_rangev[slot].rngvdesc = NULL;
37: if (declare(slot, &Parrng[slot].vardesc) != slot)
38: syserr("declare misdeclared");
39: }
40:
41: /*
42: ** RNGINIT
43: ** initializes the pointers in the range table
44: ** it should be called prior to starting the parsing
45: ** it also initializes the attrib stash stuff because
46: ** the attrib stash is really part of the range table
47: **
48: ** Trace Flags:
49: ** rnginit ~~ 66.0
50: */
51: rnginit()
52: {
53: register int slot;
54: register PARRNG *parrngptr;
55: register RANGEV *rngptr;
56:
57: # ifdef xPTR2
58: tTfp(66, 0, "rnginit\n");
59: # endif
60:
61: Rngfront = &Parrng[MAXVAR - 1]; /* ptr to head of range table */
62: parrngptr = Parrng;
63: /* initialize first element */
64: parrngptr->attlist = NULL;
65: parrngptr->backpt = NULL;
66: parrngptr->frontpt = &Parrng[1];
67:
68: rngptr = Qt.qt_rangev;
69:
70: for (slot = 0, parrngptr = &Parrng[1]; slot < MAXVAR; slot++, parrngptr++)
71: {
72: parrngptr->attlist = NULL;
73:
74: parrngptr->frontpt = parrngptr + 1;
75: parrngptr->backpt = parrngptr - 1;
76: }
77:
78: Rngback = Parrng;
79:
80: parrngptr = &Parrng[MAXVAR - 1];
81:
82: parrngptr->frontpt = NULL;
83:
84: /* MAXVAR SLOT = Resultvar */
85: (++parrngptr)->attlist = NULL;
86: parrngptr->frontpt = parrngptr->backpt = NULL;
87:
88: Rngfront->frontpt = NULL;
89:
90: clrrange();
91:
92: attinit();
93: }
94:
95: /*
96: ** RNGLOOK
97: ** returns a pointer to the range table entry else -1
98: ** type = LOOKREL lookup relation
99: ** type = LOOKVAR lookup variable
100: **
101: ** Trace Flags:
102: ** rnglook ~~ 66.4, 66.5, 66.6
103: */
104: int
105: rnglook(name, type)
106: char *name;
107: int type;
108: {
109: register PARRNG *rptr;
110:
111: register int slot;
112:
113: DESC reldesc;
114:
115: int i;
116:
117: # ifdef xPTR2
118: tTfp(66, 4, "rnglook:\ttype = %s\tname = %s\n",
119: (type == LOOKVAR ? "variable" : "relation"), name);
120:
121: if (tTf(66, 5))
122: printtable();
123: # endif
124:
125: rptr = Parrng;
126:
127: for (slot = 0; slot < MAXVAR; slot++, rptr++) /* search external vbles only */
128: {
129: if (rptr->relvused
130: && scompare(name, MAXNAME,
131: (type == LOOKVAR ? rptr->vardesc.relvname : rptr->vardesc.reldum.relid),
132: MAXNAME) == 0)
133: {
134: Qt.qt_rangev[slot].rngvmark = 1;
135:
136: # ifdef xPTR2
137: tTfp(66, 6, "fnd '%s' at '%d'\n", name, slot);
138: # endif
139:
140: rngfront(slot);
141: return (slot);
142: }
143: }
144:
145: /*
146: ** We haven't been able to find the variable, assume
147: ** it is the name of a relation, and try and insert
148: ** a new range variable under that name.
149: */
150: if (type == LOOKVAR)
151: {
152: if ((i = openr(&reldesc, OR_RELTID, name)) < 0)
153: syserr("relname: error in openr '%d'", i);
154:
155: /*
156: ** rngent will call rnglook to create var if name
157: ** was a relation name
158: */
159: if (i == 0)
160: return(rngent(R_IMPLICIT, name, &reldesc));
161: else
162: return(-1);
163: }
164: return (-1);
165: }
166:
167: /*
168: ** RNGENT
169: **
170: ** Insert variable and relation in range table.
171: **
172: ** Trace Flags:
173: ** rngent ~~ 66.8
174: */
175:
176: int
177: rngent(type, var, desc)
178: int type;
179: char *var;
180: register DESC *desc;
181: {
182: register PARRNG *rptr;
183: register int slot;
184:
185: # ifdef xPTR2
186: tTfp(66, 8, "rngent:\ttype=%s\tvar=%s\n",
187: (type == R_INTERNAL ? "internal" : "external"), var);
188: # endif
189:
190: if (type == R_INTERNAL)
191: slot = MAXVAR; /* the internal variable */
192: else
193: {
194: if ((type == R_IMPLICIT) || (slot = rnglook(var, LOOKVAR)) < 0)
195: {
196: /* not in range table */
197: slot = rngold();
198: }
199:
200: rngfront(slot);
201: }
202:
203: rptr = &Parrng[slot];
204:
205: if (!bequal(desc, &rptr->vardesc, sizeof (*desc)))
206: {
207: attfree(rptr->attlist);
208: rptr->attlist = NULL;
209: }
210:
211: rptr->relvused = 1;
212:
213: bmove(desc, &rptr->vardesc, sizeof(*desc));
214: pmove(var, rptr->vardesc.relvname, MAXNAME, ' ');
215:
216: ctlmod_decl(slot);
217:
218: return (slot);
219: }
220:
221: /*
222: ** RNGDEL
223: ** removes an entry from the range table
224: ** removes all variables for the relation name
225: **
226: ** Trace Flags:
227: ** rngdel ~~ 66.12
228: */
229: rngdel(rel)
230: register char *rel;
231: {
232: register int slot;
233:
234: # ifdef xPTR2
235: tTfp(66, 12, "rngdel: %12s\n", rel);
236: # endif
237:
238: while ((slot = rnglook(rel, LOOKREL)) >= 0)
239: {
240: Parrng[slot].relvused = 0;
241: rngback(slot);
242: attfree(Parrng[slot].attlist);
243: Parrng[slot].attlist = NULL;
244: }
245: }
246:
247:
248: /*
249: ** RNGFRONT
250: ** move entry 'r' to head of range table list
251: **
252: ** Trace Flags:
253: ** rngfront ~~ 67.0
254: */
255: rngfront(slot)
256: int slot;
257: {
258: register PARRNG *fptr;
259:
260: # ifdef xPTR2
261: tTfp(67, 0, "rngfront:\tslot %d\n", slot);
262: # endif
263:
264:
265: rngget(slot);
266:
267: fptr = &Parrng[slot];
268:
269: fptr->frontpt = NULL;
270: fptr->backpt = Rngfront;
271: Rngfront->frontpt = fptr;
272:
273: Rngfront = fptr;
274: }
275:
276: /*
277: ** RNGBACK
278: ** move entry 'r' to back of range table list
279: **
280: ** Trace Flags:
281: ** rngback ~~ 67.4
282: */
283: rngback(slot)
284: int slot;
285: {
286: register PARRNG *bptr;
287:
288: # ifdef xPTR2
289: tTfp(67, 4, "rngback:\tslot %d\n", slot);
290: # endif
291:
292: rngget(slot);
293:
294: bptr = &Parrng[slot];
295:
296: bptr->backpt = NULL;
297: bptr->frontpt = Rngback;
298: Rngback->backpt = bptr;
299:
300: Rngback = bptr;
301: }
302:
303: /*
304: ** RNGGET -- get a descriptor from range table
305: **
306: ** Trace Flags:
307: ** rngget ~~ 67.8
308: */
309:
310: rngget(slot)
311: int slot;
312: {
313: register PARRNG *slotptr;
314: register PARRNG *forward;
315: register PARRNG *backward;
316:
317: # ifdef xPTR2
318: tTfp(67, 8, "rngget:\tslot %d\n", slot);
319: # endif
320:
321:
322: slotptr = &Parrng[slot];
323: forward = slotptr->frontpt;
324: backward = slotptr->backpt;
325:
326: if (slotptr == Rngfront)
327: {
328: Rngfront = backward;
329: backward->frontpt = NULL;
330: }
331: else if (slotptr == Rngback)
332: {
333: Rngback = forward;
334: forward->backpt = NULL;
335: }
336: else
337: {
338: forward->backpt = backward;
339: backward->frontpt = forward;
340: }
341:
342: slotptr->backpt = slotptr->frontpt = NULL;
343: }
344:
345: /*
346: ** RNGOLD -- find least recently used vble entry
347: **
348: ** Trace Flags:
349: ** rngold ~~ 67.9
350: */
351: int
352: rngold()
353: {
354: # ifdef xPTR2
355: tTfp(67, 9, "rngold %d.\n", Rngback - (PARRNG *) Parrng);
356: # endif
357:
358: return(Rngback - (PARRNG *) Parrng);
359: }
360:
361: /*
362: ** RNGRESET
363: ** reset the used marks to '0'
364: **
365: ** Trace Flags:
366: ** rngreset ~~ 67.10
367: */
368: rngreset()
369: {
370: register int i;
371: register RANGEV *rangevptr;
372:
373: # ifdef xPTR2
374: tTfp(67, 10, "rngreset().\n");
375: # endif
376:
377: rangevptr = Qt.qt_rangev;
378:
379: for (i = 0; i < MAXVAR; i++, rangevptr++) /* only do external ones */
380: rangevptr->rngvmark = 0;
381: }
382:
383: /*
384: ** CHECKUPD
385: ** checks to make sure that the user can update the relation 'name1'
386: ** the 'open' parameter is set if 'Reldesc' contains the openr info
387: ** for the relation in question.
388: **
389: ** Trace Flags:
390: ** checkupd ~~ 67.11
391: */
392: checkupd(entnum)
393: int entnum;
394: {
395: extern int Noupdt;
396: extern PARRNG Parrng[];
397: register PARRNG *rptr;
398:
399: # ifdef xPTR2
400: tTfp(67, 11, "checkupd(%d).\n", entnum);
401: # endif
402:
403: rptr = &Parrng[entnum];
404:
405: if (!Noupdt)
406: return;
407: if (rptr->vardesc.reldum.relstat & S_NOUPDT)
408: /* no updates allowed on this relation */
409: par_error(CANTUPDATE, WARN, trim_relname(rptr->vardesc.reldum.relid), 0);
410: }
411:
412: /*
413: ** RNGFRESH -- check the range table relstat information for accuracy
414: **
415: ** If the command specified could have changed the relstat info
416: ** make the appropriate adjustments to the range table
417: */
418: rngfresh(op)
419: int op;
420: {
421: register PARRNG *rptr;
422: register int slot;
423: DESC desc;
424: char var[MAXNAME];
425:
426: # ifdef xPTR2
427: tTfp(67, 11, "rngfresh %d.\n", op);
428: # endif
429:
430: /* search the entire table! */
431: for (slot = 0, rptr = Parrng; slot <= MAXVAR; slot++, rptr++)
432: {
433: if (!(rptr->relvused))
434: continue;
435:
436: switch (op)
437: {
438: case mdDESTROY:
439: if ((rptr->vardesc.reldum.relstat & (S_VBASE | S_INTEG | S_PROTUPS | S_INDEX)) != 0)
440: {
441: fixordel:
442: /*
443: ** openr the relation, if it doesn't exist make
444: ** sure that all range table entries are gone
445: */
446: if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
447: rptr->vardesc.reldum.relstat = desc.reldum.relstat;
448: else
449: /* relation not there, purge table */
450: rngdel(rptr->vardesc.reldum.relid);
451: }
452: break;
453:
454: case mdVIEW:
455: if ((rptr->vardesc.reldum.relstat & S_VBASE) == 0)
456: {
457: fixorerr:
458: /*
459: ** if the relation doesn't exist then it is
460: ** a syserr, otherwise, copy the bits.
461: */
462: if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
463: rptr->vardesc.reldum.relstat = desc.reldum.relstat;
464: else
465: {
466: /* not there, syserr */
467: syserr("RNGFRESH: extra entry: %s", rptr->vardesc.reldum.relid);
468: }
469: }
470: break;
471:
472: case mdPROT:
473: if ((rptr->vardesc.reldum.relstat & S_PROTUPS) == 0)
474: goto fixorerr;
475: break;
476:
477: case mdINTEG:
478: if ((rptr->vardesc.reldum.relstat & S_INTEG) == 0)
479: goto fixorerr;
480: break;
481:
482: case mdMODIFY:
483: if (!openr(&desc, OR_RELTID, rptr->vardesc.reldum.relid))
484: if (!bequal(&rptr->vardesc, &desc, sizeof desc))
485: /* relation structure may have changed, adjust range variable */
486: {
487: bmove(rptr->vardesc.relvname, var, MAXNAME);
488: rngent(R_EXTERNAL, var, &desc);
489: }
490: if ((rptr->vardesc.reldum.relstat & S_INDEX) != 0)
491: goto fixordel;
492: break;
493:
494: default:
495: return; /* command ok, dont waste time on rest of table */
496: }
497: }
498: }
499:
500: printtable()
501: {
502: register PARRNG *rptr;
503: int slot[MAXRANGE];
504: int i;
505:
506: printf("Range table:\n");
507:
508: for (i = 0; i < MAXRANGE; i++)
509: slot[i] = 0;
510:
511: for (rptr = Rngfront; rptr != NULL; rptr = rptr->backpt)
512: {
513: i = rptr - (PARRNG *) Parrng;
514: slot[i] = 1;
515: printslot(i);
516: }
517: printf("\nEntries not in list:\n");
518: for (i = 0; i < MAXRANGE; i++)
519: {
520: if (!slot[i])
521: {
522: printslot(i);
523: }
524: }
525: }
526:
527: printslot(slot)
528: int slot;
529: {
530: register RANGEV *rptr;
531: register PARRNG *auxptr;
532:
533: rptr = &Qt.qt_rangev[slot];
534: auxptr = &Parrng[slot];
535:
536: printf("slot:\t%d\n{\trvar:\t%.12s,\trelnm:\t%.12s.\n",
537: slot, auxptr->vardesc.relvname,
538: auxptr->vardesc.reldum.relid);
539: printf("\tRELVUSED: %d, RELVSEND %d.\n",
540: auxptr->relvused,
541: rptr->rngvmark);
542:
543:
544: printf("\tratts: %d, attlist: %d.\n}\n", auxptr->vardesc.reldum.relatts, auxptr->attlist);
545: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.