Annotation of 43BSD/ingres/source/dbu/modify.c, revision 1.1.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.