001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.SYSSTATEMENTSRowFactory
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.catalog;
023:
024: import org.apache.derby.iapi.reference.Property;
025:
026: import org.apache.derby.iapi.types.DataTypeDescriptor;
027: import org.apache.derby.iapi.types.TypeId;
028: import org.apache.derby.iapi.types.DataValueDescriptor;
029:
030: import org.apache.derby.iapi.store.raw.RawStoreFactory;
031:
032: import org.apache.derby.iapi.types.TypeId;
033: import org.apache.derby.iapi.sql.dictionary.SystemColumn;
034: import org.apache.derby.catalog.TypeDescriptor;
035:
036: import org.apache.derby.iapi.types.DataValueFactory;
037: import org.apache.derby.iapi.types.RowLocation;
038:
039: import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
040: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
041: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
042: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
043: import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
044: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
045:
046: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
047: import org.apache.derby.iapi.sql.execute.ExecRow;
048: import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
049: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
050:
051: import org.apache.derby.iapi.error.StandardException;
052:
053: import org.apache.derby.iapi.services.monitor.Monitor;
054: import org.apache.derby.catalog.UUID;
055: import org.apache.derby.iapi.services.uuid.UUIDFactory;
056: import org.apache.derby.iapi.types.*;
057:
058: import org.apache.derby.iapi.services.sanity.SanityManager;
059:
060: import java.sql.Timestamp;
061: import java.util.Properties;
062:
063: /**
064: * Factory for creating a SYSSTATEMENTS row.
065: *
066: *
067: * @version 0.1
068: * @author Jamie
069: */
070:
071: public class SYSSTATEMENTSRowFactory extends CatalogRowFactory {
072: static final String TABLENAME_STRING = "SYSSTATEMENTS";
073:
074: /* Column #s for sysinfo (1 based) */
075: public static final int SYSSTATEMENTS_STMTID = 1;
076: public static final int SYSSTATEMENTS_STMTNAME = 2;
077: public static final int SYSSTATEMENTS_SCHEMAID = 3;
078: public static final int SYSSTATEMENTS_TYPE = 4;
079: public static final int SYSSTATEMENTS_VALID = 5;
080: public static final int SYSSTATEMENTS_TEXT = 6;
081: public static final int SYSSTATEMENTS_LASTCOMPILED = 7;
082: public static final int SYSSTATEMENTS_COMPILATION_SCHEMAID = 8;
083: public static final int SYSSTATEMENTS_USINGTEXT = 9;
084: public static final int SYSSTATEMENTS_CONSTANTSTATE = 10;
085: public static final int SYSSTATEMENTS_INITIALLY_COMPILABLE = 11;
086:
087: public static final int SYSSTATEMENTS_COLUMN_COUNT = SYSSTATEMENTS_INITIALLY_COMPILABLE;
088:
089: public static final int SYSSTATEMENTS_HIDDEN_COLUMN_COUNT = 2;
090:
091: protected static final int SYSSTATEMENTS_INDEX1_ID = 0;
092: protected static final int SYSSTATEMENTS_INDEX2_ID = 1;
093:
094: private static final int[][] indexColumnPositions = {
095: { SYSSTATEMENTS_STMTID },
096: { SYSSTATEMENTS_STMTNAME, SYSSTATEMENTS_SCHEMAID } };
097:
098: private static final boolean[] uniqueness = null;
099:
100: private static final String[] uuids = {
101: "80000000-00d1-15f7-ab70-000a0a0b1500" // catalog UUID
102: , "80000000-00d1-15fc-60b9-000a0a0b1500" // heap UUID
103: , "80000000-00d1-15fc-eda1-000a0a0b1500" // SYSSTATEMENTS_INDEX1
104: , "80000000-00d1-15fe-bdf8-000a0a0b1500" // SYSSTATEMENTS_INDEX2
105: };
106:
107: /////////////////////////////////////////////////////////////////////////////
108: //
109: // CONSTRUCTORS
110: //
111: /////////////////////////////////////////////////////////////////////////////
112:
113: public SYSSTATEMENTSRowFactory(UUIDFactory uuidf,
114: ExecutionFactory ef, DataValueFactory dvf,
115: boolean convertIdToLower) {
116: super (uuidf, ef, dvf, convertIdToLower);
117: initInfo(SYSSTATEMENTS_COLUMN_COUNT, TABLENAME_STRING,
118: indexColumnPositions, uniqueness, uuids);
119: }
120:
121: /////////////////////////////////////////////////////////////////////////////
122: //
123: // METHODS
124: //
125: /////////////////////////////////////////////////////////////////////////////
126:
127: /**
128: * Make a SYSSTATEMENTS row.
129: * <p>
130: * <B>WARNING</B>: When empty row is true, this method takes
131: * a snapshot of the SPSD and creates a row. It is imperative
132: * that that row remain consistent with the descriptor (the
133: * valid and StorablePreparedStatement fields must be in sync).
134: * If this row is to be written out and valid is true, then
135: * this call and the insert should be synchronized on the
136: * SPSD. This method has <B>NO</B> synchronization.
137: *
138: * @param compileMe passed into SPSDescriptorImpl.getPreparedStatement().
139: * if true, we (re)compile the stmt
140: * @param spsDescriptor In-memory tuple to be converted to a disk row.
141: *
142: * @return Row suitable for inserting into SYSSTATEMENTS.
143: *
144: * @exception StandardException thrown on failure
145: */
146:
147: public ExecRow makeSYSSTATEMENTSrow(boolean compileMe,
148: SPSDescriptor spsDescriptor) throws StandardException {
149: DataTypeDescriptor dtd;
150: ExecRow row;
151: DataValueDescriptor col;
152: String name = null;
153: UUID uuid = null;
154: String uuidStr = null;
155: String suuidStr = null; // schema
156: String compUuidStr = null; // compilation schema
157: String text = null;
158: String usingText = null;
159: ExecPreparedStatement preparedStatement = null;
160: String typeStr = null;
161: boolean valid = true;
162: Timestamp time = null;
163: boolean initiallyCompilable = true;
164:
165: if (spsDescriptor != null) {
166: name = spsDescriptor.getName();
167: uuid = spsDescriptor.getUUID();
168: if (uuid == null) {
169: uuid = getUUIDFactory().createUUID();
170: spsDescriptor.setUUID(uuid);
171: }
172: suuidStr = spsDescriptor.getSchemaDescriptor().getUUID()
173: .toString();
174: uuidStr = uuid.toString();
175: text = spsDescriptor.getText();
176: valid = spsDescriptor.isValid();
177: time = spsDescriptor.getCompileTime();
178: typeStr = spsDescriptor.getTypeAsString();
179: initiallyCompilable = spsDescriptor.initiallyCompilable();
180: preparedStatement = spsDescriptor
181: .getPreparedStatement(compileMe);
182: compUuidStr = spsDescriptor.getCompSchemaId().toString();
183: usingText = spsDescriptor.getUsingText();
184: }
185:
186: /* Build the row to insert */
187: row = getExecutionFactory().getValueRow(
188: SYSSTATEMENTS_COLUMN_COUNT);
189:
190: /* 1st column is STMTID */
191: row.setColumn(1, dvf.getCharDataValue(uuidStr));
192:
193: /* 2nd column is STMTNAME */
194: row.setColumn(2, dvf.getVarcharDataValue(name));
195:
196: /* 3rd column is SCHEMAID */
197: row.setColumn(3, dvf.getCharDataValue(suuidStr));
198:
199: /* 4th column is TYPE */
200: row.setColumn(4, dvf.getCharDataValue(typeStr));
201:
202: /* 5th column is VALID */
203: row.setColumn(5, dvf.getDataValue(valid));
204:
205: /* 6th column is TEXT */
206: row.setColumn(6, dvf.getLongvarcharDataValue(text));
207:
208: /* 7th column is LASTCOMPILED */
209: row.setColumn(7, new SQLTimestamp(time));
210:
211: /* 8th column is COMPILATIONSCHEMAID */
212: row.setColumn(8, dvf.getCharDataValue(compUuidStr));
213:
214: /* 9th column is USINGTEXT */
215: row.setColumn(9, dvf.getLongvarcharDataValue(usingText));
216:
217: /*
218: ** 10th column is CONSTANTSTATE
219: **
220: ** CONSTANTSTATE is really a formatable StorablePreparedStatement.
221: */
222: row.setColumn(10, dvf.getDataValue(preparedStatement));
223:
224: /* 11th column is INITIALLY_COMPILABLE */
225: row.setColumn(11, dvf.getDataValue(initiallyCompilable));
226:
227: return row;
228: }
229:
230: ///////////////////////////////////////////////////////////////////////////
231: //
232: // ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
233: //
234: ///////////////////////////////////////////////////////////////////////////
235:
236: /**
237: * Make an Tuple Descriptor out of a SYSSTATEMENTS row
238: *
239: * @param row a SYSSTATEMENTS row
240: * @param parentTupleDescriptor unused
241: * @param dd dataDictionary
242: *
243: * @return a descriptor equivalent to a SYSSTATEMENTS row
244: *
245: * @exception StandardException thrown on failure
246: */
247: public TupleDescriptor buildDescriptor(ExecRow row,
248: TupleDescriptor parentTupleDescriptor, DataDictionary dd)
249: throws StandardException {
250: DataValueDescriptor col;
251: SPSDescriptor descriptor;
252: String name;
253: String text;
254: String usingText;
255: UUID uuid;
256: UUID compUuid;
257: String uuidStr;
258: UUID suuid; // schema
259: String suuidStr; // schema
260: String typeStr;
261: char type;
262: boolean valid;
263: Timestamp time = null;
264: ExecPreparedStatement preparedStatement = null;
265: boolean initiallyCompilable;
266: DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
267:
268: if (SanityManager.DEBUG) {
269: SanityManager.ASSERT(
270: row.nColumns() == SYSSTATEMENTS_COLUMN_COUNT,
271: "Wrong number of columns for a SYSSTATEMENTS row");
272: }
273:
274: // 1st column is STMTID (UUID - char(36))
275: col = row.getColumn(1);
276: uuidStr = col.getString();
277: uuid = getUUIDFactory().recreateUUID(uuidStr);
278:
279: // 2nd column is STMTNAME (varchar(128))
280: col = row.getColumn(2);
281: name = col.getString();
282:
283: // 3rd column is SCHEMAID (UUID - char(36))
284: col = row.getColumn(3);
285: suuidStr = col.getString();
286: suuid = getUUIDFactory().recreateUUID(suuidStr);
287:
288: // 4th column is TYPE (char(1))
289: col = row.getColumn(4);
290: type = col.getString().charAt(0);
291:
292: if (SanityManager.DEBUG) {
293: if (!SPSDescriptor.validType(type)) {
294: SanityManager.THROWASSERT("Bad type value (" + type
295: + ") for statement " + name);
296: }
297: }
298:
299: // In soft upgrade mode the plan may not be understand by this engine
300: // so force a recompile.
301: if (((DataDictionaryImpl) dd).readOnlyUpgrade) {
302: valid = false;
303: } else {
304: // 5th column is VALID (boolean)
305: col = row.getColumn(5);
306: valid = col.getBoolean();
307: }
308:
309: // 6th column is TEXT (LONG VARCHAR)
310: col = row.getColumn(6);
311: text = col.getString();
312:
313: /* 7th column is LASTCOMPILED (TIMESTAMP) */
314: col = row.getColumn(7);
315: time = col.getTimestamp(new java.util.GregorianCalendar());
316:
317: // 8th column is COMPILATIONSCHEMAID (UUID - char(36))
318: col = row.getColumn(8);
319: uuidStr = col.getString();
320: compUuid = getUUIDFactory().recreateUUID(uuidStr);
321:
322: // 9th column is TEXT (LONG VARCHAR)
323: col = row.getColumn(9);
324: usingText = col.getString();
325:
326: // 10th column is CONSTANTSTATE (COM...ExecPreparedStatement)
327:
328: // Only load the compiled plan if the statement is valid
329: if (valid) {
330: col = row.getColumn(10);
331: preparedStatement = (ExecPreparedStatement) col.getObject();
332: }
333:
334: // 11th column is INITIALLY_COMPILABLE (boolean)
335: col = row.getColumn(11);
336: if (col.isNull()) {
337: initiallyCompilable = true;
338: } else {
339: initiallyCompilable = col.getBoolean();
340: }
341:
342: descriptor = new SPSDescriptor(dd, name, uuid, suuid, compUuid,
343: type, valid, text, usingText, time, preparedStatement,
344: initiallyCompilable);
345:
346: return descriptor;
347: }
348:
349: public ExecRow makeEmptyRow() throws StandardException {
350: return makeSYSSTATEMENTSrow(false, (SPSDescriptor) null);
351: }
352:
353: /**
354: * Builds a list of columns suitable for creating this Catalog.
355: * The last column, the serialized statement, is not added
356: * to the column list. This is done deliberately to make it
357: * a 'hidden' column -- one that is not visible to customers,
358: * but is visible to the system.
359: *
360: *
361: * @return array of SystemColumn suitable for making this catalog.
362: */
363: public SystemColumn[] buildColumnList() {
364: /*
365: ** Create one less than the number of columns, we
366: ** skip the last one deliberately.
367: */
368: SystemColumn[] columnList = new SystemColumn[SYSSTATEMENTS_COLUMN_COUNT
369: - SYSSTATEMENTS_HIDDEN_COLUMN_COUNT];
370:
371: // describe columns
372: columnList[0] = new SystemColumnImpl(convertIdCase("STMTID"), // name
373: SYSSTATEMENTS_STMTID, // column number
374: 0, // precision
375: 0, // scale
376: false, // nullability
377: "CHAR", // dataType
378: true, // built-in type
379: 36 // maxLength
380: );
381:
382: columnList[1] = new SystemColumnImpl( // SQL IDENTIFIER
383: convertIdCase("STMTNAME"), // column name
384: SYSSTATEMENTS_STMTNAME, // column number
385: false // nullability
386: );
387:
388: columnList[2] = new SystemColumnImpl(convertIdCase("SCHEMAID"), // name
389: SYSSTATEMENTS_SCHEMAID, // column number
390: 0, // precision
391: 0, // scale
392: false, // nullability
393: "CHAR", // dataType
394: true, // built-in type
395: 36 // maxLength
396: );
397:
398: columnList[3] = new SystemColumnImpl(convertIdCase("TYPE"), // name
399: SYSSTATEMENTS_TYPE, // column number
400: 0, // precision
401: 0, // scale
402: false, // nullability
403: "CHAR", // dataType
404: true, // built-in type
405: 1 // maxLength
406: );
407:
408: columnList[4] = new SystemColumnImpl(convertIdCase("VALID"), // name
409: SYSSTATEMENTS_VALID,// column number
410: 0, // precision
411: 0, // scale
412: false, // nullability
413: "BOOLEAN", // dataType
414: true, // built-in type
415: 1 // maxLength
416: );
417:
418: columnList[5] = new SystemColumnImpl(convertIdCase("TEXT"), // name
419: SYSSTATEMENTS_TEXT, // column number
420: 0, // precision
421: 0, // scale
422: false, // nullability
423: "LONG VARCHAR", // dataType
424: true, // built-in type
425: TypeId.LONGVARCHAR_MAXWIDTH // maxLength
426: );
427:
428: columnList[6] = new SystemColumnImpl(
429: convertIdCase("LASTCOMPILED"), // name
430: SYSSTATEMENTS_LASTCOMPILED, // column number
431: 0, // precision
432: 0, // scale
433: true, // nullability
434: "TIMESTAMP", // dataType
435: true, // built-in type
436: TypeId.TIMESTAMP_MAXWIDTH // maxLength
437: );
438:
439: columnList[7] = new SystemColumnImpl(
440: convertIdCase("COMPILATIONSCHEMAID"), // name
441: SYSSTATEMENTS_COMPILATION_SCHEMAID, // column number
442: 0, // precision
443: 0, // scale
444: false, // nullability
445: "CHAR", // dataType
446: true, // built-in type
447: 36 // maxLength
448: );
449:
450: columnList[8] = new SystemColumnImpl(
451: convertIdCase("USINGTEXT"), // name
452: SYSSTATEMENTS_USINGTEXT,// column number
453: 0, // precision
454: 0, // scale
455: true, // nullability
456: "LONG VARCHAR", // dataType
457: true, // built-in type
458: TypeId.LONGVARCHAR_MAXWIDTH // maxLength
459: );
460: /*
461: ** This column is deliberately left out. It
462: ** is effectively 'hidden' from users. The code
463: ** to create it is left here to demonstrate what
464: ** it really looks like.
465: */
466: //columnList[9] =
467: // new SystemColumnImpl(
468: // convertIdCase( "CONSTANTSTATE"), // name
469: // SYSSTATEMENTS_CONSTANTSTATE,// column number
470: // 0, // precision
471: // 0, // scale
472: // false, // nullability
473: // ExecPreparedStatement.CLASS_NAME, //datatype
474: // false, // built-in type
475: // DataTypeDescriptor.MAXIMUM_WIDTH_UNKNOWN // maxLength
476: // );
477: /*
478: ** This column is also deliberately left out. It
479: ** is effectively 'hidden' from users. The code
480: ** to create it is left here to demonstrate what
481: ** it really looks like.
482: */
483: //columnList[10] =
484: // new SystemColumnImpl(
485: // convertIdCase( "INITIALLY_COMPILABLE"), // name
486: // SYSSTATEMENTS_INITIALLY_COMPILABLE,// column number
487: // 0, // precision
488: // 0, // scale
489: // true, // nullability
490: // "BOOLEAN", // dataType
491: // true, // built-in type
492: // 1 // maxLength
493: // );
494:
495: return columnList;
496: }
497:
498: /**
499: * Get the Properties associated with creating the heap.
500: *
501: * @return The Properties associated with creating the heap.
502: */
503: public Properties getCreateHeapProperties() {
504: Properties properties = new Properties();
505:
506: // keep page size at 2K since most stmts are that size
507: // anyway
508: properties.put(Property.PAGE_SIZE_PARAMETER, "2048");
509:
510: // default properties for system tables:
511: properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER,
512: "0");
513: properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,
514: "1");
515: return properties;
516: }
517:
518: }
|