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