head	1.28;
access;
symbols
	Version_2_1:1.17;
locks; strict;
comment	@ * @;


1.28
date	92.07.13.06.10.28;	author mao;	state Exp;
branches;
next	1.27;

1.27
date	92.06.28.03.49.21;	author mao;	state Exp;
branches;
next	1.26;

1.26
date	92.04.03.01.11.30;	author mer;	state Exp;
branches;
next	1.25;

1.25
date	92.03.25.17.31.03;	author hong;	state Exp;
branches;
next	1.24;

1.24
date	91.11.18.17.35.47;	author mer;	state Exp;
branches;
next	1.23;

1.23
date	91.11.17.21.04.09;	author mer;	state Exp;
branches;
next	1.22;

1.22
date	91.04.19.05.38.22;	author kemnitz;	state Exp;
branches;
next	1.21;

1.21
date	91.04.10.16.12.45;	author sp;	state Exp;
branches;
next	1.20;

1.20
date	91.04.08.18.15.27;	author sp;	state Exp;
branches;
next	1.19;

1.19
date	91.03.29.15.57.34;	author sp;	state Exp;
branches;
next	1.18;

1.18
date	91.03.20.01.07.00;	author sp;	state Exp;
branches;
next	1.17;

1.17
date	91.02.24.20.00.19;	author sp;	state Exp;
branches;
next	1.16;

1.16
date	91.02.24.12.41.28;	author sp;	state Exp;
branches;
next	1.15;

1.15
date	91.02.11.17.10.48;	author sp;	state Exp;
branches;
next	1.14;

1.14
date	91.01.17.19.06.28;	author sp;	state Exp;
branches;
next	1.13;

1.13
date	91.01.09.19.08.47;	author sp;	state Exp;
branches;
next	1.12;

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

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

1.10
date	90.10.02.08.50.46;	author hong;	state Exp;
branches;
next	1.9;

1.9
date	90.09.25.16.43.06;	author kemnitz;	state Exp;
branches;
next	1.8;

1.8
date	90.06.11.03.52.13;	author kemnitz;	state Exp;
branches;
next	1.7;

1.7
date	90.06.11.03.22.29;	author kemnitz;	state Exp;
branches;
next	1.6;

1.6
date	90.06.11.02.28.09;	author kemnitz;	state Exp;
branches;
next	1.5;

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

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

1.3
date	90.03.07.17.21.10;	author sp;	state Exp;
branches;
next	1.2;

1.2
date	90.01.31.03.54.48;	author sp;	state Exp;
branches;
next	1.1;

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


desc
@Code to retrieve/run rule plans.
@


1.28
log
@get rid of spurious elogs
@
text
@/*===================================================================
 *
 * FILE:
 *   prs2plans.c
 *
 * IDENTIFICATION:
 *   $Header: /private/mao/postgres/src/rules/prs2/RCS/prs2plans.c,v 1.27 1992/06/28 03:49:21 mao Exp mao $
 *
 * DESCRIPTION:
 *   Various useful routines called by the PRS2 code...
 *
 *
 *===================================================================
 */

#include "tmp/postgres.h"
#include "tmp/datum.h"
#include "catalog/syscache.h"
#include "utils/log.h"
#include "nodes/plannodes.h"		/* for EState */
#include "nodes/plannodes.a.h"		/* for EState */
#include "nodes/execnodes.h"		/* for EState */
#include "nodes/execnodes.a.h"		/* for EState */
#include "executor/execdefs.h"
#include "executor/x_execmain.h"
#include "parser/parsetree.h"
#include "utils/fmgr.h"
#include "tcop/dest.h"

#include "catalog/pg_prs2rule.h"
#include "catalog/pg_prs2plans.h"

extern EState CreateExecutorState();
RuleLock prs2SLOWGetLocksFromRelation();

/*-------------------------------------------------------------------
 * prs2GetRulePlanFromCatalog
 * Given a rule id and a plan number get the appropriate plan
 * from the system catalogs. At the same time construct a list
 * with all the Param nodes contained in this plan.
 */
