| /* |
| |
| 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; |
| } |
| |
| } |