Annotation of 43BSD/ingres/source/ovqp/strategy.c, revision 1.1

1.1     ! root        1: # include      <ingres.h>
        !             2: # include      <aux.h>
        !             3: # include      <catalog.h>
        !             4: # include      <symbol.h>
        !             5: # include      <tree.h>
        !             6: # include      "../decomp/globs.h"
        !             7: # include      "strategy.h"
        !             8: # include      <btree.h>
        !             9: # include      <sccs.h>
        !            10: # include      <errors.h>
        !            11: 
        !            12: SCCSID(@(#)strategy.c  8.4     2/8/85)
        !            13: 
        !            14: /*
        !            15: ** STRATEGY
        !            16: **
        !            17: **     Attempts to limit access scan to less than the entire De.ov_source
        !            18: **     relation by finding a key which can be used for associative
        !            19: **     access to the De.ov_source reln or an index thereon.  The key is
        !            20: **     constructed from domain-value specifications found in the
        !            21: **     clauses of the qualification list using sub-routine findsimp
        !            22: **     in findsimp.c and other subroutines in file key.c
        !            23: */
        !            24: 
        !            25: strategy()
        !            26: {
        !            27:        register int            i, j, allexact;
        !            28:        struct accessparam      sourceparm, indexparm;
        !            29:        struct index            itup, rtup;
        !            30:        struct key              lowikey[MAXKEYS+1], highikey[MAXKEYS+1];
        !            31:        struct key              lowbkey[MAXKEYS+1], highbkey[MAXKEYS+1];
        !            32:        register DESC           *d;
        !            33:        DESC                    *openindex();
        !            34:        extern DESC             Inddes;
        !            35:        char                    *tp;
        !            36:        long                    l_lid[MAXLID], h_lid[MAXLID];
        !            37:        int                     keytype;
        !            38:        long                    last_lid();
        !            39:        long                    page, l, t;
        !            40:        int                     lidsize;
        !            41:        struct locator          tidloc;
        !            42:        extern int              Btree_fd;
        !            43: 
        !            44: #      ifdef xOTR1
        !            45:        if (tTf(70, 0))
        !            46:                printf("STRATEGY\tSource=%.12s\tNewq = %d\n",
        !            47:                       De.ov_source ? De.ov_source->reldum.relid : "(none)",
        !            48:                       De.de_newq);
        !            49: #      endif
        !            50: 
        !            51:        while (De.de_newq)      /* if De.de_newq=TRUE then compute a new strategy */
        !            52:                        /* NOTE: This while loop is executed only once */
        !            53:        {
        !            54:                De.ov_scanr = De.ov_source;
        !            55:        
        !            56:                if (!De.ov_scanr)
        !            57:                        return (1);     /* return immediately if there is no source relation */
        !            58:        
        !            59:                De.ov_fmode = NOKEY;    /* assume a find mode with no key */
        !            60:        
        !            61:                if (!De.ov_qlist)
        !            62:                        break;  /* if no qualification then you must scan entire rel */
        !            63:                /*
        !            64:                ** Here we check for the special condition
        !            65:                ** of a where clause consisting only of a tid.
        !            66:                */
        !            67:                if (tid_only_test())
        !            68:                        return(1);
        !            69: 
        !            70:                /* copy structure of source relation into sourceparm */
        !            71:                paramd(De.ov_source, &sourceparm);
        !            72:        
        !            73:                /* if source is unkeyed and has no sec index then give up */
        !            74:                if (sourceparm.mode == NOKEY && De.ov_source->reldum.relindxd <= 0 && !De.ov_source->reldum.reldim)
        !            75:                        break;
        !            76: 
        !            77:                /* find all simple clauses if any */
        !            78:                if (!findsimps())
        !            79:                        break;  /* break if there are no simple clauses */
        !            80:        
        !            81:                /* Four steps are now performed to try and find a key.
        !            82:                ** First if the relation is hashed then an exact key is search for
        !            83:                **
        !            84:                ** Second if there are secondary indexes, then a search is made
        !            85:                ** for an exact key. If that fails then a  check is made for
        !            86:                ** a range key. The result of the rangekey check is saved.
        !            87:                **
        !            88:                ** A step to check for possible use of Btrees is made here,
        !            89:                ** although in actuality, an exact btreekey search is used
        !            90:                ** after an exact range key search but before a range key search.
        !            91:                ** A BTree range search is used only as a last alternative
        !            92:                ** to a no key search.
        !            93:                **
        !            94:                ** Third if the relation is an ISAM a check is  made for
        !            95:                ** an exact key or a range key.
        !            96:                **
        !            97:                ** Fourth if there is a secondary index, then if step two
        !            98:                ** found a key, that key is used.
        !            99:                **
        !           100:                **  Lastly, give up and scan the  entire relation
        !           101:                */
        !           102:        
        !           103:                /* step one. Try to find exact key on primary */
        !           104:                if (exactkey(&sourceparm, De.ov_lkey_struct))
        !           105:                {
        !           106:                        De.ov_fmode = EXACTKEY;
        !           107:                        break;
        !           108:                }
        !           109:        
        !           110:                /* step two. If there is an index, try to find an exactkey on one of them */
        !           111:                if (De.ov_source->reldum.relindxd > 0)
        !           112:                {
        !           113:        
        !           114:                        opencatalog("indexes", OR_READ);
        !           115:                        setkey(&Inddes, &itup, De.ov_source->reldum.relid, IRELIDP);
        !           116:                        setkey(&Inddes, &itup, De.ov_source->reldum.relowner, IOWNERP);
        !           117:                        if (i = find(&Inddes, EXACTKEY, &De.ov_lotid, &De.ov_hitid, (char *)&itup))
        !           118:                                syserr("strategy:find indexes %d", i);
        !           119:        
        !           120:                        while (!(i = get(&Inddes, &De.ov_lotid, &De.ov_hitid, (char *)&itup, NXTTUP)))
        !           121:                        {
        !           122: #                              ifdef xOTR1
        !           123:                                if (tTf(70, 3))
        !           124:                                        printup(&Inddes, (char *)&itup);
        !           125: #                              endif
        !           126:                                if (!bequal(itup.irelidp, De.ov_source->reldum.relid, MAXNAME) ||
        !           127:                                    !bequal(itup.iownerp, De.ov_source->reldum.relowner, 2))
        !           128:                                        continue;
        !           129:                                parami(&itup, &indexparm);
        !           130:                                if (exactkey(&indexparm, De.ov_lkey_struct))
        !           131:                                {
        !           132:                                        De.ov_fmode = EXACTKEY;
        !           133:                                        d = openindex(itup.irelidi);
        !           134:                                        /* temp check for 6.0 index */
        !           135:                                        if ((int) d->reldum.relindxd == -1)
        !           136:                                                ov_err(BADSECINDX);
        !           137:                                        De.ov_scanr = d;
        !           138:                                        break;
        !           139:                                }
        !           140:                                if (De.ov_fmode == LRANGEKEY)
        !           141:                                        continue;       /* a range key on a s.i. has already been found */
        !           142:                                if (allexact = rangekey(&indexparm, lowikey, highikey))
        !           143:                                {
        !           144:                                        bmove((char *)&itup, (char *)&rtup, sizeof itup);       /* save tuple */
        !           145:                                        De.ov_fmode = LRANGEKEY;
        !           146:                                }
        !           147:                        }
        !           148:                        if (i < 0)
        !           149:                                syserr("stragery:bad get from index-rel %d", i);
        !           150:                        /* If an exactkey on a secondary index was found, look no more. */
        !           151:                        if (De.ov_fmode == EXACTKEY)
        !           152:                                break;
        !           153:                }
        !           154:        
        !           155:                /* attempt to use Btree in aiding search */
        !           156:                if (i = btreekey(lowbkey, highbkey))
        !           157:                {
        !           158:                        if (i > 0)
        !           159:                                De.ov_fmode = BTREEKEY; 
        !           160:                        else if (De.ov_fmode != LRANGEKEY)
        !           161:                        /* use range key search over btree range search */
        !           162:                        {
        !           163:                                keytype = i;
        !           164:                                De.ov_fmode = BTREERANGE;
        !           165:                        }
        !           166:                }
        !           167: 
        !           168:                /* step three. Look for a range key on primary */
        !           169:                if (i = rangekey(&sourceparm, De.ov_lkey_struct, De.ov_hkey_struct))
        !           170:                {
        !           171:                        if (i < 0)
        !           172:                                De.ov_fmode = EXACTKEY;
        !           173:                        else if (De.ov_fmode == BTREEKEY)
        !           174:                        /* use exact btree search over range search */
        !           175:                        {
        !           176:                                bmove((char *) lowbkey, (char *) De.ov_lkey_struct, sizeof lowbkey);
        !           177:                                bmove((char *) highbkey, (char *) De.ov_hkey_struct, sizeof highbkey);
        !           178:                        }
        !           179:                        else
        !           180:                                De.ov_fmode = LRANGEKEY;
        !           181:                        break;
        !           182:                }
        !           183: 
        !           184:                if (De.ov_fmode == BTREEKEY)
        !           185:                {
        !           186:                        bmove((char *) lowbkey, (char *) De.ov_lkey_struct, sizeof lowbkey);
        !           187:                        bmove((char *) highbkey, (char *) De.ov_hkey_struct, sizeof highbkey);
        !           188:                        break;
        !           189:                }
        !           190:        
        !           191:                /* last step. If a secondary index range key was found, use it */
        !           192:                if (De.ov_fmode == LRANGEKEY)
        !           193:                {
        !           194:                        if (allexact < 0)
        !           195:                                De.ov_fmode = EXACTKEY;
        !           196:                        d = openindex(rtup.irelidi);
        !           197:                        /* temp check for 6.0 index */
        !           198:                        if ((int) d->reldum.relindxd == -1)
        !           199:                                ov_err(BADSECINDX);
        !           200:                        De.ov_scanr = d;
        !           201:                        bmove((char *)lowikey, (char *)De.ov_lkey_struct, sizeof lowikey);
        !           202:                        bmove((char *)highikey, (char *)De.ov_hkey_struct, sizeof highikey);
        !           203:                        break;
        !           204:                }
        !           205: 
        !           206:                /* nothing will work. give up! */
        !           207:                break;
        !           208:        
        !           209:        }
        !           210: 
        !           211:        /* check for De.de_newq = FALSE and no source relation */
        !           212:        if (!De.ov_scanr)
        !           213:                return (1);
        !           214:        /*
        !           215:        ** At this point the strategy is determined.
        !           216:        **
        !           217:        ** If De.ov_fmode is EXACTKEY then De.ov_lkey_struct contains
        !           218:        ** the pointers to the keys.
        !           219:        **
        !           220:        ** If De.ov_fmode is LRANGEKEY then De.ov_lkey_struct contains
        !           221:        ** the pointers to the low keys and De.ov_hkey_struct
        !           222:        ** contains pointers to the high keys.
        !           223:        **
        !           224:        ** If De.ov_fmode is BTREEKEY then De.ov_lkey_struct contains
        !           225:        ** pointers to the key lid.
        !           226:        **
        !           227:        ** If De.ov_fmode is BTREERANGE then lowbkey contains pointers
        !           228:        ** to the low key lid and highbkey contains pointers to the
        !           229:        ** high key lid.
        !           230:        **
        !           231:        ** If De.ov_fmode is NOKEY, then a full scan will be performed
        !           232:        */
        !           233: #      ifdef xOTR1
        !           234:        if (tTf(70, -1))
        !           235:                printf("De.ov_fmode= %d\n",De.ov_fmode);
        !           236: #      endif
        !           237: 
        !           238:        if (De.ov_fmode == BTREERANGE)
        !           239:        /* requires special type of search to limit tid scan */
        !           240:        {
        !           241:                for (i = 0; i < De.ov_scanr->reldum.reldim; ++i)
        !           242:                {
        !           243:                        l_lid[i] = 0;
        !           244:                        h_lid[i] = 0;
        !           245:                }
        !           246:                lidsize = LIDSIZE * De.ov_scanr->reldum.reldim;
        !           247:                /* get low lids */
        !           248:                if (keytype == -1 || keytype == -3)
        !           249:                {
        !           250:                        tp = De.ov_keyl + De.ov_scanr->reldum.relwid - lidsize;
        !           251:                        bmove(l_lid, tp, lidsize);
        !           252:                        setallkey(lowbkey, De.ov_keyl);
        !           253:                        bmove(tp, l_lid, lidsize);
        !           254:                }
        !           255:                /* get high lids */
        !           256:                if (keytype == -2 || keytype == -3)
        !           257:                {
        !           258:                        tp = De.ov_keyh + De.ov_scanr->reldum.relwid - lidsize;
        !           259:                        bmove(h_lid, tp, lidsize);
        !           260:                        setallkey(highbkey, De.ov_keyh);
        !           261:                        bmove(tp, h_lid, lidsize);
        !           262:                }
        !           263:                Btree_fd = De.ov_scanr->btree_fd;
        !           264:                /* scan through lids to fill in unprovided lids and to check
        !           265:                ** for lids that are too big
        !           266:                */
        !           267:                page = RT;
        !           268:                for (i = 0; i < De.ov_scanr->reldum.reldim; ++i)
        !           269:                {
        !           270:                        if (l_lid[i] <= 0) 
        !           271:                                l_lid[i] = 1;
        !           272:                        l = last_lid(page) - 1;
        !           273:                        if (h_lid < 0)
        !           274:                                return(0);
        !           275:                        if (!h_lid[i] || h_lid[i] > l)
        !           276:                                h_lid[i] = l;
        !           277:                        if ((t = get_tid(page, h_lid[i], &tidloc)) < 0)
        !           278:                                syserr("bad gettid in strategy, lid = %ld\n", h_lid[i]);
        !           279:                        page = t;
        !           280:                }
        !           281:                /* check whether lo > hi */
        !           282:                for (i = 0; i < De.ov_scanr->reldum.reldim; ++i)
        !           283:                        if (l_lid[i] < h_lid[i])
        !           284:                                break;
        !           285:                        else if (l_lid[i] > h_lid[i])
        !           286:                                return(0);
        !           287: #              ifdef xOTR1
        !           288:                if (tTf(70,0))
        !           289:                        for (i = 0 ; i < De.ov_scanr->reldum.reldim; ++i)
        !           290:                                printf("hi = %ld, lo = %ld\n", h_lid[i], l_lid[i]);
        !           291: #              endif
        !           292:                /* find the smallest and largest possible tids of the lids
        !           293:                ** within the provided range */
        !           294:                btreerange(De.ov_scanr, l_lid, h_lid, &De.ov_lotid, &De.ov_hitid);
        !           295:        }
        !           296:        else
        !           297:        {
        !           298:                /* set up the key tuples */
        !           299:                if (De.ov_fmode != NOKEY)
        !           300:                {
        !           301:                        if (setallkey(De.ov_lkey_struct, De.ov_keyl))
        !           302:                                return (0);     /* query false. There is a simple
        !           303:                                                ** clause which can never be satisfied.
        !           304:                                                ** These simple clauses can be choosey!
        !           305:                                                */
        !           306:                }
        !           307:        
        !           308:                if (i = find(De.ov_scanr, De.ov_fmode, &De.ov_lotid, &De.ov_hitid, De.ov_keyl))
        !           309:                        syserr("strategy:find1 %.12s, %d", De.ov_scanr->reldum.relid, i);
        !           310: 
        !           311:                if (De.ov_fmode == LRANGEKEY)
        !           312:                {
        !           313:                        setallkey(De.ov_hkey_struct, De.ov_keyh);
        !           314:                if (i = find(De.ov_scanr, HRANGEKEY, &De.ov_lotid, &De.ov_hitid, De.ov_keyh))
        !           315:                                syserr("strategy:find2 %.12s, %d", De.ov_scanr->reldum.relid, i);
        !           316:                }
        !           317:        }
        !           318:        
        !           319: #      ifdef xOTR1
        !           320:        if (tTf(70, 1))
        !           321:        {
        !           322:                printf("Lo");
        !           323:                dumptid(&De.ov_lotid);
        !           324:                printf("Hi");
        !           325:                dumptid(&De.ov_hitid);
        !           326:        }
        !           327: #      endif
        !           328: 
        !           329:        return (1);
        !           330: }

unix.superglobalmegacorp.com

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