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(@(#)att_fcn.c 8.2 2/8/85) 10: 11: /* 12: ** fake attribute stash entries for tid nodes (and sid in dist version) 13: ** these are provided by the system to a program only for debugging 14: ** the system source and do not have well defined (over time) meanings. 15: */ 16: struct atstash Faketid = 17: { 18: 0, INT, 4, "tid", 0 19: }; 20: #ifdef DISTRIB 21: struct atstash Fakesid 22: { 23: 0, INT, 4, "sid", 0 24: }; 25: #endif 26: 27: struct atstash Attable[MAXATT];/* attrib stash space, turned into a list later */ 28: struct atstash *Freeatt; /* free list of attrib stash */ 29: 30: /* 31: ** ATT_FCN.C -- attribute list manipulation routines 32: ** 33: ** ATT_FCN ~~ trace flags = 40, 41 34: ** 35: ** Defines: 36: ** Attable 37: ** Freeatt 38: ** attinit() 39: ** attlookup() 40: ** attadd() 41: ** attfnd() 42: ** attcheck() 43: ** attfree() 44: ** attalloc() 45: ** attcount() 46: ** 47: ** History: 48: ** modified for 6.3 (jiw) 49: */ 50: 51: /* 52: ** ATTINIT -- initializes attribute table 53: ** 54: ** Parameters: 55: ** none 56: ** 57: ** Trace Flags: 58: ** attinit ~~ 40.0 59: */ 60: 61: attinit() 62: { 63: register struct atstash *atptr; 64: register int i; 65: 66: # ifdef xPTR3 67: tTfp(40, 0, "attinit"); 68: # endif 69: 70: atptr = Attable; 71: 72: for (i = 0; i < MAXATT - 1; i++) 73: { 74: atptr->atbnext = atptr + 1; 75: atptr++; 76: } 77: 78: atptr->atbnext = NULL; 79: 80: Freeatt = Attable; /* the first attribute in chain */ 81: } 82: 83: /* 84: ** ATTLOOKUP -- finds attribute entry 85: ** 86: ** Attlookup looks up atribute 'attrib' in the att stash 87: ** for range table entry 'slot'. If the attrib is not 88: ** in the stash it is entered. 89: ** 90: ** Parameters: 91: ** attrib -- the name of the attribute to find 92: ** slot -- the number of the range variable 93: ** 94: ** Returns: 95: ** pointer to the attstash element 96: ** 97: ** Trace Flags: 98: ** attlookup ~~ 40.4, 40.5 99: */ 100: 101: struct atstash * 102: attlookup(slot, attrib) 103: int slot; 104: char *attrib; 105: { 106: register PARRNG *rptr; 107: register struct atstash *current; 108: int ik; 109: struct attribute tuple; 110: register struct attribute *ktuple; 111: struct attribute ktup; 112: TID tid; 113: 114: extern struct atstash *attfind(); 115: extern struct atstash *attadd(); 116: extern DESC Attdes; 117: extern PARRNG Parrng[]; 118: 119: rptr = &Parrng[slot]; 120: 121: ktuple = &ktup; 122: # ifdef xPTR2 123: tTfp(40, 4, "attlookup: att = %s and rel= %s\n", attrib, trim_relname(rptr->vardesc.reldum.relid)); 124: # endif 125: 126: /* attribute called "tid" is phantom attribute, use fake */ 127: if (sequal("tid", attrib)) 128: return (&Faketid); 129: # ifdef DISTRIB 130: if (sequal("sid", attrib)) 131: return (&Fakesid); 132: # endif 133: 134: /* check to see if attrib is in stash */ 135: if ((current = attfind(slot, attrib)) != NULL) 136: return (current); 137: 138: # ifdef xPTR2 139: tTfp(40, 5, "getting att info from relation\n"); 140: # endif 141: 142: /* rel name, owner, attname is unique ident */ 143: clearkeys(&Attdes); 144: setkey(&Attdes, ktuple, rptr->vardesc.reldum.relid, ATTRELID); 145: setkey(&Attdes, ktuple, rptr->vardesc.reldum.relowner, ATTOWNER); 146: setkey(&Attdes, ktuple, attrib, ATTNAME); 147: if (!(ik = getequal(&Attdes, ktuple, &tuple, &tid))) 148: { 149: /* put attrib stuff into att stash */ 150: current = attadd(slot, &tuple); 151: return (current); 152: } 153: 154: if (ik == 1) 155: /* attribute not in relation */ 156: par_error(NOATTRIN, WARN, attrib, trim_relname(rptr->vardesc.reldum.relid), 0); 157: else 158: syserr("fatal error in getequal, ret: %d", ik); 159: } 160: 161: /* 162: ** ATTADD -- add an attribute to the list for a particular range variable 163: ** 164: ** Parameters: 165: ** slot -- the number of the range variable to use 166: ** tuple -- the attribute tuple to add 167: ** 168: ** Returns: 169: ** pointer to the attribute added 170: ** 171: ** Trace Flags: 172: ** attadd ~~ 40.8 173: */ 174: 175: struct atstash * 176: attadd(slot, tuple) 177: int slot; 178: struct attribute *tuple; 179: { 180: register struct atstash *current; 181: register struct atstash *aptr; 182: register struct atstash *bptr; 183: PARRNG *rptr; 184: int i; 185: 186: extern struct atstash *attalloc(); 187: extern PARRNG Parrng[]; 188: 189: # ifdef xPTR3 190: tTfp(40, 8, "attadd slot %d, %12s\n", slot, tuple->attname); 191: # endif 192: 193: rptr = &Parrng[slot]; 194: 195: current = attalloc(); 196: current->atbid = tuple->attid; 197: current->atbfrmt = tuple->attfrmt; 198: current->atbfrml = tuple->attfrml; 199: bmove(tuple->attname, current->atbname, MAXNAME); 200: for (i = 0; i < MAXNAME; i++) 201: if (current->atbname[i] == ' ') 202: current->atbname[i] = '\0'; 203: 204: aptr = rptr->attlist; 205: bptr = 0; 206: while (aptr != 0) 207: { 208: if (aptr->atbid > current->atbid) 209: break; 210: bptr = aptr; 211: aptr = aptr->atbnext; 212: } 213: if (bptr == 0) 214: rptr->attlist = current; 215: else 216: bptr->atbnext = current; 217: 218: current->atbnext = aptr; 219: 220: return (current); 221: } 222: 223: /* 224: ** ATTFIND -- finds attribute in stash 225: ** 226: ** Attfind looks in attribute stash to see if attrib info already there 227: ** return pointer to attribute in attribute table else NULL. 228: ** 229: ** Parameters: 230: ** slot -- the number of the entry in range table 231: ** attrib -- the attribute name to find 232: ** 233: ** Returns: 234: ** pointer to entry or NULL if not in stash 235: ** 236: ** Trace Flags: 237: ** attfind ~~ 40.12 238: */ 239: 240: struct atstash * 241: attfind(slot, attrib) 242: int slot; 243: register char *attrib; 244: { 245: register struct atstash *aptr; 246: 247: extern PARRNG Parrng[]; 248: 249: # ifdef xPTR1 250: tTfp(40, 12, "attadd\n"); 251: # endif 252: 253: aptr = Parrng[slot].attlist; 254: 255: while (aptr != NULL) 256: { 257: if (!scompare(attrib, MAXNAME, aptr->atbname, MAXNAME)) 258: return (aptr); 259: 260: aptr = aptr->atbnext; 261: } 262: return (NULL); 263: } 264: 265: /* 266: ** ATTCHECK -- checks for conflicts in attributes 267: ** 268: ** Attcheck checks for type conflicts in the current query domain and 269: ** attable entry 270: ** 271: ** Parameters: 272: ** aptr -- pointer to current atttibute 273: ** 274: ** Returns: 275: ** nothing 276: ** 277: ** Requires: 278: ** Trfrmt -- for current format 279: ** 280: ** Trace Flags: 281: ** attcheck ~~ 41.0 282: */ 283: 284: attcheck(aptr) 285: register struct atstash *aptr; 286: { 287: extern char Trfrmt; 288: 289: # ifdef xPTR1 290: tTfp(41, 0, "attcheck\n"); 291: # endif 292: 293: if ((Trfrmt == CHAR) != (aptr->atbfrmt == CHAR)) 294: /* function type does not match attrib */ 295: par_error(RESTYPE, WARN, aptr->atbname, 0); 296: } 297: 298: /* 299: ** ATTFREE -- puts a list of attrib space back on the free list 300: ** 301: ** Parameters: 302: ** aptr -- pointer to list of attstash entries 303: ** 304: ** Returns: 305: ** nothing 306: ** 307: ** Requires: 308: ** Freeatt 309: ** 310: ** Trace Flags: 311: ** attfree ~~ 41.4 312: */ 313: 314: attfree(aptr) 315: struct atstash *aptr; 316: { 317: register struct atstash *att; 318: 319: # ifdef xPTR1 320: tTfp(41, 4, "attfree\n"); 321: # endif 322: 323: if ((att = aptr) == NULL) 324: return; 325: 326: while (att->atbnext != NULL) 327: att = att->atbnext; 328: 329: att->atbnext = Freeatt; 330: Freeatt = aptr; 331: } 332: 333: /* 334: ** ATTALLOC -- returns a pointer to a atstash type structure 335: ** 336: ** Attalloc checks the freelist (Freeatt) for attstash entries, 337: ** if some is there, one is removed. If the freelist is empty, 338: ** attstashes are removed from range table entries until an free 339: ** element is found. 340: ** 341: ** Parameters: 342: ** none 343: ** 344: ** Returns: 345: ** a pointer to an atstash element 346: ** 347: ** Requires: 348: ** Rngback 349: ** Freeatt 350: ** 351: ** Trace Flags: 352: ** attalloc ~~ 41.8, 41.9 353: */ 354: 355: struct atstash * 356: attalloc() 357: { 358: register struct atstash *aptr; 359: register PARRNG *rptr; 360: 361: extern PARRNG *Rngback; 362: 363: # ifdef xPTR3 364: tTfp(41, 8, "attalloc Freeatt %d\n", Freeatt); 365: # endif 366: 367: /* Note: the following loop doesn't happen if Freeatt != NULL */ 368: 369: for (rptr = Rngback; Freeatt == NULL; rptr = rptr->frontpt) 370: { 371: /* 372: ** search least recently used vbles for attrib stash space 373: ** until at least one entry is found 374: */ 375: 376: # ifdef xPTR3 377: tTfp(41, 9, "attalloc: freeing %12s\n", rptr->vardesc.relvname); 378: # endif 379: 380: if (rptr == NULL) 381: syserr("attalloc: no att space."); 382: 383: Freeatt = rptr->attlist; 384: rptr->attlist = NULL; 385: } 386: aptr = Freeatt; 387: Freeatt = Freeatt->atbnext; 388: aptr->atbnext = NULL; 389: 390: return (aptr); 391: } 392: 393: /* 394: ** ATTCOUNT -- counts atstash elems 395: ** 396: ** Attcount returns a count fof the number of attributes already in the 397: ** attrib stash. 398: ** 399: ** Parameter: 400: ** slot -- the range table entry to count 401: ** 402: ** Returns: 403: ** count of the attributes 404: ** 405: ** Trace Flags: 406: ** attcount ~~ 41.12 407: */ 408: 409: int 410: attcount(slot) 411: int slot; 412: { 413: register int cntr; 414: register struct atstash *aptr; 415: 416: extern PARRNG Parrng[]; 417: 418: # ifdef xPTR1 419: tTfp(41, 12, "attcount\n"); 420: # endif 421: 422: cntr = 0; 423: aptr = Parrng[slot].attlist; 424: while (aptr != NULL) 425: { 426: cntr++; 427: aptr = aptr->atbnext; 428: } 429: return (cntr); 430: }