LispValue
prs2GetRulePlanFromCatalog(ruleId, planNumber, paramListP)
ObjectId ruleId;
Prs2PlanNumber planNumber;
ParamListInfo *paramListP;
{
    

    HeapTuple planTuple;
    struct prs2plans *planStruct;
    char *planString;
    LispValue plan;
    char *getstruct();
    char *t;

    /*
     * get the tuple form the system cache
     */
    planTuple = SearchSysCacheTuple(PRS2PLANCODE, ruleId, planNumber);
    if (planTuple == NULL) {
	/*
	 * No such rule exist! Complain!
	 */
	elog(WARN,
	"prs2GetRulePlanFromCatalog: plan NOT found (rulid=%ld,planno=%d)\n",
	ruleId, planNumber);
	return(LispNil);
    }

    /*
     * given the tuple extract the 'struct prs2plans' structure
     */
    planStruct = (struct prs2plans *) GETSTRUCT(planTuple);

    /*
     * This is a little bit tricky but it works!
     *
     * t = VARDATA(&planStruct->prs2code);
     * planString = PSIZESKIP(t);
     *
     * Unfortunately it assumes the wrong semantics, and this
     * causes problems when things change.
     */
     planString = VARDATA(&(planStruct->prs2code));

    if (paramListP == NULL)
	plan = StringToPlan(planString);
    else
	plan = StringToPlanWithParams(planString, paramListP);

    return(plan);
}

/*------------------------------------------------------------------
 *
 * prs2GetLocksFromRelation
 *
 * Given a relation, find all its relation level locks.
 * We have to go to the RelationRelation, get the tuple that corresponds
 * to the given relation and extract its locks field.
 *
 * NOTE: we are returning a pointer to a *copy* of the locks!
 */
RuleLock
prs2GetLocksFromRelation(relationName)
Name relationName;
{
    HeapTuple relationTuple;
    RuleLock relationLocks;

    /*
     * Search the system cache for the relation tuple
     */
    relationTuple = SearchSysCacheTuple(RELNAME,
			    relationName,
			    (char *) NULL,
			    (char *) NULL,
			    (char *) NULL);
    if (!HeapTupleIsValid(relationTuple)) {
	elog(WARN, "prs2GetLocksFromRelation: no rel with name '%s'\n",
	relationName);
    }

    relationLocks = prs2GetLocksFromTuple(relationTuple, InvalidBuffer);

    return(relationLocks);
}

/*------------------------------------------------------------------
 * prs2SLOWGetLocksFromRelation
 *
 * get the locks but without using the sys cache.
 * Do a scan in the pg_class...
 * The only reason for the existence of this routine was a flaky system
 * cache... I kust keep it here in case things are broken again.
 *
 *------------------------------------------------------------------
 */
RuleLock
prs2SLOWGetLocksFromRelation(relationName)
Name relationName;
{
    Relation rel;
    TupleDescriptor tdesc;
    ScanKeyData scanKey;
    HeapScanDesc scanDesc;
    HeapTuple tuple;
    Buffer buffer;
    RuleLock locks;

    rel = RelationNameOpenHeapRelation(Name_pg_relation);
    tdesc = RelationGetTupleDescriptor(rel);
    /*----
     * Scan pg_relation
     */
	ScanKeyEntryInitialize(&scanKey.data[0], 0, Anum_pg_relation_relname,
						   F_CHAR16EQ, NameGetDatum(relationName));
    scanDesc = RelationBeginHeapScan(rel, false, NowTimeQual, 1, &scanKey);
    tuple = HeapScanGetNextTuple(scanDesc, false, &buffer);
    locks = prs2GetLocksFromTuple(tuple, buffer);
    RelationCloseHeapRelation(rel);
    HeapScanEnd(scanDesc);

    return(locks);
}
/*------------------------------------------------------------------
 *
 * prs2CheckQual
 *
 * Return 1 if the given rule qualification is true
 * (i.e. it returns at least one tuple).
 * Otherwise return 0.
 *
 * NOTE: A null qualification always evaluates to true.
 *
 */
int
prs2CheckQual(planQual, paramList, prs2EStateInfo)
LispValue planQual;
ParamListInfo paramList;
Prs2EStateInfo prs2EStateInfo;
{
    int status;

    if (planQual == LispNil)
	return(1);

    status = prs2RunOnePlanAndGetValue(
		    planQual,
		    paramList,
		    prs2EStateInfo,
		    NULL, NULL, NULL);
    
    return(status);
}

/*------------------------------------------------------------------
 *
 * prs2RunActionPlans
 *
 */

