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: ** fake attribute stash entries for tid nodes (and sid in dist version) 10: ** these are provided by the system to a program only for debugging 11: ** the system source and do not have well defined (over time) meanings. 12: */ 13: struct atstash Faketid = 14: { 15: 0, INT, 4, "tid", 0 16: }; 17: #ifdef DISTRIB 18: struct atstash Fakesid = 19: { 20: 0, INT, 4, "sid", 0 21: }; 22: #endif 23: 24: /* 25: ** ATTLOOKUP 26: ** routine to look up atribute 'attrib' in the att stash 27: ** for range table entry 'rptr'. If the attrib is not 28: ** in the stash it is entered. 29: */ 30: struct atstash * 31: attlookup(rptr1, attrib) 32: struct rngtab *rptr1; 33: char *attrib; 34: { 35: register struct rngtab *rptr; 36: register struct atstash *current, *sp; 37: int ik; 38: struct attribute tuple; 39: register struct attribute *ktuple; 40: struct attribute ktup; 41: struct tup_id tid; 42: extern struct atstash *attfind(); 43: extern struct atstash *attadd(); 44: 45: rptr = rptr1; 46: ktuple = &ktup; 47: # ifdef xPTR2 48: tTfp(10, 1, "attlookup: att = %s and rel= %s\n", attrib, rptr->relnm); 49: # endif 50: 51: /* attribute called "tid" is phantom attribute, use fake */ 52: if (sequal("tid", attrib)) 53: return (&Faketid); 54: # ifdef DISTRIB 55: if (sequal("sid", attrib)) 56: return (&Fakesid); 57: # endif 58: 59: /* check to see if attrib is in stash */ 60: if ((sp = attfind(rptr, attrib)) != 0) 61: return (sp); 62: 63: # ifdef xPTR2 64: tTfp(10, 2, "getting att info from relation\n"); 65: # endif 66: 67: /* rel name, owner, attname is unique ident */ 68: clearkeys(&Desc); 69: setkey(&Desc, ktuple, rptr->relnm, ATTRELID); 70: setkey(&Desc, ktuple, rptr->relnowner, ATTOWNER); 71: setkey(&Desc, ktuple, attrib, ATTNAME); 72: if (!(ik=getequal(&Desc, ktuple, &tuple, &tid))) 73: { 74: /* put attrib stuff into att stash */ 75: current = attadd(rptr, &tuple); 76: return (current); 77: } 78: if (ik == 1) 79: /* attribute not in relation */ 80: yyerror(NOATTRIN, attrib, rptr->relnm, 0); 81: syserr("fatal error in getequal, ret: %d", ik); 82: } 83: 84: /* 85: ** ATTADD 86: ** add an attrib to the list 87: */ 88: struct atstash * 89: attadd(rptr, tuple) 90: struct rngtab *rptr; 91: struct attribute *tuple; 92: { 93: register struct atstash *current; 94: register struct atstash *aptr; 95: register struct atstash *bptr; 96: int i; 97: extern struct atstash *attalloc(); 98: 99: current = attalloc(); 100: current->atbid = tuple->attid; 101: current->atbfrmt = tuple->attfrmt; 102: current->atbfrml = tuple->attfrml; 103: bmove(tuple->attname, current->atbname, MAXNAME); 104: for (i = 0; i < MAXNAME; i++) 105: if (current->atbname[i] == ' ') 106: current->atbname[i] = '\0'; 107: 108: aptr = rptr->attlist; 109: bptr = 0; 110: while (aptr != 0) 111: { 112: if (aptr->atbid > current->atbid) 113: break; 114: bptr = aptr; 115: aptr = aptr->atbnext; 116: } 117: if (bptr == 0) 118: rptr->attlist = current; 119: else 120: bptr->atbnext = current; 121: current->atbnext = aptr; 122: return (current); 123: } 124: 125: /* 126: ** ATTFIND 127: ** look in attribute stash to see if attrib info already there 128: ** return pointer to attribute in attribute table else zero 129: */ 130: struct atstash * 131: attfind(rptr, attrib1) 132: struct rngtab *rptr; 133: char *attrib1; 134: { 135: register struct atstash *aptr; 136: register char *attrib; 137: 138: attrib = attrib1; 139: aptr = rptr->attlist; 140: while (aptr != 0) 141: { 142: if (!scompare(attrib, MAXNAME, aptr->atbname, MAXNAME)) 143: return (aptr); 144: aptr = aptr->atbnext; 145: } 146: return (0); 147: } 148: 149: /* 150: ** ATTCHECK 151: ** checks for type conflicts in the current query domain and 152: ** attable entry 153: */ 154: attcheck(aptr1) 155: struct atstash *aptr1; 156: { 157: register struct atstash *aptr; 158: 159: aptr = aptr1; 160: if ((Trfrmt == CHAR) != (aptr->atbfrmt == CHAR)) 161: /* function type does not match attrib */ 162: yyerror(RESTYPE, aptr->atbname, 0); 163: } 164: 165: /* 166: ** ATTFREE 167: ** puts a list of attrib space back on the free list 168: */ 169: attfree(aptr) 170: struct atstash *aptr; 171: { 172: register struct atstash *att; 173: 174: if ((att = aptr) == NULL) 175: return; 176: while (att->atbnext != NULL) 177: att = att->atbnext; 178: att->atbnext = Freeatt; 179: Freeatt = aptr; 180: } 181: 182: /* 183: ** ATTALLOC 184: ** returns a pointer to a atstash type structure 185: */ 186: struct atstash * 187: attalloc() 188: { 189: register struct atstash *aptr; 190: register struct rngtab *rptr; 191: register int i; 192: extern struct rngtab *rngatndx(); 193: 194: i = MAXVAR - 1; 195: while (Freeatt == NULL) 196: { 197: /* 198: ** search least recently used vbles for attrib stash space 199: ** until at least one entry is found 200: */ 201: rptr = rngatndx(i); 202: Freeatt = rptr->attlist; 203: rptr->attlist = NULL; 204: i = rptr->rposit - 1; /* try one newer than the current */ 205: } 206: aptr = Freeatt; 207: Freeatt = Freeatt->atbnext; 208: aptr->atbnext = NULL; 209: } 210: 211: /* 212: ** ATTCOUNT 213: ** returns a count fof the number of attributes already in the 214: ** attrib stash 215: */ 216: attcount(rptr) 217: struct rngtab *rptr; 218: { 219: register int cntr; 220: register struct atstash *aptr; 221: 222: cntr = 0; 223: aptr = rptr->attlist; 224: while (aptr != NULL) 225: { 226: cntr++; 227: aptr = aptr->atbnext; 228: } 229: return (cntr); 230: }