blob: 38a6f7b5f3d05f742cf7746231cfdaaa736c94a2 [file] [log] [blame]
/*
Derby - Class org.apache.derby.impl.sql.catalog.SYSSTATEMENTSRowFactory
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.catalog;
import org.apache.derby.iapi.reference.Property;
import org.apache.derby.iapi.types.DataTypeDescriptor;
import org.apache.derby.iapi.types.SQLBoolean;
import org.apache.derby.iapi.types.SQLVarchar;
import org.apache.derby.iapi.types.TypeId;
import org.apache.derby.iapi.types.UserType;
import org.apache.derby.iapi.types.DataValueDescriptor;
import org.apache.derby.iapi.store.raw.RawStoreFactory;
import org.apache.derby.iapi.types.TypeId;
import org.apache.derby.iapi.sql.dictionary.SystemColumn;
import org.apache.derby.catalog.TypeDescriptor;
import org.apache.derby.iapi.types.DataValueFactory;
import org.apache.derby.iapi.types.RowLocation;
import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
import org.apache.derby.iapi.sql.execute.ExecIndexRow;
import org.apache.derby.iapi.sql.execute.ExecRow;
import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
import org.apache.derby.iapi.sql.execute.ExecutionFactory;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.services.monitor.Monitor;
import org.apache.derby.catalog.UUID;
import org.apache.derby.iapi.services.uuid.UUIDFactory;
import org.apache.derby.iapi.types.*;
import org.apache.derby.shared.common.sanity.SanityManager;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Properties;
/**
* Factory for creating a SYSSTATEMENTS row.
*
*
* @version 0.1
*/
public class SYSSTATEMENTSRowFactory extends CatalogRowFactory
{
static final String TABLENAME_STRING = "SYSSTATEMENTS";
/* Column #s for sysinfo (1 based) */
public static final int SYSSTATEMENTS_STMTID = 1;
public static final int SYSSTATEMENTS_STMTNAME = 2;
public static final int SYSSTATEMENTS_SCHEMAID = 3;
public static final int SYSSTATEMENTS_TYPE = 4;
public static final int SYSSTATEMENTS_VALID = 5;
public static final int SYSSTATEMENTS_TEXT = 6;
public static final int SYSSTATEMENTS_LASTCOMPILED = 7;
public static final int SYSSTATEMENTS_COMPILATION_SCHEMAID = 8;
public static final int SYSSTATEMENTS_USINGTEXT = 9;
public static final int SYSSTATEMENTS_CONSTANTSTATE = 10;
public static final int SYSSTATEMENTS_INITIALLY_COMPILABLE = 11;
public static final int SYSSTATEMENTS_COLUMN_COUNT = SYSSTATEMENTS_INITIALLY_COMPILABLE;
public static final int SYSSTATEMENTS_HIDDEN_COLUMN_COUNT = 2;
protected static final int SYSSTATEMENTS_INDEX1_ID = 0;
protected static final int SYSSTATEMENTS_INDEX2_ID = 1;
private static final int[][] indexColumnPositions =
{
{SYSSTATEMENTS_STMTID},
{SYSSTATEMENTS_STMTNAME, SYSSTATEMENTS_SCHEMAID}
};
private static final boolean[] uniqueness = null;
private static final String[] uuids =
{
"80000000-00d1-15f7-ab70-000a0a0b1500" // catalog UUID
,"80000000-00d1-15fc-60b9-000a0a0b1500" // heap UUID
,"80000000-00d1-15fc-eda1-000a0a0b1500" // SYSSTATEMENTS_INDEX1
,"80000000-00d1-15fe-bdf8-000a0a0b1500" // SYSSTATEMENTS_INDEX2
};
/////////////////////////////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
/////////////////////////////////////////////////////////////////////////////
SYSSTATEMENTSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf)
{
super(uuidf,ef,dvf);
initInfo(SYSSTATEMENTS_COLUMN_COUNT, TABLENAME_STRING,
indexColumnPositions, uniqueness, uuids);
}
/////////////////////////////////////////////////////////////////////////////
//
// METHODS
//
/////////////////////////////////////////////////////////////////////////////
/**
* Make a SYSSTATEMENTS row.
* <p>
* <B>WARNING</B>: When empty row is true, this method takes
* a snapshot of the SPSD and creates a row. It is imperative
* that that row remain consistent with the descriptor (the
* valid and StorablePreparedStatement fields must be in sync).
* If this row is to be written out and valid is true, then
* this call and the insert should be synchronized on the
* SPSD. This method has <B>NO</B> synchronization.
*
* @param compileMe passed into SPSDescriptorImpl.getPreparedStatement().
* if true, we (re)compile the stmt
* @param spsDescriptor In-memory tuple to be converted to a disk row.
*
* @return Row suitable for inserting into SYSSTATEMENTS.
*
* @exception StandardException thrown on failure
*/
public ExecRow makeSYSSTATEMENTSrow(
boolean compileMe,
SPSDescriptor spsDescriptor
) throws StandardException
{
DataTypeDescriptor dtd;
ExecRow row;
DataValueDescriptor col;
String name = null;
UUID uuid = null;
String uuidStr = null;
String suuidStr = null; // schema
String compUuidStr = null; // compilation schema
String text = null;
String usingText = null;
ExecPreparedStatement preparedStatement = null;
String typeStr = null;
boolean valid = true;
Timestamp time = null;
boolean initiallyCompilable = true;
if (spsDescriptor != null)
{
name = spsDescriptor.getName();
uuid = spsDescriptor.getUUID();
suuidStr = spsDescriptor.getSchemaDescriptor().getUUID().toString();
uuidStr = uuid.toString();
text = spsDescriptor.getText();
valid = spsDescriptor.isValid();
time = spsDescriptor.getCompileTime();
typeStr = spsDescriptor.getTypeAsString();
initiallyCompilable = spsDescriptor.initiallyCompilable();
preparedStatement = spsDescriptor.getPreparedStatement(compileMe);
compUuidStr = (spsDescriptor.getCompSchemaId() != null)?
spsDescriptor.getCompSchemaId().toString():null;
usingText = spsDescriptor.getUsingText();
}
/* Build the row to insert */
row = getExecutionFactory().getValueRow(SYSSTATEMENTS_COLUMN_COUNT);
/* 1st column is STMTID */
row.setColumn(1, new SQLChar(uuidStr));
/* 2nd column is STMTNAME */
row.setColumn(2, new SQLVarchar(name));
/* 3rd column is SCHEMAID */
row.setColumn(3, new SQLChar(suuidStr));
/* 4th column is TYPE */
row.setColumn(4, new SQLChar(typeStr));
/* 5th column is VALID */
row.setColumn(5, new SQLBoolean(valid));
/* 6th column is TEXT */
row.setColumn(6, dvf.getLongvarcharDataValue(text));
/* 7th column is LASTCOMPILED */
row.setColumn(7, new SQLTimestamp(time));
/* 8th column is COMPILATIONSCHEMAID */
row.setColumn(8, new SQLChar(compUuidStr));
/* 9th column is USINGTEXT */
row.setColumn(9, dvf.getLongvarcharDataValue(usingText));
/*
** 10th column is CONSTANTSTATE
**
** CONSTANTSTATE is really a formatable StorablePreparedStatement.
*/
row.setColumn(10, new UserType(preparedStatement));
/* 11th column is INITIALLY_COMPILABLE */
row.setColumn(11, new SQLBoolean(initiallyCompilable));
return row;
}
///////////////////////////////////////////////////////////////////////////
//
// ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
//
///////////////////////////////////////////////////////////////////////////
/**
* Make an Tuple Descriptor out of a SYSSTATEMENTS row
*
* @param row a SYSSTATEMENTS row
* @param parentTupleDescriptor unused
* @param dd dataDictionary
*
* @return a descriptor equivalent to a SYSSTATEMENTS row
*
* @exception StandardException thrown on failure
*/
public TupleDescriptor buildDescriptor(
ExecRow row,
TupleDescriptor parentTupleDescriptor,
DataDictionary dd )
throws StandardException
{
DataValueDescriptor col;
SPSDescriptor descriptor;
String name;
String text;
String usingText;
UUID uuid;
UUID compUuid = null;
String uuidStr;
UUID suuid; // schema
String suuidStr; // schema
String typeStr;
char type;
boolean valid;
Timestamp time = null;
ExecPreparedStatement preparedStatement = null;
boolean initiallyCompilable;
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(row.nColumns() == SYSSTATEMENTS_COLUMN_COUNT,
"Wrong number of columns for a SYSSTATEMENTS row");
}
// 1st column is STMTID (UUID - char(36))
col = row.getColumn(1);
uuidStr = col.getString();
uuid = getUUIDFactory().recreateUUID(uuidStr);
// 2nd column is STMTNAME (varchar(128))
col = row.getColumn(2);
name = col.getString();
// 3rd column is SCHEMAID (UUID - char(36))
col = row.getColumn(3);
suuidStr = col.getString();
suuid = getUUIDFactory().recreateUUID(suuidStr);
// 4th column is TYPE (char(1))
col = row.getColumn(4);
type = col.getString().charAt(0);
if (SanityManager.DEBUG)
{
if (!SPSDescriptor.validType(type))
{
SanityManager.THROWASSERT("Bad type value ("+type+") for statement "+name);
}
}
// In soft upgrade mode the plan may not be understand by this engine
// so force a recompile.
if (dd.isReadOnlyUpgrade()) {
valid = false;
} else {
// 5th column is VALID (boolean)
col = row.getColumn(5);
valid = col.getBoolean();
}
// 6th column is TEXT (LONG VARCHAR)
col = row.getColumn(6);
text = col.getString();
/* 7th column is LASTCOMPILED (TIMESTAMP) */
col = row.getColumn(7);
time = col.getTimestamp(new java.util.GregorianCalendar());
// 8th column is COMPILATIONSCHEMAID (UUID - char(36))
col = row.getColumn(8);
uuidStr = col.getString();
if (uuidStr != null)
compUuid = getUUIDFactory().recreateUUID(uuidStr);
// 9th column is TEXT (LONG VARCHAR)
col = row.getColumn(9);
usingText = col.getString();
// 10th column is CONSTANTSTATE (COM...ExecPreparedStatement)
// Only load the compiled plan if the statement is valid
if (valid) {
col = row.getColumn(10);
preparedStatement = (ExecPreparedStatement) col.getObject();
}
// 11th column is INITIALLY_COMPILABLE (boolean)
col = row.getColumn(11);
if ( col.isNull() ) { initiallyCompilable = true; }
else { initiallyCompilable = col.getBoolean(); }
descriptor = new SPSDescriptor(dd, name,
uuid,
suuid,
compUuid,
type,
valid,
text,
usingText,
time,
preparedStatement,
initiallyCompilable
);
return descriptor;
}
public ExecRow makeEmptyRow()
throws StandardException
{
return makeSYSSTATEMENTSrow(false,
(SPSDescriptor) null);
}
/**
* Builds a list of columns suitable for creating this Catalog.
* The last column, the serialized statement, is not added
* to the column list. This is done deliberately to make it
* a 'hidden' column -- one that is not visible to customers,
* but is visible to the system.
*
*
* @return array of SystemColumn suitable for making this catalog.
*/
public SystemColumn[] buildColumnList()
throws StandardException
{
return new SystemColumn[] {
SystemColumnImpl.getUUIDColumn("STMTID", false),
SystemColumnImpl.getIdentifierColumn("STMTNAME", false),
SystemColumnImpl.getUUIDColumn("SCHEMAID", false),
SystemColumnImpl.getIndicatorColumn("TYPE"),
SystemColumnImpl.getColumn("VALID", Types.BOOLEAN, false),
SystemColumnImpl.getColumn("TEXT", Types.LONGVARCHAR, false,
TypeId.LONGVARCHAR_MAXWIDTH),
SystemColumnImpl.getColumn("LASTCOMPILED", Types.TIMESTAMP, true),
SystemColumnImpl.getUUIDColumn("COMPILATIONSCHEMAID", true),
SystemColumnImpl.getColumn("USINGTEXT", Types.LONGVARCHAR, true,
TypeId.LONGVARCHAR_MAXWIDTH),
};
/*
** This column is deliberately left out. It
** is effectively 'hidden' from users. The code
** to create it is left here to demonstrate what
** it really looks like.
*/
//columnList[9] =
// new SystemColumnImpl(
// convertIdCase( "CONSTANTSTATE"), // name
// SYSSTATEMENTS_CONSTANTSTATE,// column number
// 0, // precision
// 0, // scale
// false, // nullability
// ExecPreparedStatement.CLASS_NAME, //datatype
// false, // built-in type
// DataTypeDescriptor.MAXIMUM_WIDTH_UNKNOWN // maxLength
// );
/*
** This column is also deliberately left out. It
** is effectively 'hidden' from users. The code
** to create it is left here to demonstrate what
** it really looks like.
*/
//columnList[10] =
// new SystemColumnImpl(
// convertIdCase( "INITIALLY_COMPILABLE"), // name
// SYSSTATEMENTS_INITIALLY_COMPILABLE,// column number
// 0, // precision
// 0, // scale
// true, // nullability
// "BOOLEAN", // dataType
// true, // built-in type
// 1 // maxLength
// );
}
/**
* Get the Properties associated with creating the heap.
*
* @return The Properties associated with creating the heap.
*/
public Properties getCreateHeapProperties()
{
Properties properties = new Properties();
// keep page size at 2K since most stmts are that size
// anyway
properties.put(Property.PAGE_SIZE_PARAMETER,"2048");
// default properties for system tables:
properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER,"0");
properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,"1");
return properties;
}
}