4.3BSD/usr/ingres/source/parser/att_fcn.c
# include <ingres.h>
# include <aux.h>
# include <tree.h>
# include <symbol.h>
# include "parser.h"
# include <sccs.h>
# include <errors.h>
SCCSID(@(#)att_fcn.c 8.2 2/8/85)
/*
** fake attribute stash entries for tid nodes (and sid in dist version)
** these are provided by the system to a program only for debugging
** the system source and do not have well defined (over time) meanings.
*/
struct atstash Faketid =
{
0, INT, 4, "tid", 0
};
#ifdef DISTRIB
struct atstash Fakesid
{
0, INT, 4, "sid", 0
};
#endif
struct atstash Attable[MAXATT];/* attrib stash space, turned into a list later */
struct atstash *Freeatt; /* free list of attrib stash */
/*
** ATT_FCN.C -- attribute list manipulation routines
**
** ATT_FCN ~~ trace flags = 40, 41
**
** Defines:
** Attable
** Freeatt
** attinit()
** attlookup()
** attadd()
** attfnd()
** attcheck()
** attfree()
** attalloc()
** attcount()
**
** History:
** modified for 6.3 (jiw)
*/
/*
** ATTINIT -- initializes attribute table
**
** Parameters:
** none
**
** Trace Flags:
** attinit ~~ 40.0
*/
attinit()
{
register struct atstash *atptr;
register int i;
# ifdef xPTR3
tTfp(40, 0, "attinit");
# endif
atptr = Attable;
for (i = 0; i < MAXATT - 1; i++)
{
atptr->atbnext = atptr + 1;
atptr++;
}
atptr->atbnext = NULL;
Freeatt = Attable; /* the first attribute in chain */
}
/*
** ATTLOOKUP -- finds attribute entry
**
** Attlookup looks up atribute 'attrib' in the att stash
** for range table entry 'slot'. If the attrib is not
** in the stash it is entered.
**
** Parameters:
** attrib -- the name of the attribute to find
** slot -- the number of the range variable
**
** Returns:
** pointer to the attstash element
**
** Trace Flags:
** attlookup ~~ 40.4, 40.5
*/
struct atstash *
attlookup(slot, attrib)
int slot;
char *attrib;
{
register PARRNG *rptr;
register struct atstash *current;
int ik;
struct attribute tuple;
register struct attribute *ktuple;
struct attribute ktup;
TID tid;
extern struct atstash *attfind();
extern struct atstash *attadd();
extern DESC Attdes;
extern PARRNG Parrng[];
rptr = &Parrng[slot];
ktuple = &ktup;
# ifdef xPTR2
tTfp(40, 4, "attlookup: att = %s and rel= %s\n", attrib, trim_relname(rptr->vardesc.reldum.relid));
# endif
/* attribute called "tid" is phantom attribute, use fake */
if (sequal("tid", attrib))
return (&Faketid);
# ifdef DISTRIB
if (sequal("sid", attrib))
return (&Fakesid);
# endif
/* check to see if attrib is in stash */
if ((current = attfind(slot, attrib)) != NULL)
return (current);
# ifdef xPTR2
tTfp(40, 5, "getting att info from relation\n");
# endif
/* rel name, owner, attname is unique ident */
clearkeys(&Attdes);
setkey(&Attdes, ktuple, rptr->vardesc.reldum.relid, ATTRELID);
setkey(&Attdes, ktuple, rptr->vardesc.reldum.relowner, ATTOWNER);
setkey(&Attdes, ktuple, attrib, ATTNAME);
if (!(ik = getequal(&Attdes, ktuple, &tuple, &tid)))
{
/* put attrib stuff into att stash */
current = attadd(slot, &tuple);
return (current);
}
if (ik == 1)
/* attribute not in relation */
par_error(NOATTRIN, WARN, attrib, trim_relname(rptr->vardesc.reldum.relid), 0);
else
syserr("fatal error in getequal, ret: %d", ik);
}
/*
** ATTADD -- add an attribute to the list for a particular range variable
**
** Parameters:
** slot -- the number of the range variable to use
** tuple -- the attribute tuple to add
**
** Returns:
** pointer to the attribute added
**
** Trace Flags:
** attadd ~~ 40.8
*/
struct atstash *
attadd(slot, tuple)
int slot;
struct attribute *tuple;
{
register struct atstash *current;
register struct atstash *aptr;
register struct atstash *bptr;
PARRNG *rptr;
int i;
extern struct atstash *attalloc();
extern PARRNG Parrng[];
# ifdef xPTR3
tTfp(40, 8, "attadd slot %d, %12s\n", slot, tuple->attname);
# endif
rptr = &Parrng[slot];
current = attalloc();
current->atbid = tuple->attid;
current->atbfrmt = tuple->attfrmt;
current->atbfrml = tuple->attfrml;
bmove(tuple->attname, current->atbname, MAXNAME);
for (i = 0; i < MAXNAME; i++)
if (current->atbname[i] == ' ')
current->atbname[i] = '\0';
aptr = rptr->attlist;
bptr = 0;
while (aptr != 0)
{
if (aptr->atbid > current->atbid)
break;
bptr = aptr;
aptr = aptr->atbnext;
}
if (bptr == 0)
rptr->attlist = current;
else
bptr->atbnext = current;
current->atbnext = aptr;
return (current);
}
/*
** ATTFIND -- finds attribute in stash
**
** Attfind looks in attribute stash to see if attrib info already there
** return pointer to attribute in attribute table else NULL.
**
** Parameters:
** slot -- the number of the entry in range table
** attrib -- the attribute name to find
**
** Returns:
** pointer to entry or NULL if not in stash
**
** Trace Flags:
** attfind ~~ 40.12
*/
struct atstash *
attfind(slot, attrib)
int slot;
register char *attrib;
{
register struct atstash *aptr;
extern PARRNG Parrng[];
# ifdef xPTR1
tTfp(40, 12, "attadd\n");
# endif
aptr = Parrng[slot].attlist;
while (aptr != NULL)
{
if (!scompare(attrib, MAXNAME, aptr->atbname, MAXNAME))
return (aptr);
aptr = aptr->atbnext;
}
return (NULL);
}
/*
** ATTCHECK -- checks for conflicts in attributes
**
** Attcheck checks for type conflicts in the current query domain and
** attable entry
**
** Parameters:
** aptr -- pointer to current atttibute
**
** Returns:
** nothing
**
** Requires:
** Trfrmt -- for current format
**
** Trace Flags:
** attcheck ~~ 41.0
*/
attcheck(aptr)
register struct atstash *aptr;
{
extern char Trfrmt;
# ifdef xPTR1
tTfp(41, 0, "attcheck\n");
# endif
if ((Trfrmt == CHAR) != (aptr->atbfrmt == CHAR))
/* function type does not match attrib */
par_error(RESTYPE, WARN, aptr->atbname, 0);
}
/*
** ATTFREE -- puts a list of attrib space back on the free list
**
** Parameters:
** aptr -- pointer to list of attstash entries
**
** Returns:
** nothing
**
** Requires:
** Freeatt
**
** Trace Flags:
** attfree ~~ 41.4
*/
attfree(aptr)
struct atstash *aptr;
{
register struct atstash *att;
# ifdef xPTR1
tTfp(41, 4, "attfree\n");
# endif
if ((att = aptr) == NULL)
return;
while (att->atbnext != NULL)
att = att->atbnext;
att->atbnext = Freeatt;
Freeatt = aptr;
}
/*
** ATTALLOC -- returns a pointer to a atstash type structure
**
** Attalloc checks the freelist (Freeatt) for attstash entries,
** if some is there, one is removed. If the freelist is empty,
** attstashes are removed from range table entries until an free
** element is found.
**
** Parameters:
** none
**
** Returns:
** a pointer to an atstash element
**
** Requires:
** Rngback
** Freeatt
**
** Trace Flags:
** attalloc ~~ 41.8, 41.9
*/
struct atstash *
attalloc()
{
register struct atstash *aptr;
register PARRNG *rptr;
extern PARRNG *Rngback;
# ifdef xPTR3
tTfp(41, 8, "attalloc Freeatt %d\n", Freeatt);
# endif
/* Note: the following loop doesn't happen if Freeatt != NULL */
for (rptr = Rngback; Freeatt == NULL; rptr = rptr->frontpt)
{
/*
** search least recently used vbles for attrib stash space
** until at least one entry is found
*/
# ifdef xPTR3
tTfp(41, 9, "attalloc: freeing %12s\n", rptr->vardesc.relvname);
# endif
if (rptr == NULL)
syserr("attalloc: no att space.");
Freeatt = rptr->attlist;
rptr->attlist = NULL;
}
aptr = Freeatt;
Freeatt = Freeatt->atbnext;
aptr->atbnext = NULL;
return (aptr);
}
/*
** ATTCOUNT -- counts atstash elems
**
** Attcount returns a count fof the number of attributes already in the
** attrib stash.
**
** Parameter:
** slot -- the range table entry to count
**
** Returns:
** count of the attributes
**
** Trace Flags:
** attcount ~~ 41.12
*/
int
attcount(slot)
int slot;
{
register int cntr;
register struct atstash *aptr;
extern PARRNG Parrng[];
# ifdef xPTR1
tTfp(41, 12, "attcount\n");
# endif
cntr = 0;
aptr = Parrng[slot].attlist;
while (aptr != NULL)
{
cntr++;
aptr = aptr->atbnext;
}
return (cntr);
}