Annotation of 42BSD/ingres/source/dbu/nmodify.c, revision 1.1

1.1     ! root        1: # include      <pv.h>
        !             2: # include      <ingres.h>
        !             3: # include      <aux.h>
        !             4: # include      <access.h>
        !             5: # include      <batch.h>
        !             6: # include      <lock.h>
        !             7: # include      <fileio.h>
        !             8: # include      <opsys.h>
        !             9: # include      <func.h>
        !            10: # include      <sccs.h>
        !            11: 
        !            12: SCCSID(@(#)nmodify.c   7.2     6/4/83)
        !            13: 
        !            14: extern short   tTdbu[];
        !            15: extern int     modify();
        !            16: extern         int     null_fn();
        !            17: 
        !            18: struct fn_def ModifyFn =
        !            19: {
        !            20:        "MODIFY",
        !            21:        modify,
        !            22:        null_fn,
        !            23:        null_fn,
        !            24:        NULL,
        !            25:        0,
        !            26:        tTdbu,
        !            27:        100,
        !            28:        'Z',
        !            29:        0
        !            30: };
        !            31: 
        !            32: /*
        !            33: **  MODIFY -- converts any relation to the specified
        !            34: **             storage structure
        !            35: **
        !            36: **     arguments:
        !            37: **     0 - relation name
        !            38: **     1 - storage structure ("heap", "cheap", "hash", "chash",
        !            39: **             "isam", "cisam", "btree")
        !            40: **     2 - "name" for attribute names, or "num" for numbers
        !            41: **     3 - key1
        !            42: **     4 - key2
        !            43: **         .
        !            44: **         .
        !            45: **     i - null
        !            46: **     i+1 - option name (e.g., "fillfactor")
        !            47: **     i+2 - option value
        !            48: **         .
        !            49: **         .
        !            50: **
        !            51: **     If all the options default, parameter i -> pc are omitted.
        !            52: **     If no keys are provided, parameter 2 is omitted.
        !            53: **
        !            54: **     History:
        !            55: **             12/28/78 (rse) -- added descending sort option
        !            56: **             9/12/78 -- (marc) modified to give error message
        !            57: **                     5519 when someone tries to modify a view.
        !            58: **                     For this I split the openr mode 0 into 2,
        !            59: **                     mode -1 then -2.
        !            60: **             9/25/78 -- (marc) 2 openr's replaced by one
        !            61: **                     as view error code put in openr
        !            62: **
        !            63: */
        !            64: 
        !            65: int            F_fac, Mn_pages, Mx_pages;
        !            66: 
        !            67: struct modtab
        !            68: {
        !            69:        char    *type;
        !            70:        char    newrelspec;
        !            71:        char    yeskeys;
        !            72:        char    sortit;
        !            73:        char    yes_seq;
        !            74:        int     f_fac;
        !            75:        int     mn_pages;
        !            76:        int     mx_pages;
        !            77: };
        !            78: 
        !            79: 
        !            80: struct modtab  Modtab[] =
        !            81: {
        !            82:        /* type         spec    keys    sort    seq     ffac    min     max */
        !            83: 
        !            84:        "heap",         M_HEAP, FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            85:        "cheap",        -M_HEAP,FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            86:        "hash",         M_HASH, TRUE,   TRUE,   FALSE,  50,     10,     -1,
        !            87:        "chash",        -M_HASH,TRUE,   TRUE,   FALSE,  75,     1,      -1,
        !            88:        "isam",         M_ISAM, TRUE,   TRUE,   FALSE,  80,     0,      0,
        !            89:        "cisam",        -M_ISAM,TRUE,   TRUE,   FALSE,  100,    0,      0,
        !            90:        "btree",        M_BTREE, TRUE,  TRUE,   FALSE,  66,     0,      0,
        !            91:        "heapsort",     M_HEAP, TRUE,   TRUE,   TRUE,   0,      0,      0,
        !            92:        "cheapsort",    -M_HEAP,TRUE,   TRUE,   TRUE,   0,      0,      0,
        !            93:        "truncated",    M_TRUNC,FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            94:        0
        !            95: };
        !            96: 
        !            97: struct mod_info
        !            98: {
        !            99:        char    outfile[MAXNAME + 4];   /* result file filled by ksort */
        !           100:        char    formfile[MAXNAME + 4];  /* file with descriptor for ksort */
        !           101:        char    infile[MAXNAME + 4];    /* input file for ksort (relation itself */
        !           102:        char    reltemp[MAXNAME + 4];   /* file holding new relation */
        !           103:        char    spfile[MAXNAME + 4], spflag;    /* isam spool file for overflow */
        !           104: };
        !           105: 
        !           106: struct mod_info        Mod_info;
        !           107: 
        !           108: modify(pc, pv)
        !           109: int    pc;
        !           110: PARM   *pv;
        !           111: {
        !           112:        register int            i;
        !           113:        register char           *rname;
        !           114:        register struct modtab  *mp;
        !           115:        int                     sorted;
        !           116:        DESC                    dold, dnew;
        !           117:        long                    temptid;
        !           118:        extern int              Noupdt;
        !           119: 
        !           120:        
        !           121: #      ifdef xZTR1
        !           122:        if (tTf(34, -1))
        !           123:        {
        !           124:                printf("enter modify\n");
        !           125:                prvect(pc, pv);
        !           126:        }
        !           127: #      endif
        !           128: 
        !           129:        pv[pc].pv_val.pv_str = NULL;
        !           130: 
        !           131:        /* check for nice parameters */
        !           132:        if (pc < 2)
        !           133:                syserr("MODIFY: pc %d", pc);
        !           134: 
        !           135:        /* save relation name for error messages */
        !           136:        rname = (pv++)->pv_val.pv_str;  /* *pv now pointes to storage spec */
        !           137: 
        !           138:        /* check for good relation */
        !           139:        i = openr(&dold, 0, rname);
        !           140:        if (i == AMOPNVIEW_ERR)
        !           141:                return (error(5519, rname, 0));
        !           142:        if (i > 0)
        !           143:                /* reln does not exist */
        !           144:                return (error(5500, rname, 0)); 
        !           145:        else if (i < 0)
        !           146:                syserr("MODIFY: openr (%.14s) %d", rname, i);
        !           147:        /* can only modify a relation you own and isn't a sys rel */
        !           148:        
        !           149:        if (!bequal(Usercode, dold.reldum.relowner, 2))
        !           150:        {
        !           151:                i = 5501;
        !           152:        }
        !           153:        if ((dold.reldum.relstat & S_CATALOG) && Noupdt)
        !           154:        {
        !           155:                i = 5504;
        !           156:        }
        !           157:        if (i)
        !           158:        {
        !           159:                closer(&dold);
        !           160:                return (error(i, rname, 0));
        !           161:        }
        !           162: 
        !           163:        /*
        !           164:        ** Form descriptor for new relation. Here we need to
        !           165:        ** separate the pages from the old and new relations.
        !           166:        ** Since pages are identified by the TID of the relation
        !           167:        ** relation tuple, both old and new have the same identifiers.
        !           168:        ** To avoid this problem, a special TID is hand crafted for
        !           169:        ** the new relation.
        !           170:        */
        !           171:        bmove(&dold, &dnew, sizeof dnew);
        !           172:        dnew.reltid.line_id = (char) -2;        /* choose impossible reltid */
        !           173: 
        !           174:        /* In case of an interrupt from a previous modify,
        !           175:        ** there might be pages around. Get rid of them.
        !           176:        */
        !           177:        cleanrel(&dnew);
        !           178: 
        !           179:        ingresname(dold.reldum.relid, dold.reldum.relowner, Mod_info.infile);
        !           180: 
        !           181:        /* scan for entry in relspec table */
        !           182:        for (mp = Modtab; mp->type; mp++)
        !           183:                if (sequal(mp->type, pv->pv_val.pv_str))
        !           184:                        break;
        !           185: 
        !           186:        /* if not found, error */
        !           187:        if (!mp->type)
        !           188:        {
        !           189:                closer(&dold);
        !           190:                return (error(5510, rname, pv->pv_val.pv_str, 0));      /* bad relspec */
        !           191:        }
        !           192:        dnew.reldum.relspec = mp->newrelspec;
        !           193: 
        !           194:        if (dnew.reldum.relspec == M_TRUNC)
        !           195:                dnew.reldum.relspec = M_HEAP;
        !           196: 
        !           197:        pv++;   /* now points to first parameter */
        !           198: 
        !           199:        F_fac = mp->f_fac;
        !           200:        Mn_pages = mp->mn_pages;
        !           201:        Mx_pages = mp->mx_pages;
        !           202: 
        !           203:        /* get the key domains information */
        !           204:        if (i = getkeys(&pv, rname, &dnew, mp))
        !           205:        {
        !           206:                closer(&dold);
        !           207:                return (i);     /* user error */
        !           208:        }
        !           209: 
        !           210:        /* get fillfactor and other options if any */
        !           211:        if (i = getfill(pv, rname, mp))
        !           212:        {
        !           213:                closer(&dold);
        !           214:                return (i);     /* user error */
        !           215:        }
        !           216: 
        !           217: 
        !           218:        /* lock the relation relation */
        !           219:        if (Lockrel)
        !           220:        {
        !           221:                get_p_tid(&dold, &temptid);
        !           222:                setrll(A_SLP, temptid, M_EXCL);
        !           223:        }
        !           224: 
        !           225:        /* compute new relation parameters & build descriptor */
        !           226:        make_newrel(&dnew);
        !           227: 
        !           228:        if (sorted = (mp->sortit && (dold.reldum.reltups != 0)))
        !           229:                sortrel(&dold, &dnew);
        !           230: 
        !           231:        /* physically create the new relation */
        !           232:        if (formatpg(&dnew, (dnew.reldum.relspec == M_BTREE) ? dnew.reldum.relprim + 1 : dnew.reldum.relprim) != 0)
        !           233:                syserr("modify: formatpg");
        !           234: 
        !           235:        /* clear relgiven field; if heap remove any keys */
        !           236:        clearkeys(&dnew);
        !           237:        if (abs(dnew.reldum.relspec) == M_HEAP)
        !           238:                for (i = 1; i <= dnew.reldum.relatts; i++)
        !           239:                        dnew.relxtra[i] = 0;
        !           240: 
        !           241:        if (mp->newrelspec != M_TRUNC)
        !           242:                fill_rel(&dold, &dnew, sorted);
        !           243: 
        !           244:        closer(&dold);  /* error return is impossible */
        !           245:        if (abs(dnew.reldum.relspec) == M_ISAM)
        !           246:        {
        !           247:                if (i = bldindex(&dnew))
        !           248:                        syserr("bldindex: %.14s %d", dnew.reldum.relid, i);
        !           249:                unspool(&dnew);
        !           250:        }
        !           251:        else if (dnew.reldum.relspec == M_BTREE)
        !           252:        {
        !           253:                if (i = bldbindex(&dnew))
        !           254:                        syserr("bldbindex: %.14s %d", dnew.reldum.relid, i);
        !           255:        }
        !           256: 
        !           257:        /*
        !           258:        ** New relation is now complete. The system relations need to
        !           259:        ** be updated. First destroy all buffers with pages from the
        !           260:        ** new relation.
        !           261:        */
        !           262:        if (i = cleanrel(&dnew))
        !           263:                syserr("modify:clean new %d,%.14s", i, dnew.reldum.relid);
        !           264: 
        !           265:        fill_batch(&dold, &dnew);
        !           266: 
        !           267:        /*
        !           268:        ** Close the file for the new relation. This must be
        !           269:        ** done after the fill_batch in case we are modifing
        !           270:        ** the attribute relation.
        !           271:        */
        !           272:        close(dnew.relfp);
        !           273:        dnew.relopn = 0;
        !           274:        ruboff("modify");
        !           275:        modupdate();
        !           276:        rubon();
        !           277: 
        !           278:        if (Lockrel)
        !           279:                unlrl(temptid);
        !           280: 
        !           281: #      ifdef xZTM
        !           282:        if (tTf(35, 1))
        !           283:                timtrace(16, 0);
        !           284: #      endif
        !           285:        return (0);
        !           286: }
        !           287: 
        !           288: 
        !           289: getkeys(ppv, relname, desc, mp)
        !           290: PARM           **ppv;
        !           291: char           *relname;
        !           292: DESC           *desc;
        !           293: struct modtab  *mp;
        !           294: {
        !           295:        register PARM           *pv;
        !           296:        register char           *cp;
        !           297:        register DESC           *d;
        !           298:        int                     namemode, sort_only, as_ds;
        !           299:        int                     i, keyno, keywid;
        !           300:        struct attribute        attkey, atttup;
        !           301:        TID                     tid;
        !           302:        extern DESC             Attdes;
        !           303: 
        !           304:        pv = *ppv;      /* copy list of params */
        !           305: 
        !           306:        d = desc;
        !           307: 
        !           308:        /* zero key info */
        !           309:        for (i = 0; i <= d->reldum.relatts; i++)
        !           310:                d->relxtra[i] = d->relgiven[i] = 0;
        !           311: 
        !           312:        /* determine whether there are any keys at all */
        !           313:        keyno = 0;
        !           314:        keywid = 0;
        !           315:        sort_only = FALSE;
        !           316:        cp = pv->pv_val.pv_str;
        !           317: 
        !           318:        if (cp == NULL || *cp == NULL)
        !           319:        {
        !           320:                /* no key information. default as needed */
        !           321:                if (mp->yeskeys)
        !           322:                {
        !           323:                        cp = "\1";      /* default to first key */
        !           324:                        namemode = FALSE;
        !           325:                }
        !           326:                else
        !           327:                        pv++;   /* point one to far */
        !           328:        }
        !           329:        else
        !           330:        {
        !           331:                /* check for name mode */
        !           332:                if (namemode = sequal(cp, "name"))
        !           333:                {
        !           334: 
        !           335:                        /* check attribute names, and convert them to numbers */
        !           336:                        opencatalog("attribute", 0);
        !           337:                        setkey(&Attdes, &attkey, Mod_info.infile, ATTRELID);
        !           338:                        setkey(&Attdes, &attkey, Usercode, ATTOWNER);
        !           339:                }
        !           340:                pv++;   /* inc to next key */
        !           341:                cp = (pv++)->pv_val.pv_str;
        !           342:        }
        !           343: 
        !           344: 
        !           345:        /* scan for attribute names */
        !           346:        for (; cp != NULL; cp = (pv++)->pv_val.pv_str)
        !           347:        {
        !           348:                /* check for separator between keys & options */
        !           349:                if (*cp == NULL)
        !           350:                {
        !           351:                        pv++;   /* point two past NULL */
        !           352:                        break;
        !           353:                }
        !           354: 
        !           355:                if (namemode)
        !           356:                {
        !           357:                        /* check for "sort only" attribute */
        !           358:                        if (*cp == '#')
        !           359:                        {
        !           360:                                cp++;   /* inc to start of name */
        !           361:                                sort_only = TRUE;
        !           362:                        }
        !           363: 
        !           364:                        /* check for ascending/descending modifier */
        !           365:                        if ((as_ds = modseqkey(cp, relname, mp->yes_seq)) > 0)
        !           366:                                return (as_ds); /* error */
        !           367: 
        !           368:                        setkey(&Attdes, &attkey, cp, ATTNAME);
        !           369:                        i = getequal(&Attdes, &attkey, &atttup, &tid);
        !           370:                        if (i < 0)
        !           371:                                syserr("MODIFY: geteq(att) %d", i);
        !           372:                        if (i > 0)
        !           373:                        {
        !           374:                                return (error(5511, relname, cp, 0));   /* bad att name */
        !           375:                        }
        !           376:                        i = atttup.attid;
        !           377:                }
        !           378:                else
        !           379:                {
        !           380:                        i = *cp;
        !           381:                        as_ds = 0;
        !           382:                }
        !           383: 
        !           384:                /* add new key to descriptor */
        !           385:                keyno++;
        !           386:                if (!sort_only)
        !           387:                {
        !           388:                        d->relxtra[i] = keyno;
        !           389:                        keywid += (d->relfrml[i] & I1MASK);
        !           390:                }
        !           391:                if (d->relgiven[i])
        !           392:                        return (error(5507, relname, cp, 0));   /* duplicate attribute */
        !           393:                d->relgiven[i] = as_ds == 0 ? keyno : -keyno;
        !           394:        }
        !           395:        pv--;   /* back up one to point to "-1" terminator */
        !           396: 
        !           397: 
        !           398:        if (abs(d->reldum.relspec) == M_ISAM && keywid > (MAXTUP / 2 - 4))
        !           399:        {
        !           400:                return (error(5508, relname, iocv(keywid), 0));
        !           401:        }
        !           402: 
        !           403:        /* if a heap, there can be no keys */
        !           404:        if (!mp->yeskeys && keyno != 0)
        !           405:        {
        !           406:                return (error(5502, relname, mp->type, 0));     /* no keys allowed on heap */
        !           407:        }
        !           408: 
        !           409:        /* fill out default sort on remainder of keys */
        !           410:        if (mp->yeskeys)
        !           411:                for (i = 1; i <= d->reldum.relatts; i++)
        !           412:                        if (d->relgiven[i] == 0)
        !           413:                                d->relgiven[i] = ++keyno;
        !           414:        *ppv = pv;
        !           415:        return (0);
        !           416: }
        !           417: 
        !           418: 
        !           419: modseqkey(domain, relname, seq_ok)
        !           420: char   *domain;
        !           421: char   *relname;
        !           422: int    seq_ok;
        !           423: {
        !           424:        register char   *cp, c;
        !           425:        register int    ret;
        !           426: 
        !           427:        ret = 0;
        !           428: 
        !           429:        for (cp = domain; c = *cp++; )
        !           430:                if (c == ':')
        !           431:                        break;
        !           432: 
        !           433:        if (c != '\0')
        !           434:        {
        !           435:                /* replace ":" with null */
        !           436:                *(cp - 1) = '\0';
        !           437: 
        !           438:                /* verify sequence is valid */
        !           439:                if (!seq_ok)
        !           440:                        ret = error(5520, relname, cp, domain, 0);
        !           441:                else if (sequal("descending", cp) || sequal("d", cp))
        !           442:                        ret = -1;
        !           443:                else if (!(sequal("ascending", cp) || sequal("a", cp)))
        !           444:                        ret = error(5518, relname, cp, domain, 0);
        !           445:        }
        !           446: 
        !           447:        return (ret);
        !           448: }
        !           449: /*
        !           450: **     GETFILL -- Get fill factor and minimum pages parameters
        !           451: **             from argument list, convert them from ascii to integer
        !           452: **             and store them in global variables.  If the global
        !           453: **             variable for the corresponding parameter is zero,
        !           454: **             it means that that parameter is not allowed and an
        !           455: **             error is generated.
        !           456: */
        !           457: 
        !           458: getfill(pvx, rel, mp)
        !           459: PARM           *pvx;
        !           460: char           *rel;
        !           461: struct modinfo *mp;
        !           462: {
        !           463:        register PARM   *pv;
        !           464:        register char   *p1;
        !           465:        register int    err;
        !           466:        char            *p2;
        !           467:        int             fill_flag, min_flag, max_flag;
        !           468: 
        !           469:        pv = pvx;
        !           470:        err = 0;
        !           471:        fill_flag = min_flag = max_flag = FALSE;
        !           472: 
        !           473:        while ((p1 = (pv++)->pv_val.pv_str) != NULL)
        !           474:        {
        !           475:                p2 = (pv++)->pv_val.pv_str;
        !           476:                if (sequal(p1, "fillfactor"))
        !           477:                {
        !           478:                        if (F_fac == 0 || fill_flag)
        !           479:                        {
        !           480:                                err = 5512;
        !           481:                                break;
        !           482:                        }
        !           483:                        p1 = p2;
        !           484:                        F_fac = atoi(p1);
        !           485:                        if (F_fac > 100 || F_fac < 1)
        !           486:                        {
        !           487:                                err = 5513;
        !           488:                                break;
        !           489:                        }
        !           490:                        fill_flag = TRUE;
        !           491:                        continue;
        !           492:                }
        !           493:                if (sequal(p1, "minpages"))
        !           494:                {
        !           495:                        if (Mn_pages == 0 || min_flag)
        !           496:                        {
        !           497:                                err = 5512;
        !           498:                                break;
        !           499:                        }
        !           500:                        p1 = p2;
        !           501:                        Mn_pages = atoi(p1);
        !           502:                        if (Mn_pages < 1)
        !           503:                        {
        !           504:                                err = 5514;
        !           505:                                break;
        !           506:                        }
        !           507:                        if (max_flag && (Mn_pages > Mx_pages))
        !           508:                        {
        !           509:                                err = 5517;
        !           510:                                break;
        !           511:                        }
        !           512:                        min_flag = TRUE;
        !           513:                        continue;
        !           514:                }
        !           515:                if (sequal(p1, "maxpages"))
        !           516:                {
        !           517:                        if (Mx_pages == 0 || max_flag)
        !           518:                        {
        !           519:                                err = 5512;
        !           520:                                break;
        !           521:                        }
        !           522:                        p1 = p2;
        !           523:                        Mx_pages = atoi(p1);
        !           524:                        if (Mx_pages < 1)
        !           525:                        {
        !           526:                                err = 5516;
        !           527:                                break;
        !           528:                        }
        !           529:                        if (min_flag && (Mn_pages > Mx_pages))
        !           530:                        {
        !           531:                                err = 5517;
        !           532:                                break;
        !           533:                        }
        !           534:                        max_flag = TRUE;
        !           535:                        continue;
        !           536:                }
        !           537:                err = 5515;
        !           538:                break;
        !           539:        }
        !           540:        if (err)
        !           541:                return (error(err, rel, p1, 0));
        !           542:        return (0);
        !           543: }
        !           544: /*
        !           545: **     MAKE_NEWREL -- Create a file for the modified relation
        !           546: **             and build one or more primary pages for the
        !           547: **             relation based on its storage structure and the
        !           548: **             number of tuples it must hold.
        !           549: */
        !           550: 
        !           551: make_newrel(descx)
        !           552: DESC   *descx;
        !           553: {
        !           554:        register DESC   *desc;
        !           555:        register int    i, tups_p_page;
        !           556: 
        !           557:        desc = descx;
        !           558:        concat(MODTEMP, Fileset, Mod_info.reltemp);
        !           559:        close(creat(Mod_info.reltemp, FILEMODE));
        !           560:        if ((desc->relfp = open(Mod_info.reltemp, 2)) < 0)
        !           561:                syserr("MAKE_NEWREL: open %.14s %d", Mod_info.reltemp, desc->relfp);
        !           562:        desc->relopn = (desc->relfp + 1) * -5;
        !           563:        desc->reldum.relprim = 1;
        !           564:        if (abs(desc->reldum.relspec) == M_HASH && F_fac > 0 && Mn_pages > 0)
        !           565:        {
        !           566:                /*
        !           567:                ** Determine the number of primary pages. The following
        !           568:                ** first determines the number of tuples/page which the
        !           569:                ** relation should have in order to get the requested
        !           570:                ** fillfactor. Then that number is divided into the
        !           571:                ** number of tuples to get the number of primary pages.
        !           572:                ** To avoid round off, it must guaranteed that the
        !           573:                ** number of tuples per page must be at least 1.
        !           574:                **
        !           575:                ** primary_pages = #tuples / (#tuples/page * fillfactor)
        !           576:                */
        !           577:                tups_p_page = (((MAXTUP+2) / (desc->reldum.relwid+2)) * F_fac) / 100;
        !           578:                if (tups_p_page == 0)
        !           579:                        tups_p_page = 1;
        !           580:                 /* we add one to simulate a ceiling function */
        !           581:                desc->reldum.relprim = desc->reldum.reltups / tups_p_page + 1;
        !           582:                if (desc->reldum.relprim < Mn_pages)
        !           583:                        desc->reldum.relprim = Mn_pages;
        !           584:                if (Mx_pages > 0 && desc->reldum.relprim > Mx_pages)
        !           585:                        desc->reldum.relprim = Mx_pages;
        !           586: #              ifdef xZTR1
        !           587:                if (tTf(36, 0))
        !           588:                        printf("using %ld prim pages\n", desc->reldum.relprim);
        !           589: #              endif
        !           590:        }
        !           591:        desc->reldum.reltups = 0;
        !           592:        return (0);
        !           593: }
        !           594: /*
        !           595: **     SORTREL - Call KSORT to sort the given relation.  SORTREL
        !           596: **             sets up the descriptor struct specifying the sort
        !           597: **             keys and tells KSORT whether or not the hash key should
        !           598: **             be included as a sort key.
        !           599: */
        !           600: 
        !           601: sortrel(odesc, descx)
        !           602: DESC   *odesc, *descx;
        !           603: {
        !           604:        extern char     *Pathname;
        !           605:        register DESC   *desc;
        !           606:        register int    fp, i;
        !           607:        char            savespec;
        !           608:        char            buf[50];
        !           609: 
        !           610:        desc = descx;
        !           611:        concat(ISAM_SORTED, Fileset, Mod_info.outfile);
        !           612:        if (close(creat(Mod_info.outfile, FILEMODE)))
        !           613:                syserr("SORTREL: creat %.14s", Mod_info.outfile);
        !           614:        concat(ISAM_DESC, Fileset, Mod_info.formfile);
        !           615:        if ((fp = creat(Mod_info.formfile, FILEMODE)) < 0)
        !           616:                syserr("SORTREL: creat %.14s %d", Mod_info.formfile, fp);
        !           617:        if (abs(desc->reldum.relspec) == M_HASH)
        !           618:        {
        !           619:                /* sort on hash bucket first */
        !           620:                desc->relgiven[0] = 1;
        !           621:                for (i = 1; i <= desc->reldum.relatts; i++)
        !           622:                        desc->relgiven[i]++;
        !           623:        }
        !           624:        savespec = desc->reldum.relspec;
        !           625:        desc->reldum.relspec = odesc->reldum.relspec;
        !           626: 
        !           627:        if (write(fp, desc, sizeof *desc) != sizeof *desc)
        !           628:                syserr("SORTREL: desc write err");
        !           629:        close(fp);
        !           630:        desc->reldum.relspec = savespec;
        !           631: 
        !           632:        i = fork();
        !           633:        if (i == -1)
        !           634:                syserr("SORTREL: fork");
        !           635:        if (i == 0)
        !           636:        {
        !           637:                for (i = 3; i < NOFILE; i++)
        !           638:                        close(i);
        !           639:                concat(Pathname, "/bin/ksort", buf);
        !           640:                execl(buf, buf, Fileset, iocv(tTf(37, -1)),
        !           641:                        Mod_info.formfile, Mod_info.infile,
        !           642:                        Mod_info.outfile, 0);
        !           643:                syserr("SORTREL: exec %s", buf);
        !           644:        }
        !           645: 
        !           646: # ifdef        xZTR1
        !           647:        tTfp(37, 1, "SORTREL: after execl; pid = %d\n", i);
        !           648: # endif
        !           649: 
        !           650:        if (fp = fullwait(i, "modify")) /* wait for ksort to complete */
        !           651:                syserr("modify:ksort failed %d", fp);
        !           652: 
        !           653: # ifdef        xZTR1
        !           654:        tTfp(37, 2, "SORTREL: after fullwait\n");
        !           655: # endif
        !           656: 
        !           657:        unlink(Mod_info.formfile);
        !           658:        return (0);
        !           659: }
        !           660: /*
        !           661: **     FILL_REL -- Fill the new relation with tuples from either
        !           662: **             the old relation or the output file of KSORT.
        !           663: */
        !           664: 
        !           665: fill_rel(sdescx, descx, sortit)
        !           666: DESC   *sdescx, *descx;
        !           667: char   sortit;
        !           668: {
        !           669:        register DESC   *sdesc, *desc;
        !           670:        register int    i;
        !           671:        char            tup_buf[MAXTUP], last_tup[MAXTUP];
        !           672:        char            junk[4], newreltype, anytups, chkdups;
        !           673:        char            sortbuf[IOBUFSIZ], spoolbuf[IOBUFSIZ];
        !           674:        int             need, j;
        !           675:        long            lnum;
        !           676:        TID             tid, stid, stidlim;
        !           677:        FILE            *fp, *spfp;
        !           678: 
        !           679:        sdesc = sdescx;
        !           680:        desc = descx;
        !           681:        newreltype = abs(desc->reldum.relspec);
        !           682:        if (sortit)
        !           683:        {
        !           684:                if ((fp = fopen(Mod_info.outfile, "read", sortbuf)) == NULL)
        !           685:                        syserr("FILL_REL: fopen %.14s", Mod_info.outfile);
        !           686:        }
        !           687:        else
        !           688:        {
        !           689:                cleanrel(sdesc);        /* make sure each page is read fresh */
        !           690:                find(sdesc, NOKEY, &stid, &stidlim);
        !           691:        }
        !           692:        if (newreltype == M_ISAM)
        !           693:        {
        !           694:                lnum = 0;
        !           695:                stuff_page(&tid, &lnum);
        !           696:                tid.line_id = 0;
        !           697:                get_page(desc, &tid);
        !           698:                concat(ISAM_SPOOL, Fileset, Mod_info.spfile);
        !           699:                /* assume that spool file is not needed */
        !           700:                spfp = NULL;
        !           701:                Mod_info.spflag = FALSE;
        !           702:                if (F_fac == 0)
        !           703:                        F_fac = 100;
        !           704:                /* setup relgiven field for kcompare later on */
        !           705:                for (i = 1; i <= desc->reldum.relatts; i++)
        !           706:                        desc->relgiven[i] = desc->relxtra[i];
        !           707:        }
        !           708:        else if (newreltype == M_BTREE)
        !           709:        {
        !           710:                lnum = 1;
        !           711:                stuff_page(&tid, &lnum);
        !           712:                tid.line_id = 0;
        !           713:                get_page(desc, &tid);
        !           714:                concat(ISAM_SPOOL, Fileset, Mod_info.spfile);
        !           715:                /* assume that spool file is not needed */
        !           716:                spfp = NULL;
        !           717:                Mod_info.spflag = FALSE;
        !           718:                if (F_fac == 0)
        !           719:                        F_fac = 100;
        !           720:                /* setup relgiven field for kcompare later on */
        !           721:                for (i = 1; i <= desc->reldum.relatts; i++)
        !           722:                        desc->relgiven[i] = desc->relxtra[i];
        !           723:        }
        !           724:        desc->reladds = 0;
        !           725:        anytups = FALSE;
        !           726:        chkdups = !sortit;
        !           727:        for (;;)
        !           728:        {
        !           729:                if (sortit)
        !           730:                {
        !           731:                        i = fread(fp, tup_buf, desc->reldum.relwid);
        !           732:                        if (i == 0)
        !           733:                                break;
        !           734:                        if (i != desc->reldum.relwid)
        !           735:                                syserr("FILL_REL: fread A %d", i);
        !           736:                        if (newreltype == M_HASH)
        !           737:                                if (fread(fp, junk, 4) != 4)
        !           738:                                        syserr("FILL_REL: fread B");
        !           739:                }
        !           740:                else
        !           741:                {
        !           742: #                      ifdef xZTR2
        !           743:                        if (tTf(36, 1))
        !           744:                        {
        !           745:                                printf("FILL_REL: stid ");
        !           746:                                dumptid(&stid);
        !           747:                                printf("FILL_REL: stidlim ");
        !           748:                                dumptid(&stidlim);
        !           749:                        }
        !           750: #                      endif
        !           751:                        i = get(sdesc, &stid, &stidlim, tup_buf, TRUE);
        !           752: #                      ifdef xZTR2
        !           753:                        if (tTf(36, 1))
        !           754:                        {
        !           755:                                printf("FILLREL: get %d ", i);
        !           756:                                printup(sdesc, tup_buf);
        !           757:                        }
        !           758: #                      endif
        !           759:                        if (i < 0)
        !           760:                                syserr("FILL_REL: get %d", i);
        !           761:                        if (i == 1)
        !           762:                                break;
        !           763:                }
        !           764:                if (newreltype != M_ISAM && newreltype != M_BTREE)
        !           765:                {
        !           766:                        if ((i = insert(desc, &tid, tup_buf, chkdups)) < 0)
        !           767:                                syserr("FILL_REL: insert %d", i);
        !           768: #                      ifdef xZTR2
        !           769:                        if (tTf(36, 2))
        !           770:                        {
        !           771:                                printf("FILL_REL: insert ");
        !           772:                                printup(desc, tup_buf);
        !           773:                                printf("FILL_REL: insert ret %d at", i);
        !           774:                                dumptid(&tid);
        !           775:                        }
        !           776: #                      endif
        !           777:                        continue;
        !           778:                }
        !           779:                if (anytups)
        !           780:                        i = kcompare(desc, tup_buf, last_tup);
        !           781:                else
        !           782:                {
        !           783:                        anytups = TRUE;
        !           784:                        i = 1;
        !           785:                }
        !           786:                bmove(tup_buf, last_tup, desc->reldum.relwid);
        !           787:                need = canonical(desc, tup_buf);
        !           788:                if (i == 0 && need > space_left(Acc_head))
        !           789:                {
        !           790:                        /* spool out this tuple. will go on overflow page later */
        !           791:                        if (spfp == NULL)
        !           792:                        {
        !           793:                                if ((spfp = fopen(Mod_info.spfile, "write", spoolbuf)) == NULL)
        !           794:                                        syserr("FILL_REL: fopen %.14s", Mod_info.spfile);
        !           795:                                Mod_info.spflag = TRUE;
        !           796:                        }
        !           797:                        if (fwrite(spfp, tup_buf, desc->reldum.relwid) != desc->reldum.relwid)
        !           798:                                syserr("FILL_REL: putb spool");
        !           799:                        continue;
        !           800:                }
        !           801:                j = (100 - F_fac) * MAXTUP / 100;
        !           802:                if (j < need)
        !           803:                        j = need;
        !           804:                if (i != 0 && j > space_left(Acc_head))
        !           805:                {
        !           806:                        if (i = add_prim(desc, &tid))
        !           807:                                syserr("FILL_REL: force ovflo %d", i);
        !           808:                }
        !           809:                tid.line_id = newlino(need);
        !           810:                put_tuple(&tid, Acctuple, need);
        !           811:                desc->reladds++;
        !           812:        }
        !           813:        if (sortit)
        !           814:        {
        !           815:                fclose(fp);
        !           816:                unlink(Mod_info.outfile);
        !           817:        }
        !           818:        if (newreltype == M_ISAM || newreltype == M_BTREE)
        !           819:        {
        !           820:                if (i = pageflush(Acc_head))
        !           821:                        syserr("fill_rel:pg clean %d", i);
        !           822:                if (spfp != NULL)
        !           823:                        fclose(spfp);
        !           824:        }
        !           825:        desc->reldum.reltups = desc->reladds;
        !           826:        desc->reladds = 0;
        !           827:        return (0);
        !           828: }
        !           829: 
        !           830: 
        !           831: bldindex(dx)
        !           832: DESC   *dx;
        !           833: {
        !           834:        register DESC   *d;
        !           835:        register TID    *tid;
        !           836:        register int    tmp;
        !           837:        TID             tidx;
        !           838:        struct accbuf   dirbuf;
        !           839:        int             keywid, level, savespec, keyx[MAXDOM];
        !           840:        int             offset, len;
        !           841:        char            tuple[MAXTUP], temptup[MAXTUP], *key;
        !           842:        long            pageid, start, stop, newstart, newstop;
        !           843: 
        !           844:        d = dx;
        !           845:        tid = &tidx;
        !           846:        for (tmp = 0; tmp < MAXDOM; tmp++)
        !           847:                keyx[tmp] = 0;
        !           848:        for (tmp = 1; tmp <= d->reldum.relatts; tmp++)
        !           849:                if (d->relxtra[tmp] > 0)
        !           850:                {
        !           851:                        keyx[d->relxtra[tmp] - 1] = tmp;
        !           852:                        keywid += d->relfrml[tmp] & I1MASK;
        !           853:                }
        !           854: 
        !           855:        /* Determine the last page of the relation. This will
        !           856:        ** only work if all pages have been written out. Fill_rel
        !           857:        ** must guarantee that all pages have been written
        !           858:        */
        !           859:        level = 0;
        !           860:        last_page(d, tid, 0);
        !           861:        pluck_page(tid, &stop);
        !           862:        start = 0;
        !           863:        dirbuf.filedesc = d->relfp;
        !           864:        dirbuf.rel_tupid = d->reltid.ltid;
        !           865:        savespec = d->reldum.relspec;
        !           866:        for (;;)
        !           867:        {
        !           868: #              ifdef xZTR2
        !           869:                if (tTf(38, 7))
        !           870:                        printf("isam: level %d\n", level);
        !           871: #              endif
        !           872:                dirbuf.ovflopg = start;
        !           873:                dirbuf.mainpg = level;
        !           874:                dirbuf.thispage = stop + 1;
        !           875:                dirbuf.linetab[0] = (short) (dirbuf.firstup - (char *) &dirbuf);
        !           876:                offset = dirbuf.linetab[0];
        !           877:                dirbuf.bufstatus = BUF_DIRTY | BUF_DIRECT;
        !           878: 
        !           879:                dirbuf.nxtlino = 0;
        !           880:                newstart = stop + 1;
        !           881:                newstop = newstart;
        !           882:                for (pageid = start; pageid <= stop; pageid++)
        !           883:                {
        !           884: #                      ifdef xZTR2
        !           885:                        if (tTf(38, 8))
        !           886:                                printf("isam:get key from %ld\n", pageid);
        !           887: #                      endif
        !           888:                        stuff_page(tid, &pageid);
        !           889:                        tid->line_id = 0;
        !           890:                        if (tmp = get(d, tid, tid, tuple, FALSE))
        !           891:                        {
        !           892:                                /*
        !           893:                                ** If the relation is empty, then page 0 will
        !           894:                                ** return AMINVL_ERR on a get(). Form a blank tuple
        !           895:                                ** and use it to create a one tuple directory
        !           896:                                */
        !           897:                                if (pageid == 0 && tmp == AMINVL_ERR)
        !           898:                                {
        !           899:                                        clr_tuple(d, tuple);
        !           900:                                }
        !           901:                                else
        !           902:                                {
        !           903:                                        return (-2);
        !           904:                                }
        !           905:                        }
        !           906: 
        !           907:                        /*
        !           908:                        ** If this is the first level then form the tuple
        !           909:                        ** from the mainpage of the relation. Otherwise
        !           910:                        ** the tuple is the first tuple of a directory page
        !           911:                        ** and it is already correctly formed.
        !           912:                        */
        !           913:                        if (level == 0)
        !           914:                        {
        !           915:                                key = temptup;
        !           916:                                for (tmp = 0; keyx[tmp] != 0; tmp++)
        !           917:                                {
        !           918:                                        len = d->relfrml[keyx[tmp]] & I1MASK;
        !           919:                                        bmove(&tuple[d->reloff[keyx[tmp]]], key, len);
        !           920:                                        key += len;
        !           921:                                }
        !           922:                                key = temptup;
        !           923:                        }
        !           924:                        else
        !           925:                                key = tuple;
        !           926: 
        !           927:                        if (keywid > space_left(&dirbuf))
        !           928:                        {
        !           929:                                if (pageflush(&dirbuf))
        !           930:                                        return (-3);
        !           931:                                dirbuf.thispage++;
        !           932:                                newstop = dirbuf.thispage;
        !           933:                                dirbuf.ovflopg = pageid;
        !           934:                                dirbuf.linetab[0] = (short) (dirbuf.firstup - (char *) &dirbuf);
        !           935:                                offset = dirbuf.linetab[0];
        !           936:                                dirbuf.bufstatus = BUF_DIRTY;
        !           937:                                dirbuf.nxtlino = 0;
        !           938:                        }
        !           939:                        /* copy key to directory page */
        !           940:                        bmove(key, (char *) &dirbuf + offset, keywid);
        !           941: 
        !           942:                        /* update next line number */
        !           943:                        offset += keywid;
        !           944:                        dirbuf.nxtlino++;
        !           945:                        dirbuf.linetab[-dirbuf.nxtlino] = offset;
        !           946:                }
        !           947:                if (pageflush(&dirbuf))
        !           948:                        return (-4);
        !           949:                if (newstart == newstop)
        !           950:                        break;
        !           951:                d->reldum.relspec = abs(d->reldum.relspec);
        !           952:                level++;
        !           953:                start = newstart;
        !           954:                stop = newstop;
        !           955:        }
        !           956:        d->reldum.relspec = savespec;
        !           957:        d->reldum.relprim = newstart;
        !           958:        return (0);
        !           959: }
        !           960: 
        !           961: bldbindex(dx)
        !           962: register DESC  *dx;
        !           963: {
        !           964:        register TID    *tid;
        !           965:        register int    tmp;
        !           966:        TID             tidx;
        !           967:        struct accbuf   dirbuf;
        !           968:        int             keywid, level, savespec, keyx[MAXDOM];
        !           969:        int             offset, len;
        !           970:        struct pgtuple  tuple, temptup;
        !           971:        char            *key;
        !           972:        long            pageid, start, stop, newstart, newstop;
        !           973:        int             fill_leave;
        !           974: 
        !           975:        tid = &tidx;
        !           976:        keywid = 0;
        !           977:        for (tmp = 0; tmp < MAXDOM; tmp++)
        !           978:                keyx[tmp] = 0;
        !           979:        for (tmp = 1; tmp <= d->reldum.relatts; tmp++)
        !           980:                if (d->relxtra[tmp] > 0)
        !           981:                {
        !           982:                        keyx[d->relxtra[tmp - 1]] = tmp;
        !           983:                        keywid += d->relfrml[tmp] & I1MASK;
        !           984:                }
        !           985: 
        !           986:        keywid += PGPTRSIZ;
        !           987: 
        !           988:        /* determine fill factor for directory pages */
        !           989: 
        !           990:        fill_leave = (100 - F_fac) * MAXTUP / 100;
        !           991:        if (keywid > fill_leave)
        !           992:                fill_leave = keywid;
        !           993: 
        !           994:        /* Determine the last page of the relation. This will
        !           995:        ** only work if all pages have been written out. Fill_rel
        !           996:        ** must guarantee that all pages have been written
        !           997:        */
        !           998: 
        !           999:        level = 0;
        !          1000:        last_page(d, tid, 0);
        !          1001:        pluck_page(tid, &stop);
        !          1002:        start = 1;                      /* page 0 is the root */
        !          1003:        dirbuf.filedesc = d->relfp;
        !          1004:        dirbuf.rel_tupid = d->reltid.ltid;
        !          1005:        savespec = d->reldum.relspec;
        !          1006:        for (;;)
        !          1007:        {
        !          1008: #              ifdef xZTR2
        !          1009:                if (tTf(38, 7))
        !          1010:                        printf("btree: level %d\n", level);
        !          1011: #              endif
        !          1012:                dirbuf.mainpg = level;
        !          1013:                dirbuf.thispage = stop + 1;
        !          1014:                dirbuf.ovflopg = dirbuf.thispage + 1;
        !          1015:                dirbuf.linetab[0] = (short) (&dirbuf.firstup[PGPTRSIZ] - (char *) &dirbuf);
        !          1016: 
        !          1017:                stuff_page(dirbuf.firstup, &start);     /* put first pgnum in */
        !          1018:                start++;
        !          1019: 
        !          1020:                offset = dirbuf.linetab[0];
        !          1021:                dirbuf.bufstatus = BUF_DIRTY | BUF_DIRECT;
        !          1022: 
        !          1023:                dirbuf.nxtlino = 0;
        !          1024:                newstart = stop + 1;
        !          1025:                newstop = newstart;
        !          1026:                for (pageid = start; pageid <= stop; pageid++)
        !          1027:                {
        !          1028: #                      ifdef xZTR2
        !          1029:                        if (tTf(38, 8))
        !          1030:                                printf("btree:get key from %ld\n", pageid);
        !          1031: #                      endif
        !          1032:                        stuff_page(tid, &pageid);
        !          1033:                        tid->line_id = 0;
        !          1034:                        if (tmp = get(d, tid, tid, &tuple, FALSE))
        !          1035:                        {
        !          1036:                                syserr("modify: bldbindex: get %d\n", tmp);
        !          1037:                        }
        !          1038: 
        !          1039:                        /*
        !          1040:                        ** If this is the first level then form the tuple
        !          1041:                        ** from the mainpage of the relation. Otherwise
        !          1042:                        ** the tuple is the first tuple of a directory page
        !          1043:                        ** and it is already correctly formed.
        !          1044:                        */
        !          1045:                        if (level == 0)
        !          1046:                        {
        !          1047:                                bndxkey(d, tuple.childtup, &temptup, &pageid, keyx);
        !          1048:                                /*
        !          1049:                                stuff_page(&temptup.childtid, &pageid);
        !          1050:                                key = temptup.childtup;
        !          1051:                                for (tmp = 0; keyx[tmp] != 0; tmp++)
        !          1052:                                {
        !          1053:                                        len = d->relfrml[keyx[tmp]] & I1MASK;
        !          1054:                                        bmove(&((char *) &tuple)[d->reloff[keyx[tmp]]], key, len);
        !          1055:                                        key += len;
        !          1056:                                }
        !          1057:                                */
        !          1058: 
        !          1059:                                
        !          1060:                                printf("primary ");
        !          1061:                                key = &temptup;
        !          1062:                        }
        !          1063:                        else
        !          1064:                        {
        !          1065:                                stuff_page(&tuple.childtid, &pageid);
        !          1066:                                key = &tuple;
        !          1067:                                printf("secondary %d: ", level);
        !          1068:                        }
        !          1069: 
        !          1070:                        printf("adding: ");
        !          1071:                        prbndxkey(d, key, keyx);
        !          1072:                        printf("\n");
        !          1073: 
        !          1074:                        if (fill_leave > space_left(&dirbuf))
        !          1075:                        {
        !          1076:                                if (pageflush(&dirbuf))
        !          1077:                                        return (-3);
        !          1078:                                dirbuf.thispage++;
        !          1079:                                newstop = dirbuf.thispage;
        !          1080:                                dirbuf.ovflopg = dirbuf.thispage + 1;
        !          1081:                                dirbuf.linetab[0] = (short) (&dirbuf.firstup[PGPTRSIZ] - (char *) &dirbuf);
        !          1082: 
        !          1083:                                stuff_page(dirbuf.firstup, &pageid);
        !          1084: 
        !          1085:                                offset = dirbuf.linetab[0];
        !          1086:                                dirbuf.bufstatus = BUF_DIRTY;
        !          1087:                                dirbuf.nxtlino = 0;
        !          1088:                                continue;
        !          1089:                        }
        !          1090:                        /* copy key to directory page */
        !          1091:                        bmove(key, (char *) &dirbuf + offset, keywid);
        !          1092: 
        !          1093:                        /* update next line number */
        !          1094:                        offset += keywid;
        !          1095:                        dirbuf.nxtlino++;
        !          1096:                        dirbuf.linetab[-dirbuf.nxtlino] = offset;
        !          1097:                }
        !          1098:                if (newstart == newstop)                /* must be root */
        !          1099:                        dirbuf.thispage = 0;            /* root is page 0 */
        !          1100: 
        !          1101:                dirbuf.ovflopg = 0;                     /* no more pages */
        !          1102: 
        !          1103:                if (pageflush(&dirbuf))
        !          1104:                        return (-4);
        !          1105: 
        !          1106:                if (newstart == newstop)
        !          1107:                        break;
        !          1108:                d->reldum.relspec = abs(d->reldum.relspec);
        !          1109:                level++;
        !          1110:                start = newstart;
        !          1111:                stop = newstop;
        !          1112:        }
        !          1113:        d->reldum.relspec = savespec;
        !          1114:        d->reldum.relprim = newstart;
        !          1115:        return (0);
        !          1116: }
        !          1117: /*
        !          1118: **     UNSPOOL -- Take tuples saved in spool file and insert them
        !          1119: **             in new relation.  This is only for ISAM relations.
        !          1120: */
        !          1121: 
        !          1122: unspool(descx)
        !          1123: DESC   *descx;
        !          1124: {
        !          1125:        register DESC   *desc;
        !          1126:        register int    i;
        !          1127:        TID             tid;
        !          1128:        char            tup_buf[MAXTUP], spoolbuf[IOBUFSIZ];
        !          1129:        FILE            *spfp;
        !          1130: 
        !          1131:        desc = descx;
        !          1132:        if (Mod_info.spflag)
        !          1133:        {
        !          1134:                if ((spfp = fopen(Mod_info.spfile, "read", spoolbuf)) == NULL)
        !          1135:                        syserr("UNSPOOL: fopen spool");
        !          1136:                while ((i = fread(spfp, tup_buf, desc->reldum.relwid)) == desc->reldum.relwid)
        !          1137:                        if ((i = insert(desc, &tid, tup_buf, FALSE)) < 0)
        !          1138:                                syserr("UNSPOOL: insert %.14s %d", desc->reldum.relid, i);
        !          1139:                if (i != 0)
        !          1140:                        syserr("UNSPOOL: read %d", i);
        !          1141:                fclose(spfp);
        !          1142:                unlink(Mod_info.spfile);
        !          1143:        }
        !          1144:        desc->reldum.reltups += desc->reladds;
        !          1145:        desc->reladds = 0;
        !          1146:        return (0);
        !          1147: }
        !          1148: /*
        !          1149: **     FILL_BATCH -- Create and fill a batch file containing the
        !          1150: **             updates for the system catalog so that MODIFY will
        !          1151: **             be recoverable if the system crashes.
        !          1152: */
        !          1153: 
        !          1154: fill_batch(odesc, descx)
        !          1155: DESC   *odesc, *descx;
        !          1156: {
        !          1157:        register DESC           *desc, *dessys;
        !          1158:        register int            i;
        !          1159:        struct relation         reltup, rkey;
        !          1160:        TID                     tid, lotid, hitid;
        !          1161:        struct attribute        atttup, akey;
        !          1162:        int                     j;
        !          1163:        char                    prebatch[MAXNAME + 4], modbatch[MAXNAME + 4];
        !          1164: 
        !          1165:        desc = descx;
        !          1166:        if (bequal(desc->reldum.relid, "relation    ", 12))
        !          1167:        {
        !          1168:                clearkeys(desc);
        !          1169:                setkey(desc, &rkey, desc->reldum.relid, RELID);
        !          1170:                setkey(desc, &rkey, desc->reldum.relowner, RELOWNER);
        !          1171:                if (i = getequal(desc, &rkey, &reltup, &tid))
        !          1172:                        syserr("FILL_BATCH: geteq rel rel %d", i);
        !          1173:                bmove(&tid, &desc->reltid, sizeof desc->reltid);
        !          1174:        }
        !          1175:        else
        !          1176:                bmove(&odesc->reltid, &desc->reltid, sizeof desc->reltid);
        !          1177:        resetacc(Acc_head);
        !          1178:        concat(MOD_PREBATCH, Fileset, prebatch);
        !          1179:        close(creat(prebatch, FILEMODE));
        !          1180:        if ((Batch_fp = open(prebatch, 2)) < 0)
        !          1181:                syserr("FILL_BATCH: open %.14s %d", prebatch, Batch_fp);
        !          1182:        smove(Fileset, Batchbuf.file_id);
        !          1183:        Batch_cnt = 0;
        !          1184:        wrbatch(desc, sizeof *desc);
        !          1185:        if (bequal(desc->reldum.relid, "attribute   ", 12))
        !          1186:                dessys = desc;
        !          1187:        else
        !          1188:                dessys = &Admin.adattd;
        !          1189:        clearkeys(dessys);
        !          1190:        setkey(dessys, &akey, desc->reldum.relid, ATTRELID);
        !          1191:        setkey(dessys, &akey, desc->reldum.relowner, ATTOWNER);
        !          1192:        if (i = find(dessys, EXACTKEY, &lotid, &hitid, &akey))
        !          1193:                syserr("FILL_BATCH: find %d", i);
        !          1194:        j = desc->reldum.relatts;
        !          1195:        while(!(i = get(dessys, &lotid, &hitid, &atttup, TRUE)) && j > 0)
        !          1196:                if (!kcompare(dessys, &akey, &atttup))
        !          1197:                {
        !          1198:                        j--;
        !          1199:                        atttup.attxtra = desc->relxtra[atttup.attid];
        !          1200:                        wrbatch(&lotid, sizeof lotid);
        !          1201:                        wrbatch(&atttup, sizeof atttup);
        !          1202:                }
        !          1203:        if (i < 0 || j > 0)
        !          1204:                syserr("FILL_BATCH: get att %d count %d", i, j);
        !          1205:        /* get rid of attribute pages */
        !          1206:        cleanrel(dessys);
        !          1207:        flushbatch();
        !          1208:        close(Batch_fp);
        !          1209:        concat(MODBATCH, Fileset, modbatch);
        !          1210:        if (link(prebatch, modbatch) == -1)
        !          1211:                syserr("FILL_BATCH: can't link %.14s %.14s",
        !          1212:                        prebatch, modbatch);
        !          1213:        unlink(prebatch);
        !          1214:        return (0);
        !          1215: 
        !          1216: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.