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