head	1.13;
access;
symbols
	release_4_2:1.13
	aix_ok:1.13
	Version_2_1:1.10
	Version_2:1.2;
locks; strict;
comment	@ * @;


1.13
date	93.01.16.03.14.59;	author aoki;	state Exp;
branches;
next	1.12;

1.12
date	91.08.08.16.07.14;	author sp;	state Exp;
branches;
next	1.11;

1.11
date	91.07.16.13.17.28;	author sp;	state Exp;
branches;
next	1.10;

1.10
date	91.02.24.00.47.41;	author cimarron;	state Exp;
branches;
next	1.9;

1.9
date	91.02.08.13.11.28;	author sp;	state Exp;
branches;
next	1.8;

1.8
date	91.01.17.19.10.18;	author sp;	state Exp;
branches;
next	1.7;

1.7
date	91.01.09.19.13.57;	author sp;	state Exp;
branches;
next	1.6;

1.6
date	90.08.18.00.41.44;	author cimarron;	state Exp;
branches;
next	1.5;

1.5
date	90.08.13.20.32.41;	author sp;	state Exp;
branches;
next	1.4;

1.4
date	90.08.11.22.33.19;	author sp;	state Exp;
branches;
next	1.3;

1.3
date	90.08.08.08.33.47;	author cimarron;	state Exp;
branches;
next	1.2;

1.2
date	90.07.10.15.52.53;	author sp;	state Version_2;
branches;
next	1.1;

1.1
date	90.05.20.17.54.09;	author sp;	state Exp;
branches;
next	;


desc
@Go from a 'Prs2RawStub' to a 'Prs2Stub' and vice versa
@


1.13
log
@removed references to utils/fmgr.h and parser/parse.h
@
text
@/*========================================================================
 *
 * FILE:
 * stubraw.c
 *
 * IDENTIFICATION:
 * $Header: /home2/aoki/postgres/src/backend/rules/stubs/RCS/stubraw.c,v 1.12 1991/08/08 16:07:14 sp Exp aoki $
 *
 * DESCRIPTION:
 *
 * Routines that transform a 'Prs2RawStub' to a 'Prs2Stub' and vice versa.
 *
 *========================================================================
 */

#include <stdio.h>
#include "tmp/postgres.h"
#include "parse.h"       	/* for the AND, NOT, OR */
#include "utils/log.h"
#include "rules/prs2.h"
#include "rules/prs2stub.h"
#include "tmp/datum.h"
#include "nodes/primnodes.h"
#include "nodes/primnodes.a.h"

extern Const RMakeConst();
extern Param RMakeParam();
extern LispValue StringToPlan();


/*-----------------------------------------------------------------------
 *
 * prs2StubToRawStub
 *
 * given a 'Prs2Stub' (which is a spaghetti of pointers)
 * transform it to a stream of bytes suitable for disk storage
 *
 *-----------------------------------------------------------------------
 */
Prs2RawStub
prs2StubToRawStub(relstub)
Prs2Stub relstub;
{
    Prs2RawStub *pieces, res;
    int npieces;
    int maxsize;
    int i;

    maxsize = 1000000000;
    pieces = prs2StubToSmallRawStubs(relstub, maxsize, &npieces);
    if (npieces != 1) {
	elog(WARN, "Hey! this is a pretty hefty stub you've got there!");
    }

    res = pieces[0];
    pfree(pieces);

    return(res);
}

/*-----------------------------------------------------------------------
 *
 * prs2StubToSmallRawStubs
 *
 * Similar to 'prs2StubToRawStub' but if the resulting stub is too big,
 * then it breaks it in many pieces, each one of them being
 * less than 'maxSize' bytes long.
 * It returns an array of 'Prs2RawStub'. This array has '*nStubPiecesP'
 * entries.
 *
 * THE ECOLOGICAL MESSAGE OF THE WEEK:
 * Do not waste memory, recycle it! So, don't forget to pfree the stubs
 * and the array when you are done!
 *-----------------------------------------------------------------------
 */
