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