1: # include "../ingres.h"
2: # include "../access.h"
3:
4: /*
5: ** Seq_attributes - get all attributes of a relation in their correct order.
6: **
7: ** Seq_attributes() can be called when it is desired to get all
8: ** attribute tuples for a relation. They are guaranteed to be in
9: ** the same order as they were created in; that is "attid" order.
10: **
11: ** The calling convention is:
12: **
13: ** seq_init(Attribute_descriptor, Descriptor_for_relation)
14: **
15: ** while (seq_attributes(Att_desc, Des_for_rel, Tuple)
16: ** {
17: ** }
18: **
19: ** The first parameter is an OPEN descriptor for the attribute
20: ** relation. The second parameter is a descriptor for the relation.
21: ** It must have the relation-relation tuple (ie openr mode -1).
22: ** The third parameter is a place to put the attribute. Its
23: ** dimension must be at least sizeof (attribute structure).
24: **
25: ** Seq_attribute attempts to optimize the retrieval of the
26: ** attributes. It assumes initially that the are physically
27: ** stored sequentially. If so it will retrieve them in the
28: ** minimum possible number of accesses.
29: **
30: ** If it finds one tuple out of sequence then all future
31: ** scans will start from that first out of sequence tuple.
32: */
33:
34: struct tup_id Seq_tdl, Seq_tdh, Seq_tdf;
35: int Seq_seqmode, Seq_next;
36:
37:
38:
39: seq_init(atr, rel)
40: struct descriptor *atr;
41: struct descriptor *rel;
42: {
43: register struct descriptor *a, *r;
44: register int i;
45: struct attribute attkey;
46:
47: a = atr;
48: r = rel;
49:
50: clearkeys(a);
51: setkey(a, &attkey, r->relid, ATTRELID);
52: setkey(a, &attkey, r->relowner, ATTOWNER);
53: if (i = find(a, EXACTKEY, &Seq_tdl, &Seq_tdh, &attkey))
54: syserr("seq_init:find:%d", i);
55:
56: Seq_seqmode = TRUE;
57: Seq_next = 1;
58: }
59:
60:
61: seq_attributes(atr, rel, att_tuple)
62: struct descriptor *atr;
63: struct descriptor *rel;
64: struct attribute *att_tuple;
65: {
66: register struct descriptor *a, *r;
67: register struct attribute *atup;
68: int i, nxttup;
69:
70: a = atr;
71: r = rel;
72: atup = att_tuple;
73:
74: if (Seq_next > r->relatts)
75: return (0); /* no more attributes */
76:
77: if (!Seq_seqmode)
78: {
79: /* attributes not stored sequencially, start from first attribute */
80: bmove(&Seq_tdf, &Seq_tdl, sizeof (Seq_tdl));
81: nxttup = FALSE;
82: }
83: else
84: nxttup = TRUE;
85:
86: while ((i = get(a, &Seq_tdl, &Seq_tdh, atup, nxttup)) == 0)
87: {
88:
89: nxttup = TRUE;
90: /* make sure this is a tuple for the right relation */
91: if (kcompare(a, atup, r))
92: continue;
93:
94: /* is this the attribute we want? */
95: if (atup->attid != Seq_next)
96: {
97: if (Seq_seqmode)
98: {
99: /*
100: ** Turn off seq mode. Save the tid of
101: ** the current tuple. It will be the
102: ** starting point for the next call
103: ** to seq_attributes
104: */
105: bmove(&Seq_tdl, &Seq_tdf, sizeof (Seq_tdf));
106: Seq_seqmode = FALSE;
107: }
108:
109: continue;
110: }
111:
112: /* got current attribute. increment to next attribute */
113: Seq_next++;
114: return (1);
115: }
116:
117: /* fell out of loop. either bad get return or missing attribute */
118: syserr("seq_att:bad or missing %d,%d", i, Seq_next);
119: }
Defined functions
Defined variables