Prs2RawStub *
prs2StubToSmallRawStubs(relstub, maxSize, nStubPiecesP)
Prs2Stub relstub;
int *nStubPiecesP;
{
    Size thisSize, headerSize, sumSizes, locksize;
    int nPieces;
    Prs2RawStub *res;
    Prs2OneStub oneStub;
    char **stubQual;
    int *stubSizes;
    int i,j;
    int len;
    char *s;
    int nstubs;

    /*
     * NOTE: this routine does a two pass "parsing" of 'relstub'.
     * The first one to find the size needed for the raw stub
     * representation and the second to actually store the information.
     * However as in order to complete the first step we must 
     * transform the stub qualifications to strings and then repeat
     * this process again during the second pass and as this takes
     * quite some time, we instead opt to store the strings
     * (the ascii reperesentations) of the stubs quals in an array
     * during the first pass so we do not have to recalculate them 
     * during the second!)
     */
    if (relstub->numOfStubs>0) {
	stubQual = (char **)palloc(sizeof(char *) * relstub->numOfStubs);
	if (stubQual == NULL) {
	    elog(WARN, "prs2StubToRawStub: Out of memory!\n");
	}
	stubSizes = (int *)palloc(sizeof(int) * relstub->numOfStubs);
	if (stubSizes == NULL) {
	    elog(WARN, "prs2StubToRawStub: Out of memory!\n");
	}
    } else {
	stubQual = NULL;
	stubSizes = NULL;
    }

    /*
     * calculate the number of bytes needed to hold
     * the raw representation of this stub record.
     * First we calculate the # of bytes needed for
     * each individual `Prs2OneStub' and we store it
     * in array 'stubSizes'
     */

    for (i=0; i< relstub->numOfStubs; i++) {
	/*
	 * calculate the size of each individual `Prs2OneStub'
	 * Start with the fixed size part of the struct.
	 */
	oneStub = relstub->stubRecords[i];
	thisSize = sizeof(oneStub->ruleId) +
		sizeof(oneStub->stubId) +
		sizeof(oneStub->counter);
	/*
	 * now add the rule lock size
	 */
	thisSize = thisSize +
		prs2LockSize( prs2GetNumberOfLocks(oneStub->lock));
	/*
	 * finally add the size of the stub's qualification.
	 * NOTE: we store it a string preceded by an integer
	 * holding its length.
	 * Don't forget to store this string to an array
	 * so that we don't have to recalculate it later.
	 */
	s = lispOut(oneStub->qualification);
	stubQual[i] = s;
	thisSize = thisSize + (strlen(s) + sizeof(int));
	/*
	 * store the size to 'stubSizes' and also
	 * add it to the total size
	 */
	stubSizes[i] = thisSize;

    }

    /*
     * calculate in how many pieces we have to break
     * the stub so that each piece is less than 'maxSize'
     * bytes long.
     *
     * NOTE: Just as like in the "varlena" structure, the "size" field
     * in the Prs2RawStubData is the sum of its own size + the (variable)
     * size of the data that is following.
     */
    nPieces = 0;
    headerSize = sizeof(res[0]->vl_len) + sizeof(relstub->numOfStubs);
    sumSizes = headerSize;
    for (i=0; i< relstub->numOfStubs; i++) {
	if (sumSizes + stubSizes[i] > maxSize) {
	    nPieces++;
	    sumSizes = stubSizes[i] + headerSize;
	} else {
	    sumSizes = sumSizes + stubSizes[i];
	}
    }
    nPieces++;

    /*
     * OK, allocate an array of that many raw stub pieces
     */
    res = (Prs2RawStub *) palloc(sizeof(Prs2RawStub) * nPieces);
    if (res==NULL) {
	elog(WARN,"prs2StubToRawStub: Out of memory");
    }

    /*
     * Now allocate enough space for each 
     * such piece
     */
    j=0;
    sumSizes = headerSize;
    for (i=0; i< relstub->numOfStubs; i++) {
	if (sumSizes + stubSizes[i] > maxSize) {
	    res[j] = (Prs2RawStub)palloc(sumSizes);
	    if (res[j]==NULL) {
		elog(WARN,"prs2StubToRawStub: Out of memory");
	    }
	    res[j]->vl_len = sumSizes;
	    j++;
	    sumSizes = stubSizes[i] + headerSize;
	} else {
	    sumSizes = sumSizes + stubSizes[i];
	}
    }
    res[j] = (Prs2RawStub)palloc(sumSizes);
    if (res[j]==NULL) {
	elog(WARN,"prs2StubToRawStub: Out of memory");
    }
    res[j]->vl_len = sumSizes;

    
    /*
     * now copy the stubs to the raw stub pieces.
     */
    j=0;
    s = &(res[j]->vl_dat[0]) + sizeof(relstub->numOfStubs);
    sumSizes = headerSize;
    nstubs = 0;


    for (i=0; i< relstub->numOfStubs; i++) {
	if (sumSizes + stubSizes[i] > maxSize) {
	    /*
	     * time to start a new piece...
	     * first update the 'numOfStubs' field of the previous
	     * piece
	     */
	    bcopy((char *) &nstubs, &(res[j]->vl_dat[0]), sizeof(nstubs));
	    /*
	     * now continue with the next stub
	     */
	    j++;
	    s = &(res[j]->vl_dat[0]) + sizeof(relstub->numOfStubs);
	    sumSizes = headerSize;
	    nstubs = 0;
	}
	sumSizes = sumSizes + stubSizes[i];
	nstubs ++;
	/*
	 * copy this prs2OneStub to the raw stub piece
	 */
	oneStub = relstub->stubRecords[i];
	/*
	 * copy the fixed size part of the record
	 */
	bcopy((char *)&(oneStub->ruleId), s, sizeof(oneStub->ruleId));
	s += sizeof(oneStub->ruleId);
	bcopy((char *)&(oneStub->stubId), s, sizeof(oneStub->stubId));
	s += sizeof(oneStub->stubId);
	bcopy((char *)&(oneStub->counter), s, sizeof(oneStub->counter));
	s += sizeof(oneStub->counter);
	/*
	 * now copy the rule lock
	 */
	locksize = prs2LockSize(prs2GetNumberOfLocks(oneStub->lock));
	bcopy((char *) oneStub->lock, s, locksize);
	s+=locksize;
	/*
	 * finally copy the qualification
	 * First the length of the string and then the string itself.
	 */
	len = strlen(stubQual[i]);
	bcopy((char *) &len, s, sizeof(int));
	s += sizeof(int);
	bcopy(stubQual[i], s, len);
	s += len;
    }
    /*
     * Don't forget to update the 'numOfStubs' field of the
     * last piece!
     */
    bcopy((char *) &nstubs, &(res[j]->vl_dat[0]), sizeof(nstubs));

    /*
     * Keep POSTGRES memory clean!
     */
    for (i=0; i< relstub->numOfStubs; i++) {
	pfree(stubQual[i]);
    }
    if (relstub->numOfStubs > 0) {
	pfree(stubQual);
	pfree(stubSizes);
    }

    /* 
     * OK we are done!
     */
    *nStubPiecesP = nPieces;
    return(res);
}

/*----------------------------------------------------------------------
 *
 * prs2RawStubToStub
 *
 * given a stream of bytes (like the one created by
 * 'prs2StubToRawStub') recreate the original stub record
 *
 *----------------------------------------------------------------------
 */
