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