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
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1108
Valid CSS Valid XHTML 1.0 Strict