Prs2Stub
prs2RawStubToStub(rawStub)
Prs2RawStub rawStub;
{
    Prs2Stub relstub;
    Prs2OneStub oneStub;
    Size size;
    int i,j;
    int len;
    char *data;
    char *s;
    Prs2LocksData ruleLock;

    /*
     * create a new stub record
     */
    relstub = prs2MakeStub();
    if (relstub == NULL) {
	elog(WARN, "prs2RawStubToStub: Out of memory");
    }

    /*
     * copy the number of individual stub records
     */
    data = VARDATA(rawStub);
    bcopy(data, (char *)&(relstub->numOfStubs), sizeof(relstub->numOfStubs));
    data += sizeof(relstub->numOfStubs);

    /*
     * allocate space for the `relstub->numOfStubs' records of
     *type 'Prs2OneStubData'
     */
    if (relstub->numOfStubs > 0 ) {
	size = relstub->numOfStubs * sizeof(Prs2OneStub);
	relstub->stubRecords = (Prs2OneStub *) palloc(size);
	if (relstub->stubRecords == NULL) {
	    elog(WARN, "prs2RawStubToStub: Out of memory");
	}
    } else {
	relstub->stubRecords = NULL;
    }
    
    for (i=0; i< relstub->numOfStubs; i++) {
	oneStub = prs2MakeOneStub();
	relstub->stubRecords[i] = oneStub;
	/*
	 * copy the fixed part of the 'Prs2OneStub' first.
	 */
        bcopy(data, (char *)&(oneStub->ruleId), sizeof(oneStub->ruleId));
        data += sizeof(oneStub->ruleId);
        bcopy(data, (char *)&(oneStub->stubId), sizeof(oneStub->stubId));
        data += sizeof(oneStub->stubId);
        bcopy(data, (char *)&(oneStub->counter), sizeof(oneStub->counter));
        data += sizeof(oneStub->counter);

	/*
	 * now copy the rule lock
	 * XXX: NOTE:
	 * In order to copy the rule lock, we have to find its
	 * size. But in order to find its size we must read
	 * the 'numberOfLocks' field.
	 * We can not just cast 'data' to a RuleLock because
	 * of alignment problems, so we must copy it.
	 */
	bcopy(data, (char *) &ruleLock,
		sizeof(Prs2LocksData)-sizeof(Prs2OneLockData));
	size = prs2LockSize(prs2GetNumberOfLocks(&ruleLock));
	oneStub->lock = (RuleLock) palloc(size);
	if (oneStub->lock == NULL) {
	    elog(WARN, "prs2RawStubToStub: Out of memory");
	}
	bcopy(data, (char*)(oneStub->lock), size);
	data += size;

	/*
	 * now recreate the qualification (which is stored
	 * as a string containing the ascii representation
	 * of a LispValue).
	 * First read the length of the string & then 
	 * create the LispValue out of the string.
	 */
	bcopy(data, (char*)&len, sizeof(int));
	data += sizeof(int);
	oneStub->qualification = StringToPlan(data);
	data += len;
    }

    /*
     * At last! we are done...
     */
    return(relstub);
}

/*----------------------------------------------------------------------
 * prs2RawStubUnion
 *
 * Make and return the union of the two given raw stubs.
 *----------------------------------------------------------------------
 */
Prs2RawStub
prs2RawStubUnion(stub1, stub2)
Prs2RawStub stub1;
Prs2RawStub stub2;
{
    Prs2RawStub res;
    int size, size1, size2;
    int nstubs, nstubs1, nstubs2;
    char *data1, *data2;
    char *s;

    /*
     * the data of each stub consists of the 4 bytes used
     * to store the number of the "small stub record" (i.e.
     * the equivalent to 'Prs2OneStubData' structure) contained
     * in this stub + the data for these "small stub records".
     * All this data is stored in the "vl_dat" field.
     *
     * Note that the number stored in "vl_len" is the size of all
     * this stuff + the size of the "vl_len" field itself.
     *
     * The size of data  of the union will be the sum of space needed
     * for the "small stub records" for stub 1, the space
     * needed for the "small stub records" of stub2 and
     * finally the 4 bytes to store the total number of
     * new "small stub records".
     */

    /*
     * read the 'number of stubs' information into 'nstubs1'
     * and make 'data1' point to the first "small stub record"
     * 'size1' is the size of the information for the "small
     * stub records" only.
     */
    s = &(stub1->vl_dat[0]);
    bcopy(s, (char *) &nstubs1, sizeof(nstubs1));
    data1 = s + sizeof(nstubs1);
    size1 = stub1->vl_len - sizeof(stub1->vl_len) - sizeof(nstubs1);

    /*
     * same thing for stub 2
     */
    s = &(stub2->vl_dat[0]);
    bcopy(s, (char *) &nstubs2, sizeof(nstubs2));
    data2 = s + sizeof(nstubs2);
    size2 = stub2->vl_len - sizeof(stub2->vl_len) - sizeof(nstubs2);

    /*
     * find the total number of stubs and calculate the
     * total size of the their union (including the number of
     * small stub records and the size of 'vl_len')
     */
    nstubs = nstubs1 + nstubs2;
    size = size1 + size2 + sizeof(nstubs) + sizeof(res->vl_len);


    /*
     * allocate space for the new stub and copy there the
     * information about the number of stubs
     */
    res = (Prs2RawStub) palloc(size);
    if (res == NULL) {
	elog(WARN,"prs2RawStubUnion: Out of memory");
    }
    res->vl_len = size;
    s = &(res->vl_dat[0]);
    bcopy((char *)&nstubs, s, sizeof(nstubs));

    /*
     * now concatenate the data for the small stub records of
     * stub1 and stub2 and copy them in the new union stub
     */
    s += sizeof(nstubs);
    bcopy(data1, s, size1);
    s += size1;
    bcopy(data2, s, size2);

    /*
     * OK, we are done...
     */
    return(res);
}


@


1.12
log
@various bug fixes...
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.11 91/07/16 13:17:28 sp Exp $
d18 1
a18 1
#include "parser/parse.h"       /* for the AND, NOT, OR */
@


1.11
log
@New routines: prs2StubToSmallRawStubs and prs2RawStubUnion
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.10 91/02/24 00:47:41 cimarron Exp $
d239 1
d475 1
a475 1
    bcopy(&(stub1->vl_dat[0]), s, size1);
d477 1
a477 1
    bcopy(&(stub2->vl_dat[0]), s, size2);
@


1.10
log
@added palloc_debug tracing facility
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.9 91/02/08 13:11:28 sp Exp Locker: cimarron $
d44 40
a83 2
    Size size;
    Prs2RawStub res;
d86 1
d90 1
d109 7
d119 1
a119 1
     * calculate the number fo bytes needed to hold
d121 3
a124 1
    size = sizeof(relstub->numOfStubs);
a128 1
	 * and add it ti the total size.
d132 1
a132 2
	size = size +
		sizeof(oneStub->ruleId) +
d138 1
a138 1
	size = size +
d149 7
a155 1
	size = size + (strlen(s) + sizeof(int));
