2.11BSD/ingres/source/parser/attfcn.c
# include "../ingres.h"
# include "../aux.h"
# include "../tree.h"
# include "../pipes.h"
# include "../symbol.h"
# include "parser.h"
/*
** 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
/*
** ATTLOOKUP
** routine to look up atribute 'attrib' in the att stash
** for range table entry 'rptr'. If the attrib is not
** in the stash it is entered.
*/
struct atstash *
attlookup(rptr1, attrib)
struct rngtab *rptr1;
char *attrib;
{
register struct rngtab *rptr;
register struct atstash *current, *sp;
int ik;
struct attribute tuple;
register struct attribute *ktuple;
struct attribute ktup;
struct tup_id tid;
extern struct atstash *attfind();
extern struct atstash *attadd();
rptr = rptr1;
ktuple = &ktup;
# ifdef xPTR2
tTfp(10, 1, "attlookup: att = %s and rel= %s\n", attrib, rptr->relnm);
# 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 ((sp = attfind(rptr, attrib)) != 0)
return (sp);
# ifdef xPTR2
tTfp(10, 2, "getting att info from relation\n");
# endif
/* rel name, owner, attname is unique ident */
clearkeys(&Desc);
setkey(&Desc, ktuple, rptr->relnm, ATTRELID);
setkey(&Desc, ktuple, rptr->relnowner, ATTOWNER);
setkey(&Desc, ktuple, attrib, ATTNAME);
if (!(ik=getequal(&Desc, ktuple, &tuple, &tid)))
{
/* put attrib stuff into att stash */
current = attadd(rptr, &tuple);
return (current);
}
if (ik == 1)
/* attribute not in relation */
yyerror(NOATTRIN, attrib, rptr->relnm, 0);
syserr("fatal error in getequal, ret: %d", ik);
}
/*
** ATTADD
** add an attrib to the list
*/
struct atstash *
attadd(rptr, tuple)
struct rngtab *rptr;
struct attribute *tuple;
{
register struct atstash *current;
register struct atstash *aptr;
register struct atstash *bptr;
int i;
extern struct atstash *attalloc();
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
** look in attribute stash to see if attrib info already there
** return pointer to attribute in attribute table else zero
*/
struct atstash *
attfind(rptr, attrib1)
struct rngtab *rptr;
char *attrib1;
{
register struct atstash *aptr;
register char *attrib;
attrib = attrib1;
aptr = rptr->attlist;
while (aptr != 0)
{
if (!scompare(attrib, MAXNAME, aptr->atbname, MAXNAME))
return (aptr);
aptr = aptr->atbnext;
}
return (0);
}
/*
** ATTCHECK
** checks for type conflicts in the current query domain and
** attable entry
*/
attcheck(aptr1)
struct atstash *aptr1;
{
register struct atstash *aptr;
aptr = aptr1;
if ((Trfrmt == CHAR) != (aptr->atbfrmt == CHAR))
/* function type does not match attrib */
yyerror(RESTYPE, aptr->atbname, 0);
}
/*
** ATTFREE
** puts a list of attrib space back on the free list
*/
attfree(aptr)
struct atstash *aptr;
{
register struct atstash *att;
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
*/
struct atstash *
attalloc()
{
register struct atstash *aptr;
register struct rngtab *rptr;
register int i;
extern struct rngtab *rngatndx();
i = MAXVAR - 1;
while (Freeatt == NULL)
{
/*
** search least recently used vbles for attrib stash space
** until at least one entry is found
*/
rptr = rngatndx(i);
Freeatt = rptr->attlist;
rptr->attlist = NULL;
i = rptr->rposit - 1; /* try one newer than the current */
}
aptr = Freeatt;
Freeatt = Freeatt->atbnext;
aptr->atbnext = NULL;
}
/*
** ATTCOUNT
** returns a count fof the number of attributes already in the
** attrib stash
*/
attcount(rptr)
struct rngtab *rptr;
{
register int cntr;
register struct atstash *aptr;
cntr = 0;
aptr = rptr->attlist;
while (aptr != NULL)
{
cntr++;
aptr = aptr->atbnext;
}
return (cntr);
}