|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <catalog.h>
4: # include <tree.h>
5: # include <symbol.h>
6: # include <pv.h>
7: # include <resp.h>
8: # include <func.h>
9: # include "qrymod.h"
10: # include <sccs.h>
11: # include <errors.h>
12:
13: SCCSID(@(#)d_integ.c 8.3 2/8/85)
14:
15:
16: /*
17: ** D_INTEG -- define integrity constraint
18: **
19: ** An integrity constraint (as partially defined by the last
20: ** tree defined by d_tree) is defined.
21: **
22: ** Parameters:
23: ** none
24: **
25: ** Returns:
26: ** none
27: **
28: ** Side Effects:
29: ** Activity in 'relation' and 'integrities' catalogs.
30: **
31: ** Trace Flags:
32: ** 49
33: */
34:
35: extern DESC Intdes;
36: extern DESC Reldes;
37:
38: extern d_integ(), null_fn();
39: extern short tTqm[80];
40:
41: struct fn_def DefIntFn =
42: {
43: "DINTEG",
44: d_integ,
45: null_fn,
46: null_fn,
47: NULL,
48: 0,
49: tTqm,
50: 80,
51: 'Q',
52: 0
53: };
54:
55:
56:
57: d_integ(pc, pv)
58: int pc;
59: PARM *pv;
60: {
61: register int i;
62: register QTREE *t; /* definition tree */
63: struct integrity inttup;
64: struct tup_id tid;
65: register int rv; /* result variable */
66: struct relation relkey;
67: struct relation reltup;
68: char relid[MAXNAME];
69: char relowner[2];
70: long relstat;
71: struct qthdr qt;
72:
73: if (pv[0].pv_type != PV_QTREE)
74: syserr("d_integ: tree");
75: t = pv[0].pv_val.pv_qtree;
76: rv = Qt.qt_resvar;
77:
78: /*
79: ** Check for valid environment.
80: ** The tree must exist, have a qualification, and have
81: ** no target list. The query mode must be mdINTEG.
82: **
83: ** User level stuff checks to see that this is single
84: ** variable aggregate free, since that's all we know
85: ** about thusfar. Also, the relation in question must
86: ** not be a view.
87: */
88:
89: # ifdef xQTR3
90: if (t == NULL)
91: syserr("d_integ: NULL tree");
92: if ((i = t->right->sym.type) != AND)
93: syserr("d_integ: qual %d", i);
94: if ((i = t->left->sym.type) != TREE)
95: syserr("d_integ: TL %d", i);
96: if (Qt.qt_qmode != mdINTEG)
97: syserr("d_integ: Qmode %d", Qt.qt_qmode);
98: # endif
99:
100: /* check for aggregates */
101: if (aggcheck(t))
102: qmerror(NOAGGINT, -1, rv, 0); /* aggregates in qual */
103:
104: /* check for multi-variable */
105: for (i = 0; i < MAXRANGE; i++)
106: {
107: if (Qt.qt_rangev[i].rngvdesc == NULL)
108: continue;
109: if (i != rv)
110: {
111: # ifdef xQTR3
112: if (tTf(49, 1))
113: printf("d_integ: Rv %d(%.14s) i %d(%.14s)\n",
114: rv, Qt.qt_rangev[rv].rngvdesc->reldum.relid,
115: i, Qt.qt_rangev[i].rngvdesc->reldum.relid);
116: # endif
117: qmerror(NOMULTIVAR, -1, rv, 0); /* too many vars */
118: }
119: }
120:
121:
122: /* check for the resultvariable being a real relation */
123: if (bitset(S_VIEW, Qt.qt_rangev[rv].rngvdesc->reldum.relstat))
124: qmerror(INTVIEW, -1, rv, 0); /* is a view */
125:
126: /* guarantee that you own this relation */
127: if (!bequal(Usercode, Qt.qt_rangev[rv].rngvdesc->reldum.relowner, UCODE_SZ))
128: qmerror(MUSTOWN, -1, rv, 0); /* don't own reln */
129: bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relid, relid, MAXNAME);
130: bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relowner, relowner, 2);
131: bmove(&Qt,&qt, sizeof (Qt));
132: relstat = Qt.qt_rangev[rv].rngvdesc->reldum.relstat;
133:
134: /*
135: ** Guarantee that the integrity constraint is true now.
136: ** This involves issuing a retrieve statement for the
137: ** inverse of the qualification. The target list is
138: ** already null, so we will get nothing printed out
139: ** (only a return status).
140: **
141: ** We reset resp_tups if ok so that the user isn't annoyed
142: ** by a tuple count. On error, it is a count of the
143: ** number of tuples that don't satisfy.
144: */
145:
146: Qt.qt_qmode = mdRETR;
147: Qt.qt_resvar = -1;
148:
149: /* issue the invert of the query */
150: issueinvert(t);
151: if (Resp.resp_tups != 0)
152: qmerror(INITCONST, -1, rv, 0); /* constraint not satisfied */
153: Resp.resp_tups = -1;
154: bmove(&qt,&Qt, sizeof (Qt));
155:
156: /*
157: ** Set up the rest of the environment.
158: */
159:
160: opencatalog("integrities", OR_WRITE);
161: clr_tuple(&Intdes, &inttup);
162: Qt.qt_resvar = -1;
163: Qt.qt_qmode = -1;
164:
165: /*
166: ** Set up integrity relation tuple.
167: ** The qualification will be scanned, and a set of
168: ** domains referenced will be created. Other stuff
169: ** is filled in from the range table and from the
170: ** parser.
171: **
172: ** The tree is actually inserted into the tree catalog
173: ** in this step. Extra information is cleared here.
174: */
175:
176: inttup.intresvar = rv;
177: bmove(relid, inttup.intrelid, MAXNAME);
178: bmove(relowner, inttup.intrelowner, 2);
179: makeidset(rv, t, inttup.intdomset);
180: inttup.inttree = puttree(t, inttup.intrelid, inttup.intrelowner, mdINTEG);
181:
182: /*
183: ** Insert tuple into integrity catalog.
184: */
185:
186: i = insert(&Intdes, &tid, &inttup, FALSE);
187: if (i < 0)
188: syserr("d_integ: insert");
189: if (noclose(&Intdes) != 0)
190: syserr("d_integ: noclose int");
191:
192: /*
193: ** Update relstat S_INTEG bit.
194: */
195:
196: if (!bitset(S_INTEG, relstat))
197: {
198: opencatalog("relation", OR_WRITE);
199: clearkeys(&Reldes);
200: setkey(&Reldes, &relkey, inttup.intrelid, RELID);
201: setkey(&Reldes, &relkey, inttup.intrelowner, RELOWNER);
202: i = getequal(&Reldes, &relkey, &reltup, &tid);
203: if (i != 0)
204: syserr("d_integ: geteq returns %d",i);
205: reltup.relstat |= S_INTEG;
206: i = replace(&Reldes, &tid, &reltup, FALSE);
207: if (i != 0)
208: syserr("d_integ: replace returns %d",i);
209: if (noclose(&Reldes) != 0)
210: syserr("d_integ: noclose rel");
211: }
212:
213: return (0);
214: }
215:
216:
217: makeidset(varno, tree, dset)
218: int varno;
219: QTREE *tree;
220: int dset[8];
221: {
222: register int vn;
223: register QTREE *t;
224:
225: vn = varno;
226: t = tree;
227:
228: while (t != NULL)
229: {
230: if (t->sym.type == VAR && t->sym.value.sym_var.varno == vn)
231: lsetbit(t->sym.value.sym_var.attno, dset);
232:
233: /* handle left subtree recursively */
234: makeidset(vn, t->left, dset);
235:
236: /* handle right subtree iteratively */
237: t = t->right;
238: }
239: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.