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