/*

   Derby - Class org.apache.derby.impl.sql.GenericPreparedStatement

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to you under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */

package org.apache.derby.impl.sql;

import java.security.PrivilegedAction;
import java.security.AccessController;
import java.sql.SQLWarning;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.derby.catalog.Dependable;
import org.apache.derby.catalog.DependableFinder;
import org.apache.derby.catalog.UUID;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.services.cache.Cacheable;
import org.apache.derby.iapi.services.context.ContextManager;
import org.apache.derby.iapi.services.context.ContextService;
import org.apache.derby.iapi.services.io.ArrayUtil;
import org.apache.derby.iapi.services.loader.GeneratedClass;
import org.apache.derby.iapi.services.monitor.ModuleFactory;
import org.apache.derby.iapi.services.monitor.Monitor;
import org.apache.derby.shared.common.sanity.SanityManager;
import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
import org.apache.derby.iapi.services.uuid.UUIDFactory;
import org.apache.derby.iapi.sql.Activation;
import org.apache.derby.iapi.sql.ParameterValueSet;
import org.apache.derby.iapi.sql.PreparedStatement;
import org.apache.derby.iapi.sql.ResultDescription;
import org.apache.derby.iapi.sql.ResultSet;
import org.apache.derby.iapi.sql.Statement;
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.iapi.sql.conn.StatementContext;
import org.apache.derby.iapi.sql.depend.DependencyManager;
import org.apache.derby.iapi.sql.depend.Provider;
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
import org.apache.derby.iapi.sql.dictionary.StatementPermission;
import org.apache.derby.iapi.sql.execute.ConstantAction;
import org.apache.derby.iapi.sql.execute.ExecCursorTableReference;
import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
import org.apache.derby.iapi.types.DataTypeDescriptor;
import org.apache.derby.iapi.types.DataTypeUtilities;
import org.apache.derby.iapi.util.ByteArray;
import org.apache.derby.impl.sql.compile.CursorNode;
import org.apache.derby.impl.sql.compile.StatementNode;

/**
 * Basic implementation of prepared statement.
 * relies on implementation of ResultDescription and Statement that
 * are also in this package.
 * <p>
 * These are both dependents (of the schema objects and prepared statements
 * they depend on) and providers.  Prepared statements that are providers
 * are cursors that end up being used in positioned delete and update
 * statements (at present).
 * <p>
 * This is impl with the regular prepared statements; they will never
 * have the cursor info fields set.
 * <p>
 * Stored prepared statements extend this implementation
 *
 */