d159 3
a161 2
     * allocate a big enough `Prs2RawStubData' struct to hold the
     * whole thing...
d167 18
a184 3
    size = size + sizeof(res->vl_len);
    res = (Prs2RawStub) palloc(size);
    if (res == NULL) {
a186 1
    res->vl_len = size;
d189 2
a190 1
     * now copy the whole thing to the res->vl_dat;
d192 20
a211 1
    s = &(res->vl_dat[0]);
d213 8
a220 2
    bcopy((char *) &(relstub->numOfStubs), s, sizeof(relstub->numOfStubs));
    s += sizeof(relstub->numOfStubs);
d222 1
d224 19
d256 3
a258 3
	size = prs2LockSize(prs2GetNumberOfLocks(oneStub->lock));
	bcopy((char *) oneStub->lock, s, size);
	s+=size;
d269 5
d281 1
a281 1
    if (relstub->numOfStubs > 0)
d283 2
d289 1
d300 1
d394 91
@


1.9
log
@Stub qualifications are now LispValues...
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.8 91/01/17 19:10:18 sp Exp $
a25 1
extern char *palloc();
@


1.8
log
@Changes in the structure of 'Prs2SimpleSrubQual'
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.7 91/01/09 19:13:57 sp Exp Locker: sp $
d26 4
a29 3
char *palloc();
Const RMakeConst();
Param RMakeParam();
a30 5
/*--------- static routines local to this file ---------------*/
static int prs2StubQualToRawStubQual();
static Prs2StubQual prs2RawStubQualToStubQual();
static int prs2OperandToRawOperand();
static Node prs2RawOperandToOperand();
d48 1
d50 1
d54 19
d96 4
a99 2
	 * NOTE: the first argument to 'prs2StubQualToRawStubQual'
	 * is NULL, so this routine will only return the size.
d101 3
a103 1
	size = size + prs2StubQualToRawStubQual(NULL, oneStub->qualification);
d148 1
d150 5
a154 2
	size = prs2StubQualToRawStubQual(s, oneStub->qualification);
	s += size;
a156 34
    /* 
     * OK we are done!
     */
    return(res);
}

/*-------------------------------------------------------------------------
 *
 * prs2StubQualToRawStubQual
 *
 * Given a stub qualification (a 'Prs2StubQual') transform it
 * to a "flat" stream of bytes and return its size..
 *
 * If the pointer "s" is NULL, then this routine does no copying and
 * returns the number of bytes needed to hold the raw (flat)
 * representation of the qual.
 *
 * If "s" is non-NULL, then we also copy the flat representation there.
 *
 * 'Prs2StubQual' is a tree and we do a depth-first traversal...
 *-------------------------------------------------------------------------
 */
static
int 
prs2StubQualToRawStubQual(s, qual)
char *s;
Prs2StubQual qual;
{
    int i;
    Size size;
    int tempsize;
    Prs2SimpleStubQualData *simple;
    Prs2ComplexStubQualData *complex;

d158 1
a158 1
     * first the fixed part of "Prs2StubQual"
d160 2
a161 4
    size = sizeof(qual->qualType);
    if (s!=NULL) {
	bcopy((char*)&(qual->qualType), s, sizeof(qual->qualType));
	s += sizeof(qual->qualType);
d163 2
d166 2
a167 4
    /*
     * Now take care of the union. This contains either
     * a "Prs2SimpleQualData" (a leaf node) or a "Prs2ComplexQualData"
     * (non-leaf node)
d169 1
a169 66
    if (qual->qualType == PRS2_COMPLEX_STUBQUAL) {
	/*
	 * We have a non leaf node.
	 * First take care of the fixed length part.
	 */
	complex = &(qual->qual.complex);
	size += sizeof(complex->boolOper);
	size += sizeof(complex->nOperands);
	if (s!=NULL) {
            bcopy((char *)&(complex->boolOper), s, sizeof(complex->boolOper));
            s += sizeof(complex->boolOper);
            bcopy((char *)&(complex->nOperands), s, sizeof(complex->nOperands));
            s += sizeof(complex->nOperands);
	}
	/*
	 * Now recursively copy its children.
	 */
	for (i=0; i<complex->nOperands; i++) {
	    tempsize = prs2StubQualToRawStubQual(s, complex->operands[i]);
	    size += tempsize;
	    if (s!=NULL) {
		s += tempsize;
	    }
	}
    } else if (qual->qualType == PRS2_SIMPLE_STUBQUAL) {
	/*
	 * this is a leaf node, so the union "qual" contains a
	 * "Prs2SimpleQualData" struct. Find its size & copy it.
	 * First start with the operator oid.
	 */
	simple = &(qual->qual.simple);
	size = size +
		sizeof(simple->operator);
	if (s!=NULL) {
            bcopy((char *)&(simple->operator), s, sizeof(simple->operator));
            s += sizeof(simple->operator);
	}
	/*
	 * now the two operands.
	 */
	tempsize = prs2OperandToRawOperand(s, simple->left);
	size += tempsize;
	if (s!= NULL) {
	    s += tempsize;
	}
	tempsize = prs2OperandToRawOperand(s, simple->right);
	size += tempsize;
	if (s!= NULL) {
	    s += tempsize;
	}
    } else if (qual->qualType == PRS2_NULL_STUBQUAL) {
	/*
	 * Do nothing!
	 */
    } else {
	/*
	 * Oooops! a bad-bad-bad thing to happen...
	 */
	elog(WARN, "Prs2StubQualToRawStubQual: Bad qual type!");
    }


    /*
     * we are done, return the size.
     */
    return(size);
d188 1
d255 5
a259 3
	 * now recreate the qualification
	 * NOTE: we passe a pointer to 'data', so that 'data'
	 * will advance accordingly as bytes are read.
d261 4
a264 1
	oneStub->qualification = prs2RawStubQualToStubQual(&data);
a270 285
}

/*-------------------------------------------------------------------------
 *
 * prs2RawStubQualToStubQual
 *
 * This is the inverse of "prs2StubQualToRawStubQual". Given a stream
 * of bytes recreate the stub's qualification.
 *
 * NOTE: XXX XXX XXX !!! !!! !!! SOS SOS SOS !!! !!! !!! XXX XXX XXX
 *
 * The argument 's' is a POINTER to a char POINTER !
 * The value of the char pointer (i.e. '*s') because the pointer is
 * advanced as we read the bytes. Make SURE that you make a copy of the
 * pointer if you want to use it after the call to this routine !!!!!
 *
 * NOTE 2 : we traverse the qualification tree in depth first order.
 *
 *-------------------------------------------------------------------------
 */
static
Prs2StubQual
prs2RawStubQualToStubQual(s)
char **s;
{

    int i;
    Size size;
    char *ptr;
    Prs2StubQual qual;
    Prs2SimpleStubQualData *simple;
    Prs2ComplexStubQualData *complex;

    /*
     * Create a "Prs2StubQual" struct
     */
    qual = prs2MakeStubQual();

    /*
     * Now read the fixed part of "Prs2StubQual"
     */
    bcopy(*s, (char*)&(qual->qualType), sizeof(qual->qualType));
    *s += sizeof(qual->qualType);

    /*
     * Now take care of the union. This contains either
     * a "Prs2SimpleQualData" (a leaf node) or a "Prs2ComplexQualData"
     * (non-leaf node)
     */
    if (qual->qualType == PRS2_COMPLEX_STUBQUAL) {
	/*
	 * We have a non leaf node.
	 * First take care of the fixed length part.
	 */
	complex = &(qual->qual.complex);
	bcopy(*s, (char *)&(complex->boolOper), sizeof(complex->boolOper));
	*s += sizeof(complex->boolOper);
	bcopy(*s, (char *)&(complex->nOperands), sizeof(complex->nOperands));
	*s += sizeof(complex->nOperands);
	/*
	 * Now recursively recreate the children.
	 * First allocate the array of pointers to "Pr2StubQualData"
	 * structures (i.e. an array of "Prs2StubQual").
	 */
	if (complex->nOperands <= 0) {	/* better be safe than sorry... */
	    elog(WARN,"prs2RawStubQualToStubQual: nOperands<=0!!!");
	}
	size = complex->nOperands * sizeof(Prs2StubQual);
	complex->operands = (Prs2StubQual *)palloc(size);
	if (complex->operands == NULL) {
	    elog(WARN, "Prs2RawStubQualToStubQual: Out of memory!");
	}
	for (i=0; i<complex->nOperands; i++) {
	    complex->operands[i] = prs2RawStubQualToStubQual(s);
	}
    } else if (qual->qualType == PRS2_SIMPLE_STUBQUAL) {
	/*
	 * this is a leaf node, so the union "qual" contains a
	 * "Prs2SimpleQualData" struct. Find its size & copy it.
	 */
	simple = &(qual->qual.simple);
	bcopy(*s, (char *)&(simple->operator), sizeof(simple->operator));
	*s += sizeof(simple->operator);
	simple->left = prs2RawOperandToOperand(s);
	simple->right = prs2RawOperandToOperand(s);
    } else if (qual->qualType == PRS2_NULL_STUBQUAL) {
	/*
	 * Do nothing
	 */
    } else {
	/*
	 * Oooops! a bad-bad-bad thing to happen...
	 */
	elog(WARN, "Prs2RawStubQualToStubQual: Bad qual type!");
    }

    /*
     * we are done, return the "Prs2StubQual"
     */
    return(qual);
}

/*-------------------------------------------------------------------
 * prs2OperandToRawOperand
 *
 * Given an operand which must be a Param or Const node,
 * create their "flat" representation. If pointer 's' is not NULL,
 * copy it there, otherwise just return the size needed for 's'.
 *-------------------------------------------------------------------
 */
static
int
prs2OperandToRawOperand(s, operand)
char *s;
Node operand;
{

    int size;
    int tempsize;
    Param param;
    Const constant;

    size = 0;

    if (IsA(operand,Param)) {
	size ++;
	if (s!= NULL) {
	    *s = 'p';		/* to indicate a Param node */
	    s++;
	}
	param = (Param) operand;
	if (param->paramkind != PARAM_NEW && param->paramkind != PARAM_OLD) {
	    elog(WARN,"prs2OperandToRawOperand: param is not NEW or OLD");
	}
	size += sizeof(param->paramkind) +
		    sizeof(param->paramid) +
		    sizeof(*(param->paramname)) +
		    sizeof(param->paramtype);
	if (s!= NULL) {
	    bcopy((char *)&(param->paramkind), s, sizeof(param->paramkind));
	    s += sizeof(param->paramkind);
	    bcopy((char *)&(param->paramid), s, sizeof(param->paramid));
	    s += sizeof(param->paramid);
	    bcopy((char *)(param->paramname), s, sizeof(*(param->paramname)));
	    s += sizeof(*(param->paramname));
	    bcopy((char *)&(param->paramtype), s, sizeof(param->paramtype));
	    s += sizeof(param->paramtype);
	}
    } else if (IsA(operand,Const)) {
	size ++;
	if (s!= NULL) {
	    *s = 'c';		/* to indicate a Const node */
	    s++;
	}
	constant = (Const) operand;
	/*
	 * First copy the fixed part of the Const node
	 */
	size += sizeof(constant->consttype) +
		    sizeof(constant->constlen) +
		    sizeof(constant->constbyval) +
		    sizeof(constant->constisnull);
	if (s!= NULL) {
	    bcopy((char *)&constant->consttype, s, sizeof(constant->consttype));
	    s += sizeof(constant->consttype);
	    bcopy((char *)&constant->constlen, s, sizeof(constant->constlen));
	    s += sizeof(constant->constlen);
	    bcopy((char *)&constant->constbyval, s, sizeof(constant->constbyval));
	    s += sizeof(constant->constbyval);
	    bcopy((char *)&constant->constisnull, s,
				sizeof(constant->constisnull));
	    s += sizeof(constant->constisnull);
	}
	/*
	 * Now copy the datum value...
	 */
	tempsize = datumGetSize(constant->constvalue,
				constant->consttype,
				constant->constbyval,
				constant->constlen);
	size += tempsize + sizeof(tempsize);
	if (s!= NULL) {
	    if (constant->constbyval) {
		bcopy((char *)&tempsize, s, sizeof(tempsize));
		s += sizeof(tempsize);
		bcopy((char *)&(constant->constvalue), s, tempsize);
		s += tempsize;
	    } else {
		bcopy((char *)&tempsize, s, sizeof(tempsize));
		s += sizeof(tempsize);
		bcopy((char *)DatumGetPointer(constant->constvalue), s, tempsize);
		s += tempsize;
	    }
	}
    } else {
	/*
	 * operand is not Const or Param
	 */
	elog(WARN, "prs2OperandToRawOperand: operand is not Const or Param");
    }

    return(size);
}

/*---------------------------------------------------------------------
 * prs2RawOperandToOperand
 *
 * This is the inverse of 'prs2OperandToRawOperand'.
 * Given a stream of bytes (the "flat" representation of an operand)
 * recreate the operand itself.
 *
 * NOTE: 's' is a pointer to a pointer.
 *---------------------------------------------------------------------
 */
static
Node
prs2RawOperandToOperand(s)
char **s;
{
    Size size;
    char *ptr;
    Param param;
    Const constant;

    if (**s == 'p') {
	/*
	 * This is a param node.
	 */
	*s += 1;	/* skip the 'p' */
	param = RMakeParam();
	bcopy(*s, (char*)&(param->paramkind), sizeof(param->paramkind));
	*s += sizeof(param->paramkind);
	if (param->paramkind != PARAM_NEW && param->paramkind != PARAM_OLD) {
	    elog(WARN,"prs2RawOperandToOperand: param is not NEW or OLD");
	}
	bcopy(*s, (char*)&(param->paramid), sizeof(param->paramid));
	*s += sizeof(param->paramid);
	param->paramname = (Name) palloc(sizeof(*(param->paramname)));
	bcopy(*s, (char*)(param->paramname), sizeof(*(param->paramname)));
	*s += sizeof(*(param->paramname));
	bcopy(*s, (char*)&(param->paramtype), sizeof(param->paramtype));
	*s += sizeof(param->paramtype);
	return((Node) param);
    } else if (**s == 'c') {
	/*
	 * This is a const node
	 */
	*s += 1;	/* skip the 'c' */
	constant = RMakeConst();
	bcopy(*s, (char*)&(constant->consttype), sizeof(constant->consttype));
	*s += sizeof(constant->consttype);
	bcopy(*s, (char*)&(constant->constlen), sizeof(constant->constlen));
	*s += sizeof(constant->constlen);
	bcopy(*s, (char*)&(constant->constbyval), sizeof(constant->constbyval));
	*s += sizeof(constant->constbyval);
	bcopy(*s, (char*)&(constant->constisnull), sizeof(constant->constisnull));
	*s += sizeof(constant->constisnull);
	/*
	 * now the variable length part...
	 */
	bcopy(*s, (char *)&(size), sizeof(size));
	*s += sizeof(size);
	if (constant->constbyval) {
	    bcopy(*s, (char *)&(constant->constvalue), size);
	    *s += size;
	} else {
	    if (size > 0) {
		/*
		 * allocate memory for the constant's value
		 */
		ptr = palloc(size);
		if (ptr==NULL) {
		    elog(WARN,"prs2RawOperandToOperand: out of memory!");
		}
		bcopy(*s, ptr, size);
		*s += size;
	    } else {
		ptr = NULL;
	    }
	    constant->constvalue = PointerGetDatum(ptr);
	}
	return((Node) constant);
    } else {
	elog(WARN, "prs2RawOperandToOperand: This is node a Param or Const");
    }
@


1.7
log
@ Quite a few changes because the structure of 'Prs2Stub' has changed.
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.6 90/08/18 00:41:44 cimarron Exp Locker: sp $
d23 2
d27 2
d33 2
d162 1
a162 1
    Size tempsize;
d208 1
a208 1
	 * First start with the fixed size part.
d212 1
a212 5
		sizeof(simple->attrNo) +
		sizeof(simple->operator) +
		sizeof(simple->constType) +
		sizeof(simple->constByVal) +
		sizeof(simple->constLength);
a213 2
            bcopy((char *)&(simple->attrNo), s, sizeof(simple->attrNo));
            s += sizeof(simple->attrNo);
a215 6
            bcopy((char *)&(simple->constType), s, sizeof(simple->constType));
            s += sizeof(simple->constType);
            bcopy((char *)&(simple->constByVal), s, sizeof(simple->constByVal));
            s += sizeof(simple->constByVal);
            bcopy((char *)&(simple->constLength),s,sizeof(simple->constLength));
            s += sizeof(simple->constLength);
d218 1
a218 8
	 * now take care of the variable length part
	 * (i.e. the actual value of the constant
	 *
	 * First copy the "real length" of the value. This is NOT
	 * always equal to constLength, because the later can be
	 * -1 (i.e. variable length type).
	 *
	 * Then copy one by one the bytes...
d220 4
a223 17
	tempsize = datumGetSize(simple->constType,
			    simple->constByVal,
			    simple->constLength,
			    simple->constData);
	size += tempsize + sizeof(Size);
	if (s!=NULL) {
            if (simple->constByVal) {
		bcopy((char *)&tempsize, s, sizeof(Size));
		s += sizeof(Size);
                bcopy((char *)&(simple->constData), s, tempsize);
		s += tempsize;
            } else {
		bcopy((char *)&tempsize, s, sizeof(Size));
		s += sizeof(Size);
                bcopy((char *)DatumGetPointer(simple->constData), s, tempsize);
		s += tempsize;
            }
d225 5
a419 1
	 * First start with the fixed size part.
a421 2
	bcopy(*s, (char *)&(simple->attrNo), sizeof(simple->attrNo));
	*s += sizeof(simple->attrNo);
d424 2
a425 32
	bcopy(*s, (char *)&(simple->constType), sizeof(simple->constType));
	*s += sizeof(simple->constType);
	bcopy(*s, (char *)&(simple->constByVal), sizeof(simple->constByVal));
	*s += sizeof(simple->constByVal);
	bcopy(*s, (char *)&(simple->constLength),sizeof(simple->constLength));
	*s += sizeof(simple->constLength);
	/*
	 * now take care of the variable length part
	 * (i.e. the actual value of the constant)
	 * First exctract its "real" size (which is not always
	 * equal to constLengt,h because teh later can be -1
	 * to indicate a variable length type....)
	 */
	bcopy(*s, (char *)&(size), sizeof(Size));
	*s += sizeof(Size);
	if (simple->constByVal) {
	    bcopy(*s, (char *)&(simple->constData), size);
	    *s += size;
	} else {
	    if (size > 0) {
		/*
		 * allocate memory for the constant value
		 */
		ptr = palloc(size);
		if (ptr == NULL) {
		    elog(WARN, "Prs2RawStubQualToStubQual:Out of memory");
		}
	    }
	    bcopy(*s, ptr, size);
	    *s += size;
	    simple->constData = PointerGetDatum(ptr);
	}
d443 184
@


1.6
log
@eliminated less significant .h files
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.5 90/08/13 20:32:41 sp Exp Locker: cimarron $
d18 1
a18 1

d22 1
d26 4
d37 1
d43 1
a43 1
    long size;
a45 1
    Prs2SimpleQual qual;
d61 1
a61 1
	oneStub = &(relstub->stubRecords[i]);
d65 1
a65 2
		sizeof(oneStub->counter) +
		sizeof(oneStub->numQuals);
d72 3
a74 2
	 * finally add the size of each one of the
	 * `PrsSimpleQualData'
