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
Last modified: 1995-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2984
Valid CSS Valid XHTML 1.0 Strict