void
prs2RunActionPlans(plans, paramList, prs2EStateInfo)
LispValue plans;
ParamListInfo paramList;
Prs2EStateInfo prs2EStateInfo;
{
    int feature;
    LispValue onePlan;

    foreach(onePlan, plans) {
	/*
	 * XXX SOS XXX
	 * What kind of 'feature' should we use ??
	 */
	feature = EXEC_RUN;
	prs2RunOnePlan(CAR(onePlan), paramList, prs2EStateInfo, feature);
    }
	
}

/*------------------------------------------------------------------
 *
 * prs2RunOnePlanAndGetValue
 *
 * Run a retrieve plan and return 1 if a tuple was found or 0 if there
 * was no tuple.
 * 
 * Sometimes when we call this routine, we are only interested in
 * whether there is a tuple returned or not, but we are *not*
 * interested in the tuple itself (for instance, when we test
 * a rule qualification).
 * In this case, "valueP" and "isNullP" are NULL
 *
 * On the other hand, sometimes (when we execute the action part of an 
 * "on retrieve ... do instead retrieve ..." rule) we want the value of
 * the tuple's attribute too. This tuple has always one attribute.
 * NOTE: We make a copy of the attribute!
 * 
 */

int
prs2RunOnePlanAndGetValue(actionPlan, paramList, prs2EStateInfo,
			    valueP, isNullP)
LispValue actionPlan;
ParamListInfo paramList;
Prs2EStateInfo prs2EStateInfo;
Datum *valueP;
Boolean *isNullP;
{
    
    AttributeNumber numberOfAttributes;
    TupleDescriptor resultTupleDescriptor;
    LispValue queryDescriptor;
    LispValue res1, res2, res3;
    EState executorState;
    HeapTuple resultTuple;
    TupleTableSlot slot;
    bool oldPolicy;
    int status;

    queryDescriptor = prs2MakeQueryDescriptorFromPlan(actionPlan);

    executorState = CreateExecutorState();
    set_es_param_list_info(executorState, paramList);
    set_es_prs2_info(executorState, prs2EStateInfo);

    res1 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_START), LispNil));


    /*
     * When the executor is called with EXEC_START it returns
     * "lispCons(LispInteger(n), lispCons(t, lispNil))"
     * where 'n' is the number of attributes in the result tuple
     * and 't' is an 'AttributePtr'.
     * XXX Note: it appears that 'AttributePtr' and 'TupleDescriptor'
     * are the same thing!
     */

    /*
     * XXX - 
     * Unfortunately, by now the executor has freed (with pfree) the tuple
     * descriptor!!!  You will have to either copy it or work out something
     * with Cim - I hacked the executor to avoid freeing this for now,
     * but it *should* be freeing these things to prevent memory leaks.
     *
     * -- Greg
     */
    numberOfAttributes = (AttributeNumber) CInteger(CAR(res1));
    resultTupleDescriptor = (TupleDescriptor) CADR(res1);


    /*
     * now retrieve one tuple
     */
    res2 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_RETONE), LispNil));
    /*
     * "res2" is a 'TupleTableSlot', containing a tuple that will
     * might be freed by the next call to the executor (with operation
     * EXEC_END). However, we might want to use the values of this
     * tuple, in which case we must not free it.
     * To do that, we copy the given slot to another one
     * and change the "freeing policy" of the original slot
     * to "false"
     */
    slot = (TupleTableSlot) res2;
    resultTuple = (HeapTuple) ExecFetchTuple(slot);
    if (resultTuple == NULL) { 
	/*
	 * No tuple was returned...
	 * XXX What shall we do??
	 * Options:
	 *    1) bomb!
	 *    2) continue with the next rule
	 *    3) assume a nil value
	 * Currently option (2) is implemented.
	 */
	status = 0;	/* this means no value found */
    } else {
	/*
	 * A tuple was found. Find the value of its attribute.
	 * NOTE: for the time being we assume that this tuple
	 * has only one attribute!
	 */
	Datum val;

	if (valueP != NULL && isNullP != NULL) {
	    val = HeapTupleGetAttributeValue(
			resultTuple,
			InvalidBuffer,
			(AttributeNumber) 1,
			resultTupleDescriptor,
			isNullP);
	    *valueP = datumCopy(val,
			resultTupleDescriptor->data[0]->atttypid,
			resultTupleDescriptor->data[0]->attbyval,
			(Size) resultTupleDescriptor->data[0]->attlen);

	}
	status = 1;
    }

    /*
     * let the executor do the cleaning up...
     */
    res3 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_END), LispNil));
    
    return(status);
}

