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

unix.superglobalmegacorp.com

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