Annotation of 43BSD/ingres/source/dbu/modify.c, revision 1.1

1.1     ! root        1: # include      <stdio.h>
        !             2: # include      <ingres.h>
        !             3: # include      <pv.h>
        !             4: # include      <aux.h>
        !             5: # include      <access.h>
        !             6: # include      <batch.h>
        !             7: # include      <lock.h>
        !             8: # include      <opsys.h>
        !             9: # include      <func.h>
        !            10: # include      <version.h>
        !            11: # include      <symbol.h>
        !            12: # include      <catalog.h>
        !            13: # include      <btree.h>
        !            14: # include      <sccs.h>
        !            15: # include      <errors.h>
        !            16: 
        !            17: SCCSID(@(#)modify.c    8.8     5/7/85)
        !            18: 
        !            19: extern short   tTdbu[];
        !            20: extern int     modify();
        !            21: extern         int     null_fn();
        !            22: 
        !            23: struct fn_def ModifyFn =
        !            24: {
        !            25:        "MODIFY",
        !            26:        modify,
        !            27:        null_fn,
        !            28:        null_fn,
        !            29:        NULL,
        !            30:        0,
        !            31:        tTdbu,
        !            32:        100,
        !            33:        'Z',
        !            34:        0
        !            35: };
        !            36: 
        !            37: /*
        !            38: **  MODIFY -- converts any relation to the specified
        !            39: **             storage structure
        !            40: **
        !            41: **     arguments:
        !            42: **     0 - relation name
        !            43: **     1 - storage structure ("heap", "cheap", "hash", "chash",
        !            44: **             "isam", "cisam")
        !            45: **     2 - "name" for attribute names, or "num" for numbers
        !            46: **     3 - key1
        !            47: **     4 - key2
        !            48: **         .
        !            49: **         .
        !            50: **     i - null
        !            51: **     i+1 - option name (e.g., "fillfactor")
        !            52: **     i+2 - option value
        !            53: **         .
        !            54: **         .
        !            55: **
        !            56: **     If all the options default, parameter i -> pc are omitted.
        !            57: **     If no keys are provided, parameter 2 is omitted.
        !            58: */
        !            59: 
        !            60: int            F_fac, Mn_pages, Mx_pages;
        !            61: char           Lid[MAXLID][MAXNAME];
        !            62: int            NLidKeys;
        !            63: int            LidKey[MAXLID];
        !            64: 
        !            65: struct modtab
        !            66: {
        !            67:        char    *type;
        !            68:        char    newrelspec;
        !            69:        char    yeskeys;
        !            70:        char    sortit;
        !            71:        char    yes_seq;
        !            72:        int     f_fac;
        !            73:        int     mn_pages;
        !            74:        int     mx_pages;
        !            75: };
        !            76: 
        !            77: 
        !            78: struct modtab  Modtab[] =
        !            79: {
        !            80:        /* type         spec    keys    sort    seq     ffac    min     max */
        !            81: 
        !            82:        "heap",         M_HEAP, FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            83:        "cheap",        -M_HEAP,FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            84:        "hash",         M_HASH, TRUE,   TRUE,   FALSE,  50,     10,     -1,
        !            85:        "chash",        -M_HASH,TRUE,   TRUE,   FALSE,  75,     1,      -1,
        !            86:        "isam",         M_ISAM, TRUE,   TRUE,   FALSE,  80,     0,      0,
        !            87:        "cisam",        -M_ISAM,TRUE,   TRUE,   FALSE,  100,    0,      0,
        !            88:        "heapsort",     M_HEAP, TRUE,   TRUE,   TRUE,   0,      0,      0,
        !            89:        "cheapsort",    -M_HEAP,TRUE,   TRUE,   TRUE,   0,      0,      0,
        !            90:        "truncated",    M_TRUNC,FALSE,  FALSE,  FALSE,  0,      0,      0,
        !            91:        "ordered",      M_ORDER,TRUE,   FALSE,  FALSE,  0,      0,      0,
        !            92:        0
        !            93: };
        !            94: 
        !            95: struct mod_info
        !            96: {
        !            97:        char    outfile[MAXNAME + 4];   /* result file filled by ksort */
        !            98:        char    formfile[MAXNAME + 4];  /* file with descriptor for ksort */
        !            99:        char    infile[MAXNAME + 4];    /* input file for ksort (relation itself */
        !           100:        char    reltemp[MAXNAME + 4];   /* file holding new relation */
        !           101:        char    spfile[MAXNAME + 4], spflag;    /* isam spool file for overflow */
        !           102:        char    btree[MAXNAME + 4];     /* file holding temporary btree structure */
        !           103:        char    temp_sort[MAXNAME + 4]; /* file holding result of special isam
        !           104:                                        ** required when ordering on a field
        !           105:                                        */
        !           106: };
        !           107: 
        !           108: struct mod_info        Mod_info;
        !           109: 
        !           110: extern DESC Btreesec;
        !           111: extern int Btree_fd;
        !           112: 
        !           113: 
        !           114: 
        !           115: modify(pc, pv)
        !           116: int    pc;
        !           117: PARM   *pv;
        !           118: {
        !           119:        register int            i, j;
        !           120:        register char           *rname;
        !           121:        register struct modtab  *mp;
        !           122:        struct modtab           *p;
        !           123:        int                     sorted, dim;
        !           124:        DESC                    dold, dnew;
        !           125:        long                    temptid;
        !           126:        extern int              Noupdt;
        !           127:        extern DESC             Attdes;
        !           128:        struct attribute        atttup, attkey;
        !           129:        TID                     tid;
        !           130:        int                     lidkey, numatts;
        !           131:        extern char             *trim_relname();
        !           132:        extern char             *iocv();
        !           133: 
        !           134:        
        !           135: #      ifdef xZTR1
        !           136:        if (tTf(34, -1))
        !           137:        {
        !           138:                printf("enter modify\n");
        !           139:                prvect(pc, pv);
        !           140:        }
        !           141: #      endif
        !           142: 
        !           143:        pv[pc].pv_val.pv_str = NULL;
        !           144: 
        !           145:        /* check for nice parameters */
        !           146:        if (pc < 2)
        !           147:                syserr("MODIFY: pc %d", pc);
        !           148: 
        !           149:        /* save relation name for error messages */
        !           150:        rname = (pv++)->pv_val.pv_str;  /* *pv now pointes to storage spec */
        !           151: 
        !           152:        /* check for good relation */
        !           153:        i = openr(&dold, OR_READ, rname);
        !           154:        if (i == AMOPNVIEW_ERR)
        !           155:                return (error(NOMODVIEW, rname, 0));
        !           156:        if (i > 0)
        !           157:                /* reln does not exist */
        !           158:                return (error(NOREL, rname, 0));        
        !           159:        else if (i < 0)
        !           160:                syserr("MODIFY: openr (%.14s) %d", rname, i);
        !           161:        /* can only modify a relation you own and isn't a sys rel */
        !           162:        
        !           163:        if (!bequal(Usercode, dold.reldum.relowner, UCODE_SZ))
        !           164:        {
        !           165:                i = NOOWN;
        !           166:        }
        !           167:        if ((dold.reldum.relstat & S_CATALOG) && Noupdt)
        !           168:        {
        !           169:                i = NOMODSYSREL;
        !           170:        }
        !           171:        if (i)
        !           172:        {
        !           173:                closer(&dold);
        !           174:                return (error(i, rname, 0));
        !           175:        }
        !           176: 
        !           177:        /*
        !           178:        ** Form descriptor for new relation. Here we need to
        !           179:        ** separate the pages from the old and new relations.
        !           180:        ** Since pages are identified by the TID of the relation
        !           181:        ** relation tuple, both old and new have the same identifiers.
        !           182:        ** To avoid this problem, a special TID is hand crafted for
        !           183:        ** the new relation.
        !           184:        */
        !           185:        bmove(&dold, &dnew, sizeof dnew);
        !           186:        dnew.reltid.s_tupid.line_id = (char) -2;        /* choose impossible reltid */
        !           187:        /* assume new relation isn't ordered */
        !           188:        if (dold.reldum.reldim)
        !           189:        {
        !           190:                dnew.reldum.relatts -= dold.reldum.reldim;
        !           191:                dnew.reldum.relwid -= dold.reldum.reldim * LIDSIZE;
        !           192:                dnew.reldum.reldim = 0;
        !           193:        }
        !           194: 
        !           195:        /* In case of an interrupt from a previous modify,
        !           196:        ** there might be pages around. Get rid of them.
        !           197:        */
        !           198:        cleanrel(&dnew);
        !           199: 
        !           200:        ingresname(dold.reldum.relid, dold.reldum.relowner, Mod_info.infile);
        !           201:        dim = 0;
        !           202:        NLidKeys = 0;
        !           203: 
        !           204:        /* scan for entry in relspec table */
        !           205:        for (mp = Modtab; mp->type; mp++)
        !           206:        {
        !           207:                if (bequal(mp->type, pv->pv_val.pv_str, 7) && bequal("ordered", pv->pv_val.pv_str, 7))
        !           208:                {
        !           209:                        if ((dim = atoi(pv->pv_val.pv_str + 7)) <= 0 || dim > MAXLID)
        !           210:                        {
        !           211:                                closer(&dold);
        !           212:                                return(error(BADORDDIM, rname, iocv(dim), 0));
        !           213:                        }
        !           214:                        break;
        !           215:                }
        !           216:                if (sequal(mp->type, pv->pv_val.pv_str))
        !           217:                        break;
        !           218:        }
        !           219: 
        !           220:        /* if not found, error */
        !           221:        if (!mp->type)
        !           222:        {
        !           223:                closer(&dold);
        !           224:                return (error(BADSTORAGE, rname, pv->pv_val.pv_str, 0));        /* bad relspec */
        !           225:        }
        !           226: 
        !           227:        if (mp->newrelspec == M_ORDER && dold.reldum.relindxd == SECINDEX)
        !           228:        /* can't order an index relation */
        !           229:        {
        !           230:                closer(&dold);
        !           231:                return(error(NOORDINDX, rname,0));
        !           232:        }
        !           233: 
        !           234:        if (mp->newrelspec == M_ORDER)
        !           235:        {
        !           236:                dnew.reldum.reldim = dim;
        !           237:                for (i = 0; i < dim; ++i)
        !           238:                {
        !           239:                        ++dnew.reldum.relatts;
        !           240:                        dnew.relxtra[dnew.reldum.relatts] = 0;
        !           241:                        dnew.reloff[dnew.reldum.relatts] = dnew.reldum.relwid;
        !           242:                        dnew.relfrmt[dnew.reldum.relatts] = INT;
        !           243:                        dnew.relfrml[dnew.reldum.relatts] = LIDSIZE;
        !           244:                        dnew.reldum.relwid += LIDSIZE;
        !           245:                }
        !           246:                concat(BTREE, Fileset, Mod_info.btree);
        !           247:                create_btree(Mod_info.btree);
        !           248:                dnew.btree_fd = Btree_fd;
        !           249:                /* ok to order ascending/descending */
        !           250:                mp->yes_seq = TRUE;
        !           251:        }
        !           252:        else
        !           253:        {
        !           254:                dnew.reldum.relspec = mp->newrelspec;
        !           255:                if (dold.reldum.reldim)
        !           256:                {
        !           257:                        dold.reldum.relatts -= dold.reldum.reldim;
        !           258:                        dold.reldum.relwid -= dold.reldum.reldim * LIDSIZE;
        !           259:                        dold.reldum.reldim = 0;
        !           260:                        closer(dold.relbtree);
        !           261:                        close(dold.btree_fd);
        !           262:                }
        !           263:        }
        !           264: 
        !           265:        if (dnew.reldum.relspec == M_TRUNC)
        !           266:                dnew.reldum.relspec = M_HEAP;
        !           267: 
        !           268:        pv++;   /* now points to first parameter */
        !           269: 
        !           270:        /* get the key domains information */
        !           271:        if ((i = getkeys(&pv, rname, &dnew, mp)) > 0)
        !           272:        {
        !           273:                closer(&dold);
        !           274:                return (i);     /* user error */
        !           275:        }
        !           276: 
        !           277:        j = 0;
        !           278:        for (i = 0; i < NLidKeys; ++i)
        !           279:                if (LidKey[i] > dold.reldum.relatts - dold.reldum.reldim)
        !           280:                {
        !           281:                        j = 1;
        !           282:                        break;
        !           283:                }
        !           284: 
        !           285:        if (!j && dold.reldum.reldim)
        !           286:        /* treat old relation as if not ordered since lid field not needed */
        !           287:        {
        !           288:                dold.reldum.relatts -= dold.reldum.reldim;
        !           289:                dold.reldum.relwid -= dold.reldum.reldim * LIDSIZE;
        !           290:                dold.reldum.reldim = 0;
        !           291:                closer(dold.relbtree);
        !           292:                close(dold.btree_fd);
        !           293:        }
        !           294: 
        !           295:        if (!dnew.reldum.reldim || !NLidKeys)
        !           296:        {
        !           297:                F_fac = mp->f_fac;
        !           298:                Mn_pages = mp->mn_pages;
        !           299:                Mx_pages = mp->mx_pages;
        !           300:        }
        !           301:        else
        !           302:        /* set parameters to that of storage type of relation to be ordered */
        !           303:        {
        !           304:                for (p = Modtab; p->type; p++)
        !           305:                        if (dnew.reldum.relspec == p->newrelspec)
        !           306:                                break;
        !           307:                F_fac = p->f_fac;
        !           308:                Mn_pages = p->mn_pages;
        !           309:                Mx_pages = p->mx_pages;
        !           310:        }
        !           311: 
        !           312:        if (mp->newrelspec != M_ORDER)
        !           313:                for (i = 0; i < dnew.reldum.reldim; ++i)
        !           314:                        Lid[i][0] = NULL;
        !           315:        else
        !           316:                for (i = 1; i <= dnew.reldum.reldim; ++i)
        !           317:                        concat("lid", iocv(i), Lid[i-1]);
        !           318: 
        !           319:        /* get fillfactor and other options if any */
        !           320:        if (i = getfill(&dnew, pv, rname, mp))
        !           321:        {
        !           322:                closer(&dold);
        !           323:                return (i);     /* user error */
        !           324:        }
        !           325: 
        !           326:        /* check for duplicate attribute name */
        !           327:        if (mp->newrelspec == M_ORDER)
        !           328:        {
        !           329:                opencatalog("attribute", OR_READ);
        !           330:                setkey(&Attdes, &attkey, dnew.reldum.relid, ATTRELID);
        !           331:                setkey(&Attdes, &attkey, dnew.reldum.relowner, ATTOWNER);
        !           332:                numatts = dold.reldum.relatts - dold.reldum.reldim;
        !           333:                for (i = 0; i < dnew.reldum.reldim; ++i)
        !           334:                {
        !           335:                        setkey(&Attdes, &attkey, Lid[i], ATTNAME);
        !           336:                        if (getequal(&Attdes, &attkey, &atttup, &tid) == 0)
        !           337:                        {
        !           338:                                if (atttup.attid <= numatts)
        !           339:                                /* ok to duplicate attributes that will be removed */
        !           340:                                {
        !           341:                                        closer(&dold);
        !           342:                                        return(error(INVALIDATTR, rname, Lid[i], 0));
        !           343:                                }
        !           344:                        }
        !           345:                }
        !           346:        }
        !           347: 
        !           348:        /* lock the relation relation */
        !           349:        if (Lockrel)
        !           350:        {
        !           351:                get_p_tid(&dold, &temptid);
        !           352:                setrll(A_SLP, temptid, M_EXCL);
        !           353:        }
        !           354: 
        !           355:        if (!dnew.reldum.reldim || NLidKeys > 0)
        !           356:                /* compute new relation parameters & build descriptor */
        !           357:                make_newrel(&dnew);
        !           358: 
        !           359:        if (sorted = ((mp->sortit || NLidKeys > 0) && (dold.reldum.reltups != 0)))
        !           360:        {
        !           361:                sortrel(&dold, &dnew);
        !           362:                dold.reldum.relindxd = 0;
        !           363:        }
        !           364: 
        !           365:        if (!dnew.reldum.reldim || NLidKeys > 0)
        !           366:                /* physically create the new relation */
        !           367:                if (formatpg(&dnew, dnew.reldum.relprim) != 0)
        !           368:                        syserr("modify: formatpg");
        !           369: 
        !           370:        /* clear relgiven field; if heap remove any keys */
        !           371:        clearkeys(&dnew);
        !           372: 
        !           373:        if (abs(dnew.reldum.relspec) == M_HEAP)
        !           374:                for (i = 1; i <= dnew.reldum.relatts; i++)
        !           375:                        dnew.relxtra[i] = 0;
        !           376: 
        !           377:        if (NLidKeys > 0 && dnew.reldum.relspec == M_ISAM)
        !           378:                sort_isam(&dold, &dnew);
        !           379: 
        !           380:        if (mp->newrelspec != M_TRUNC)
        !           381:                fill_rel(&dold, &dnew, sorted);
        !           382: 
        !           383:        closer(&dold);  /* error return is impossible */
        !           384:        if (abs(dnew.reldum.relspec) == M_ISAM && (!dnew.reldum.reldim || NLidKeys > 0))
        !           385:        {
        !           386:                j = dnew.reldum.reldim;
        !           387:                dnew.reldum.reldim = 0;
        !           388:                if (i = bldindex(&dnew))
        !           389:                        syserr("bldindex: %.14s %d", dnew.reldum.relid, i);
        !           390:                dnew.reldum.reldim = j;
        !           391:                unspool(&dold, &dnew);
        !           392:        }
        !           393: 
        !           394:        /*
        !           395:        ** New relation is now complete. The system relations need to
        !           396:        ** be updated. First destroy all buffers with pages from the
        !           397:        ** new relation.
        !           398:        */
        !           399:        if (i = cleanrel(&dnew))
        !           400:                syserr("modify:clean new %d,%.14s", i, dnew.reldum.relid);
        !           401: 
        !           402:        fill_batch(&dold, &dnew);
        !           403: 
        !           404:        /*
        !           405:        ** Close the file for the new relation. This must be
        !           406:        ** done after the fill_batch in case we are modifing
        !           407:        ** the attribute relation.
        !           408:        */
        !           409:        if (!dnew.reldum.reldim || NLidKeys > 0)
        !           410:                close(dnew.relfp);
        !           411:        dnew.relopn = 0;
        !           412:        ruboff("modify");
        !           413:        modupdate();
        !           414:        if (mp->newrelspec == M_ORDER)
        !           415:        {
        !           416:                close(dnew.btree_fd);
        !           417:                make_bsec(dnew.reldum.relid, dim);
        !           418:        }
        !           419:        rubon();
        !           420: 
        !           421:        if (Lockrel)
        !           422:                unlrl(temptid);
        !           423: 
        !           424:        return (0);
        !           425: }
        !           426: 
        !           427: 
        !           428: /*
        !           429: **     GETKEYS - get key domains information
        !           430: **
        !           431: **     Parameters:
        !           432: **             ppv - parameter vector with info about keys
        !           433: **             relname - relation name
        !           434: **             d - new descriptor for the relation
        !           435: **             mp - mod table
        !           436: **
        !           437: **     Return Codes:
        !           438: **             0 - ok
        !           439: **             >0 - error from modseqkey               
        !           440: */
        !           441: getkeys(ppv, relname, d, mp)
        !           442: PARM           **ppv;
        !           443: char           *relname;
        !           444: register DESC  *d;
        !           445: struct modtab  *mp;
        !           446: {
        !           447:        register PARM           *pv;
        !           448:        register char           *cp;
        !           449:        int                     namemode, sort_only, as_ds;
        !           450:        int                     i, j, keyno, keywid;
        !           451:        struct attribute        attkey, atttup;
        !           452:        struct index            ikey, itup;
        !           453:        TID                     tid;
        !           454:        extern DESC             Attdes, Inddes;
        !           455:        extern char             *iocv();
        !           456: 
        !           457:        pv = *ppv;      /* copy list of params */
        !           458: 
        !           459:        if (mp->newrelspec != M_ORDER)
        !           460:                /* zero key info (ordering does not change keyed fields) */
        !           461:                for (i = 0; i <= d->reldum.relatts; i++)
        !           462:                        d->relxtra[i] = 0;
        !           463:        for (i = 0; i <= d->reldum.relatts; ++i)
        !           464:                d->relgiven[i] = 0;
        !           465: 
        !           466:        /* determine whether there are any keys at all */
        !           467:        keywid = 0;
        !           468:        keyno = 0;
        !           469:        sort_only = FALSE;
        !           470:        cp = pv->pv_val.pv_str;
        !           471: 
        !           472:        if (cp == NULL || *cp == NULL)
        !           473:        {
        !           474:                /* no key information. default as needed */
        !           475:                if (mp->yeskeys && mp->newrelspec != M_ORDER)
        !           476:                {
        !           477:                        cp = "\1";      /* default to first key */
        !           478:                        namemode = FALSE;
        !           479:                }
        !           480:                else
        !           481:                        pv++;   /* point one to far */
        !           482:        }
        !           483:        else
        !           484:        {
        !           485:                /* check for name mode */
        !           486:                if (namemode = sequal(cp, "name"))
        !           487:                {
        !           488: 
        !           489:                        /* check attribute names, and convert them to numbers */
        !           490:                        opencatalog("attribute", OR_READ);
        !           491:                        setkey(&Attdes, &attkey, Mod_info.infile, ATTRELID);
        !           492:                        setkey(&Attdes, &attkey, Usercode, ATTOWNER);
        !           493:                }
        !           494:                pv++;   /* inc to next key */
        !           495:                cp = (pv++)->pv_val.pv_str;
        !           496:        }
        !           497: 
        !           498:        /* scan for attribute names */
        !           499:        for (; cp != NULL; cp = (pv++)->pv_val.pv_str)
        !           500:        {
        !           501:                /* check for separator between keys & options */
        !           502:                if (*cp == NULL)
        !           503:                {
        !           504:                        pv++;   /* point two past NULL */
        !           505:                        break;
        !           506:                }
        !           507: 
        !           508:                if (NLidKeys >= d->reldum.reldim && mp->newrelspec == M_ORDER)
        !           509:                {
        !           510:                        /* more than one field specified as ordering key */
        !           511:                        closeall(0l, 0l);
        !           512:                        return(error(TOOMANYORDKEYS, relname, 0));
        !           513:                }
        !           514: 
        !           515:                if (namemode)
        !           516:                {
        !           517:                        /* check for "sort only" attribute */
        !           518:                        if (*cp == '#')
        !           519:                        {
        !           520:                                cp++;   /* inc to start of name */
        !           521:                                sort_only = TRUE;
        !           522:                        }
        !           523: 
        !           524:                        /* check for ascending/descending modifier */
        !           525:                        if ((as_ds = modseqkey(cp, relname, mp->yes_seq)) > 0)
        !           526:                                return (as_ds); /* error */
        !           527: 
        !           528:                        setkey(&Attdes, &attkey, cp, ATTNAME);
        !           529:                        i = getequal(&Attdes, &attkey, &atttup, &tid);
        !           530:                        if (i < 0)
        !           531:                                syserr("MODIFY: geteq(att) %d", i);
        !           532:                        if (i > 0)
        !           533:                        {
        !           534:                                closeall(0l, 0l);
        !           535:                                return (error(INVALIDATTR, relname, cp, 0));    /* bad att name */
        !           536:                        }
        !           537:                        i = atttup.attid;
        !           538:                        if (i > d->reldum.relatts)
        !           539:                        {
        !           540:                                /* attempting to key on lid field which will be
        !           541:                                ** removed
        !           542:                                */
        !           543:                                closeall(0l,0l);
        !           544:                                return(error(ATTRREMV, relname, cp, 0));
        !           545:                        }
        !           546:                }
        !           547:                else
        !           548:                {
        !           549:                        i = *cp;
        !           550:                        as_ds = 0;
        !           551:                }
        !           552: 
        !           553:                keyno++;
        !           554:                /* add new key to descriptor */
        !           555:                if (mp->newrelspec == M_ORDER)
        !           556:                        LidKey[NLidKeys++] = i;
        !           557:                if (!sort_only && mp->newrelspec != M_ORDER)
        !           558:                {
        !           559:                        d->relxtra[i] = keyno;
        !           560:                        keywid += (d->relfrml[i] & I1MASK);
        !           561:                }
        !           562:                if (d->relgiven[i])
        !           563:                {
        !           564:                        closeall(0l, 0l);
        !           565:                        return (error(DUPKEY, relname, cp, 0)); /* duplicate attribute */
        !           566:                }
        !           567:                d->relgiven[i] = as_ds == 0 ? keyno : -keyno;
        !           568:        }
        !           569:        pv--;   /* back up one to point to "-1" terminator */
        !           570: 
        !           571: 
        !           572:        if (abs(d->reldum.relspec) == M_ISAM && keywid > (MAXTUP / 2 - 4))
        !           573:        {
        !           574:                closeall(0l, 0l);
        !           575:                return (error(TOOWIDEISAM, relname, iocv(keywid), 0));
        !           576:        }
        !           577: 
        !           578:        /* if a heap, there can be no keys */
        !           579:        if (!mp->yeskeys && keyno != 0)
        !           580:        {
        !           581:                closeall(0l, 0l);
        !           582:                return (error(NOKEYSHEAP, relname, mp->type, 0));       /* no keys allowed on heap */
        !           583:        }
        !           584:        /* fill out default sort on remainder of keys */
        !           585:        if (mp->yeskeys)
        !           586:                for (i = 1; i <= d->reldum.relatts; i++)
        !           587:                        if (d->relgiven[i] == 0)
        !           588:                                d->relgiven[i] = ++keyno;
        !           589:        *ppv = pv;
        !           590:        return (0);
        !           591: }
        !           592: 
        !           593: 
        !           594: /*
        !           595: **     MODSEQKEY - verify that sequence specified is valid
        !           596: **
        !           597: **     Parameters:
        !           598: **             domain - list of domains
        !           599: **             relname - relation name
        !           600: **             seq_ok - whether it is ok to specify the sequence
        !           601: **                             ascending or descending
        !           602: **
        !           603: **     Return Codes:
        !           604: **             0 - ok
        !           605: **             > 0 - error in sequence specified
        !           606: **
        !           607: **     Called by:
        !           608: **             getkeys
        !           609: */
        !           610: modseqkey(domain, relname, seq_ok)
        !           611: char   *domain;
        !           612: char   *relname;
        !           613: int    seq_ok;
        !           614: {
        !           615:        register char   *cp, c;
        !           616:        register int    ret;
        !           617: 
        !           618:        ret = 0;
        !           619: 
        !           620:        for (cp = domain; c = *cp++; )
        !           621:                if (c == ':')
        !           622:                        break;
        !           623: 
        !           624:        if (c != '\0')
        !           625:        {
        !           626:                /* replace ":" with null */
        !           627:                *(cp - 1) = '\0';
        !           628: 
        !           629:                /* verify sequence is valid */
        !           630:                if (!seq_ok)
        !           631:                {
        !           632:                        closeall(0l, 0l);
        !           633:                        ret = error(BADSEQSPEC, relname, cp, domain, 0);
        !           634:                }
        !           635:                else if (sequal("descending", cp) || sequal("d", cp))
        !           636:                        ret = -1;
        !           637:                else if (!(sequal("ascending", cp) || sequal("a", cp)))
        !           638:                {
        !           639:                        closeall(0l, 0l);
        !           640:                        ret = error(INVALIDSEQ, relname, cp, domain, 0);
        !           641:                }
        !           642:        }
        !           643: 
        !           644:        return (ret);
        !           645: }
        !           646: /*
        !           647: **     GETFILL -- Get fill factor and minimum pages parameters
        !           648: **             from argument list, convert them from ascii to integer
        !           649: **             and store them in global variables.  If the global
        !           650: **             variable for the corresponding parameter is zero,
        !           651: **             it means that that parameter is not allowed and an
        !           652: **             error is generated.
        !           653: */
        !           654: 
        !           655: /*ARGSUSED*/
        !           656: getfill(d, pv, rel, mp)
        !           657: DESC           *d;
        !           658: register PARM  *pv;
        !           659: char           *rel;
        !           660: struct modtab  *mp;
        !           661: {
        !           662:        register char           *p1;
        !           663:        register int            err;
        !           664:        char                    *p2;
        !           665:        int                     i, j;
        !           666:        int                     fill_flag, min_flag, max_flag, lid_flag[MAXLID];
        !           667: 
        !           668:        err = 0;
        !           669:        fill_flag = min_flag = max_flag = FALSE;
        !           670:        for (i = 0; i < d->reldum.reldim; ++i)
        !           671:                lid_flag[i] = FALSE;
        !           672: 
        !           673:        while ((p1 = (pv++)->pv_val.pv_str) != NULL)
        !           674:        {
        !           675:                p2 = (pv++)->pv_val.pv_str;
        !           676:                if (sequal(p1, "fillfactor"))
        !           677:                {
        !           678:                        if (F_fac == 0 || fill_flag)
        !           679:                        {
        !           680:                                err = NOTALLOWED;
        !           681:                                break;
        !           682:                        }
        !           683:                        p1 = p2;
        !           684:                        F_fac = atoi(p1);
        !           685:                        if (F_fac > 100 || F_fac < 1)
        !           686:                        {
        !           687:                                err = FILLBOUND;
        !           688:                                break;
        !           689:                        }
        !           690:                        fill_flag = TRUE;
        !           691:                        continue;
        !           692:                }
        !           693:                if (sequal(p1, "minpages"))
        !           694:                {
        !           695:                        if (Mn_pages == 0 || min_flag)
        !           696:                        {
        !           697:                                err = NOTALLOWED;
        !           698:                                break;
        !           699:                        }
        !           700:                        p1 = p2;
        !           701:                        Mn_pages = atoi(p1);
        !           702:                        if (Mn_pages < 1)
        !           703:                        {
        !           704:                                err = MINPGBOUND;
        !           705:                                break;
        !           706:                        }
        !           707:                        if (max_flag && (Mn_pages > Mx_pages))
        !           708:                        {
        !           709:                                err = MINGTMAX;
        !           710:                                break;
        !           711:                        }
        !           712:                        min_flag = TRUE;
        !           713:                        continue;
        !           714:                }
        !           715:                if (sequal(p1, "maxpages"))
        !           716:                {
        !           717:                        if (Mx_pages == 0 || max_flag)
        !           718:                        {
        !           719:                                err = NOTALLOWED;
        !           720:                                break;
        !           721:                        }
        !           722:                        p1 = p2;
        !           723:                        Mx_pages = atoi(p1);
        !           724:                        if (Mx_pages < 1)
        !           725:                        {
        !           726:                                err = MAXPGBOUND;
        !           727:                                break;
        !           728:                        }
        !           729:                        if (min_flag && (Mn_pages > Mx_pages))
        !           730:                        {
        !           731:                                err = MINGTMAX;
        !           732:                                break;
        !           733:                        }
        !           734:                        max_flag = TRUE;
        !           735:                        continue;
        !           736:                }
        !           737:                for ( i  = 1; i <= d->reldum.reldim && !err; ++i)
        !           738:                        if (sequal(p1, ztack("lid", iocv(i))))
        !           739:                        {
        !           740:                                if (lid_flag[i-1] || *Lid[i-1] == NULL)
        !           741:                                {
        !           742:                                        err = NOTALLOWED;
        !           743:                                        break;
        !           744:                                }
        !           745:                                for (j = 0; j < d->reldum.reldim; ++j)
        !           746:                                        if (i - 1 != j && sequal(p2, Lid[j]) && lid_flag[j])
        !           747:                                        {
        !           748:                                                err = NOTALLOWED;
        !           749:                                                break;
        !           750:                                        }
        !           751:                                p1 = p2;
        !           752:                                smove(p1, Lid[i - 1]);
        !           753:                                lid_flag[i - 1] = TRUE;
        !           754:                                break;
        !           755:                        }
        !           756:                        if (err)
        !           757:                                break;
        !           758:                if (i <= d->reldum.reldim)
        !           759:                        continue;
        !           760:                err = NEEDFILL;
        !           761:                break;
        !           762:        }
        !           763:        if (err)
        !           764:        {
        !           765:                closeall(0l, 0l);
        !           766:                return (error(err, rel, p1, 0));
        !           767:        }
        !           768:        return (0);
        !           769: }
        !           770: /*
        !           771: **  MAKE_NEWREL -- Create a file for the modified relation
        !           772: **     and build one or more primary pages for the
        !           773: **     relation based on its storage structure and the
        !           774: **     number of tuples it must hold.
        !           775: */
        !           776: 
        !           777: make_newrel(desc)
        !           778: register DESC  *desc;
        !           779: {
        !           780:        register int    tups_p_page;
        !           781:        int             width;
        !           782: 
        !           783:        concat(MODTEMP, Fileset, Mod_info.reltemp);
        !           784:        close(creat(Mod_info.reltemp, FILEMODE));
        !           785:        if ((desc->relfp = open(Mod_info.reltemp, O_RDWR)) < 0)
        !           786:                syserr("MAKE_NEWREL: open %.14s %d", Mod_info.reltemp, desc->relfp);
        !           787:        desc->relopn = (desc->relfp + 1) * -5;
        !           788:        desc->reldum.relprim = 1;
        !           789:        if (abs(desc->reldum.relspec) == M_HASH && F_fac > 0 && Mn_pages > 0)
        !           790:        {
        !           791:                /*
        !           792:                ** Determine the number of primary pages. The following
        !           793:                ** first determines the number of tuples/page which the
        !           794:                ** relation should have in order to get the requested
        !           795:                ** fillfactor. Then that number is divided into the
        !           796:                ** number of tuples to get the number of primary pages.
        !           797:                ** To avoid round off, it must guaranteed that the
        !           798:                ** number of tuples per page must be at least 1.
        !           799:                **
        !           800:                ** primary_pages = #tuples / (#tuples/page * fillfactor)
        !           801:                */
        !           802:                width = desc->reldum.relwid + 2 - LIDSIZE * desc->reldum.reldim;
        !           803:                tups_p_page = (((MAXTUP+2) / width) * F_fac) / 100;
        !           804:                if (tups_p_page == 0)
        !           805:                        tups_p_page = 1;
        !           806:                 /* we add one to simulate a ceiling function */
        !           807:                desc->reldum.relprim = desc->reldum.reltups / tups_p_page + 1;
        !           808:                if (desc->reldum.relprim < Mn_pages)
        !           809:                        desc->reldum.relprim = Mn_pages;
        !           810:                if (Mx_pages > 0 && desc->reldum.relprim > Mx_pages)
        !           811:                        desc->reldum.relprim = Mx_pages;
        !           812: #              ifdef xZTR1
        !           813:                if (tTf(36, 0))
        !           814:                        printf("using %ld prim pages\n", desc->reldum.relprim);
        !           815: #              endif
        !           816:        }
        !           817:        desc->reldum.reltups = 0;
        !           818:        return (0);
        !           819: }
        !           820: /*
        !           821: **     SORTREL - Call KSORT to sort the given relation.  SORTREL
        !           822: **             sets up the descriptor struct specifying the sort
        !           823: **             keys and tells KSORT whether or not the hash key should
        !           824: **             be included as a sort key.
        !           825: */
        !           826: 
        !           827: sortrel(odesc, desc)
        !           828: DESC           *odesc;
        !           829: register DESC  *desc;
        !           830: {
        !           831:        extern char     *Pathname;
        !           832:        register int    i;
        !           833:        char            buf[50];
        !           834:        DESC            tempdesc;
        !           835:        char            *temp;
        !           836:        int             len;
        !           837:        short           smalli;
        !           838: 
        !           839:        concat(ISAM_SORTED, Fileset, Mod_info.outfile);
        !           840:        if (close(creat(Mod_info.outfile, FILEMODE)))
        !           841:                syserr("SORTREL: creat %.14s", Mod_info.outfile);
        !           842:        bmove(odesc, &tempdesc, sizeof *odesc);
        !           843:        for (i = 1; i <= desc->reldum.relatts; ++i)
        !           844:        /* set up temporary descriptor for ksort with new keyed fields */
        !           845:        {
        !           846:                tempdesc.relxtra[i] = desc->relxtra[i];
        !           847:                tempdesc.relgiven[i] = desc->relgiven[i];
        !           848:        }
        !           849: 
        !           850:        if (abs(desc->reldum.relspec) == M_HASH && !desc->reldum.reldim)
        !           851:        {
        !           852:                /* sort on hash bucket first, (if ordering sort on ordering key, not bucket) */
        !           853:                tempdesc.relgiven[0] = 1;
        !           854:                for (i = 1; i <= desc->reldum.relatts; i++)
        !           855:                        tempdesc.relgiven[i]++;
        !           856:        }
        !           857: 
        !           858: # ifdef xZTR2
        !           859:        if (tTf(36, 4))
        !           860:        {
        !           861:                printf("sortrel: ");
        !           862:                printdesc(&tempdesc);
        !           863:        }
        !           864: # endif
        !           865: 
        !           866:        /* flush buffers used by modify so that ksort can't look at them */
        !           867:        flush_rel(desc, TRUE);
        !           868:        resetacc(NULL);
        !           869: 
        !           870:        /* copy Fileset so it can't get trashed */
        !           871: 
        !           872:        len = length(Fileset) + 1;
        !           873:        temp = (char *) need(Qbuf, len);
        !           874:        bmove(Fileset, temp, len);
        !           875: 
        !           876:        initp();
        !           877:        setp(PV_STR, temp);
        !           878:        setp(PV_STR, Mod_info.infile);
        !           879:        setp(PV_STR, Mod_info.outfile);
        !           880: 
        !           881:        /* Descriptor for new relation */
        !           882:        setp(PV_STR, tempdesc.reldum.relid);
        !           883:        setp(PV_STR, tempdesc.reldum.relowner);
        !           884:        setp(PV_INT, tempdesc.reldum.relspec);
        !           885:        setp(PV_INT, tempdesc.reldum.relindxd);
        !           886:        setp(PV_INT, tempdesc.reldum.relstat2);
        !           887:        setp(PV_INT, tempdesc.reldum.relstat);
        !           888:        setp(PV_INT, (short) tempdesc.reldum.relsave);
        !           889:        setp(PV_INT, (short) tempdesc.reldum.reltups);
        !           890:        setp(PV_INT, tempdesc.reldum.relatts);
        !           891:        setp(PV_INT, tempdesc.reldum.relwid);
        !           892:        setp(PV_INT, (short) tempdesc.reldum.relprim);
        !           893:        setp(PV_INT, (short) tempdesc.reldum.relfree);
        !           894:        setp(PV_INT, (short) tempdesc.reldum.relstamp);
        !           895:        setp(PV_INT, tempdesc.reldum.reldim);
        !           896: 
        !           897:        setp(PV_STR, tempdesc.relvname);
        !           898:        setp(PV_INT, tempdesc.relfp);
        !           899:        setp(PV_INT, tempdesc.relopn);
        !           900:        setp(PV_INT, (short) tempdesc.reladds);
        !           901:        setp(PV_INT, tempdesc.reltid.ltid);
        !           902:        for (i = 0; i <= tempdesc.reldum.relatts; ++i)
        !           903:        {
        !           904:                smalli = (short) tempdesc.reloff[i];
        !           905:                setp(PV_INT, smalli);
        !           906:                smalli = (short) tempdesc.relfrmt[i];
        !           907:                setp(PV_INT, smalli);
        !           908:                smalli = (short) tempdesc.relfrml[i];
        !           909:                setp(PV_INT, smalli);
        !           910:                smalli = (short) tempdesc.relxtra[i];
        !           911:                setp(PV_INT, smalli);
        !           912:                smalli = (short) tempdesc.relgiven[i];
        !           913:                setp(PV_INT, smalli);
        !           914:        }
        !           915: 
        !           916:        if (tempdesc.reldum.reldim > 0)
        !           917:        {
        !           918:                setp(PV_STR, odesc->relbtree->reldum.relid);
        !           919:                setp(PV_STR, odesc->relbtree->reldum.relowner);
        !           920:                setp(PV_INT, odesc->relbtree->reldum.relspec);
        !           921:                setp(PV_INT, odesc->relbtree->reldum.relindxd);
        !           922:                setp(PV_INT, odesc->relbtree->reldum.relstat2);
        !           923:                setp(PV_INT, odesc->relbtree->reldum.relstat);
        !           924:                setp(PV_INT, (short) odesc->relbtree->reldum.relsave);
        !           925:                setp(PV_INT, (short) odesc->relbtree->reldum.reltups);
        !           926:                setp(PV_INT, odesc->relbtree->reldum.relatts);
        !           927:                setp(PV_INT, odesc->relbtree->reldum.relwid);
        !           928:                setp(PV_INT, (short) odesc->relbtree->reldum.relprim);
        !           929:                setp(PV_INT, (short) odesc->relbtree->reldum.relfree);
        !           930:                setp(PV_INT, (short) odesc->relbtree->reldum.relstamp);
        !           931:                setp(PV_INT, odesc->relbtree->reldum.reldim);
        !           932: 
        !           933:                setp(PV_STR, odesc->relbtree->relvname);
        !           934:                setp(PV_INT, odesc->relbtree->relfp);
        !           935:                setp(PV_INT, odesc->relbtree->relopn);
        !           936:                setp(PV_INT, (short) odesc->relbtree->reladds);
        !           937:                setp(PV_INT, odesc->relbtree->reltid.ltid);
        !           938: 
        !           939:                for (i = 0; i <= odesc->relbtree->reldum.relatts; ++i)
        !           940:                {
        !           941:                        smalli = (short) odesc->relbtree->reloff[i];
        !           942:                        setp(PV_INT, smalli);
        !           943:                        smalli = (short) odesc->relbtree->relfrmt[i];
        !           944:                        setp(PV_INT, smalli);
        !           945:                        smalli = (short) odesc->relbtree->relfrml[i];
        !           946:                        setp(PV_INT, smalli);
        !           947:                        smalli = (short) odesc->relbtree->relxtra[i];
        !           948:                        setp(PV_INT, smalli);
        !           949:                        smalli = (short) odesc->relbtree->relgiven[i];
        !           950:                        setp(PV_INT, smalli);
        !           951:                }
        !           952:        }
        !           953: 
        !           954:        call(mdKSORT, NULL);
        !           955: 
        !           956:        /* flush buffers used by ksort so that modify can't look at them */
        !           957:        flush_rel(desc, TRUE);
        !           958:        resetacc(NULL);
        !           959: 
        !           960: # ifdef xZTR1
        !           961:        if (tTf(36,9))
        !           962:                printf("SORTREL: done calling ksort\n");
        !           963: #endif
        !           964:        return (0);
        !           965: }
        !           966: /*
        !           967: **     SORT_ISAM -- Sorts an isam relation back to its original order
        !           968: **     so that it will be inserted into the relation in the proper order.
        !           969: **     It is presently not in order because it has been sorted according
        !           970: **     to a specified field for ordering.
        !           971: */
        !           972: sort_isam(sdesc, desc)
        !           973: DESC *sdesc;
        !           974: DESC *desc;
        !           975: {
        !           976:        long            lid[MAXLID];
        !           977:        register int    i, j, k;
        !           978:        char            tup_buf[MAXTUP], last_tup[MAXTUP], *dp, *sp;
        !           979:        FILE            *sfp, *fp;
        !           980:        TID             tid, tidpos;
        !           981:        DESC            tempdesc;
        !           982:        int             w;
        !           983: 
        !           984:        if (desc->reldum.reldim > 0)
        !           985:                Btree_fd = desc->btree_fd;
        !           986:        concat(STEMP, Fileset, Mod_info.temp_sort);
        !           987:        if ((sfp = fopen(Mod_info.temp_sort, "w")) == NULL)
        !           988:                syserr("sort_isam: can't open %s", Mod_info.temp_sort);
        !           989:        if ((fp = fopen(Mod_info.outfile, "r")) == NULL)
        !           990:                syserr("sort_isam: can't open %s", Mod_info.outfile);
        !           991:        for (i = 0; i < desc->reldum.reldim; lid[i++] = 0);
        !           992:        /* create input file for sort with proper lid attached to each tuple */
        !           993:        w = sdesc->reldum.relwid - LIDSIZE * sdesc->reldum.reldim;
        !           994:        for ( ; ; )
        !           995:        {
        !           996:                i = fread(tup_buf, 1, sdesc->reldum.relwid, fp);
        !           997:                if (i == 0)
        !           998:                        break;
        !           999:                if (i != sdesc->reldum.relwid)
        !          1000:                        syserr("sort_isam: read error in %s", Mod_info.outfile);
        !          1001:                for (j = 0; j < desc->reldum.reldim; ++j)
        !          1002:                        if (j < NLidKeys && j < desc->reldum.reldim - 1)
        !          1003:                        {
        !          1004:                                dp = tup_buf + (sdesc->reloff[LidKey[j]] & I1MASK);
        !          1005:                                sp = last_tup + (sdesc->reloff[LidKey[j]] & I1MASK);
        !          1006:                                if (!bequal(dp, sp, sdesc->relfrml[LidKey[j]]) || !lid[j])
        !          1007:                                {
        !          1008:                                        ++lid[j];
        !          1009:                                        for (k = j + 1; k < desc->reldum.reldim; ++k)
        !          1010:                                                lid[k] = 0;
        !          1011:                                        break;
        !          1012:                                }
        !          1013:                        }
        !          1014:                        else
        !          1015:                        {
        !          1016:                                if (!lid[0])
        !          1017:                                {
        !          1018:                                        lid[0] = 1;
        !          1019:                                        if (!(desc->reldum.reldim - 1))
        !          1020:                                                break;
        !          1021:                                }
        !          1022:                                ++lid[desc->reldum.reldim - 1];
        !          1023:                                break;
        !          1024:                        }
        !          1025:                bmove(tup_buf, last_tup, sdesc->reldum.relwid);
        !          1026:                /* reserve a slot in btree for tuple */
        !          1027:                insert_mbtree(desc, Mod_info.btree, lid, &tid, &tidpos);
        !          1028:                bmove(lid, tup_buf + w, LIDSIZE * desc->reldum.reldim);
        !          1029:                if (fwrite(tup_buf, 1, sdesc->reldum.relwid + LIDSIZE * desc->reldum.reldim, sfp) != sdesc->reldum.relwid + LIDSIZE * desc->reldum.reldim)
        !          1030:                        syserr("sort_isam: write error in %s", Mod_info.temp_sort);
        !          1031:        }
        !          1032:        fclose(fp);
        !          1033:        fclose(sfp);
        !          1034:        /* set up new descriptor accounting for lid field */
        !          1035:        bmove(sdesc, &tempdesc, sizeof *sdesc);
        !          1036:        tempdesc.reldum.relspec = M_ORDER;
        !          1037:        for (i = 0; i < desc->reldum.reldim; ++i)
        !          1038:        {
        !          1039:                tempdesc.reldum.relwid += LIDSIZE;
        !          1040:                ++tempdesc.reldum.relatts;
        !          1041:                tempdesc.reloff[tempdesc.reldum.relatts] = tempdesc.reldum.relwid - LIDSIZE;
        !          1042:                tempdesc.relfrmt[tempdesc.reldum.relatts] = INT;
        !          1043:                tempdesc.relfrml[tempdesc.reldum.relatts] = LIDSIZE;
        !          1044:        }
        !          1045:        j = 0;
        !          1046:        /* use old keying attributes for specifying sort order */
        !          1047:        clearkeys(&tempdesc);
        !          1048:        for (i = 1; i <= sdesc->reldum.relatts; ++i)
        !          1049:                if (sdesc->relxtra[i])
        !          1050:                {
        !          1051:                        tempdesc.relgiven[i] = sdesc->relxtra[i];
        !          1052:                        ++j;
        !          1053:                }
        !          1054:        for (i = 1; i <= tempdesc.reldum.relatts; ++i)
        !          1055:                if (!tempdesc.relgiven[i])
        !          1056:                        tempdesc.relgiven[i] = ++j;
        !          1057:        sortfile(Mod_info.temp_sort, &tempdesc, FALSE);
        !          1058:        if (unlink(Mod_info.outfile) < 0)
        !          1059:                syserr("can't unlink %s", Mod_info.outfile);
        !          1060:        if (link(ztack(REPL_OUT, Fileset), Mod_info.outfile) == -1)
        !          1061:                syserr("can't link %s to %s", ztack(REPL_OUT, Fileset), Mod_info.outfile);
        !          1062:        if (unlink(Mod_info.temp_sort) < 0)
        !          1063:                syserr("sort_isam: can't unlink %s", Mod_info.temp_sort);
        !          1064:        if (unlink(ztack(REPL_OUT, Fileset)) < 0)
        !          1065:                syserr("sort_isam: can't unlink replout file");
        !          1066: }
        !          1067: /*
        !          1068: **     FILL_REL -- Fill the new relation with tuples from either
        !          1069: **             the old relation or the output file of KSORT.
        !          1070: */
        !          1071: 
        !          1072: fill_rel(sdesc, desc, sortit)
        !          1073: register DESC  *sdesc, *desc;
        !          1074: char                   sortit;
        !          1075: {
        !          1076:        register int    i;
        !          1077:        char            tup_buf[MAXTUP], last_tup[MAXTUP], tup[2 * LIDSIZE]; 
        !          1078:        char            junk[4], newreltype, anytups, chkdups;
        !          1079:        int             need, j, k;
        !          1080:        long            lnum, lid[MAXLID], l, page, t;
        !          1081:        TID             tid, stid, stidlim, ntid, tidpos, btid;
        !          1082:        FILE            *fp, *spfp;
        !          1083:        char            *dp, *sp;
        !          1084:        int             w, temp;
        !          1085:        struct locator  tidloc;
        !          1086: 
        !          1087:        newreltype = abs(desc->reldum.relspec);
        !          1088:        if (sortit)
        !          1089:        {
        !          1090:                if ((fp = fopen(Mod_info.outfile, "r")) == NULL)
        !          1091:                        syserr("FILL_REL: fopen %.14s", Mod_info.outfile);
        !          1092:        }
        !          1093:        else
        !          1094:        {
        !          1095:                cleanrel(sdesc);        /* make sure each page is read fresh */
        !          1096:                find(sdesc, NOKEY, &stid, &stidlim);
        !          1097:        }
        !          1098:        if (newreltype == M_ISAM && (NLidKeys > 0 || !desc->reldum.reldim))
        !          1099:        {
        !          1100:                lnum = 0;
        !          1101:                stuff_page(&tid, &lnum);
        !          1102:                tid.line_id = 0;
        !          1103:                get_page(desc, &tid);
        !          1104:                concat(ISAM_SPOOL, Fileset, Mod_info.spfile);
        !          1105:                /* assume that spool file is not needed */
        !          1106:                spfp = NULL;
        !          1107:                Mod_info.spflag = FALSE;
        !          1108:                if (F_fac == 0)
        !          1109:                        F_fac = 100;
        !          1110:                /* setup relgiven field for kcompare later on */
        !          1111:                for (i = 1; i <= desc->reldum.relatts; i++)
        !          1112:                        desc->relgiven[i] = desc->relxtra[i];
        !          1113:                if (desc->reldum.reldim)
        !          1114:                        Btree_fd = desc->btree_fd;
        !          1115:        }
        !          1116:        desc->reladds = 0;
        !          1117:        for (i = 0; i < desc->reldum.reldim; lid[i++] = 0)
        !          1118:                continue;
        !          1119:        anytups = FALSE;
        !          1120:        chkdups = !sortit && (newreltype != M_ORDER);
        !          1121: # ifdef xZTR2
        !          1122:        if (tTf(36, 3))
        !          1123:        {
        !          1124:                printf("  FILLREL: ");
        !          1125:                printdesc(sdesc);
        !          1126:                printdesc(desc);
        !          1127:        }
        !          1128: # endif
        !          1129:        for (;;)
        !          1130:        {
        !          1131:                w = (newreltype == M_ISAM) ? sdesc->reldum.relwid + desc->reldum.reldim * LIDSIZE : sdesc->reldum.relwid;
        !          1132:                if (sortit)
        !          1133:                {
        !          1134:                        i = fread(tup_buf, 1, w, fp);
        !          1135:                        if (i == 0)
        !          1136:                                break;
        !          1137:                        if (i != w)
        !          1138:                                syserr("FILL_REL: fread A %d", i);
        !          1139:                        if (newreltype == M_HASH && !desc->reldum.reldim)
        !          1140:                                if (fread(junk, 1, 4, fp) != 4)
        !          1141:                                        syserr("FILL_REL: fread B");
        !          1142:                }
        !          1143:                else
        !          1144:                {
        !          1145: #                      ifdef xZTR2
        !          1146:                        if (tTf(36, 1))
        !          1147:                        {
        !          1148:                                printf("FILL_REL: stid ");
        !          1149:                                dumptid(&stid);
        !          1150:                                printf("FILL_REL: stidlim ");
        !          1151:                                dumptid(&stidlim);
        !          1152:                        }
        !          1153: #                      endif
        !          1154:                        i = get(sdesc, &stid, &stidlim, tup_buf, TRUE);
        !          1155: #                      ifdef xZTR2
        !          1156:                        if (tTf(36, 1))
        !          1157:                        {
        !          1158:                                printf("FILLREL: get %d ", i);
        !          1159:                                printup(sdesc, tup_buf);
        !          1160:                        }
        !          1161: #                      endif
        !          1162:                        if (i < 0)
        !          1163:                                syserr("FILL_REL: get %d", i);
        !          1164:                        if (i == 1)
        !          1165:                                break;
        !          1166:                }
        !          1167:                if (newreltype != M_ISAM || (newreltype == M_ISAM && NLidKeys == 0 && desc->reldum.reldim > 0))
        !          1168:                {
        !          1169:                        for (j = 0; j < desc->reldum.reldim; ++j)
        !          1170:                                if (j < NLidKeys && j < desc->reldum.reldim - 1)
        !          1171:                                {
        !          1172:                                        dp = tup_buf + (sdesc->reloff[LidKey[j]] & I1MASK);
        !          1173:                                        sp = last_tup + (sdesc->reloff[LidKey[j]] & I1MASK);
        !          1174:                                        if (!bequal(dp, sp, sdesc->relfrml[LidKey[j]]) || !lid[j])
        !          1175:                                        {
        !          1176:                                                ++lid[j];
        !          1177:                                                for (k = j + 1; k < desc->reldum.reldim; ++k)
        !          1178:                                                        lid[k] = 0;
        !          1179:                                                break;
        !          1180:                                        }
        !          1181:                                }
        !          1182:                                else
        !          1183:                                {
        !          1184:                                        if (!lid[0])
        !          1185:                                        {
        !          1186:                                                lid[0] = 1;
        !          1187:                                                if (!(desc->reldum.reldim -1))
        !          1188:                                                        break;
        !          1189:                                        }
        !          1190:                                        ++lid[desc->reldum.reldim - 1];
        !          1191:                                        break;
        !          1192:                                }
        !          1193:                        Btree_fd = desc->btree_fd;
        !          1194:                        if (!desc->reldum.reldim || NLidKeys > 0)
        !          1195:                        {
        !          1196:                                /* assume unordered so btree inserts done
        !          1197:                                ** separately */
        !          1198:                                temp = 0;
        !          1199:                                if (desc->reldum.reldim > 0)
        !          1200:                                {
        !          1201:                                        temp = desc->reldum.reldim;
        !          1202:                                        desc->reldum.reldim = 0;
        !          1203:                                        desc->reldum.relwid -= temp * LIDSIZE;
        !          1204:                                }
        !          1205:                                if ((i = insert(desc, &tid, tup_buf, chkdups)) < 0)
        !          1206:                                        syserr("FILL_REL: insert %d", i);
        !          1207:                                if (NLidKeys > 0)
        !          1208:                                {
        !          1209:                                        bmove(&tid, &stid, LIDSIZE);
        !          1210:                                        desc->reldum.reldim = temp;
        !          1211:                                        desc->reldum.relwid += temp * LIDSIZE;
        !          1212:                                        insert_mbtree(desc, Mod_info.btree, lid, &tid, &tidpos);
        !          1213:                                }
        !          1214:                        }
        !          1215:                        if (desc->reldum.reldim && !NLidKeys)
        !          1216:                        {
        !          1217:                                /* new relation not changed, only lids added */
        !          1218:                                page = RT;
        !          1219:                                for (j = 0; j < desc->reldum.reldim - 1; ++j)
        !          1220:                                {
        !          1221:                                        if (!lid[j])
        !          1222:                                                lid[j] = 1;
        !          1223:                                        if ((t = get_tid(page, lid[j], &tidloc)) < 0)
        !          1224:                                        {
        !          1225:                                                insert_btree(Mod_info.btree, page, lid[j], &ntid, &tidpos, j + 2);
        !          1226:                                                bmove(&ntid, &page, LIDSIZE);
        !          1227:                                        }
        !          1228:                                        else
        !          1229:                                                bmove(&t, &page, LIDSIZE);
        !          1230:                                }
        !          1231:                                insert_btree(Mod_info.btree, page, lid[abs(desc->reldum.reldim) - 1], &stid, &tidpos, FALSE);
        !          1232:                        }
        !          1233:                        bmove(tup_buf, last_tup, sdesc->reldum.relwid);
        !          1234:                        if (desc->reldum.reldim > 0)
        !          1235:                        {
        !          1236:                                dp = tup_buf + desc->reldum.relwid - desc->reldum.reldim * LIDSIZE;
        !          1237:                                bmove(lid, dp, LIDSIZE * desc->reldum.reldim);
        !          1238:                        }
        !          1239: #                      ifdef xZTR2
        !          1240:                        if (tTf(36, 2))
        !          1241:                        {
        !          1242:                                printf("FILL_REL: insert ");
        !          1243:                                printup(desc, tup_buf);
        !          1244:                                printf("FILL_REL: insert ret %d at", i);
        !          1245:                                dumptid(&tid);
        !          1246:                        }
        !          1247: #                      endif
        !          1248:                        continue;
        !          1249:                }
        !          1250:                if (anytups)
        !          1251:                        i = kcompare(desc, tup_buf, last_tup);
        !          1252:                else
        !          1253:                {
        !          1254:                        anytups = TRUE;
        !          1255:                        i = 1;
        !          1256:                }
        !          1257:                bmove(tup_buf, last_tup, desc->reldum.relwid);
        !          1258:                need = canonical(desc, tup_buf);
        !          1259:                if (i == 0 && need > space_left(Acc_head))
        !          1260:                {
        !          1261:                        /* spool out this tuple. will go on overflow page later */
        !          1262:                        if (spfp == NULL)
        !          1263:                        {
        !          1264:                                if ((spfp = fopen(Mod_info.spfile, "w")) == NULL)
        !          1265:                                        syserr("FILL_REL: fopen %.14s", Mod_info.spfile);
        !          1266:                                Mod_info.spflag = TRUE;
        !          1267:                        }
        !          1268:                        if (fwrite(tup_buf, 1, desc->reldum.relwid, spfp) != desc->reldum.relwid)
        !          1269:                                syserr("FILL_REL: putb spool");
        !          1270:                        continue;
        !          1271:                }
        !          1272:                j = (100 - F_fac) * MAXTUP / 100;
        !          1273:                if (j < need)
        !          1274:                        j = need;
        !          1275:                if (i != 0 && j > space_left(Acc_head))
        !          1276:                {
        !          1277:                        if (i = add_prim(desc, &tid))
        !          1278:                                syserr("FILL_REL: force ovflo %d", i);
        !          1279:                }
        !          1280:                tid.line_id = newlino(need);
        !          1281:                put_tuple(&tid, Acctuple, need);
        !          1282:                if (NLidKeys > 0)
        !          1283:                {
        !          1284:                        bmove(tup_buf + desc->reldum.relwid - LIDSIZE * desc->reldum.reldim, lid, LIDSIZE * desc->reldum.reldim);
        !          1285:                        page = RT;
        !          1286:                        for (j = 0; j < desc->reldum.reldim; ++j)
        !          1287:                        {
        !          1288:                                if ((t = get_tid(page, lid[j], &tidloc)) < 0)
        !          1289:                                        syserr("get_tid error in modify isam ordered");
        !          1290:                                page = t;
        !          1291:                        }
        !          1292:                        stuff_page(&btid, &tidloc.pageno);
        !          1293:                        btid.line_id = tidloc.page.node.leafnode.tid_loc[tidloc.offset];
        !          1294:                        /* place proper tid in tree */
        !          1295:                        replace_btree(tid, &btid);
        !          1296:                }
        !          1297:                desc->reladds++;
        !          1298:        }
        !          1299:        if (sortit)
        !          1300:        {
        !          1301:                fclose(fp);
        !          1302:                unlink(Mod_info.outfile);
        !          1303:        }
        !          1304:        if (newreltype == M_ISAM && desc->reldum.reldim <= 0)
        !          1305:        {
        !          1306:                if (i = pageflush(Acc_head))
        !          1307:                        syserr("fill_rel:pg clean %d", i);
        !          1308:                if (spfp != NULL)
        !          1309:                        fclose(spfp);
        !          1310:        }
        !          1311:        if (!desc->reldum.reldim || NLidKeys > 0)
        !          1312:                desc->reldum.reltups = desc->reladds;
        !          1313:        desc->reladds = 0;
        !          1314:        return (0);
        !          1315: }
        !          1316: 
        !          1317: 
        !          1318: /*
        !          1319: **     BLDINDEX -      
        !          1320: **
        !          1321: **     Parameters:
        !          1322: **             d - descriptor for relation
        !          1323: **
        !          1324: **     Return Codes:
        !          1325: **             0 - ok
        !          1326: **             <0 - error
        !          1327: **
        !          1328: **     Trace Flags:
        !          1329: **             Z38.7, Z38.8
        !          1330: **
        !          1331: **     Called by:
        !          1332: **             modify
        !          1333: **
        !          1334: */
        !          1335: bldindex(d)
        !          1336: register DESC  *d;
        !          1337: {
        !          1338:        register TID    *tid;
        !          1339:        register int    tmp;
        !          1340:        TID             tidx;
        !          1341:        struct accbuf   dirbuf;
        !          1342:        int             keywid, level, savespec, keyx[MAXDOM];
        !          1343:        int             offset, len;
        !          1344:        char            tuple[MAXTUP], temptup[MAXTUP], *key;
        !          1345:        long            pageid, start, stop, newstart, newstop;
        !          1346: 
        !          1347:        tid = &tidx;
        !          1348:        keywid = 0;
        !          1349:        for (tmp = 0; tmp < MAXDOM; tmp++)
        !          1350:                keyx[tmp] = 0;
        !          1351:        for (tmp = 1; tmp <= d->reldum.relatts; tmp++)
        !          1352:                if (d->relxtra[tmp] > 0)
        !          1353:                {
        !          1354:                        keyx[d->relxtra[tmp] - 1] = tmp;
        !          1355:                        keywid += d->relfrml[tmp] & I1MASK;
        !          1356:                }
        !          1357: 
        !          1358:        /* Determine the last page of the relation. This will
        !          1359:        ** only work if all pages have been written out. Fill_rel
        !          1360:        ** must guarantee that all pages have been written
        !          1361:        */
        !          1362:        level = 0;
        !          1363:        last_page(d, tid, 0);
        !          1364:        pluck_page(tid, &stop);
        !          1365:        start = 0;
        !          1366:        dirbuf.filedesc = d->relfp;
        !          1367:        dirbuf.rel_tupid = d->reltid.ltid;
        !          1368:        savespec = d->reldum.relspec;
        !          1369:        for (;;)
        !          1370:        {
        !          1371: #              ifdef xZTR2
        !          1372:                if (tTf(38, 7))
        !          1373:                        printf("isam: level %d\n", level);
        !          1374: #              endif
        !          1375:                dirbuf.ovflopg = start;
        !          1376:                dirbuf.mainpg = level;
        !          1377:                dirbuf.thispage = stop + 1;
        !          1378:                dirbuf.linetab[0] = (short) (dirbuf.firstup - (char *) &dirbuf);
        !          1379:                offset = dirbuf.linetab[0];
        !          1380:                dirbuf.bufstatus = BUF_DIRTY | BUF_DIRECT;
        !          1381: 
        !          1382:                dirbuf.nxtlino = 0;
        !          1383:                newstart = stop + 1;
        !          1384:                newstop = newstart;
        !          1385:                for (pageid = start; pageid <= stop; pageid++)
        !          1386:                {
        !          1387: #                      ifdef xZTR2
        !          1388:                        if (tTf(38, 8))
        !          1389:                                printf("isam:get key from %ld\n", pageid);
        !          1390: #                      endif
        !          1391:                        stuff_page(tid, &pageid);
        !          1392:                        tid->line_id = 0;
        !          1393:                        if (tmp = get(d, tid, tid, tuple, FALSE))
        !          1394:                        {
        !          1395:                                /*
        !          1396:                                ** If the relation is empty, then page 0 will
        !          1397:                                ** return AMINVL_ERR on a get(). Form a blank tuple
        !          1398:                                ** and use it to create a one tuple directory
        !          1399:                                */
        !          1400:                                if (pageid == 0 && tmp == AMINVL_ERR)
        !          1401:                                {
        !          1402:                                        clr_tuple(d, tuple);
        !          1403:                                }
        !          1404:                                else
        !          1405:                                {
        !          1406:                                        return (-2);
        !          1407:                                }
        !          1408:                        }
        !          1409: 
        !          1410:                        /*
        !          1411:                        ** If this is the first level then form the tuple
        !          1412:                        ** from the mainpage of the relation. Otherwise
        !          1413:                        ** the tuple is the first tuple of a directory page
        !          1414:                        ** and it is already correctly formed.
        !          1415:                        */
        !          1416:                        if (level == 0)
        !          1417:                        {
        !          1418:                                key = temptup;
        !          1419:                                for (tmp = 0; keyx[tmp] != 0; tmp++)
        !          1420:                                {
        !          1421:                                        len = d->relfrml[keyx[tmp]] & I1MASK;
        !          1422:                                        bmove(&tuple[d->reloff[keyx[tmp]]], key, len);
        !          1423:                                        key += len;
        !          1424:                                }
        !          1425:                                key = temptup;
        !          1426:                        }
        !          1427:                        else
        !          1428:                                key = tuple;
        !          1429: 
        !          1430:                        if (keywid > space_left(&dirbuf))
        !          1431:                        {
        !          1432:                                if (pageflush(&dirbuf))
        !          1433:                                        return (-3);
        !          1434:                                dirbuf.thispage++;
        !          1435:                                newstop = dirbuf.thispage;
        !          1436:                                dirbuf.ovflopg = pageid;
        !          1437:                                dirbuf.linetab[0] = (short) (dirbuf.firstup - (char *) &dirbuf);
        !          1438:                                offset = dirbuf.linetab[0];
        !          1439:                                dirbuf.bufstatus = BUF_DIRTY;
        !          1440:                                dirbuf.nxtlino = 0;
        !          1441:                        }
        !          1442:                        /* copy key to directory page */
        !          1443:                        bmove(key, (char *) &dirbuf + offset, keywid);
        !          1444: 
        !          1445:                        /* update next line number */
        !          1446:                        offset += keywid;
        !          1447:                        dirbuf.nxtlino++;
        !          1448:                        dirbuf.linetab[-dirbuf.nxtlino] = offset;
        !          1449:                }
        !          1450:                if (pageflush(&dirbuf))
        !          1451:                        return (-4);
        !          1452:                if (newstart == newstop)
        !          1453:                        break;
        !          1454:                d->reldum.relspec = abs(d->reldum.relspec);
        !          1455:                level++;
        !          1456:                start = newstart;
        !          1457:                stop = newstop;
        !          1458:        }
        !          1459:        d->reldum.relspec = savespec;
        !          1460:        d->reldum.relprim = newstart;
        !          1461:        return (0);
        !          1462: }
        !          1463: /*
        !          1464: **     UNSPOOL -- Take tuples saved in spool file and insert them
        !          1465: **             in new relation.  This is only for ISAM relations.
        !          1466: */
        !          1467: 
        !          1468: unspool(sdesc, desc)
        !          1469: register DESC  *sdesc, *desc;
        !          1470: {
        !          1471:        register int    i, j;
        !          1472:        TID             tid, btid;
        !          1473:        char            tup_buf[MAXTUP], tup[2 * LIDSIZE];
        !          1474:        FILE            *spfp;
        !          1475:        long            lid[MAXLID], page, t;
        !          1476:        int             w;
        !          1477:        struct locator  tidpos;
        !          1478: 
        !          1479:        w = sdesc->reldum.relwid + desc->reldum.reldim * LIDSIZE;
        !          1480:        if (Mod_info.spflag)
        !          1481:        {
        !          1482:                if ((spfp = fopen(Mod_info.spfile, "r")) == NULL)
        !          1483:                        syserr("UNSPOOL: fopen spool");
        !          1484:                while ((i = fread(tup_buf, 1, w, spfp)) == w)
        !          1485:                {
        !          1486:                        if ((i = insert(desc, &tid, tup_buf, FALSE)) < 0)
        !          1487:                                syserr("UNSPOOL: insert %.14s %d", desc->reldum.relid, i);
        !          1488:                        if (NLidKeys > 0)
        !          1489:                        {
        !          1490:                                bmove(tup_buf + desc->reldum.relwid - LIDSIZE * desc->reldum.reldim, lid, LIDSIZE * desc->reldum.reldim);
        !          1491:                                page = RT;
        !          1492:                                for (j = 0; j < desc->reldum.reldim; ++j)
        !          1493:                                {
        !          1494:                                        if ((t = get_tid(page, lid[j], &tidpos)) < 0)
        !          1495:                                                syserr("get_tid error in unspool");
        !          1496:                                        page = t;
        !          1497:                                }
        !          1498:                                stuff_page(&btid, &tidpos.pageno);
        !          1499:                                btid.line_id = tidpos.page.node.leafnode.tid_loc[tidpos.offset];
        !          1500:                                replace_btree(tid, &btid);
        !          1501:                        }
        !          1502:                }
        !          1503:                if (i != 0)
        !          1504:                        syserr("UNSPOOL: read %d", i);
        !          1505:                fclose(spfp);
        !          1506:                unlink(Mod_info.spfile);
        !          1507:        }
        !          1508:        desc->reldum.reltups += desc->reladds;
        !          1509:        desc->reladds = 0;
        !          1510:        return (0);
        !          1511: }
        !          1512: /*
        !          1513: **     FILL_BATCH -- Create and fill a batch file containing the
        !          1514: **             updates for the system catalog so that MODIFY will
        !          1515: **             be recoverable if the system crashes.
        !          1516: */
        !          1517: 
        !          1518: fill_batch(odesc, desc)
        !          1519: DESC           *odesc;
        !          1520: register DESC  *desc;
        !          1521: {
        !          1522:        register DESC           *dessys;
        !          1523:        register int            i, k;
        !          1524:        struct relation         reltup, rkey;
        !          1525:        TID                     tid, lotid, hitid;
        !          1526:        struct attribute        atttup, akey;
        !          1527:        int                     numatts, j;
        !          1528:        char                    prebatch[MAXNAME + 4], modbatch[MAXNAME + 4];
        !          1529: 
        !          1530:        if (bequal(desc->reldum.relid, "relation    ", 12))
        !          1531:        {
        !          1532:                clearkeys(desc);
        !          1533:                setkey(desc, &rkey, desc->reldum.relid, RELID);
        !          1534:                setkey(desc, &rkey, desc->reldum.relowner, RELOWNER);
        !          1535:                if (i = getequal(desc, &rkey, &reltup, &tid))
        !          1536:                        syserr("FILL_BATCH: geteq rel rel %d", i);
        !          1537:                bmove(&tid, &desc->reltid, sizeof desc->reltid);
        !          1538:        }
        !          1539:        else
        !          1540:                bmove(&odesc->reltid, &desc->reltid, sizeof desc->reltid);
        !          1541:        resetacc(Acc_head);
        !          1542:        concat(MOD_PREBATCH, Fileset, prebatch);
        !          1543:        close(creat(prebatch, FILEMODE));
        !          1544:        if ((Batch_fp = open(prebatch, O_RDWR)) < 0)
        !          1545:                syserr("FILL_BATCH: open %.14s %d", prebatch, Batch_fp);
        !          1546:        smove(Fileset, Batchbuf.file_id);
        !          1547:        Batch_cnt = 0;
        !          1548:        wrbatch(desc, sizeof *desc);
        !          1549:        if (bequal(desc->reldum.relid, "attribute   ", 12))
        !          1550:                dessys = desc;
        !          1551:        else
        !          1552:                dessys = &Admin.adattd;
        !          1553:        clearkeys(dessys);
        !          1554:        setkey(dessys, &akey, desc->reldum.relid, ATTRELID);
        !          1555:        setkey(dessys, &akey, desc->reldum.relowner, ATTOWNER);
        !          1556:        if (i = find(dessys, EXACTKEY, &lotid, &hitid, &akey))
        !          1557:                syserr("FILL_BATCH: find %d", i);
        !          1558: 
        !          1559:        /* if ordered relation, one of attributes is LID field */
        !          1560:        numatts = j = desc->reldum.relatts - desc->reldum.reldim;
        !          1561: 
        !          1562:        while(!(i = get(dessys, &lotid, &hitid, &atttup, TRUE)) && j > 0)
        !          1563:                if (!kcompare(dessys, &akey, &atttup))
        !          1564:                        if (atttup.attid <= numatts)
        !          1565:                        {
        !          1566:                                j--;
        !          1567:                                atttup.attxtra = desc->relxtra[atttup.attid];
        !          1568:                                wrbatch(&lotid, sizeof lotid);
        !          1569:                                wrbatch(&atttup, sizeof atttup);
        !          1570:                        }
        !          1571:        for (k = 1; k <= desc->reldum.reldim; ++k)
        !          1572:        /* create new tuple corresponding to LID field; LID field is the
        !          1573:        ** last field of relation, a 4-byte integer 
        !          1574:        */
        !          1575:        {
        !          1576:                smove(desc->reldum.relid, atttup.attrelid);
        !          1577:                bmove(desc->reldum.relowner, atttup.attowner, 2);
        !          1578:                atttup.attid = numatts + k;
        !          1579:                smove(Lid[k - 1], atttup.attname);
        !          1580:                pad(atttup.attname, MAXNAME);
        !          1581:                atttup.attoff = desc->reldum.relwid - (desc->reldum.reldim - k + 1) * LIDSIZE;
        !          1582:                atttup.attfrmt = INT;
        !          1583:                atttup.attfrml = LIDSIZE;
        !          1584:                atttup.attxtra = 0;
        !          1585:                wrbatch(&atttup, sizeof atttup);
        !          1586:        }
        !          1587:        if (i < 0 || j > 0)
        !          1588:                syserr("FILL_BATCH: get att %d count %d", i, j);
        !          1589:        /* get rid of attribute pages */
        !          1590:        cleanrel(dessys);
        !          1591:        flushbatch();
        !          1592:        close(Batch_fp);
        !          1593:        concat(MODBATCH, Fileset, modbatch);
        !          1594:        if (link(prebatch, modbatch) == -1)
        !          1595:                syserr("FILL_BATCH: can't link %.14s %.14s",
        !          1596:                        prebatch, modbatch);
        !          1597:        unlink(prebatch);
        !          1598:        return (0);
        !          1599: 
        !          1600: }
        !          1601: 
        !          1602: /*
        !          1603: **     MAKE_BSEC -- Creates the seecondary btree relation by first creating
        !          1604: **             a heaped relation.  The main relation tids are found by
        !          1605: **             scanning the leaves of the btree.  The relation is then 
        !          1606: **             modified to an isam relation.
        !          1607: */     
        !          1608: 
        !          1609: make_bsec(relname, dim)
        !          1610: char *relname;
        !          1611: int dim;
        !          1612: {
        !          1613:        PARM            pv[8];
        !          1614:        register int    i;
        !          1615:        DESC            bdesc;
        !          1616:        TID             tid, btid;
        !          1617:        long            mtid, page, t, next;
        !          1618:        char            tuple[2 * LIDSIZE], btree[MAXNAME], btreefile[MAXNAME + 4];
        !          1619:        struct locator  tidpos;
        !          1620:        extern char     *iocv();
        !          1621:        extern DESC     Reldes;
        !          1622: 
        !          1623:        pv[0].pv_val.pv_str = "0000002";
        !          1624:        capital(trim_relname(relname), btree);
        !          1625:        pv[1].pv_val.pv_str = btree;
        !          1626:        pv[2].pv_val.pv_str = "mtid";
        !          1627:        pv[3].pv_val.pv_str = "i4";
        !          1628:        pv[4].pv_val.pv_str = "btid";
        !          1629:        pv[5].pv_val.pv_str = "i4";
        !          1630:        pv[6].pv_type = PV_EOF;
        !          1631:        if (create(6, pv))
        !          1632:                syserr("can't create btreesec %s", pv[1].pv_val.pv_str);
        !          1633:        
        !          1634:        if (noclose(&Reldes))
        !          1635:                syserr("noclose in make_bsec");
        !          1636: 
        !          1637:        if (i = openr(&bdesc, OR_WRITE, btree))
        !          1638:                syserr("opening bsec relation %d", i);
        !          1639:        btreename(relname, btreefile);
        !          1640:        if ((Btree_fd = open(btreefile, O_RDWR)) < 0)
        !          1641:                syserr("make_bsec: can't open %s", btreefile);
        !          1642:        page = RT;
        !          1643:        for (i = 0; i < dim - 1; ++i)
        !          1644:        {
        !          1645:                t = get_tid(page, 1, &tidpos);
        !          1646:                if (t < 0)
        !          1647:                        break;  /* lid value doesn't exist */
        !          1648:                bmove(&t, &page, LIDSIZE);
        !          1649:        }
        !          1650:        if (t >= 0)     /* only do inserts if there are lids! */
        !          1651:        {
        !          1652:                do
        !          1653:                {
        !          1654:                        get_node(page, &tidpos.page);
        !          1655:                        next = tidpos.page.nexttree;
        !          1656:                        get_tid(page, 1, &tidpos);
        !          1657:                        page = tidpos.pageno;
        !          1658:                        for (;;)
        !          1659:                        /* scan through leaves of btree */
        !          1660:                        {
        !          1661:                                stuff_page(&btid, &page);
        !          1662:                                for (i = 0; i < tidpos.page.nelmts; ++i)
        !          1663:                                {
        !          1664:                                        btid.line_id = tidpos.page.node.leafnode.tid_loc[i];
        !          1665:                                        mtid = tidpos.page.node.leafnode.tid_pos[btid.line_id];
        !          1666:                                        /* form tuple */
        !          1667:                                        bmove(&mtid, tuple, LIDSIZE);
        !          1668:                                        bmove(&btid, tuple + LIDSIZE, LIDSIZE);
        !          1669:                                        if (insert(&bdesc, &tid, tuple, TRUE) < 0)
        !          1670:                                                syserr("insert error in btreesec");
        !          1671:                                }
        !          1672:                                page = tidpos.page.node.leafnode.nextleaf;
        !          1673:                                if (page == NULL)
        !          1674:                                        break;
        !          1675:                                else 
        !          1676:                                        get_node(page, &tidpos.page);
        !          1677:                        }
        !          1678:                } while (page = next);
        !          1679:        }
        !          1680:        close(Btree_fd);
        !          1681:        closer(&bdesc);
        !          1682: 
        !          1683:        /* modify to isam on mtid */
        !          1684:        pv[0].pv_val.pv_str = btree;
        !          1685:        pv[1].pv_val.pv_str = "isam";
        !          1686:        pv[2].pv_val.pv_str = "name";
        !          1687:        pv[3].pv_val.pv_str = "mtid";
        !          1688:        pv[4].pv_val.pv_str = "\0";
        !          1689:        pv[5].pv_val.pv_str = "fillfactor";
        !          1690:        /* use fillfactor provided for main relation */
        !          1691:        if (F_fac == 0)
        !          1692:                pv[6].pv_val.pv_str = iocv(80);
        !          1693:        else
        !          1694:                pv[6].pv_val.pv_str = iocv(F_fac);
        !          1695:        pv[7].pv_type = PV_EOF;
        !          1696:        if (modify(7, pv))
        !          1697:                syserr("can't modify btreesec to isam");
        !          1698: }

unix.superglobalmegacorp.com

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