|
|
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: # 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.