/*------------------------------------------------------------------
 *
 * prs2RunOnePlan
 *
 * Run one plan. Ignore the return values from the executor.
 *
 */

void
prs2RunOnePlan(actionPlan, paramList, prs2EStateInfo, operation)
LispValue actionPlan;
ParamListInfo paramList;
Prs2EStateInfo prs2EStateInfo;
int operation;
{
    LispValue queryDescriptor;
    LispValue res1, res2, res3;
    EState executorState;
	TupleDescriptor foo; /* XXX Hack for making copy of tuple descriptor */

    queryDescriptor = prs2MakeQueryDescriptorFromPlan(actionPlan);

    executorState = CreateExecutorState();
    set_es_param_list_info(executorState, paramList);
    set_es_prs2_info(executorState, prs2EStateInfo);

    res1 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_START), LispNil));

    res2 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(operation), LispNil));
    res3 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_END), LispNil));
}

/*------------------------------------------------------------------
 *
 * prs2IsRuleInsteadFromRuleInfo
 *
 * Given the 'rule info' stored in pg_prs2plans return true iff
 * a rule is an 'instead' rule, otherwise return false
 */
Boolean
prs2IsRuleInsteadFromRuleInfo(ruleInfo)
LispValue ruleInfo;
{
    LispValue t;
    char *s;

    t = CAR(ruleInfo);
    s = CString(t);

    if (!strcmp("instead", s)) {
	return((Boolean) 1);
    } else {
	return((Boolean) 0);
    }
}

/*------------------------------------------------------------------
 *
 * prs2GetEventAttributeNumberFromRuleInfo
 *
 * Given the 'rule info' as stored in pg_prs2plans, 
 * return the attribute number of the attribute specified in the
 * 'ON EVENT to REL.attr' clause
 */
AttributeNumber
prs2GetEventAttributeNumberFromRuleInfo(ruleInfo)
LispValue ruleInfo;
{
    LispValue t;
    int n;

    t = CAR(CDR(ruleInfo));
    n = CInteger(t);

    return(n);
}


/*------------------------------------------------------------------
 *
 * prs2GetUpdatedAttributeNumberFromRuleInfo
 *
 * Given the 'rule info' as stored in pg_prs2plans, 
 * return the attribute number of the attribute of the CURRENT tuple
 * which is updated by the rule. This only applies to rules of the
 * form 'ON RETRIEVE TO REL.X DO RETRIEVE INSTEAD (X = ...)' or
 * 'ON REPLACE TO REL.Y DO REPLACE CURRENT(X = ....)'.
 */
AttributeNumber
prs2GetUpdatedAttributeNumberFromRuleInfo(ruleInfo)
LispValue ruleInfo;
{
    LispValue t;
    int n;

    t = CAR(CDR(CDR(ruleInfo)));
    n = CInteger(t);

    return(n);
}


/*------------------------------------------------------------------
 *
 * prs2MakeQueryDescriptorFromPlan
 *
 * Given the actionPlan, the paramList and the prs2EStateInfo,
 * create a query descriptor
 */

LispValue
prs2MakeQueryDescriptorFromPlan(actionPlan)
LispValue actionPlan;
{
    LispValue queryDescriptor;
    LispValue parseTree;
    LispValue plan;
    LispValue command;


    /*
     * the actionPlan must be a list containing the parsetree & the
     * plan that has to be executed.
     */
    parseTree = prs2GetParseTreeFromOneActionPlan(actionPlan);
    plan = prs2GetPlanFromOneActionPlan(actionPlan);

    command = root_command_type_atom(parse_root(parseTree));

    queryDescriptor = (LispValue)
			MakeQueryDesc(
			    command,
			    parseTree,
			    plan,
			    LispNil,
			    LispNil,
			    LispNil,
			    LispNil,
			    lispInteger(0),
			    None);

    return(queryDescriptor);
}
@


1.27
log
@rearrange parse, plan to support postquel function invocations
@
text
@d7 1
a7 1
 *   $Header: /private/mao/postgres/src/rules/prs2/RCS/prs2plans.c,v 1.26 1992/04/03 01:11:30 mer Exp mao $