public class GenericPreparedStatement
	implements ExecPreparedStatement
{
	///////////////////////////////////////////////
	//
	// WARNING: when adding members to this class, be
	// sure to do the right thing in getClone(): if
	// it is PreparedStatement specific like finished,
	// then it shouldn't be copied, but stuff like parameters 
	// must be copied.	
	//
	////////////////////////////////////////////////

	////////////////////////////////////////////////
	// STATE that is copied by getClone()
	////////////////////////////////////////////////
	public Statement statement;
	protected GeneratedClass activationClass; // satisfies Activation
	protected ResultDescription resultDesc;
	protected DataTypeDescriptor[] paramTypeDescriptors;
	private String			spsName;
	private SQLWarning		warnings;

	//If the query node for this statement references SESSION schema tables, mark it so in the boolean below
	//This information will be used by EXECUTE STATEMENT if it is executing a statement that was created with NOCOMPILE. Because
	//of NOCOMPILE, we could not catch SESSION schema table reference by the statement at CREATE STATEMENT time. Need to catch
	//such statements at EXECUTE STATEMENT time when the query is getting compiled.
	//This information will also be used to decide if the statement should be cached or not. Any statement referencing SESSION
	//schema tables will not be cached.
	private boolean		referencesSessionSchema;

	// fields used for cursors
	protected ExecCursorTableReference	targetTable; 
    protected List<String>           updateColumns;
	protected int 						updateMode;

	protected ConstantAction	executionConstants;
	protected Object[]	savedObjects;
    protected List<StatementPermission> requiredPermissionsList;

	// fields for dependency tracking
	protected String UUIDString;
	protected UUID   UUIDValue;

	private boolean needsSavepoint;

	private String execStmtName;
	private String execSchemaName;
	protected boolean isAtomic;
	protected String sourceTxt;

	private int inUseCount;

	// true if the statement is being compiled.
    private boolean compilingStatement;

    /** True if the statement was invalidated while it was being compiled. */
    boolean invalidatedWhileCompiling;

	////////////////////////////////////////////////
	// STATE that is not copied by getClone()
	////////////////////////////////////////////////
	// fields for run time stats
	protected long parseTime;
	protected long bindTime;
	protected long optimizeTime;
	protected long generateTime;
	protected long compileTime;
	protected Timestamp beginCompileTimestamp;
	protected Timestamp endCompileTimestamp;

	//private boolean finished;
	protected boolean isValid;
	protected boolean spsAction;

	// state for caching.
	/**
		If non-null then this object is the cacheable
		that holds us in the cache.
	*/
	private Cacheable cacheHolder;

    /**
     * Incremented for each (re)compile.
     */
    private long versionCounter;

    /**
     * Holder for row counts and execution count. Used for determining
     * whether the statement should be recompiled.
     */
    private RowCountStatistics rowCountStats = new RowCountStatistics();

	//
	// constructors
	//

	GenericPreparedStatement() {
		/* Get the UUID for this prepared statement */
		UUIDFactory uuidFactory = 
			getMonitor().getUUIDFactory();

		UUIDValue = uuidFactory.createUUID();
		UUIDString = UUIDValue.toString();
		spsAction = false;
	}

	/**
	 */
	public GenericPreparedStatement(Statement st)
	{
		this();

		statement = st;
	}

	//
	// PreparedStatement interface
	//
	public synchronized boolean	upToDate()
		throws StandardException
	{
		return isUpToDate();
	}

    /**
     * Check whether this statement is up to date and its generated class is
     * identical to the supplied class object.
     * @see ExecPreparedStatement#upToDate(GeneratedClass)
     */
    public synchronized boolean upToDate(GeneratedClass gc) {
        return (activationClass == gc) && isUpToDate();
    }

    /**
     * Unsynchronized helper method for {@link #upToDate()} and {@link
     * #upToDate(GeneratedClass)}. Checks whether this statement is up to date.
     *
     * @return {@code true} if this statement is up to date, {@code false}
     * otherwise
     */
    private boolean isUpToDate() {
        return isValid && (activationClass != null) && !compilingStatement;
    }

    /** Check if this statement is currently being compiled. */
    final synchronized boolean isCompiling() {
        return compilingStatement;
    }

    /**
     * Signal that the statement is about to be compiled. This will block
     * others from attempting to compile it.
     */
    final synchronized void beginCompiling() {
        compilingStatement = true;
        setActivationClass(null);
    }

    /**
     * Signal that we're done compiling the statement and unblock others
     * that are waiting for the compilation to finish.
     */
    final synchronized void endCompiling() {
        compilingStatement = false;
        notifyAll();
    }

	public void rePrepare(LanguageConnectionContext lcc) 
		throws StandardException {
        rePrepare(lcc, false);
    }

    public void rePrepare(LanguageConnectionContext lcc, boolean forMetaData)
        throws StandardException {
		if (!upToDate()) {
            PreparedStatement ps = statement.prepare(lcc, forMetaData);

			if (SanityManager.DEBUG)
				SanityManager.ASSERT(ps == this, "ps != this");
		}
	}

	/**
	 * Get a new activation instance.
	 *
	 * @exception StandardException thrown if finished.
	 */
	public Activation getActivation(LanguageConnectionContext lcc,
									boolean scrollable)
		throws StandardException
	{
		Activation ac;
		synchronized (this) {
			GeneratedClass gc = getActivationClass();

			if (gc == null) {
				rePrepare(lcc);
				gc = getActivationClass();
			}

			ac = new GenericActivationHolder(lcc, gc, this, scrollable);

			inUseCount++;
		}
		// DERBY-2689. Close unused activations-- this method should be called
		// when I'm not holding a lock on a prepared statement to avoid
		// deadlock.
		lcc.closeUnusedActivations();

		Activation parentAct = null;
		StatementContext stmctx = lcc.getStatementContext();

		if (stmctx != null) {
			// If not null, parentAct represents one of 1) the activation of a
			// calling statement and this activation corresponds to a statement
			// inside a stored procedure or function, and 2) the activation of
			// a statement that performs a substatement, e.g. trigger body
			// execution.
			parentAct = stmctx.getActivation();
		}

		ac.setParentActivation(parentAct);

		return ac;
	}

	/**
	 * @see PreparedStatement#executeSubStatement(LanguageConnectionContext, boolean, long)
	 */
    public ResultSet executeSubStatement(LanguageConnectionContext lcc,
										 boolean rollbackParentContext,
										 long timeoutMillis)
		throws StandardException
	{
		Activation parent = lcc.getLastActivation();
		Activation a = getActivation(lcc, false);
		a.setSingleExecution();
		lcc.setupSubStatementSessionContext(parent);
        return executeStmt(a, rollbackParentContext, false, timeoutMillis);
	}

	/**
	 * @see PreparedStatement#executeSubStatement(Activation, Activation, boolean, long)
	 */
    public ResultSet executeSubStatement(Activation parent,
										 Activation activation,
										 boolean rollbackParentContext,
										 long timeoutMillis)
		throws StandardException
	{
		parent.getLanguageConnectionContext().
			setupSubStatementSessionContext(parent);
        return executeStmt(activation, rollbackParentContext,
                           false, timeoutMillis);
	}


	/**
	 * @see PreparedStatement#execute
	 */
	public ResultSet execute(Activation activation,
                             boolean forMetaData,
							 long timeoutMillis)
			throws StandardException
	{
        return executeStmt(activation, false, forMetaData, timeoutMillis);
	}


	/**
	  *	The guts of execution.
	  *
	  *	@param	activation					the activation to run.
	  * @param rollbackParentContext True if 1) the statement context is
	  *  NOT a top-level context, AND 2) in the event of a statement-level
	  *	 exception, the parent context needs to be rolled back, too.
      * @param forMetaData true if this is a meta-data query
      * @param timeoutMillis timeout value in milliseconds.
	  *	@return	the result set to be pawed through
	  *
	  *	@exception	StandardException thrown on error
	  */
    private ResultSet executeStmt(Activation activation,
								  boolean rollbackParentContext,
                                  boolean forMetaData,
								  long timeoutMillis)
        throws
            StandardException 
	{
		boolean				needToClearSavePoint = false;

		if (activation == null || activation.getPreparedStatement() != this)
		{
			throw StandardException.newException(SQLState.LANG_WRONG_ACTIVATION, "execute");
		}

recompileOutOfDatePlan:
		while (true) {
			// verify the activation is for me--somehow.  NOTE: This is
			// different from the above check for whether the activation is
			// associated with the right PreparedStatement - it's conceivable
			// that someone could construct an activation of the wrong type
			// that points to the right PreparedStatement.
			//
			//SanityManager.ASSERT(activation instanceof activationClass, "executing wrong activation");

			/* This is where we set and clear savepoints around each individual
			 * statement which needs one.  We don't set savepoints for cursors because
			 * they're not needed and they wouldn't work in a read only database.
			 * We can't set savepoints for commit/rollback because they'll get
			 * blown away before we try to clear them.
			 */

			LanguageConnectionContext lccToUse = activation.getLanguageConnectionContext();

 			if (lccToUse.getLogStatementText())
			{
				HeaderPrintWriter istream = Monitor.getStream();
				String xactId = lccToUse.getTransactionExecute().getActiveStateTxIdString();
				String pvsString = "";
				ParameterValueSet pvs = activation.getParameterValueSet();
				if (pvs != null && pvs.getParameterCount() > 0)
				{
					pvsString = " with " + pvs.getParameterCount() +
							" parameters " + pvs.toString();
				}
				istream.printlnWithHeader(LanguageConnectionContext.xidStr + 
										  xactId + 
										  "), " +
										  LanguageConnectionContext.lccStr +
										  lccToUse.getInstanceNumber() +
										  "), " +
										  LanguageConnectionContext.dbnameStr +
										  lccToUse.getDbname() +
										  "), " +
										  LanguageConnectionContext.drdaStr +
										  lccToUse.getDrdaID() +
										  "), Executing prepared statement: " +
										  getSource() +
										  " :End prepared statement" +
										  pvsString);
			}

			ParameterValueSet pvs = activation.getParameterValueSet();

			/* put it in try block to unlock the PS in any case
			 */
			if (!spsAction) {
			// only re-prepare if this isn't an SPS for a trigger-action;
			// if it _is_ an SPS for a trigger action, then we can't just
			// do a regular prepare because the statement might contain
			// internal SQL that isn't allowed in other statements (such as a
			// static method call to get the trigger context for retrieval
			// of "new row" or "old row" values).  So in that case we
			// skip the call to 'rePrepare' and if the statement is out
			// of date, we'll get a NEEDS_COMPILE exception when we try
			// to execute.  That exception will be caught by the executeSPS()
			// method of the GenericTriggerExecutor class, and at that time
			// the SPS action will be recompiled correctly.
                rePrepare(lccToUse, forMetaData);
			}

			StatementContext statementContext = lccToUse.pushStatementContext(
				isAtomic, updateMode==CursorNode.READ_ONLY, getSource(), pvs, rollbackParentContext, timeoutMillis);

			statementContext.setActivation(activation);

			if (needsSavepoint())
			{
				/* Mark this position in the log so that a statement
				* rollback will undo any changes.
				*/
				statementContext.setSavePoint();
				needToClearSavePoint = true;
			}

			if (executionConstants != null)
			{
				lccToUse.validateStmtExecution(executionConstants);
			}

            ResultSet resultSet;
			try {
	
				resultSet = activation.execute();

				resultSet.open();
			} catch (StandardException se) {
				/* Cann't handle recompiling SPS action recompile here */
				if (!se.getMessageId().equals(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE)
						 || spsAction)
					throw se;
				statementContext.cleanupOnError(se);
				continue recompileOutOfDatePlan;

			}


			if (needToClearSavePoint)
			{
				/* We're done with our updates */
				statementContext.clearSavePoint();
			}

            lccToUse.popStatementContext(statementContext, null);

            if (activation.getSQLSessionContextForChildren() != null) {
                lccToUse.popNestedSessionContext(activation);
            }

			if (activation.isSingleExecution() && resultSet.isClosed())
			{
				// if the result set is 'done', i.e. not openable,
				// then we can also release the activation.
				// Note that a result set with output parameters 
				// or rows to return is explicitly finished 
				// by the user.
				activation.close();
			}

			return resultSet;
			
		}
	}

	public ResultDescription	getResultDescription()	{
		return resultDesc;
	}

	public DataTypeDescriptor[]	getParameterTypes()	{
        return ArrayUtil.copy(paramTypeDescriptors);
	}

    /** Return the type of the parameter (0-based indexing) */
    public DataTypeDescriptor  getParameterType( int idx ) throws StandardException
    {
		if ( paramTypeDescriptors == null )
        {
			throw StandardException.newException( SQLState.NO_INPUT_PARAMETERS );
		}

		/* Check that the parameterIndex is in range. */
		if ( (idx < 0) || (idx >= paramTypeDescriptors.length) )
        {
			/* This message matches the one used by the DBMS */
			throw StandardException.newException
                (
                 SQLState.LANG_INVALID_PARAM_POSITION, 
                 idx+1,
                 paramTypeDescriptors.length
                 );
		}

        return paramTypeDescriptors[ idx ];
    }
    

	public String getSource() {
		return (sourceTxt != null) ?
			sourceTxt : 
			(statement == null) ? 
				"null" : 
				statement.getSource();
	}

	public void setSource(String text)
	{
		sourceTxt = text;
	}

	public final void setSPSName(String name) {
		spsName = name;
	}

	public String getSPSName() {
		return spsName;
	}


	/**
	 * Get the total compile time for the associated query in milliseconds.
	 * Compile time can be divided into parse, bind, optimize and generate times.
	 * 
	 * @return long		The total compile time for the associated query in milliseconds.
	 */
	public long getCompileTimeInMillis()
	{
		return compileTime;
	}

	/**
	 * Get the parse time for the associated query in milliseconds.
	 * 
	 * @return long		The parse time for the associated query in milliseconds.
	 */
	public long getParseTimeInMillis()
	{
		return parseTime;
	}

	/**
	 * Get the bind time for the associated query in milliseconds.
	 * 
	 * @return long		The bind time for the associated query in milliseconds.
	 */
	public long getBindTimeInMillis()
	{
		return bindTime;
	}

	/**
	 * Get the optimize time for the associated query in milliseconds.
	 * 
	 * @return long		The optimize time for the associated query in milliseconds.
	 */
	public long getOptimizeTimeInMillis()
	{
		return optimizeTime;
	}

	/**
	 * Get the generate time for the associated query in milliseconds.
	 * 
	 * @return long		The generate time for the associated query in milliseconds.
	 */
	public long getGenerateTimeInMillis()
	{
		return generateTime;
	}

	/**
	 * Get the timestamp for the beginning of compilation
	 *
	 * @return Timestamp	The timestamp for the beginning of compilation.
	 */
	public Timestamp getBeginCompileTimestamp()
	{
		return DataTypeUtilities.clone( beginCompileTimestamp );
	}

	/**
	 * Get the timestamp for the end of compilation
	 *
	 * @return Timestamp	The timestamp for the end of compilation.
	 */
	public Timestamp getEndCompileTimestamp()
	{
		return DataTypeUtilities.clone( endCompileTimestamp );
	}

	void setCompileTimeWarnings(SQLWarning warnings) {
		this.warnings = warnings;
	}

	public final SQLWarning getCompileTimeWarnings() {
		return warnings;
	}

	/**
	 * Set the compile time for this prepared statement.
	 *
	 * @param compileTime	The compile time
	 */
	protected void setCompileTimeMillis(long parseTime, long bindTime,
										long optimizeTime, 
										long generateTime,
										long compileTime,
										Timestamp beginCompileTimestamp,
										Timestamp endCompileTimestamp)
	{
		this.parseTime = parseTime;
		this.bindTime = bindTime;
		this.optimizeTime = optimizeTime;
		this.generateTime = generateTime;
		this.compileTime = compileTime;
		this.beginCompileTimestamp = beginCompileTimestamp;
		this.endCompileTimestamp = endCompileTimestamp;
	}


	/**
		Finish marks a statement as totally unusable.
	 */
	public void finish(LanguageConnectionContext lcc) {

		synchronized (this) {
			inUseCount--;

			if (cacheHolder != null)
				return;

			if (inUseCount != 0) {
				//if (SanityManager.DEBUG) {
				//	if (inUseCount < 0)
				//		SanityManager.THROWASSERT("inUseCount is negative " + inUseCount + " for " + this);
				//}
				return; 
			}
		}
			
		// invalidate any prepared statements that
		// depended on this statement (including this one)
		// prepareToInvalidate(this, DependencyManager.PREPARED_STATEMENT_INVALID);
		try
		{
			/* NOTE: Since we are non-persistent, we "know" that no exception
			 * will be thrown under us.
			 */
			makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
		}
		catch (StandardException se)
		{
			if (SanityManager.DEBUG)
			{
				SanityManager.THROWASSERT("Unexpected exception", se);
			}
		}
	}

	/**
	 *	Set the Execution constants. This routine is called as we Prepare the
	 *	statement.
	 *
	 *	@param constantAction The big structure enclosing the Execution constants.
	 */
	final void	setConstantAction( ConstantAction constantAction )
	{
		executionConstants = constantAction;
	}


	/**
	 *	Get the Execution constants. This routine is called at Execution time.
	 *
	 *	@return	ConstantAction	The big structure enclosing the Execution constants.
	 */
	public	final ConstantAction	getConstantAction()
	{
		return	executionConstants;
	}

	/**
	 *	Set the saved objects. Called when compilation completes.
	 *
	 *	@param	objects	The objects to save from compilation
	 */
	final void	setSavedObjects( Object[] objects )
	{
		savedObjects = objects;
	}

	/**
	 *	Get the specified saved object.
	 *
	 *	@param	objectNum	The object to get.
	 *	@return	the requested saved object.
	 */
	public final Object	getSavedObject(int objectNum)
	{
		if (SanityManager.DEBUG) {
			if (!(objectNum>=0 && objectNum<savedObjects.length))
			SanityManager.THROWASSERT(
				"request for savedObject entry "+objectNum+" invalid; "+
				"savedObjects has "+savedObjects.length+" entries");
		}
		return	savedObjects[objectNum];
	}

	/**
	 *	Get the saved objects.
	 *
	 *	@return all the saved objects
	 */
    public final List<Object> getSavedObjects()
	{
        // Return an unmodifiable view of the underlying array, so that
        // the caller cannot modify the internal state.
        return ArrayUtil.asReadOnlyList(savedObjects);
	}

	//
	// Dependent interface
	//
	/**
		Check that all of the dependent's dependencies are valid.

		@return true if the dependent is currently valid
	 */
	public boolean isValid() {
		return isValid;
	}

	/**
	 * set this prepared statement to be valid, currently used by
	 * GenericTriggerExecutor.
	 */
	public void setValid()
	{
		isValid = true;
	}

	/**
	 * Indicate this prepared statement is an SPS action, currently used
	 * by GenericTriggerExecutor.
	 */
	public void setSPSAction()
	{
		spsAction = true;
	}

	/**
		Prepare to mark the dependent as invalid (due to at least one of
		its dependencies being invalid).

		@param	action	The action causing the invalidation
		@param	p		the provider

		@exception StandardException thrown if unable to make it invalid
	 */
	public void prepareToInvalidate(Provider p, int action, 
									LanguageConnectionContext lcc) 
		throws StandardException {

		/*
			this statement can have other open result sets
			if another one is closing without any problems.

			It is not a problem to create an index when there is an open
			result set, since it doesn't invalidate the access path that was
			chosen for the result set.
		*/
		switch (action) {
		case DependencyManager.CHANGED_CURSOR:
		case DependencyManager.CREATE_INDEX:
			// Used by activations only:
		case DependencyManager.RECHECK_PRIVILEGES:
			return;
		}

		/* Verify that there are no activations with open result sets
		 * on this prepared statement.
		 */
		lcc.verifyNoOpenResultSets(this, p, action);
	}


	/**
		Mark the dependent as invalid (due to at least one of
		its dependencies being invalid).

		@param	action	The action causing the invalidation

	 	@exception StandardException Standard Derby error policy.
	 */
	public void makeInvalid(int action, LanguageConnectionContext lcc)
		 throws StandardException
	{

		boolean alreadyInvalid;

		switch (action) {
		case DependencyManager.RECHECK_PRIVILEGES:
			return;
		}

		synchronized (this) {

			if (compilingStatement)
            {
                // Since the statement is in the process of being compiled,
                // and at the end of the compilation it will set isValid to
                // true and overwrite whatever we set it to here, set another
                // flag to indicate that an invalidation was requested. A
                // re-compilation will be triggered if this flag is set, but
                // not until the current compilation is done.
                invalidatedWhileCompiling = true;
				return;
            }

			alreadyInvalid = !isValid;
		
			// make ourseleves invalid
			isValid = false;

			// block compiles while we are invalidating
            beginCompiling();
		}

		try {

			DependencyManager dm = lcc.getDataDictionary().getDependencyManager();

			/* Clear out the old dependencies on this statement as we
			 * will build the new set during the reprepare in makeValid().
			 */
			dm.clearDependencies(lcc, this);

			/*
			** If we are invalidating an EXECUTE STATEMENT because of a stale
			** plan, we also need to invalidate the stored prepared statement.
			*/
			if (execStmtName != null) {
				switch (action) {
				case DependencyManager.INTERNAL_RECOMPILE_REQUEST:
				case DependencyManager.CHANGED_CURSOR:
				{
					/*
					** Get the DataDictionary, so we can get the descriptor for
					** the SPP to invalidate it.
					*/
					DataDictionary dd = lcc.getDataDictionary();
						
					SchemaDescriptor sd = dd.getSchemaDescriptor(execSchemaName, lcc.getTransactionCompile(), true);
					SPSDescriptor spsd = dd.getSPSDescriptor(execStmtName, sd);
					spsd.makeInvalid(action, lcc);
					break;
				}
				}
			}
		} finally {
            endCompiling();
		}
	}

	/**
	 * Is this dependent persistent?  A stored dependency will be required
	 * if both the dependent and provider are persistent.
	 *
	 * @return boolean		Whether or not this dependent is persistent.
	 */
	public boolean isPersistent()
	{
		/* Non-stored prepared statements are not persistent */
		return false;
	}

	//
	// Dependable interface
	//

	/**		
		@return the stored form of this Dependable

		@see Dependable#getDependableFinder
	 */
	public DependableFinder getDependableFinder()
	{
	    return null;
	}

	/**
	 * Return the name of this Dependable.  (Useful for errors.)
	 *
	 * @return String	The name of this Dependable..
	 */
	public String getObjectName()
	{
		return UUIDString;
	}

	/**
	 * Get the Dependable's UUID String.
	 *
	 * @return String	The Dependable's UUID String.
	 */
	public UUID getObjectID()
	{
		return UUIDValue;
	}

	/**
	 * Get the Dependable's class type.
	 *
	 * @return String		Classname that this Dependable belongs to.
	 */
	public String getClassType()
	{
		return Dependable.PREPARED_STATEMENT;
	}

	/**
	 * Return true if the query node for this statement references SESSION schema
	 * tables/views.
	 * This method gets called at the very beginning of the compile phase of any statement.
	 * If the statement which needs to be compiled is already found in cache, then there is
	 * no need to compile it again except the case when the statement is referencing SESSION
	 * schema objects. There is a small window where such a statement might get cached 
	 * temporarily (a statement referencing SESSION schema object will be removed from the
	 * cache after the bind phase is over because that is when we know for sure that the 
	 * statement is referencing SESSION schema objects.)
	 *
	 * @return	true if references SESSION schema tables, else false
	 */
	public boolean referencesSessionSchema()
	{
		return referencesSessionSchema;
	}
	
	/**
	 * Return true if the QueryTreeNode references SESSION schema tables/views.
	 * The return value is also saved in the local field because it will be 
	 * used by referencesSessionSchema() method. 
	 * This method gets called when the statement is not found in cache and 
	 * hence it is getting compiled.
	 * At the beginning of compilation for any statement, first we check if
	 * the statement's plan already exist in the cache. If not, then we add
	 * the statement to the cache and continue with the parsing and binding.
	 * At the end of the binding, this method gets called to see if the 
	 * QueryTreeNode references a SESSION schema object. If it does, then
	 * we want to remove it from the cache, since any statements referencing
	 * SESSION schema objects should never get cached.  
	 *
	 * @return	true if references SESSION schema tables/views, else false
	 */
	public boolean referencesSessionSchema(StatementNode qt)
	throws StandardException {
		//If the query references a SESSION schema table (temporary or permanent), then
		// mark so in this statement
		referencesSessionSchema = qt.referencesSessionSchema();
		return(referencesSessionSchema);
	}

	//
	// class interface
	//

	/**
		Makes the prepared statement valid, assigning
		values for its query tree, generated class,
		and associated information.

		@param qt the query tree for this statement

		@exception StandardException thrown on failure.
	 */
	void completeCompile(StatementNode qt)
						throws StandardException {
		//if (finished)
		//	throw StandardException.newException(SQLState.LANG_STATEMENT_CLOSED, "completeCompile()");

		paramTypeDescriptors = qt.getParameterTypes();

		// erase cursor info in case statement text changed
		if (targetTable!=null) {
			targetTable = null;
			updateMode = 0;
			updateColumns = null;
		}

		// get the result description (null for non-cursor statements)
		// would we want to reuse an old resultDesc?
		// or do we need to always replace in case this was select *?
		resultDesc = qt.makeResultDescription();

		// would look at resultDesc.getStatementType() but it
		// doesn't call out cursors as such, so we check
		// the root node type instead.

		if (resultDesc != null)
		{
			/*
				For cursors, we carry around some extra information.
			 */
            setCursorInfo((CursorInfo) qt.getCursorInfo());
		}
		isValid = true;

        rowCountStats.reset();
	}

	public GeneratedClass getActivationClass()
		throws StandardException
	{
		return activationClass;
	}

	void setActivationClass(GeneratedClass ac)
	{
		activationClass = ac;
	}

	//
	// ExecPreparedStatement
	//

	/**
	 * the update mode of the cursor
	 *
	 * @return	The update mode of the cursor
	 */
	public int	getUpdateMode() {
		return updateMode;
	}

	/**
	 * the target table of the cursor
	 *
	 * @return	target table of the cursor
	 */
	public ExecCursorTableReference getTargetTable() 
	{
		if (SanityManager.DEBUG)
		{
			SanityManager.ASSERT(targetTable!=null, "Not a cursor, no target table");
		}
		return targetTable;
	}

    public boolean hasUpdateColumns() {
        return updateColumns != null && !updateColumns.isEmpty();
    }

    public boolean isUpdateColumn(String columnName) {
        return updateColumns != null && updateColumns.contains(columnName);
    }

	/**
	 * Return the cursor info in a single chunk.  Used
	 * by StrorablePreparedStatement
	 */
	public Object getCursorInfo()
	{
		return new CursorInfo(
			updateMode,
			targetTable, 
			updateColumns);
	}

	void setCursorInfo(CursorInfo cursorInfo)
	{
		if (cursorInfo != null)
		{
			updateMode = cursorInfo.updateMode;
			targetTable = cursorInfo.targetTable;
			updateColumns = cursorInfo.updateColumns;
		}
	}


	//
	// class implementation
	//

	/**
	 * Get the byte code saver for this statement.
	 * Overridden for StorablePreparedStatement.  We
	 * don't want to save anything
	 *
	 * @return a byte code saver (null for us)
	 */
	ByteArray getByteCodeSaver()
	{
		return null;
	}

	/**
	 * Does this statement need a savepoint?  
	 * 
	 * @return true if this statement needs a savepoint.
	 */
	public boolean needsSavepoint()
	{
		return needsSavepoint;
	}

	/**
	 * Set the stmts 'needsSavepoint' state.  Used
	 * by an SPS to convey whether the underlying stmt
	 * needs a savepoint or not.
	 * 
	 * @param needsSavepoint true if this statement needs a savepoint.
	 */
	void setNeedsSavepoint(boolean needsSavepoint)
	{
	 	this.needsSavepoint = needsSavepoint;
	}

	/**
	 * Set the stmts 'isAtomic' state.  
	 * 
	 * @param isAtomic true if this statement must be atomic
	 * (i.e. it is not ok to do a commit/rollback in the middle)
	 */
	void setIsAtomic(boolean isAtomic)
	{
	 	this.isAtomic = isAtomic;
	}

	/**
	 * Returns whether or not this Statement requires should
	 * behave atomically -- i.e. whether a user is permitted
	 * to do a commit/rollback during the execution of this
	 * statement.
	 *
	 * @return boolean	Whether or not this Statement is atomic
	 */
	public boolean isAtomic()
	{
		return isAtomic;
	}

	/**
	 * Set the name of the statement and schema for an "execute statement"
	 * command.
	 */
	void setExecuteStatementNameAndSchema(String execStmtName,
												 String execSchemaName)
	{
		this.execStmtName = execStmtName;
		this.execSchemaName = execSchemaName;
	}

	/**
	 * Get a new prepared statement that is a shallow copy
	 * of the current one.
	 *
	 * @return a new prepared statement
	 * 
	 * @exception StandardException on error
	 */
	public ExecPreparedStatement getClone() throws StandardException
	{

		GenericPreparedStatement clone = new GenericPreparedStatement(statement);

		clone.activationClass = getActivationClass();
		clone.resultDesc = resultDesc;
		clone.paramTypeDescriptors = paramTypeDescriptors;
		clone.executionConstants = executionConstants;
		clone.UUIDString = UUIDString;
		clone.UUIDValue = UUIDValue;
		clone.savedObjects = savedObjects;
		clone.execStmtName = execStmtName;
		clone.execSchemaName = execSchemaName;
		clone.isAtomic = isAtomic;
		clone.sourceTxt = sourceTxt;
		clone.targetTable = targetTable;
		clone.updateColumns = updateColumns;
		clone.updateMode = updateMode;	
		clone.needsSavepoint = needsSavepoint;
        clone.rowCountStats = rowCountStats;

		return clone;
	}

	// cache holder stuff.
	public void setCacheHolder(Cacheable cacheHolder) {

		this.cacheHolder = cacheHolder;

		if (cacheHolder == null) {

			// need to invalidate the statement
			if (!isValid || (inUseCount != 0))
				return;

			ContextManager cm = getContextService().getCurrentContextManager();
			LanguageConnectionContext lcc = 
				(LanguageConnectionContext) 
				(cm.getContext(LanguageConnectionContext.CONTEXT_ID));

			// invalidate any prepared statements that
			// depended on this statement (including this one)
			// prepareToInvalidate(this, DependencyManager.PREPARED_STATEMENT_INVALID);
			try
			{
				/* NOTE: Since we are non-persistent, we "know" that no exception
				 * will be thrown under us.
				 */
				makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
			}
			catch (StandardException se)
			{
				if (SanityManager.DEBUG)
				{
					SanityManager.THROWASSERT("Unexpected exception", se);
				}
			}
		}
	}

    @Override
	public String toString() {
		return getObjectName();
	}

	public boolean isStorable() {
		return false;
	}

    public void setRequiredPermissionsList(
            List<StatementPermission> requiredPermissionsList)
	{
		this.requiredPermissionsList = requiredPermissionsList;
	}

    public List<StatementPermission> getRequiredPermissionsList()
	{
		return requiredPermissionsList;
	}

    public final long getVersionCounter() {
        return versionCounter;
    }

    public final void incrementVersionCounter() {
        ++versionCounter;
    }

    // Stale plan checking.

    /**
     * This class holds information about stale plan check interval,
     * execution count and row count statistics for a GenericPreparedStatement.
     *
     * The fields and methods should ideally live in GenericPreparedStatement,
     * not in a separate class. However, triggers clone the GPS on each
     * execution, which means the statistics would be reset on each execution
     * if they lived directly inside GPS. Instead, keep the statistics in an
     * object that can be shared between multiple GPS instances when they
     * are cloned.
     */
    private static class RowCountStatistics {
        private int stalePlanCheckInterval;
        private int executionCount;
        private ArrayList<Long> rowCounts;

        // No synchronization for executionCount. Since it's accessed on
        // every execution, we want to avoid synchronization. Nothing serious
        // happens if the execution count is off, we just risk checking for
        // stale plans at a different frequency than specified by
        // derby.language.stalePlanCheckInterval.
        //
        // We might want to use a java.util.concurrent.atomic.AtomicInteger
        // and its atomic incrementAndGet() method once support for pre-Java 5
        // JVMs is dropped.

        /** @see ExecPreparedStatement#incrementExecutionCount() */
        int incrementExecutionCount() {
            return ++executionCount;
        }

        /** @see ExecPreparedStatement#getInitialRowCount(int, long) */
        synchronized long getInitialRowCount(int rsNum, long rowCount) {
            // Allocate the list of row counts lazily.
            if (rowCounts == null) {
                rowCounts = new ArrayList<Long>();
            }

            // Make sure the list is big enough to hold the row count for
            // the specified result set number.
            if (rsNum >= rowCounts.size()) {
                int newSize = rsNum + 1;
                rowCounts.addAll(
                                 Collections.nCopies(newSize - rowCounts.size(), (Long) null));
            }

            // Get the initial row count for the specified result set, and
            // set it if it is not already set.
            Long initialCount = rowCounts.get(rsNum);
            if (initialCount == null) {
                rowCounts.set(rsNum, rowCount);
                return rowCount;
            } else {
                return initialCount.longValue();
            }
        }

        // No synchronization for stale plan check interval. Same reason as
        // stated above for executionCount. Since int accesses are guaranteed
        // atomic, the worst that could happen is that one thread sees it as
        // uninitialized (zero) when another thread in fact has initialized it,
        // and we end up doing the initialization work twice.

        /** @see ExecPreparedStatement#setStalePlanCheckInterval(int) */
        void setStalePlanCheckInterval(int interval) {
            stalePlanCheckInterval = interval;
        }

        /** @see ExecPreparedStatement#getStalePlanCheckInterval() */
        int getStalePlanCheckInterval() {
            return stalePlanCheckInterval;
        }

        /** Reset all the row count statistics. */
        synchronized void reset() {
            stalePlanCheckInterval = 0;
            executionCount = 0;
            rowCounts = null;
        }
    }

    /** @see ExecPreparedStatement#incrementExecutionCount() */
    public int incrementExecutionCount() {
        return rowCountStats.incrementExecutionCount();
    }

    /** @see ExecPreparedStatement#setStalePlanCheckInterval(int) */
    public void setStalePlanCheckInterval(int interval) {
        rowCountStats.setStalePlanCheckInterval(interval);
    }

    /** @see ExecPreparedStatement#getStalePlanCheckInterval() */
    public int getStalePlanCheckInterval() {
        return rowCountStats.getStalePlanCheckInterval();
    }

    /** @see ExecPreparedStatement#getInitialRowCount(int, long) */
    public long getInitialRowCount(int rsNum, long currentRowCount) {
        return rowCountStats.getInitialRowCount(rsNum, currentRowCount);
    }
    
    /**
     * Privileged lookup of the ContextService. Must be private so that user code
     * can't call this entry point.
     */
    private  static  ContextService    getContextService()
    {
        return AccessController.doPrivileged
            (
             new PrivilegedAction<ContextService>()
             {
                 public ContextService run()
                 {
                     return ContextService.getFactory();
                 }
             }
             );
    }

    
    /**
     * Privileged Monitor lookup. Must be private so that user code
     * can't call this entry point.
     */
    private  static  ModuleFactory  getMonitor()
    {
        return AccessController.doPrivileged
            (
             new PrivilegedAction<ModuleFactory>()
             {
                 public ModuleFactory run()
                 {
                     return Monitor.getMonitor();
                 }
             }
             );
    }

}
