|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <tree.h>
4: # include <symbol.h>
5: # include "parser.h"
6: # include <sccs.h>
7:
8: SCCSID(@(#)format.c 7.1 2/5/81)
9:
10: /*
11: ** FORMAT
12: ** routine to compute the format of the result relation attributes
13: ** it is called after ATTLOOKUP so the tuple defining the current
14: ** attribute is already available.
15: ** if the element is a function of more than one attribute, the result
16: ** domain format is computed by the following rules:
17: ** - no fcns allowed on character attributes
18: ** - fcn of integer attribs is an integer fcn with
19: ** length = MAX(length of all attributes)
20: ** - fcn of floating point attribs is a floating point
21: ** fcn with length = MIN(length of all attribs)
22: ** - fcn of integer and floating attributes is a
23: ** floating fcn with length = MIN(length of all floating
24: ** attributes)
25: **
26: ** Trace Flags:
27: ** Format ~~ 52.0, 52.1
28: */
29:
30: format(result1)
31: QTREE *result1;
32: {
33: register char rfrmt;
34: register char rfrml;
35: register QTREE *result;
36: struct constop *cpt;
37:
38: extern struct out_arg Out_arg;
39: extern struct constop Coptab[];
40: extern char Trfrml;
41: extern char Trfrmt;
42: extern int Qlflag;
43:
44: # ifdef xPTR2
45: tTfp(52, 0, "format:.\n");
46: # endif
47:
48: result = result1;
49: switch (result->sym.type)
50: {
51: case VAR:
52: rfrmt = result->sym.value.sym_var.varfrmt;
53: rfrml = result->sym.value.sym_var.varfrml;
54: break;
55:
56: case AOP:
57: switch (result->sym.value.sym_op.opno)
58: {
59: case opAVG:
60: case opAVGU:
61: rfrmt = FLOAT;
62: rfrml = 8;
63: if (result->sym.value.sym_op.agfrmt == CHAR)
64: /* character domain not allowed in these aggs */
65: par_error(AVGTYPE, WARN, 0);
66: break;
67:
68: case opCOUNT:
69: case opCOUNTU:
70: rfrmt = INT;
71: rfrml = 4;
72: break;
73:
74: case opANY:
75: rfrmt = INT;
76: rfrml = 2;
77: break;
78:
79: case opSUM:
80: case opSUMU:
81: rfrmt = result->sym.value.sym_op.agfrmt;
82: rfrml = result->sym.value.sym_op.agfrml;
83: if (rfrmt == CHAR)
84: /* no char domains for these aggs */
85: par_error(SUMTYPE, WARN, 0);
86: break;
87:
88: default:
89: rfrmt = result->sym.value.sym_op.agfrmt;
90: rfrml = result->sym.value.sym_op.agfrml;
91: break;
92: }
93: break;
94:
95: case AGHEAD:
96: /*
97: ** can get format info from the AOP node because
98: ** it already has format info computed
99: */
100: if (result->left->sym.type == AOP)
101: {
102: /* no by-list */
103: rfrmt = result->left->sym.value.sym_op.opfrmt;
104: rfrml = result->left->sym.value.sym_op.opfrml;
105: }
106: else
107: {
108: /* skip over by-list */
109: rfrmt = result->left->right->sym.value.sym_resdom.resfrmt;
110: rfrml = result->left->right->sym.value.sym_resdom.resfrml;
111: }
112: break;
113:
114: case RESDOM:
115: format(result->right);
116: return;
117:
118: case INT:
119: case FLOAT:
120: case CHAR:
121: rfrmt = result->sym.type;
122: rfrml = result->sym.len;
123: break;
124:
125: case COP:
126: for (cpt = Coptab; cpt->copname; cpt++)
127: {
128: if (result->sym.value.sym_op.opno == cpt->copnum)
129: {
130: rfrmt = cpt->coptype;
131: rfrml = cpt->coplen;
132: break;
133: }
134: }
135: if (!cpt->copname)
136: syserr("bad cop in format(%d)", result->sym.value.sym_op.opno);
137: break;
138:
139: case UOP:
140: switch (result->sym.value.sym_op.opno)
141: {
142: case opATAN:
143: case opCOS:
144: # ifdef xV6_UNIX
145: case opGAMMA:
146: # endif
147: case opLOG:
148: case opSIN:
149: case opSQRT:
150: case opEXP:
151: format(result->left);
152: if (Trfrmt == CHAR)
153: /*
154: ** no character expr in FOP
155: ** if more ops are added, must change error message */
156: par_error(FOPTYPE, WARN, 0);
157:
158: case opFLOAT8:
159: /* float8 is type conversion and can have char values */
160: rfrmt = FLOAT;
161: rfrml = 8;
162: break;
163:
164: case opFLOAT4:
165: rfrmt = FLOAT;
166: rfrml = 4;
167: break;
168:
169: case opINT1:
170: rfrmt = INT;
171: rfrml = 1;
172: break;
173:
174: case opINT2:
175: rfrmt = INT;
176: rfrml = 2;
177: break;
178:
179: case opINT4:
180: rfrmt = INT;
181: rfrml = 4;
182: break;
183:
184: case opASCII:
185: format(result->left);
186: rfrmt = CHAR;
187: rfrml = Trfrml;
188: if (Trfrmt == INT)
189: {
190: if (Trfrml == 2)
191: rfrml = Out_arg.i2width;
192: else if (Trfrml == 4)
193: rfrml = Out_arg.i4width;
194: else if (Trfrml == 1)
195: rfrml = Out_arg.i1width;
196: else
197: syserr("bad length %d for INT", Trfrml);
198: break;
199: }
200: if (Trfrmt == FLOAT)
201: {
202: if (Trfrml == 8)
203: rfrml = Out_arg.f8width;
204: else if (Trfrml == 4)
205: rfrml = Out_arg.f4width;
206: else
207: syserr("bad length %d for FLOAT", Trfrml);
208: break;
209: }
210: if (Trfrmt == CHAR)
211: break;
212: syserr("bad frmt in opASCII %d", Trfrmt);
213:
214: case opNOT:
215: if (!Qlflag)
216: syserr("opNOT in targ list");
217: return;
218:
219: case opMINUS:
220: case opPLUS:
221: format(result->right);
222: if (Trfrmt == CHAR)
223: /* no chars for these unary ops */
224: par_error(UOPTYPE, WARN, 0);
225: return;
226:
227: case opABS:
228: format(result->left);
229: if (Trfrmt == CHAR)
230: /* no char values in fcn */
231: par_error(FOPTYPE, WARN, 0);
232: return;
233:
234: default:
235: syserr("bad UOP in format %d", result->sym.value.sym_op.opno);
236: }
237: break;
238:
239: case BOP:
240: switch (result->sym.value.sym_op.opno)
241: {
242:
243: case opEQ:
244: case opNE:
245: case opLT:
246: case opLE:
247: case opGT:
248: case opGE:
249: if (!Qlflag)
250: syserr("LBOP in targ list");
251: format(result->right);
252: rfrmt = Trfrmt;
253: format(result->left);
254: if ((rfrmt == CHAR) != (Trfrmt == CHAR))
255: /* type conflict on relational operator */
256: par_error(RELTYPE, WARN, 0);
257: return;
258:
259: case opADD:
260: case opSUB:
261: case opMUL:
262: case opDIV:
263: format(result->left);
264: rfrmt = Trfrmt;
265: rfrml = Trfrml;
266: format(result->right);
267: if (rfrmt == CHAR || Trfrmt == CHAR)
268: /* no opns on characters allowed */
269: par_error(NUMTYPE, WARN, 0);
270: if (rfrmt == FLOAT || Trfrmt == FLOAT)
271: {
272: if (rfrmt == FLOAT && Trfrmt == FLOAT)
273: {
274: if (Trfrml < rfrml)
275: rfrml = Trfrml;
276: }
277: else if (Trfrmt == FLOAT)
278: rfrml = Trfrml;
279: rfrmt = FLOAT;
280: }
281: else
282: if (Trfrml > rfrml)
283: rfrml = Trfrml;
284: break;
285:
286: case opMOD:
287: format(result->left);
288: rfrmt = Trfrmt;
289: rfrml = Trfrml;
290: format(result->right);
291: if (rfrmt != INT || Trfrmt != INT)
292: /* mod operator not defined */
293: par_error(MODTYPE, WARN, 0);
294: if (Trfrml > rfrml)
295: rfrml = Trfrml;
296: break;
297:
298: case opPOW:
299: format(result->right);
300: rfrmt = Trfrmt;
301: rfrml = Trfrml;
302: format(result->left);
303: if (rfrmt == CHAR || Trfrmt == CHAR)
304: /* no char values for pow */
305: par_error(NUMTYPE, WARN, 0);
306: if ((rfrmt == FLOAT && rfrml == 4) || (Trfrmt == FLOAT && Trfrml == 4))
307: {
308: rfrmt = FLOAT;
309: rfrml = 4;
310: }
311: else
312: {
313: rfrmt = FLOAT;
314: rfrml = 8;
315: }
316: break;
317:
318: case opCONCAT:
319: format(result->left);
320: rfrmt = Trfrmt;
321: rfrml = Trfrml;
322: format(result->right);
323: if (rfrmt != CHAR || Trfrmt != CHAR)
324: /* only character domains allowed */
325: par_error(CONCATTYPE, WARN, 0);
326: rfrml += Trfrml;
327: break;
328:
329: default:
330: syserr("bad BOP in format %d", result->sym.value.sym_op.opno);
331: }
332: }
333: Trfrmt = rfrmt;
334: Trfrml = rfrml;
335: # ifdef xPTR2
336: tTfp(52, 2, "format>>: Trfrmt = %d, Trfrml = %d.\n", Trfrmt, Trfrml);
337: # endif
338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.