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