|
|
BSD 4.3
# include <ingres.h>
# include <access.h>
# include <catalog.h>
# include <batch.h>
# include <btree.h>
# include <sccs.h>
SCCSID(@(#)replace.c 8.2 2/8/85)
# define SAMETUP 0
# define SAMEKEYS 1
# define DIFFTUP 2
/*
** REPLACE - replace an already existing tuple
**
** Replace will replace the tuple specified by TID
** with the new tuple. An attempt is made to not
** move the tuple if at all possible.
**
** Three separate conditions are dealt with. If the
** new tuple is the same as the old tuple, a return
** of zero occures and the page is not changed.
**
** If the keys(if any) are the same and the canonical
** tuple lengths are the same, then the new tuple will
** be placed in the same location.
**
** If the lengths or the keys are different, then the
** tuple is deleted and the new tuple inserted
**
** Checkdups specifies whether to check for duplicates.
** If the new tuple is a duplicate of one already there,
** then the tuple at TID is deleted
**
** Returns:
** <0 fatal error
** 1(DUPTUP) new tuple was duplicate of returned tid
** 2(DELTUP) tuple identified by tid has been deleted
** 3(BADLID) bad lid
**
** If replace returns 1 then tid is set to the
** duplicate tuple. This is necessary for updating
** secondary indices.
**
** Trace Flags:
** 24.4-7
*/
replace(d, tid, tuple, checkdups)
register DESC *d;
register TID *tid;
char *tuple;
int checkdups;
{
register int i;
int j;
char oldtuple[MAXTUP];
TID primtid, tidloc, tidpos;
long primpage, old_lid[MAXLID], new_lid[MAXLID], page, t;
int need, same, numatts;
int len, oldlength;
char *new, *old, *oldt;
char *getint_tuple();
char btree[MAXNAME + 4];
long oldtid;
int lidwid, compare;
struct locator temp;
# ifdef xATR1
if (tTf(24, 4))
{
printf("replace: %.14s,", d->reldum.relid);
dumptid(tid);
printf("replace: ");
printup(d, tuple);
}
# endif
/* make tuple canonical */
need = canonical(d, tuple);
/* if heap or ordered, no dup checking */
if (abs(d->reldum.relspec) == M_HEAP || d->reldum.reldim > 0)
checkdups = FALSE;
if (i = get_page(d, tid))
return (i); /* fatal error */
/* check if tid exists */
if (i = invalid(tid))
return (i); /* already deleted or invalid */
oldt = getint_tuple(d, tid, oldtuple);
/* reset page back to main relation page */
if (i = get_page(d, tid))
return(i);
oldlength = tup_len(tid);
lidwid = LIDSIZE * d->reldum.reldim;
if (d->reldum.reldim > 0)
{
/* extract lid values from tuples */
btreename(d->reldum.relid, btree);
old = oldt + d->reldum.relwid - lidwid;
bmove(old, old_lid, lidwid);
new = tuple + d->reldum.relwid - lidwid;
bmove(new, new_lid, lidwid);
compare = 0;
for (i = 0; i < d->reldum.reldim; ++i)
{
if (new_lid[i] > old_lid[i])
{
compare = 1;
break;
}
else if (new_lid[i] == old_lid[i])
compare = -1;
else
{
compare = 0;
break;
}
}
if (compare >= 0)
{
/* do insertion and deletion of new lid and old values in
** order that insures that they will be placed in the proper
** place
*/
if (compare == 1)
{
if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0)
return(BADLID);
if (fwrite(old_lid, 1, lidwid, Del_infp) != lidwid)
syserr("write error in replace");
++Del_cnt;
}
else if (compare == 0)
{
page = RT;
for (j = 0; j < d->reldum.reldim; ++j)
{
if (new_lid[j] > 0 && (t = get_tid(page, new_lid[j], &temp)) > 0)
page = t;
else if (t == -1)
{
for (i = j + 1; i < d->reldum.reldim; ++i)
{
if (new_lid[i] != 1 && new_lid[i] != 0)
return(BADLID);
}
break;
}
else if (new_lid[j] == 0)
{
for (i = j + 1; i < d->reldum.reldim; ++i)
{
if (new_lid[i] != 0)
return(BADLID);
}
break;
}
else
return(BADLID);
}
for (i = 0; i < d->reldum.reldim; ++i)
if (new_lid[i] < 0)
return(BADLID);
delete_btree(old_lid, d->reldum.reldim);
if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0)
return(BADLID);
}
}
}
/* check whether tuples are the same, different lengths, different keys */
same = DIFFTUP; /* assume diff lengths or keys */
if (oldlength == need)
{
/* same size. check for same domains */
same = SAMETUP; /* assume identical */
new = tuple;
old = oldt;
/* ignore lid field */
numatts = d->reldum.relatts - d->reldum.reldim;
for (i = 1; i <= numatts; i++)
{
len = d->relfrml[i] & I1MASK;
if (icompare(new, old, d->relfrmt[i], len))
{
if (d->relxtra[i])
{
same = DIFFTUP;
break;
}
same = SAMEKEYS;
}
old += len;
new += len;
}
}
# ifdef xATR2
if (tTf(24, 5))
printf("replace:same=%d\n", same);
# endif
switch (same)
{
case SAMETUP:
/* new tuple same as old tuple */
i = DUPTUP; /* flag as duplicate */
/* though character strings may compare equal,
** they can look different, so if they do look different
** go ahead and do the replace using put_tuple. */
if (!bequal(tuple, oldt, d->reldum.relwid - lidwid))
goto puttuple;
break;
case SAMEKEYS:
/* keys the same, lengths the same, tuples different */
if (checkdups)
{
/* This is either an ISAM or HASH file. If mainpg
** is non-zero, then the primary page=mainpg -1.
** Otherwise, "find" must be called to determine
** the primary page
*/
if (Acc_head->mainpg)
{
primpage = Acc_head->mainpg -1;
stuff_page(&primtid, &primpage);
}
else
{
if (i = find(d, FULLKEY, &primtid, &primtid, tuple))
return (i); /* fatal error */
if (i = get_page(d, tid)) /* restore page for tuple */
return (i);
}
if (i = scan_dups(d, &primtid, tuple))
{
if (i == DUPTUP)
{
del_tuple(tid, oldlength); /* tuple a duplicate */
d->reladds--;
/* copy tid of duplicate tuple */
bmove(&primtid, tid, sizeof(primtid));
}
break;
}
}
goto puttuple;
case DIFFTUP:
/* keys different or lengths different */
get_page(d, tid);
del_tuple(tid, oldlength);
bmove(tid, &oldtid, LIDSIZE);
/* find where to put tuple */
if (i = findbest(d, tid, tuple, need, checkdups))
{
d->reladds--;
break;
}
/* place new tuple in page */
puttuple:
put_tuple(tid, Acctuple, need);
i = NEWTUP;
if (same == DIFFTUP && d->reldum.reldim > 0)
{
/* main tid value has changed, update btree */
if (compare < 0)
search_btree(oldtid, &tidpos);
/* tid different, must be reflected in BTree */
replace_btree(*tid, &tidpos);
}
}
# ifdef xATR1
if (tTf(24, 6))
{
printf("replace rets %d,", i);
dumptid(tid);
}
# endif
return (i);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.