d76 1
a76 20
	for (j=0; j<oneStub->numQuals; j++) {
	    qual = &(oneStub->qualification[j]);
	    /*
	     * first the fixed size part of 'Prs2SimpleQualData' struct.
	     */
	    size = size +
		    sizeof(qual->attrNo) +
		    sizeof(qual->operator) +
		    sizeof(qual->constType) +
		    sizeof(qual->constByVal) +
		    sizeof(qual->constLength);
	    /*
	     * then the variable length size (the actual value of
	     * the constant)
	     */
	    size += prs2GetDatumSize(qual->constType,
				qual->constByVal,
				qual->constLength,
				qual->constData);
	}
d103 1
a103 1
	oneStub = &(relstub->stubRecords[i]);
a112 2
	bcopy((char *)&(oneStub->numQuals), s, sizeof(oneStub->numQuals));
	s += sizeof(oneStub->numQuals);
d117 1
a117 1
	bcopy((char *) relstub->stubRecords[i].lock, s, size);
d120 1
a120 2
	 * finally copy each one of the
	 * `PrsSimpleQualData'
d122 2
a123 29
	for (j=0; j<relstub->stubRecords[i].numQuals; j++) {
	    qual = &(oneStub->qualification[j]);
	    /*
	     * fixed part first...
	     */
	    bcopy((char *)&(qual->attrNo), s, sizeof(qual->attrNo));
	    s += sizeof(qual->attrNo);
	    bcopy((char *)&(qual->operator), s, sizeof(qual->operator));
	    s += sizeof(qual->operator);
	    bcopy((char *)&(qual->constType), s, sizeof(qual->constType));
	    s += sizeof(qual->constType);
	    bcopy((char *)&(qual->constByVal), s, sizeof(qual->constByVal));
	    s += sizeof(qual->constByVal);
	    bcopy((char *)&(qual->constLength), s, sizeof(qual->constLength));
	    s += sizeof(qual->constLength);
	    /*
	     * now the value of the constant iteslf
	     */
	    size = prs2GetDatumSize(qual->constType,
				qual->constByVal,
				qual->constLength,
				qual->constData);
	    if (qual->constByVal) {
		bcopy((char *)&(qual->constData), s, size);
	    } else {
		bcopy((char *)DatumGetPointer(qual->constData), s, size);
	    }
	    s += size;
	}
d132 27
d160 109
d283 1
a283 2
    Prs2SimpleQual qual;
    long size;
d292 1
a292 1
    relstub = (Prs2Stub) palloc(sizeof(Prs2StubData));
d309 2
a310 2
	size = relstub->numOfStubs * sizeof(Prs2OneStubData);
	relstub->stubRecords = (Prs2OneStub) palloc(size);
d319 2
a320 1
	oneStub = & (relstub->stubRecords[i]);
a329 2
        bcopy(data, (char *)&(oneStub->numQuals), sizeof(oneStub->numQuals));
        data += sizeof(oneStub->numQuals);
d351 3
a353 1
	 * now allocate space for the qualification(s)
d355 2
a356 12
	if (oneStub->numQuals > 0) {
	    size = oneStub->numQuals * sizeof(Prs2SimpleQualData);
	    oneStub->qualification = (Prs2SimpleQual) palloc(size);
	    if (oneStub->qualification == NULL) {
		elog(WARN, "prs2RawStubToStub: Out of memory");
	    }
	}
	for (j=0; j<oneStub->numQuals; j++) {
	    /*
	     * copy the qualifications one by one
	     */
	    qual = & (oneStub->qualification[j]);
d358 5
a362 13
	    /*
	     * fixed part first
	     */
            bcopy(data, (char *)&(qual->attrNo), sizeof(qual->attrNo));
            data += sizeof(qual->attrNo);
            bcopy(data, (char *)&(qual->operator), sizeof(qual->operator));
            data += sizeof(qual->operator);
            bcopy(data, (char *)&(qual->constType), sizeof(qual->constType));
            data += sizeof(qual->constType);
            bcopy(data, (char *)&(qual->constByVal), sizeof(qual->constByVal));
            data += sizeof(qual->constByVal);
            bcopy(data, (char *)&(qual->constLength),sizeof(qual->constLength));
            data += sizeof(qual->constLength);
d364 110
a473 13
            size = prs2GetDatumSize(qual->constType,
                                qual->constByVal,
                                qual->constLength,
                                qual->constData);
	    if (qual->constByVal) {
		bcopy(data, (char *) &(qual->constData), size);
		data += size;
	    } else {
		if (size > 0) {
		    s = palloc(size);
		    if (s == NULL) {
			elog(WARN, "prs2RawStubToStub: Out of memory");
		    }
a474 3
		bcopy(data, s, size);
		data+=size;
		qual->constData = PointerGetDatum(s);
d476 3
d480 9
d492 1
a492 1
     * At last! we are done...
d494 1
a494 1
    return(relstub);
d496 1
@


1.5
log
@Now all #includes explicitly specify the directory of the .h files.
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.4 90/08/11 22:33:19 sp Exp Locker: sp $
d17 2
a19 1
#include "tmp/datum.h"
@


1.4
log
@minor bug fix: Prs2Stub->stubRecords initialized to NULL
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.3 90/08/08 08:33:47 cimarron Exp $
d17 4
a20 4
#include "log.h"
#include "datum.h"
#include "prs2.h"
#include "prs2stub.h"
@


1.3
log
@changed "stub" to "relstub" because "stub" is now a system type.
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.2 90/07/10 15:52:53 sp Exp Locker: sp $
d222 2
@


1.2
log
@various bug fixes...
@
text
@d7 1
a7 1
 * $Header: RCS/stubraw.c,v 1.1 90/05/20 17:54:09 sp Exp $
d33 2
a34 2
prs2StubToRawStub(stub)
Prs2Stub stub;
d47 1
a47 1
    size = sizeof(stub->numOfStubs);
d49 1
a49 1
    for (i=0; i< stub->numOfStubs; i++) {
d55 1
a55 1
	oneStub = &(stub->stubRecords[i]);
d112 2
a113 2
    bcopy((char *) &(stub->numOfStubs), s, sizeof(stub->numOfStubs));
    s += sizeof(stub->numOfStubs);
d115 2
a116 2
    for (i=0; i< stub->numOfStubs; i++) {
	oneStub = &(stub->stubRecords[i]);
d132 1
a132 1
	bcopy((char *) stub->stubRecords[i].lock, s, size);
d138 1
a138 1
	for (j=0; j<stub->stubRecords[i].numQuals; j++) {
d188 1
a188 1
    Prs2Stub stub;
d200 2
a201 2
    stub = (Prs2Stub) palloc(sizeof(Prs2StubData));
    if (stub == NULL) {
d209 2
a210 2
    bcopy(data, (char *)&(stub->numOfStubs), sizeof(stub->numOfStubs));
    data += sizeof(stub->numOfStubs);
d213 1
a213 1
     * allocate space for the `stub->numOfStubs' records of