d65 1
a65 1
	elog(DEBUG,
@


1.26
log
@used to double write the varlena size, but no more.  Don't need PSIZESKIP.
@
text
@d7 1
a7 1
 *   $Header: /u/mer/pg/src/rules/prs2/RCS/prs2plans.c,v 1.25 1992/03/25 17:31:03 hong Exp mer $
d495 3
@


1.25
log
@plugged buffer leaks
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.24 91/11/18 17:35:47 mer Exp $
d78 6
d85 1
a85 2
    t = VARDATA(&planStruct->prs2code);
    planString = PSIZESKIP(t);
@


1.24
log
@prototyping fixes - i'll be back (want to sync tree for now)
@
text
@d7 1
a7 1
 *   $Header: /users/mer/postgres/src/rules/prs2/RCS/prs2plans.c,v 1.23 1991/11/17 21:04:09 mer Exp $
d158 1
@


1.23
log
@prototyping
@
text
@d7 1
a7 1
 *   $Header: /users/mer/postgres/src/rules/prs2/RCS/prs2plans.c,v 1.22 1991/04/19 05:38:22 kemnitz Exp mer $
d20 2
@


1.22
log
@uses new scankey stuff
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.21 91/04/10 16:12:45 sp Exp Locker: kemnitz $
d480 2
a481 1
    queryDescriptor = MakeQueryDesc(
@


1.21
log
@Now `prs2GetLocksFromTuple()' only takes 2 arguments...
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.20 91/04/08 18:15:27 sp Exp Locker: sp $
d150 2
a151 4
    scanKey.data[0].flags = 0;
    scanKey.data[0].attributeNumber = Anum_pg_relation_relname;
    scanKey.data[0].procedure = F_CHAR16EQ;
    scanKey.data[0].argument = NameGetDatum(relationName);
@


1.20
log
@misc changes to support locking more than one path in the rule
qualification's tree...
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.19 91/03/29 15:57:34 sp Exp $
d118 1
a118 9
    /*
     * I hope that this is gonna work! (tupleDescriptor == NULL !!!!)
     * (Yes, it is going to work, actually prs2GetLocksFromTuple
     * does not even use the tupdesc...
     */
    relationLocks = prs2GetLocksFromTuple(
			    relationTuple,
			    InvalidBuffer,
			    (TupleDescriptor) NULL);
d156 1
a156 1
    locks = prs2GetLocksFromTuple( tuple, buffer, (TupleDescriptor) NULL);
@


1.19
log
@the system cache works just fine, use it!
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.18 91/03/20 01:07:00 sp Exp Locker: sp $
d80 4
a83 1
    plan = StringToPlanWithParams(planString, paramListP);
@


1.18
log
@HACK HACK HACK (for the video demo)
Don't use the system cache to get the rules of the relation.
but scan pg_class instead (slooooow!)
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.17 91/02/24 20:00:19 sp Exp $
a101 2
    return(prs2SLOWGetLocksFromRelation(relationName));

d117 2
a123 10
/* #define RULE_BUG_DEBUG */
#ifdef RULE_BUG_DEBUG
    {
	Relation rel;
	TupleDescriptor tdesc;
	ScanKeyData scanKey;
	HeapScanDesc scanDesc;
	HeapTuple tuple;
	Buffer buffer;
	RuleLock locks;
a124 31
	printf("------- prs2GetLocksFromRelation(%s)\n", relationName);
	/*----
	 * print the tuple as returned by the sys cache...
	 */
	rel = RelationNameOpenHeapRelation(Name_pg_relation);
	tdesc = RelationGetTupleDescriptor(rel);
	printf("------- sys cache tuple = \n");
	debugtup(relationTuple, tdesc);
	printf("------- locks of sys cache tuple:");
	prs2PrintLocks(relationLocks); printf("\n");
	/*----
	 * Scan pg_relation
	 */
	scanKey.data[0].flags = 0;
	scanKey.data[0].attributeNumber = Anum_pg_relation_relname;
	scanKey.data[0].procedure = F_CHAR16EQ;
	scanKey.data[0].argument = NameGetDatum(relationName);
	scanDesc = RelationBeginHeapScan(rel, false, NowTimeQual, 1, &scanKey);
	tuple = HeapScanGetNextTuple(scanDesc, false, &buffer);
	locks = prs2GetLocksFromTuple( tuple, buffer, (TupleDescriptor) NULL);
	printf("------- pg_relation tuple = \n");
	debugtup(tuple, tdesc);
	printf("------- locks of pg_relation tuple:");
	prs2PrintLocks(locks); printf("\n");
	/*---
	 * Close all open rel descriptors..
	 */
	RelationCloseHeapRelation(rel);
    }
#endif RULE_BUG_DEBUG

d133 2
@


1.17
log
@The executor does not understand EXEC_RESULT any more...
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.16 91/02/24 12:41:28 sp Exp $
d32 1
d102 2
d169 36
@


1.16
log
@elog NOTICE ----> elog DEBUG 
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.15 91/02/11 17:10:48 sp Exp Locker: sp $
d217 1
a217 1
	feature = EXEC_RESULT;
@


1.15
log
@MakeQueryDesc now takes an extra argument ("None" in our case).
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.14 91/01/17 19:06:28 sp Exp Locker: sp $
d62 1
a62 1
	elog(NOTICE,
d149 2
a150 2
	scanDesc = RelationBeginHeapScan(rel, 0, NowTimeQual, 1, &scanKey);
	tuple = HeapScanGetNextTuple(scanDesc, 0, &buffer);
@


1.14
log
@do not bomb if you can not find a rule plan (just ignore the rule).
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.13 91/01/09 19:08:47 sp Exp $
d26 1
d492 2
a493 1
			    LispNil);
@


1.13
log
@'copyDatum' became 'datumCopy' and takes different arguments.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.12 90/11/28 19:23:19 sp Exp $
d61 1
a61 1
	elog(WARN,
d64 1
@


1.12
log
@added some debugging code (in my desparate attmepts to trace this
infamous "rule bug") ...
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.11 90/10/16 17:20:03 sp Exp $
a326 1
	ObjectId type;
d335 5
a339 2
	    type = resultTupleDescriptor->data[0]->atttypid;
	    *valueP = copyDatum(val, type);
@


1.11
log
@quite a few changes because ExecMain returns a tuple slot & 
(unless otherwise told to) frees the tuples returned...
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.10 90/10/02 08:50:46 hong Exp $
d25 1
d119 42
@


1.10
log
@gotten rid of executor.h which fills up compiler symbol table.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.10 90/10/01 16:29:17 hong Exp $
d17 1
d125 6
a137 2
    Datum dummyDatum;
    Boolean dummyIsNull;
d147 1
a147 2
		    &dummyDatum,
		    &dummyIsNull);
d184 6
a189 3
 * In the first case, the tuple must have only one attribute,
 * and output arguments *valueP and *isNullP, contain the value and the
 * isNull flag for this attribute.
d191 5
d200 1
a200 1
                        valueP, isNullP)
a207 1
    LispValue res1, res2, res3, result;
d210 3
d214 3
d218 1
a218 1
    result = prs2RunOnePlan(actionPlan,paramList,prs2EStateInfo,EXEC_RETONE);
d220 3
a222 3
    res1 = nth(0, result);
    res2 = nth(1, result);
    res3 = nth(2, result);
d224 4
d237 9
a245 10
	/*
	 * XXX - 
	 * Unfortunately, by now the executor has freed (with pfree) the tuple
	 * descriptor!!!  You will have to either copy it or work out something
	 * with Cim - I hacked the executor to avoid freeing this for now, but it
	 * *should* be freeing these things to prevent memory leaks.
	 *
	 * -- Greg
	 */

d249 18
a266 1
    if (res2 == LispNil) { 
d276 1
a276 1
	return(0);	/* this means no value found */
d283 14
a296 8
	resultTuple = (HeapTuple) CAR(res2);
	*valueP = HeapTupleGetAttributeValue(
		    resultTuple,
		    InvalidBuffer,
		    (AttributeNumber) 1,
		    resultTupleDescriptor,
		    isNullP);
	return(1);
d298 8
d312 1
a312 1
 * Run one plan and return the executor's return values.
d316 1
a316 1
LispValue
d324 1
a324 1
    LispValue res1, res2, res3, result;
a338 1

a340 7

    
    result = lispCons(res3, LispNil);
    result = lispCons(res2, result);
    result = lispCons(res1, result);

    return(result);
@


1.9
log
@Updating from revision 1.8 to revision 1.10
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.10 90/08/13 20:30:01 sp Exp $
d19 5
a23 1
#include "executor/executor.h"		/* for EState */
@


1.8
log
@undid last checkin.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.7 90/06/11 03:22:29 kemnitz Exp Locker: kemnitz $
d16 7
a22 6
#include "c.h"
#include "postgres.h"
#include "syscache.h"
#include "log.h"
/* #include "prs2.h" */
#include "executor.h"		/* for EState */
@


1.7
log
@Hacks added to make copy - executor try unsuccessful.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.6 90/06/11 02:28:09 kemnitz Exp Locker: kemnitz $
a279 4

	foo = palloc(sizeof(TupleDescriptorData));  /* XXX Massive Hack */
	*foo = * ((TupleDescriptor) CADR(res1));    /* XXX to make copy of tuple */
	CADR(res1) = foo;                           /* XXX descriptor */
@


1.6
log
@Added a few comments.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.5 90/04/19 19:53:55 sp Exp Locker: kemnitz $
d270 1
d280 4
@


1.5
log
@New function: prs2MakeQueryDescriptorFromPlan()
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.4 90/04/03 17:15:29 sp Exp $
d210 11
@


1.4
log
@Now the 'ruleInfo' field (as stroed in pg_prs2plans)
contains information about the 'event' attribute (the one specified
in the ON xxxxx clause of the rule) and the 'updated' attribute
(the one that is actually updated by a rule).
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.3 90/03/07 17:21:10 sp Exp $
d20 1
a20 1
#include "prs2.h"
a255 1
    EState executorState;
d258 1
a258 3
    LispValue parseTree;
    LispValue plan;
    LispValue command;
d260 1
a261 16
    /*
     * the actionPlan must be a list containing the parsetree & the
     * plan that has to be executed.
     */
    parseTree = prs2GetParseTreeFromOneActionPlan(actionPlan);
    plan = prs2GetPlanFromOneActionPlan(actionPlan);

    command = root_command_type_atom(parse_root(parseTree));

    queryDescriptor = MakeQueryDesc(
			    command,
			    parseTree,
			    plan,
			    LispNil,
			    LispNil);

d352 37
@


1.3
log
@minor bug fixes.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.2 90/01/31 03:54:48 sp Exp $
d300 70
@


1.2
log
@many small modifications.
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.1 90/01/11 14:43:43 sp Exp Locker: sp $
d136 1
d155 1
d159 6
a164 1
	prs2RunOnePlan(CAR(onePlan), paramList, prs2EStateInfo);
d196 1
a196 1
    result = prs2RunOnePlan(actionPlan, paramList, prs2EStateInfo, EXEC_START);
@


1.1
log
@Initial revision
@
text
@d7 1
a7 1
 *   $Header: RCS/prs2plans.c,v 1.2 90/01/11 00:23:03 sp Exp Locker: sp $
a20 2
#include "ruleutil.h"		/* for StringToPlan(), MakeQueryDesc()
				CreateExecutorState() */
d23 2
d85 1
a85 1
Prs2Locks
d90 1
a90 1
    Prs2Locks relationLocks;
d144 20
d166 6
d176 1
a176 1
			valueP, isNullP)
d183 2
a184 3
    EState executorState;
    LispValue queryDescriptor;
    LispValue res1, res2, res3;
a187 2
    LispValue parseTree;
    LispValue plan;
d189 1
d191 3
a193 6
    /*
     * the actionPlan must be a list containing the parsetree & the
     * plan that has to be executed.
     */
    parseTree = prs2GetParseTreeFromOneActionPlan(actionPlan);
    plan = prs2GetPlanFromOneActionPlan(actionPlan);
a194 17
    if (root_command_type(parse_root(parseTree)) != RETRIEVE) {
	elog(WARN,"prs2RunPlanAndGetValue: plan is not a retrieve");
    }
    queryDescriptor = MakeQueryDesc(
			    lispAtom("retrieve"),
			    parseTree,
			    plan,
			    LispNil,
			    LispNil);

    executorState = CreateExecutorState();
    set_es_param_list_info(executorState, paramList);
    set_es_prs2_info(executorState, prs2EStateInfo);

    res1 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_START), LispNil));
    
a205 6
    res2 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_RETONE), LispNil));

    res3 = ExecMain(queryDescriptor, executorState,
		    lispCons(lispInteger(EXEC_END), LispNil));

d236 1
a236 1
 * prs2RunActionPlans
d238 2
d242 3
a244 3
void
prs2RunActionPlans(plan, paramList, prs2EStateInfo)
LispValue plan;
d247 1
d249 43
@
