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

1.1     ! root        1: # include      <pv.h>
        !             2: # include      <ingres.h>
        !             3: # include      <access.h>
        !             4: # include      <aux.h>
        !             5: # include      <catalog.h>
        !             6: # include      <symbol.h>
        !             7: # include      <lock.h>
        !             8: # include      <func.h>
        !             9: # include      <sccs.h>
        !            10: 
        !            11: SCCSID(@(#)create.c    7.2     5/31/83)
        !            12: 
        !            13: extern short   tTdbu[];
        !            14: extern int     create();
        !            15: extern int     null_fn();
        !            16: 
        !            17: struct fn_def CreateFn =
        !            18: {
        !            19:        "CREATE",
        !            20:        create,
        !            21:        null_fn,
        !            22:        null_fn,
        !            23:        NULL,
        !            24:        0,
        !            25:        tTdbu,
        !            26:        100,
        !            27:        'Z',
        !            28:        0
        !            29: };
        !            30: 
        !            31: /*
        !            32: **  CREATE -- create new relation
        !            33: **
        !            34: **     This module creates a brand new relation in the current
        !            35: **     directory (database).  The relation is always created as
        !            36: **     a paged heap.  It may not redefine an existing relation,
        !            37: **     or rename a system catalog.
        !            38: **
        !            39: **     Trace Flags:
        !            40: **             31
        !            41: */
        !            42: 
        !            43: 
        !            44: struct domain
        !            45: {
        !            46:        char    *name;
        !            47:        char    frmt;
        !            48:        char    frml;
        !            49: };
        !            50: 
        !            51: /*
        !            52: **  CREATE -- create new relation
        !            53: **
        !            54: **     This routine is the driver for the create module.
        !            55: **
        !            56: **     Parameters:
        !            57: **             pc -- parameter count
        !            58: **             pv -- parameter vector:
        !            59: **                     0 -- relation status (relstat) -- stored into
        !            60: **                             the 'relstat' field in the relation
        !            61: **                             relation, and used to determine the
        !            62: **                             caller.  Interesting bits are:
        !            63: **
        !            64: **                             S_INDEX -- means called by the index
        !            65: **                                     processor.  If set, the 'relindxd'
        !            66: **                                     field will also be set to -1
        !            67: **                                     (SECINDEX) to indicate that this
        !            68: **                                     relation is a secondary index.
        !            69: **                             S_CATALOG -- this is a system catalog.
        !            70: **                                     If set, this create was called
        !            71: **                                     from creatdb, and the physical
        !            72: **                                     file is not created.  Also, the
        !            73: **                                     expiration date is set infinite.
        !            74: **                             S_VIEW -- this is a view.  Create has
        !            75: **                                     been called by the 'define'
        !            76: **                                     statement, rather than the
        !            77: **                                     'create' statement.  The physical
        !            78: **                                     file is not created.
        !            79: **
        !            80: **                     1 -- relation name.
        !            81: **                     2 -- attname1
        !            82: **                     3 -- format1
        !            83: **                     4, etc -- attname, format pairs.
        !            84: **
        !            85: **     Returns:
        !            86: **             zero -- successful create.
        !            87: **             else -- failure somewhere.
        !            88: **
        !            89: **     Side Effects:
        !            90: **             A relation is created (this is a side effect?).  This
        !            91: **             means entries in the 'relation' and 'attribute' cata-
        !            92: **             logs, and (probably) a physical file somewhere, with
        !            93: **             one page already in it.
        !            94: **
        !            95: **     Trace Flags:
        !            96: **             31
        !            97: */
        !            98: 
        !            99: create(pc, pv)
        !           100: int    pc;
        !           101: PARM   pv[];
        !           102: {
        !           103:        register PARM           *pp;
        !           104:        register int            i;
        !           105:        int                     bad;
        !           106:        struct domain           domain[MAXDOM];
        !           107:        struct domain           *dom;
        !           108:        char                    *relname, tempname[MAXNAME+3];
        !           109:        struct tup_id           tid;
        !           110:        struct relation         rel, key;
        !           111:        struct attribute        att;
        !           112:        DESC                    desr;
        !           113:        extern char             *Usercode;
        !           114:        extern DESC             Reldes, Attdes;
        !           115:        extern int              errno;
        !           116:        register int            relstat;
        !           117:        long                    temptid;
        !           118:        long                    npages;
        !           119:        int                     fdes;
        !           120:        bool                    internal;
        !           121: 
        !           122: #      ifdef xZTR1
        !           123:        if (tTf(31, -1))
        !           124:        {
        !           125:                printf("creating %s\n", pv[1].pv_val.pv_str);
        !           126:        }
        !           127: #      endif
        !           128:        pp = pv;
        !           129:        relstat = oatoi(pp[0].pv_val.pv_str);
        !           130:        /*
        !           131:        **      If this database has query modification, then default
        !           132:        **      to denial on all user relations.
        !           133:        **      (Since views cannot be protected, this doesn't apply to them)
        !           134:        */
        !           135:        if ((Admin.adhdr.adflags & A_QRYMOD) && ((relstat & (S_VIEW || S_CATALOG)) == 0))
        !           136:                relstat |= (S_PROTALL | S_PROTRET);
        !           137:        relname = (++pp)->pv_val.pv_str;
        !           138:        internal = bequal(relname, "_SYS", 4);
        !           139:        ingresname(relname, Usercode, rel.relid);
        !           140:        bmove(rel.relid, att.attrelid, MAXNAME + 2);
        !           141:        opencatalog("relation", 2);
        !           142: 
        !           143:        /* check for duplicate relation name */
        !           144:        if ((relstat & S_CATALOG) == 0)
        !           145:        {
        !           146:                if (openr(&desr, -1, relname) == 0)
        !           147:                {
        !           148:                        if (bequal(desr.reldum.relowner, rel.relowner, 2))
        !           149:                        {
        !           150:                                return (error(5102, relname, 0));       /* bad relname */
        !           151:                        }
        !           152:                        if (desr.reldum.relstat & S_CATALOG)
        !           153:                        {
        !           154:                                return (error(5103, relname, 0));       /* attempt to rename system catalog */
        !           155:                        }
        !           156:                }
        !           157:        }
        !           158:        opencatalog("attribute", 2);
        !           159: 
        !           160:        /* initialize structures for system catalogs */
        !           161:        initstructs(&att, &rel);
        !           162:        rel.relstat = relstat;
        !           163:        if ((relstat & S_CATALOG) != 0)
        !           164:                rel.relsave = 0;
        !           165:        else if ((relstat & S_INDEX) != 0)
        !           166:                rel.relindxd = SECINDEX;
        !           167:        
        !           168: #      ifdef xZTR3
        !           169:        if (tTf(31, 2))
        !           170:        {
        !           171:                printf("\nrel->relprim = %D\n", rel.relprim);
        !           172:                printup(&Reldes, &rel);
        !           173:        }
        !           174: #      endif
        !           175: 
        !           176:        /* check attributes */
        !           177:        pp++;
        !           178:        for (i = pc - 2; i > 0; i -= 2)
        !           179:        {
        !           180:                bad = chk_att(&rel, pp[0].pv_val.pv_str, pp[1].pv_val.pv_str, domain, internal);
        !           181:                if (bad != 0)
        !           182:                {
        !           183:                        return (error(bad, relname, pp[0].pv_val.pv_str, pp[1].pv_val.pv_str, 0));
        !           184:                }
        !           185:                pp += 2;
        !           186:        }
        !           187: 
        !           188:        /*
        !           189:        ** Create files if appropriate. Concurrency control for
        !           190:        ** the create depends on the actual file. To prevent
        !           191:        ** to users with the same usercode from creating the
        !           192:        ** same relation at the same time, their is check
        !           193:        ** on the existence of the file. The important events are
        !           194:        ** (1) if a tuple exists in the relation relation then
        !           195:        ** the relation really exists. (2) if the file exists then
        !           196:        ** the relation is being created but will not exist for
        !           197:        ** use until the relation relation tuple is present.
        !           198:        ** For VIEWS, the file is used for concurrency control
        !           199:        ** during the create but is removed afterwards.
        !           200:        */
        !           201:        if ((relstat & S_CATALOG) == 0)
        !           202:        {
        !           203:                /* for non system named temporary relations
        !           204:                ** set a critical section lock while checking the
        !           205:                ** existence of a file.  If it exists, error return(5102)
        !           206:                ** else create file.
        !           207:                */
        !           208:                temptid = 0;
        !           209:                if (Lockrel && (!bequal(rel.relid,"_SYS",4)))
        !           210:                {
        !           211:                        temptid = -1;
        !           212:                        setcsl(temptid);        /* set critical section lock */
        !           213:                        if ((fdes = open(rel.relid,0)) >= 0)
        !           214:                        {
        !           215:                                                /* file already exists */
        !           216:                                close(fdes);
        !           217:                                unlcs(temptid); /* release critical section lock */
        !           218:                                return (error(5102, relname, 0));
        !           219:                        }
        !           220:                        errno = 0;      /* file doesn't exist */
        !           221:                }
        !           222:                ingresname(rel.relid, rel.relowner, tempname);
        !           223:                desr.relfp = creat(tempname, FILEMODE);
        !           224:                if (temptid != 0)
        !           225:                        unlcs(temptid); /* release critical section lock */
        !           226:                if (desr.relfp < 0)
        !           227:                        syserr("create: creat %s", rel.relid);
        !           228:                desr.reltid.ltid = -1L; /* init reltid to unused */
        !           229:                if ((relstat & S_VIEW) == 0)
        !           230:                {
        !           231:                        npages = 1;
        !           232:                        if (i = formatpg(&desr, npages))
        !           233:                                syserr("create: formatpg %d", i);
        !           234:                }
        !           235: 
        !           236:                close(desr.relfp);
        !           237:        }
        !           238: 
        !           239:        /* insert attributes into attribute relation */
        !           240:        pp = pv + 2;
        !           241:        dom = domain;
        !           242:        for (i = pc - 2; i > 0; i -= 2)
        !           243:        {
        !           244:                ins_att(&Attdes, &att, dom++);
        !           245:                pp += 2;
        !           246:        }
        !           247: 
        !           248:        /*
        !           249:        ** Flush the attributes. This is necessary for recovery reasons.
        !           250:        ** If for some reason the relation relation is flushed and the
        !           251:        ** machine crashes before the attributes are flushed, then recovery
        !           252:        ** will not detect the error.
        !           253:        ** The call below cannot be a "noclose" without major changes to
        !           254:        ** creatdb.
        !           255:        */
        !           256:        if (i = pageflush(0))
        !           257:                syserr("create:flush att %d", i);
        !           258: 
        !           259:        if (i = insert(&Reldes, &tid, &rel, FALSE))
        !           260:                syserr("create: insert(rel, %.14s) %d", rel.relid, i);
        !           261: 
        !           262:        if (relstat & S_VIEW)
        !           263:                unlink(tempname);
        !           264:        return (0);
        !           265: }
        !           266: 
        !           267: 
        !           268: 
        !           269: /*
        !           270: **  CHK_ATT -- check attribute for validity
        !           271: **
        !           272: **     The attribute is checked to see if
        !           273: **     * it's name is ok (within MAXNAME bytes)
        !           274: **     * it is not a duplicate name
        !           275: **     * the format specified is legal
        !           276: **     * there are not a ridiculous number of attributes
        !           277: **       (ridiculous being defined as anything over MAXDOM - 1)
        !           278: **     * the tuple is not too wide to fit on one page
        !           279: **
        !           280: **     Parameters:
        !           281: **             rel -- relation relation tuple for this relation.
        !           282: **             attname -- tentative name of attribute.
        !           283: **             format -- tentative format for attribute.
        !           284: **             domain -- a 'struct domain' used to determine dupli-
        !           285: **                     cation, and to store the resulting name and
        !           286: **                     format in.
        !           287: **
        !           288: **     Returns:
        !           289: **             zero -- OK
        !           290: **             5104 -- bad attribute name.
        !           291: **             5105 -- duplicate attribute name.
        !           292: **             5106 -- bad attribute format.
        !           293: **             5107 -- too many attributes.
        !           294: **             5108 -- tuple too wide.
        !           295: **
        !           296: **     Side Effects:
        !           297: **             'rel' has the relatts and relwid fields updated to
        !           298: **             reflect the new attribute.
        !           299: **
        !           300: **     Trace Flags:
        !           301: **             31
        !           302: */
        !           303: 
        !           304: chk_att(rel, attname, format, domain, internal)
        !           305: struct relation        *rel;
        !           306: char           *attname, *format;
        !           307: struct domain  domain[];
        !           308: bool           internal;
        !           309: {
        !           310:        register int                    i;
        !           311:        register struct relation        *r;
        !           312: 
        !           313:        r = rel;
        !           314: 
        !           315: #      ifdef xZTR3
        !           316:        if (tTf(31, 1))
        !           317:                printf("chk_att %s %s\n", attname, format);
        !           318: #      endif
        !           319: 
        !           320:        if (sequal(attname, "tid"))
        !           321:                return (5104);          /* bad attribute name */
        !           322:        if ((i = dup_att(attname, r->relatts, domain)) < 0)
        !           323:                return (5105);          /* duplicate attribute */
        !           324:        if (formck(format, &domain[i], internal))
        !           325:                return (5106);          /* bad attribute format */
        !           326:        r->relatts++;
        !           327:        r->relwid += domain[i].frml & 0377;
        !           328:        if (r->relatts >= MAXDOM)
        !           329:                return (5107);          /* too many attributes */
        !           330:        if (r->relwid > MAXTUP && (r->relstat & S_VIEW) == 0)
        !           331:                return (5108);          /* tuple too wide */
        !           332:        return (0);
        !           333: }
        !           334: 
        !           335: 
        !           336: 
        !           337: 
        !           338: /*
        !           339: **  INS_ATT -- insert attribute into attribute relation
        !           340: **
        !           341: **     Parameters:
        !           342: **             des -- relation descriptor for the attribute catalog.
        !           343: **             att -- attribute tuple, preinitialized with all sorts
        !           344: **                     of good stuff (everything except 'attname',
        !           345: **                     'attfrmt', and 'attfrml'; 'attid' and 'attoff'
        !           346: **                     must be initialized to zero before this routine
        !           347: **                     is called the first time.
        !           348: **             dom -- 'struct domain' -- the information needed about
        !           349: **                     each domain.
        !           350: **
        !           351: **     Returns:
        !           352: **             none
        !           353: **
        !           354: **     Side Effects:
        !           355: **             The 'att' tuple is updated in the obvious ways.
        !           356: **             A tuple is added to the 'attribute' catalog.
        !           357: **
        !           358: **     Trace Flags:
        !           359: **             none currently
        !           360: */
        !           361: 
        !           362: ins_att(des, att, dom)
        !           363: DESC                   *des;
        !           364: struct attribute       *att;
        !           365: struct domain          *dom;
        !           366: {
        !           367:        register int            i;
        !           368:        struct tup_id           tid;
        !           369:        register struct domain  *d;
        !           370: 
        !           371:        d = dom;
        !           372: 
        !           373:        pmove(d->name, att->attname, MAXNAME, ' ');
        !           374:        att->attfrmt = d->frmt;
        !           375:        att->attfrml = d->frml;
        !           376:        att->attid++;
        !           377:        if (insert(des, &tid, att, FALSE))
        !           378:                syserr("ins_att: insert(att, %s)", d->name);
        !           379:        att->attoff += att->attfrml & 0377;
        !           380: }
        !           381: 
        !           382: 
        !           383: 
        !           384: 
        !           385: /*
        !           386: **  DUP_ATT -- check for duplicate attribute
        !           387: **
        !           388: **     The attribute named 'name' is inserted into the 'attalias'
        !           389: **     vector at position 'count'.  'Count' should be the count
        !           390: **     of existing entries in 'attalias'.  'Attalias' is checked
        !           391: **     to see that 'name' is not already present.
        !           392: **
        !           393: **     Parameters:
        !           394: **             name -- the name of the attribute.
        !           395: **             count -- the count of attributes so far.
        !           396: **             domain -- 'struct domain' -- the list of domains
        !           397: **                     so far, names and types.
        !           398: **
        !           399: **     Returns:
        !           400: **             -1 -- attribute name is a duplicate.
        !           401: **             else -- index in 'domain' for this attribute (also
        !           402: **                     the attid).
        !           403: **
        !           404: **     Side Effects:
        !           405: **             The 'domain' vector is extended.
        !           406: **
        !           407: **     Trace Flags:
        !           408: **             none
        !           409: */
        !           410: 
        !           411: dup_att(name, count, domain)
        !           412: char           *name;
        !           413: int            count;
        !           414: struct domain  domain[];
        !           415: {
        !           416:        register struct domain  *d;
        !           417:        register int            lim;
        !           418:        register int            i;
        !           419: 
        !           420:        lim = count;
        !           421:        d = domain;
        !           422: 
        !           423:        for (i = 0; i < lim; i++)
        !           424:                if (sequal(name, d++->name))
        !           425:                        return (-1);
        !           426:        if (count < MAXDOM)
        !           427:                d->name = name;
        !           428:        return (i);
        !           429: }
        !           430: 
        !           431: 
        !           432: 
        !           433: 
        !           434: /*
        !           435: **  INITSTRUCTS -- initialize relation and attribute tuples
        !           436: **
        !           437: **     Structures containing images of 'relation' relation and
        !           438: **     'attribute' relation tuples are initialized with all the
        !           439: **     information initially needed to do the create.  Frankly,
        !           440: **     the only interesting part is the the expiration date
        !           441: **     computation; longconst(9, 14976) is exactly the number
        !           442: **     of seconds in one week.
        !           443: **
        !           444: **     Parameters:
        !           445: **             att -- attribute relation tuple.
        !           446: **             rel -- relation relation tuple.
        !           447: **
        !           448: **     Returns:
        !           449: **             none
        !           450: **
        !           451: **     Side Effects:
        !           452: **             'att' and 'rel' are initialized.
        !           453: **
        !           454: **     Requires:
        !           455: **             time -- to get the current date.
        !           456: **
        !           457: **     Called By:
        !           458: **             create
        !           459: **
        !           460: **     Trace Flags:
        !           461: **             none
        !           462: **
        !           463: **     Diagnostics:
        !           464: **             none
        !           465: **
        !           466: **     Syserrs:
        !           467: **             none
        !           468: **
        !           469: **     History:
        !           470: **             2/27/78 (eric) -- documented.
        !           471: */
        !           472: 
        !           473: initstructs(att, rel)
        !           474: register struct attribute      *att;
        !           475: register struct relation       *rel;
        !           476: {
        !           477:        /* setup expiration date (today + one week) */
        !           478:        time(&rel->relstamp);
        !           479:        rel->relsave = rel->relstamp + 604800L;
        !           480:        rel->relfree = 0;
        !           481:        rel->reltups = 0;
        !           482:        rel->relatts = 0;
        !           483:        rel->relwid = 0;
        !           484:        rel->relprim = 1;
        !           485:        rel->relspec = M_HEAP;
        !           486:        rel->relindxd = 0;
        !           487:        att->attxtra = 0;
        !           488:        att->attid = 0;
        !           489:        att->attoff = 0;
        !           490: }
        !           491: 
        !           492: 
        !           493: 
        !           494: /*
        !           495: **  CHECK ATTRIBUTE FORMAT AND CONVERT
        !           496: **
        !           497: **     The string 'a' is checked for a valid attribute format
        !           498: **     and is converted to internal form.
        !           499: **
        !           500: **     zero is returned if the format is good; one is returned
        !           501: **     if it is bad.  If it is bad, the conversion into a is not
        !           502: **     made.
        !           503: **
        !           504: **     A format of CHAR can be length zero only if this
        !           505: **     create was generated internally.
        !           506: */
        !           507: 
        !           508: formck(a, dom, internal)
        !           509: char           *a;
        !           510: struct domain  *dom;
        !           511: bool           internal;
        !           512: {
        !           513:        int                     len;
        !           514:        register int            i;
        !           515:        char                    c;
        !           516:        register char           *p;
        !           517:        register struct domain  *d;
        !           518: 
        !           519:        p = a;
        !           520:        c = *p++;
        !           521:        d = dom;
        !           522: 
        !           523:        len = atoi(p);
        !           524:        i = len;
        !           525: 
        !           526:        switch (c)
        !           527:        {
        !           528: 
        !           529:          case INT:
        !           530:                if (i == 1 || i == 2 || i == 4)
        !           531:                {
        !           532:                        d->frmt = INT;
        !           533:                        d->frml = i;
        !           534:                        return (0);
        !           535:                }
        !           536:                return (1);
        !           537: 
        !           538:          case FLOAT:
        !           539:                if (i == 4 || i == 8)
        !           540:                {
        !           541:                        d->frmt = FLOAT;
        !           542:                        d->frml = i;
        !           543:                        return (0);
        !           544:                }
        !           545:                return (1);
        !           546: 
        !           547:          /* note: should disallow c0 from user (but needed internally) */
        !           548:          case CHAR:
        !           549:                if (i > 255 || i < 0 || (i == 0 && !internal))
        !           550:                        return (1);
        !           551:                d->frmt = CHAR;
        !           552:                d->frml = i;
        !           553:                return (0);
        !           554:        }
        !           555:        return (1);
        !           556: 
        !           557: }

unix.superglobalmegacorp.com

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