d216 4
a219 4
    if (stub->numOfStubs > 0 ) {
	size = stub->numOfStubs * sizeof(Prs2OneStubData);
	stub->stubRecords = (Prs2OneStub) palloc(size);
	if (stub->stubRecords == NULL) {
d224 2
a225 2
    for (i=0; i< stub->numOfStubs; i++) {
	oneStub = & (stub->stubRecords[i]);
d311 1
a311 1
    return(stub);
@


1.1
log
@Initial revision
@
text
@d7 1
a7 1
 * $Header: $
d18 1
d38 2
d45 1
a45 1
     * the raw representation ofthis stub record.
d47 1
a47 1
    size = sizeof(Prs2StubData) - sizeof(Prs2OneStub);
d55 6
a60 2
	size += sizeof(Prs2OneStubData) - sizeof(RuleLock)
		    - sizeof(Prs2SimpleQual);
d64 2
a65 2
	size += prs2LockSize(
		    prs2GetNumberOfLocks(stub->stubRecords[i].lock));
d70 19
a88 3
	for (j=0; j<stub->stubRecords[i].numQuals; j++) {
	    size += sizeof(Prs2SimpleQualData) - sizeof(char *);
	    size += stub->stubRecords[i].qualification[j].constLength;
d95 4
d100 2
a101 1
    res = (Prs2RawStub) palloc(sizeof(Prs2RawStubData) -1 + size);
d105 1
a105 1
    res->size = size;
d108 1
a108 1
     * now copy the whole thing to the res->data;
d110 1
a110 1
    s = &(res->data[0]);
d116 1
d120 8
a127 4
	size += sizeof(Prs2OneStubData) - sizeof(RuleLock)
		    - sizeof(Prs2SimpleQual);
	bcopy((char *)&(stub->stubRecords[i]), s, size);
	s += size;
d131 1
a131 2
	size += prs2LockSize(
		    prs2GetNumberOfLocks(stub->stubRecords[i].lock));
d139 1
d143 22
a164 6
	    size += sizeof(Prs2SimpleQualData) - sizeof(char *);
	    bcopy((char *) &(stub->stubRecords[i].qualification[j]), s, size);
	    s+=size;
	    size += stub->stubRecords[i].qualification[j].constLength;
	    bcopy((char *) &(stub->stubRecords[i].qualification[j].constData),
		    s, size);
d185 2
a186 2
prs2RawStubToStub(data)
char *data;
d190 1
a190 1
    Prs2SimpleQual oneQual;
d193 1
a203 3
    size = sizeof(Prs2StubData) - sizeof(Prs2OneStub);
    bcopy(data, (char *)&(stub->numOfStubs), size);
    data += size;
d205 17
a221 4
    size = stub->numOfStubs * sizeof(Prs2OneStubData);
    stub->stubRecords = (Prs2OneStub) palloc(size);
    if (stub->stubRecords == NULL) {
	elog(WARN, "prs2RawStubToStub: Out of memory");
d227 1
d229 8
a236 4
	size = sizeof(Prs2OneStubData) - sizeof(RuleLock)
		    - sizeof(Prs2SimpleQual);
	bcopy(data, (char *) oneStub, size);
	data += size;
d254 1
a254 1
	bcopy(data, *(oneStub->lock), size);
d257 9
a265 4
	size = oneStub->numQuals * sizeof(Prs2SimpleQualData);
	oneStub->qualification = (Prs2SimpleQual) palloc(size);
	if (oneStub->qualification == NULL) {
	    elog(WARN, "prs2RawStubToStub: Out of memory");
d268 4
a271 4
	    oneQual = & (oneStub->qualification[j]);
	    size = sizeof(Prs2SimpleQualData) - sizeof(char *);
	    bcopy(data, (char *) oneQual, size);
	    data += size;
d273 31
a303 4
	    size = oneQual->constLength;
	    oneQual->constData = palloc(size);
	    if (oneQual->constData == NULL) {
		elog(WARN, "prs2RawStubToStub: Out of memory");
a304 2
	    bcopy(data, oneQual->constData, size);
	    data += size;
@
