1 /* Copyright (c) 2001-2016, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 package org.hsqldb.dbinfo;
33 
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.io.LineNumberReader;
37 import java.io.UnsupportedEncodingException;
38 import java.security.AccessController;
39 import java.security.PrivilegedAction;
40 
41 import org.hsqldb.ColumnSchema;
42 import org.hsqldb.Constraint;
43 import org.hsqldb.Database;
44 import org.hsqldb.Expression;
45 import org.hsqldb.ExpressionColumn;
46 import org.hsqldb.HsqlException;
47 import org.hsqldb.HsqlNameManager;
48 import org.hsqldb.HsqlNameManager.HsqlName;
49 import org.hsqldb.NumberSequence;
50 import org.hsqldb.ReferenceObject;
51 import org.hsqldb.Routine;
52 import org.hsqldb.RoutineSchema;
53 import org.hsqldb.Schema;
54 import org.hsqldb.SchemaObject;
55 import org.hsqldb.SchemaObjectSet;
56 import org.hsqldb.Session;
57 import org.hsqldb.SqlInvariants;
58 import org.hsqldb.Statement;
59 import org.hsqldb.Table;
60 import org.hsqldb.TableBase;
61 import org.hsqldb.TextTable;
62 import org.hsqldb.Tokens;
63 import org.hsqldb.TriggerDef;
64 import org.hsqldb.View;
65 import org.hsqldb.index.Index;
66 import org.hsqldb.lib.ArrayUtil;
67 import org.hsqldb.lib.FileUtil;
68 import org.hsqldb.lib.HashMappedList;
69 import org.hsqldb.lib.HashSet;
70 import org.hsqldb.lib.Iterator;
71 import org.hsqldb.lib.LineGroupReader;
72 import org.hsqldb.lib.OrderedHashSet;
73 import org.hsqldb.lib.Set;
74 import org.hsqldb.lib.WrapperIterator;
75 import org.hsqldb.map.ValuePool;
76 import org.hsqldb.persist.DataFileCache;
77 import org.hsqldb.persist.DataSpaceManager;
78 import org.hsqldb.persist.DirectoryBlockCachedObject;
79 import org.hsqldb.persist.HsqlDatabaseProperties;
80 import org.hsqldb.persist.HsqlProperties;
81 import org.hsqldb.persist.PersistentStore;
82 import org.hsqldb.persist.TableSpaceManager;
83 import org.hsqldb.persist.TextCache;
84 import org.hsqldb.persist.TextFileSettings;
85 import org.hsqldb.result.Result;
86 import org.hsqldb.rights.GrantConstants;
87 import org.hsqldb.rights.Grantee;
88 import org.hsqldb.rights.Right;
89 import org.hsqldb.types.Charset;
90 import org.hsqldb.types.Collation;
91 import org.hsqldb.types.IntervalType;
92 import org.hsqldb.types.NumberType;
93 import org.hsqldb.types.TimestampData;
94 import org.hsqldb.types.Type;
95 
96 // fredt@users - 1.7.2 - structural modifications to allow inheritance
97 // boucherb@users - 1.7.2 - 20020225
98 // - factored out all reusable code into DIXXX support classes
99 // - completed Fred's work on allowing inheritance
100 // boucherb@users - 1.7.2 - 20020304 - bug fixes, refinements, better java docs
101 // fredt@users - 1.8.0 - updated to report latest enhancements and changes
102 // boucherb@users - 1.8.0 - 20050515 - further SQL 2003 metadata support
103 // boucherb@users 20051207 - patch 1.8.x initial JDBC 4.0 support work
104 // fredt@users - 1.9.0 - new tables + renaming + upgrade of some others to SQL/SCHEMATA
105 // Revision 1.12  2006/07/12 11:42:09  boucherb
106 //  - merging back remaining material overritten by Fred's type-system upgrades
107 //  - rework to use grantee (versus user) orientation for certain system table content
108 //  - update collation and character set reporting to correctly reflect SQL3 spec
109 
110 /**
111  * Provides definitions for most of the SQL Standard Schemata views that are
112  * supported by HSQLDB.<p>
113  *
114  * Provides definitions for some of HSQLDB's additional system vies.
115  *
116  * The definitions for the rest of system vies are provided by
117  * DatabaseInformationMain, which this class extends. <p>
118  *
119  * @author Campbell Burnet (boucherb@users dot sourceforge.net)
120  * @author Fred Toussi (fredt@users dot sourceforge.net)
121  * @version 2.3.3
122  * @since 1.7.2
123  */
124 final class DatabaseInformationFull
125 extends org.hsqldb.dbinfo.DatabaseInformationMain {
126 
127     static final HashMappedList statementMap;
128 
129     static {
130         synchronized (DatabaseInformationFull.class) {
131             final String path = "/org/hsqldb/resources/information-schema.sql";
132             final String[] starters = new String[]{ "/*" };
133             InputStream fis = (InputStream) AccessController.doPrivileged(
134                 new PrivilegedAction() {
135 
136                 public InputStream run() {
137                     return getClass().getResourceAsStream(path);
138                 }
139             });
140             InputStreamReader reader = null;
141 
142             try {
143                 reader = new InputStreamReader(fis, "ISO-8859-1");
144             } catch (UnsupportedEncodingException e) {
145                 reader = new InputStreamReader(fis);
146             }
147 
148             LineNumberReader lineReader = new LineNumberReader(reader);
149             LineGroupReader  lg = new LineGroupReader(lineReader, starters);
150 
151             statementMap = lg.getAsMap();
152 
lg.close()153             lg.close();
154         }
155     }
156 
157     /**
158      * Constructs a new DatabaseInformationFull instance. <p>
159      *
160      * @param db the database for which to produce system tables.
161      */
DatabaseInformationFull(Database db)162     DatabaseInformationFull(Database db) {
163         super(db);
164     }
165 
166     /**
167      * Retrieves the system table corresponding to the specified index. <p>
168      *
169      * @param tableIndex index identifying the system table to generate
170      * @return the system table corresponding to the specified index
171      */
generateTable(Session session, PersistentStore store, int tableIndex)172     protected Table generateTable(Session session, PersistentStore store,
173                                   int tableIndex) {
174 
175         switch (tableIndex) {
176 
177             // HSQLDB-specific
178             case SYSTEM_CACHEINFO :
179                 return SYSTEM_CACHEINFO(session, store);
180 
181             case SYSTEM_COLUMN_SEQUENCE_USAGE :
182                 return SYSTEM_COLUMN_SEQUENCE_USAGE(session, store);
183 
184             case SYSTEM_COMMENTS :
185                 return SYSTEM_COMMENTS(session, store);
186 
187             case SYSTEM_INDEXSTATS :
188                 return SYSTEM_INDEXSTATS(session, store);
189 
190             case SYSTEM_SESSIONS :
191                 return SYSTEM_SESSIONS(session, store);
192 
193             case SYSTEM_SESSIONINFO :
194                 return SYSTEM_SESSIONINFO(session, store);
195 
196             case SYSTEM_PROPERTIES :
197                 return SYSTEM_PROPERTIES(session, store);
198 
199             case SYSTEM_SYNONYMS :
200                 return SYSTEM_SYNONYMS(session, store);
201 
202             case SYSTEM_TABLESTATS :
203                 return SYSTEM_TABLESTATS(session, store);
204 
205             case SYSTEM_TEXTTABLES :
206                 return SYSTEM_TEXTTABLES(session, store);
207 
208             // SQL views
209             case ADMINISTRABLE_ROLE_AUTHORIZATIONS :
210                 return ADMINISTRABLE_ROLE_AUTHORIZATIONS(session, store);
211 
212             case APPLICABLE_ROLES :
213                 return APPLICABLE_ROLES(session, store);
214 
215             case ASSERTIONS :
216                 return ASSERTIONS(session, store);
217 
218             case AUTHORIZATIONS :
219                 return AUTHORIZATIONS(session, store);
220 
221             case CHARACTER_SETS :
222                 return CHARACTER_SETS(session, store);
223 
224             case CHECK_CONSTRAINT_ROUTINE_USAGE :
225                 return CHECK_CONSTRAINT_ROUTINE_USAGE(session, store);
226 
227             case CHECK_CONSTRAINTS :
228                 return CHECK_CONSTRAINTS(session, store);
229 
230             case COLLATIONS :
231                 return COLLATIONS(session, store);
232 
233             case COLUMN_COLUMN_USAGE :
234                 return COLUMN_COLUMN_USAGE(session, store);
235 
236             case COLUMN_DOMAIN_USAGE :
237                 return COLUMN_DOMAIN_USAGE(session, store);
238 
239             case COLUMN_UDT_USAGE :
240                 return COLUMN_UDT_USAGE(session, store);
241 
242             case CONSTRAINT_COLUMN_USAGE :
243                 return CONSTRAINT_COLUMN_USAGE(session, store);
244 
245             case CONSTRAINT_TABLE_USAGE :
246                 return CONSTRAINT_TABLE_USAGE(session, store);
247 
248             case COLUMNS :
249                 return COLUMNS(session, store);
250 
251             case DATA_TYPE_PRIVILEGES :
252                 return DATA_TYPE_PRIVILEGES(session, store);
253 
254             case DOMAIN_CONSTRAINTS :
255                 return DOMAIN_CONSTRAINTS(session, store);
256 
257             case DOMAINS :
258                 return DOMAINS(session, store);
259 
260             case ELEMENT_TYPES :
261                 return ELEMENT_TYPES(session, store);
262 
263             case ENABLED_ROLES :
264                 return ENABLED_ROLES(session, store);
265 
266             case JAR_JAR_USAGE :
267                 return JAR_JAR_USAGE(session, store);
268 
269             case JARS :
270                 return JARS(session, store);
271 
272             case KEY_COLUMN_USAGE :
273                 return KEY_COLUMN_USAGE(session, store);
274 
275             case METHOD_SPECIFICATIONS :
276                 return METHOD_SPECIFICATIONS(session, store);
277 
278             case MODULE_COLUMN_USAGE :
279                 return MODULE_COLUMN_USAGE(session, store);
280 
281             case MODULE_PRIVILEGES :
282                 return MODULE_PRIVILEGES(session, store);
283 
284             case MODULE_TABLE_USAGE :
285                 return MODULE_TABLE_USAGE(session, store);
286 
287             case MODULES :
288                 return MODULES(session, store);
289 
290             case PARAMETERS :
291                 return PARAMETERS(session, store);
292 
293             case REFERENTIAL_CONSTRAINTS :
294                 return REFERENTIAL_CONSTRAINTS(session, store);
295 
296             case ROLE_AUTHORIZATION_DESCRIPTORS :
297                 return ROLE_AUTHORIZATION_DESCRIPTORS(session, store);
298 
299             case ROLE_COLUMN_GRANTS :
300                 return ROLE_COLUMN_GRANTS(session, store);
301 
302             case ROLE_ROUTINE_GRANTS :
303                 return ROLE_ROUTINE_GRANTS(session, store);
304 
305             case ROLE_TABLE_GRANTS :
306                 return ROLE_TABLE_GRANTS(session, store);
307 
308             case ROLE_USAGE_GRANTS :
309                 return ROLE_USAGE_GRANTS(session, store);
310 
311             case ROLE_UDT_GRANTS :
312                 return ROLE_UDT_GRANTS(session, store);
313 
314             case ROUTINE_COLUMN_USAGE :
315                 return ROUTINE_COLUMN_USAGE(session, store);
316 
317             case ROUTINE_JAR_USAGE :
318                 return ROUTINE_JAR_USAGE(session, store);
319 
320             case ROUTINE_PRIVILEGES :
321                 return ROUTINE_PRIVILEGES(session, store);
322 
323             case ROUTINE_ROUTINE_USAGE :
324                 return ROUTINE_ROUTINE_USAGE(session, store);
325 
326             case ROUTINE_SEQUENCE_USAGE :
327                 return ROUTINE_SEQUENCE_USAGE(session, store);
328 
329             case ROUTINE_TABLE_USAGE :
330                 return ROUTINE_TABLE_USAGE(session, store);
331 
332             case ROUTINES :
333                 return ROUTINES(session, store);
334 
335             case SCHEMATA :
336                 return SCHEMATA(session, store);
337 
338             case SEQUENCES :
339                 return SEQUENCES(session, store);
340 
341             case SQL_FEATURES :
342                 return SQL_FEATURES(session, store);
343 
344             case SQL_IMPLEMENTATION_INFO :
345                 return SQL_IMPLEMENTATION_INFO(session, store);
346 
347             case SQL_PACKAGES :
348                 return SQL_PACKAGES(session, store);
349 
350             case SQL_PARTS :
351                 return SQL_PARTS(session, store);
352 
353             case SQL_SIZING :
354                 return SQL_SIZING(session, store);
355 
356             case SQL_SIZING_PROFILES :
357                 return SQL_SIZING_PROFILES(session, store);
358 
359             case TABLE_CONSTRAINTS :
360                 return TABLE_CONSTRAINTS(session, store);
361 
362             case TABLES :
363                 return TABLES(session, store);
364 
365             case TRANSLATIONS :
366                 return TRANSLATIONS(session, store);
367 
368             case TRIGGERED_UPDATE_COLUMNS :
369                 return TRIGGERED_UPDATE_COLUMNS(session, store);
370 
371             case TRIGGER_COLUMN_USAGE :
372                 return TRIGGER_COLUMN_USAGE(session, store);
373 
374             case TRIGGER_ROUTINE_USAGE :
375                 return TRIGGER_ROUTINE_USAGE(session, store);
376 
377             case TRIGGER_SEQUENCE_USAGE :
378                 return TRIGGER_SEQUENCE_USAGE(session, store);
379 
380             case TRIGGER_TABLE_USAGE :
381                 return TRIGGER_TABLE_USAGE(session, store);
382 
383             case TRIGGERS :
384                 return TRIGGERS(session, store);
385 
386             case UDT_PRIVILEGES :
387                 return UDT_PRIVILEGES(session, store);
388 
389             case USAGE_PRIVILEGES :
390                 return USAGE_PRIVILEGES(session, store);
391 
392             case USER_DEFINED_TYPES :
393                 return USER_DEFINED_TYPES(session, store);
394 
395             case VIEW_COLUMN_USAGE :
396                 return VIEW_COLUMN_USAGE(session, store);
397 
398             case VIEW_ROUTINE_USAGE :
399                 return VIEW_ROUTINE_USAGE(session, store);
400 
401             case VIEW_TABLE_USAGE :
402                 return VIEW_TABLE_USAGE(session, store);
403 
404             case VIEWS :
405                 return VIEWS(session, store);
406 
407             default :
408                 return super.generateTable(session, store, tableIndex);
409         }
410     }
411 
412     /**
413      * SQL:2008 VIEW<p>
414      *
415      * Retrieves a <code>Table</code> object describing the current
416      * state of all row caching objects for the accessible
417      * tables defined within this database. <p>
418      *
419      * Currently, the row caching objects for which state is reported are: <p>
420      *
421      * <OL>
422      * <LI> the system-wide <code>Cache</code> object used by CACHED tables.
423      * <LI> any <code>TextCache</code> objects in use by [TEMP] TEXT tables.
424      * </OL> <p>
425      *
426      * Each row is a cache object state description with the following
427      * columns: <p>
428      *
429      * <pre class="SqlCodeExample">
430      * CACHE_FILE          CHARACTER_DATA   absolute path of cache data file
431      * MAX_CACHE_SIZE      BIGINT   maximum allowable cached Row objects
432      * MAX_CACHE_BYTE_SIZE BIGINT   maximum allowable size of cached Row objects
433      * CACHE_LENGTH        BIGINT   number of data bytes currently cached
434      * CACHE_SIZE          BIGINT   number of rows currently cached
435      * FREE_BYTES          BIGINT   total bytes in available file allocation units
436      * FREE_COUNT          BIGINT   total # of allocation units available
437      * FREE_POS            BIGINT   largest file position allocated + 1
438      * </pre> <p>
439      *
440      * <b>Notes:</b> <p>
441      *
442      * <code>TextCache</code> objects do not maintain a free list because
443      * deleted rows are only marked deleted and never reused. As such, the
444      * columns FREE_BYTES, SMALLEST_FREE_ITEM, LARGEST_FREE_ITEM, and
445      * FREE_COUNT are always reported as zero for rows reporting on
446      * <code>TextCache</code> objects. <p>
447      *
448      * Currently, CACHE_SIZE, FREE_BYTES, SMALLEST_FREE_ITEM, LARGEST_FREE_ITEM,
449      * FREE_COUNT and FREE_POS are the only dynamically changing values.
450      * All others are constant for the life of a cache object. In a future
451      * release, other column values may also change over the life of a cache
452      * object, as SQL syntax may eventually be introduced to allow runtime
453      * modification of certain cache properties. <p>
454      *
455      * @return a description of the current state of all row caching
456      *      objects associated with the accessible tables of the database
457      */
SYSTEM_CACHEINFO(Session session, PersistentStore store)458     Table SYSTEM_CACHEINFO(Session session, PersistentStore store) {
459 
460         Table t = sysTables[SYSTEM_CACHEINFO];
461 
462         if (t == null) {
463             t = createBlankTable(sysTableHsqlNames[SYSTEM_CACHEINFO]);
464 
465             addColumn(t, "CACHE_FILE", CHARACTER_DATA);          // not null
466             addColumn(t, "MAX_CACHE_COUNT", CARDINAL_NUMBER);    // not null
467             addColumn(t, "MAX_CACHE_BYTES", CARDINAL_NUMBER);    // not null
468             addColumn(t, "CACHE_SIZE", CARDINAL_NUMBER);         // not null
469             addColumn(t, "CACHE_BYTES", CARDINAL_NUMBER);        // not null
470             addColumn(t, "FILE_LOST_BYTES", CARDINAL_NUMBER);    // not null
471             addColumn(t, "FILE_FREE_POS", CARDINAL_NUMBER);      // not null
472 
473             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
474                 sysTableHsqlNames[SYSTEM_CACHEINFO].name, false,
475                 SchemaObject.INDEX);
476 
477             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
478 
479             return t;
480         }
481 
482         // column number mappings
483         final int icache_file      = 0;
484         final int imax_cache_sz    = 1;
485         final int imax_cache_bytes = 2;
486         final int icache_size      = 3;
487         final int icache_length    = 4;
488         final int ilost_bytes      = 5;
489         final int ifree_pos        = 6;
490 
491         //
492         DataFileCache cache = null;
493         Object[]      row;
494         HashSet       cacheSet;
495         Iterator      caches;
496         Iterator      tables;
497         Table         table;
498 
499         if (!session.isAdmin()) {
500             return t;
501         }
502 
503         // Initialization
504         cacheSet = new HashSet();
505 
506         // dynamic system tables are never cached
507         tables =
508             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
509 
510         while (tables.hasNext()) {
511             table = (Table) tables.next();
512 
513             if (!table.isText()) {
514                 continue;
515             }
516 
517             cache = null;
518 
519             PersistentStore currentStore = table.getRowStore(session);
520 
521             if (currentStore != null) {
522                 cache = currentStore.getCache();
523             }
524 
525             if (cache != null) {
526                 cacheSet.add(cache);
527             }
528         }
529 
530         if (database.logger.hasCache()) {
531             cache = database.logger.getCache();
532 
533             cacheSet.add(cache);
534         }
535 
536         caches = cacheSet.iterator();
537 
538         // Do it.
539         while (caches.hasNext()) {
540             cache = (DataFileCache) caches.next();
541             row   = t.getEmptyRowData();
542             row[icache_file] = FileUtil.getFileUtil().canonicalOrAbsolutePath(
543                 cache.getFileName());
544             row[imax_cache_sz]    = ValuePool.getLong(cache.capacity());
545             row[imax_cache_bytes] = ValuePool.getLong(cache.bytesCapacity());
546             row[icache_size] = ValuePool.getLong(cache.getCachedObjectCount());
547             row[icache_length] =
548                 ValuePool.getLong(cache.getTotalCachedBlockSize());
549             row[ilost_bytes] = ValuePool.getLong(cache.getLostBlockSize());
550             row[ifree_pos]   = ValuePool.getLong(cache.getFileFreePos());
551 
552             t.insertSys(session, store, row);
553         }
554 
555         return t;
556     }
557 
SYSTEM_COLUMN_SEQUENCE_USAGE(Session session, PersistentStore store)558     Table SYSTEM_COLUMN_SEQUENCE_USAGE(Session session,
559                                        PersistentStore store) {
560 
561         Table t = sysTables[SYSTEM_COLUMN_SEQUENCE_USAGE];
562 
563         if (t == null) {
564             t = createBlankTable(
565                 sysTableHsqlNames[SYSTEM_COLUMN_SEQUENCE_USAGE]);
566 
567             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);    //0
568             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
569             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
570             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
571             addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
572             addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
573             addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);
574 
575             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
576                 sysTableHsqlNames[SYSTEM_COLUMN_SEQUENCE_USAGE].name, false,
577                 SchemaObject.INDEX);
578 
579             t.createPrimaryKeyConstraint(name, new int[] {
580                 0, 1, 2, 3, 4
581             }, false);
582 
583             return t;
584         }
585 
586         final int table_cat        = 0;
587         final int table_schem      = 1;
588         final int table_name       = 2;
589         final int column_name      = 3;
590         final int sequence_catalog = 4;
591         final int sequence_schema  = 5;
592         final int sequence_name    = 6;
593 
594         //
595         // intermediate holders
596         int            columnCount;
597         Iterator       tables;
598         Table          table;
599         Object[]       row;
600         OrderedHashSet columnList;
601         NumberSequence sequence;
602 
603         // Initialization
604         tables = allTables();
605 
606         while (tables.hasNext()) {
607             table = (Table) tables.next();
608 
609             if (!table.hasIdentityColumn()) {
610                 continue;
611             }
612 
613             columnList =
614                 session.getGrantee().getColumnsForAllPrivileges(table);
615 
616             if (columnList.isEmpty()) {
617                 continue;
618             }
619 
620             columnCount = table.getColumnCount();
621 
622             for (int i = 0; i < columnCount; i++) {
623                 ColumnSchema column = table.getColumn(i);
624 
625                 if (!column.isIdentity()) {
626                     continue;
627                 }
628 
629                 sequence = column.getIdentitySequence();
630 
631                 if (sequence.getName() == null) {
632                     continue;
633                 }
634 
635                 if (!columnList.contains(column.getName())) {
636                     continue;
637                 }
638 
639                 row                   = t.getEmptyRowData();
640                 row[table_cat]        = database.getCatalogName().name;
641                 row[table_schem]      = table.getSchemaName().name;
642                 row[table_name]       = table.getName().name;
643                 row[column_name]      = column.getName().name;
644                 row[sequence_catalog] = database.getCatalogName().name;
645                 row[sequence_schema]  = sequence.getSchemaName().name;
646                 row[sequence_name]    = sequence.getName().name;
647 
648                 t.insertSys(session, store, row);
649             }
650         }
651 
652         return t;
653     }
654 
SYSTEM_COMMENTS(Session session, PersistentStore store)655     Table SYSTEM_COMMENTS(Session session, PersistentStore store) {
656 
657         Table t = sysTables[SYSTEM_COMMENTS];
658 
659         if (t == null) {
660             t = createBlankTable(sysTableHsqlNames[SYSTEM_COMMENTS]);
661 
662             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
663             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
664             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
665             addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
666             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
667             addColumn(t, "COMMENT", CHARACTER_DATA);
668 
669             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
670                 sysTableHsqlNames[SYSTEM_COMMENTS].name, false,
671                 SchemaObject.INDEX);
672 
673             t.createPrimaryKeyConstraint(name, new int[] {
674                 0, 1, 2, 3, 4
675             }, false);
676 
677             return t;
678         }
679 
680         // column number mappings
681         final int catalog     = 0;
682         final int schema      = 1;
683         final int name        = 2;
684         final int type        = 3;
685         final int column_name = 4;
686         final int remark      = 5;
687 
688         //
689         Iterator it;
690         Object[] row;
691 
692         //
693         DITableInfo ti = new DITableInfo();
694 
695         it = allTables();
696 
697         while (it.hasNext()) {
698             Table table = (Table) it.next();
699 
700             if (!session.getGrantee().isAccessible(table)) {
701                 continue;
702             }
703 
704             ti.setTable(table);
705 
706             int colCount = table.getColumnCount();
707 
708             for (int i = 0; i < colCount; i++) {
709                 ColumnSchema column = table.getColumn(i);
710 
711                 if (column.getName().comment == null) {
712                     continue;
713                 }
714 
715                 row              = t.getEmptyRowData();
716                 row[catalog]     = database.getCatalogName().name;
717                 row[schema]      = table.getSchemaName().name;
718                 row[name]        = table.getName().name;
719                 row[type]        = "COLUMN";
720                 row[column_name] = column.getName().name;
721                 row[remark]      = column.getName().comment;
722 
723                 t.insertSys(session, store, row);
724             }
725 
726             if (table.getTableType() != Table.INFO_SCHEMA_TABLE
727                     && table.getName().comment == null) {
728                 continue;
729             }
730 
731             row          = t.getEmptyRowData();
732             row[catalog] = database.getCatalogName().name;
733             row[schema]  = table.getSchemaName().name;
734             row[name]    = table.getName().name;
735             row[type] =
736                 table.isView()
737                 || table.getTableType() == Table.INFO_SCHEMA_TABLE ? "VIEW"
738                                                                    : "TABLE";
739             row[column_name] = null;
740             row[remark]      = ti.getRemark();
741 
742             t.insertSys(session, store, row);
743         }
744 
745         it = database.schemaManager.databaseObjectIterator(
746             SchemaObject.ROUTINE);
747 
748         while (it.hasNext()) {
749             SchemaObject object = (SchemaObject) it.next();
750 
751             if (!session.getGrantee().isAccessible(object)) {
752                 continue;
753             }
754 
755             if (object.getName().comment == null) {
756                 continue;
757             }
758 
759             row              = t.getEmptyRowData();
760             row[catalog]     = database.getCatalogName().name;
761             row[schema]      = object.getSchemaName().name;
762             row[name]        = object.getName().name;
763             row[type]        = "ROUTINE";
764             row[column_name] = null;
765             row[remark]      = object.getName().comment;
766 
767             t.insertSys(session, store, row);
768         }
769 
770         return t;
771     }
772 
773     /**
774      * Retrieves a <code>Table</code> object describing the capabilities
775      * and operating parameter properties for the engine hosting this
776      * database, as well as their applicability in terms of scope and
777      * name space. <p>
778      *
779      * Reported properties include certain predefined <code>Database</code>
780      * properties file values as well as certain database scope
781      * attributes. <p>
782      *
783      * It is intended that all <code>Database</code> attributes and
784      * properties that can be set via the database properties file,
785      * JDBC connection properties or SQL SET/ALTER statements will
786      * eventually be reported here or, where more applicable, in an
787      * ANSI/ISO conforming feature info base table in the definition
788      * schema. <p>
789      *
790      * Currently, the database properties reported are: <p>
791      *
792      * <OL>
793      *     <LI>hsqldb.cache_file_scale - the scaling factor used to translate data and index structure file pointers
794      *     <LI>hsqldb.cache_scale - base-2 exponent scaling allowable cache row count
795      *     <LI>hsqldb.cache_size_scale - base-2 exponent scaling allowable cache byte count
796      *     <LI>hsqldb.cache_version -
797      *     <LI>hsqldb.catalogs - whether to report the database catalog (database uri)
798      *     <LI>hsqldb.compatible_version -
799      *     <LI>hsqldb.files_readonly - whether the database is in files_readonly mode
800      *     <LI>hsqldb.gc_interval - # new records forcing gc ({0|NULL}=>never)
801      *     <LI>hsqldb.max_nio_scale - scale factor for cache nio mapped buffers
802      *     <LI>hsqldb.nio_data_file - whether cache uses nio mapped buffers
803      *     <LI>hsqldb.original_version -
804      *     <LI>sql.enforce_strict_size - column length specifications enforced strictly (raise exception on overflow)?
805      *     <LI>textdb.all_quoted - default policy regarding whether to quote all character field values
806      *     <LI>textdb.cache_scale - base-2 exponent scaling allowable cache row count
807      *     <LI>textdb.cache_size_scale - base-2 exponent scaling allowable cache byte count
808      *     <LI>textdb.encoding - default TEXT table file encoding
809      *     <LI>textdb.fs - default field separator
810      *     <LI>textdb.vs - default varchar field separator
811      *     <LI>textdb.lvs - default long varchar field separator
812      *     <LI>textdb.ignore_first - default policy regarding whether to ignore the first line
813      *     <LI>textdb.quoted - default policy regarding treatment character field values that _may_ require quoting
814      *     <LI>IGNORECASE - create table VARCHAR_IGNORECASE?
815      *     <LI>LOGSIZSE - # bytes to which REDO log grows before auto-checkpoint
816      *     <LI>REFERENTIAL_INTEGITY - currently enforcing referential integrity?
817      *     <LI>SCRIPTFORMAT - 0 : TEXT, 1 : BINARY, ...
818      *     <LI>WRITEDELAY - does REDO log currently use buffered write strategy?
819      * </OL> <p>
820      *
821      * @return table describing database and session operating parameters
822      *      and capabilities
823      */
SYSTEM_PROPERTIES(Session session, PersistentStore store)824     Table SYSTEM_PROPERTIES(Session session, PersistentStore store) {
825 
826         Table t = sysTables[SYSTEM_PROPERTIES];
827 
828         if (t == null) {
829             t = createBlankTable(sysTableHsqlNames[SYSTEM_PROPERTIES]);
830 
831             addColumn(t, "PROPERTY_SCOPE", CHARACTER_DATA);
832             addColumn(t, "PROPERTY_NAMESPACE", CHARACTER_DATA);
833             addColumn(t, "PROPERTY_NAME", CHARACTER_DATA);
834             addColumn(t, "PROPERTY_VALUE", CHARACTER_DATA);
835             addColumn(t, "PROPERTY_CLASS", CHARACTER_DATA);
836 
837             // order PROPERTY_SCOPE, PROPERTY_NAMESPACE, PROPERTY_NAME
838             // true PK
839             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
840                 sysTableHsqlNames[SYSTEM_PROPERTIES].name, false,
841                 SchemaObject.INDEX);
842 
843             t.createPrimaryKeyConstraint(name, new int[] {
844                 0, 1, 2
845             }, true);
846 
847             return t;
848         }
849 
850         // column number mappings
851         final int iscope = 0;
852         final int ins    = 1;
853         final int iname  = 2;
854         final int ivalue = 3;
855         final int iclass = 4;
856 
857         //
858         // calculated column values
859         String scope;
860         String nameSpace;
861 
862         // intermediate holders
863         Object[]               row;
864         HsqlDatabaseProperties props;
865 
866         // First, we want the names and values for
867         // all JDBC capabilities constants
868         scope     = "SESSION";
869         props     = database.getProperties();
870         nameSpace = "database.properties";
871 
872         // boolean properties
873         Iterator it = props.getUserDefinedPropertyData().iterator();
874 
875         while (it.hasNext()) {
876             Object[] metaData = (Object[]) it.next();
877 
878             row         = t.getEmptyRowData();
879             row[iscope] = scope;
880             row[ins]    = nameSpace;
881             row[iname]  = metaData[HsqlProperties.indexName];
882             row[ivalue] =
883                 database.logger.getValueStringForProperty((String) row[iname]);
884 
885             if (row[ivalue] == null) {
886                 row[ivalue] = props.getPropertyString((String) row[iname]);
887             }
888 
889             row[iclass] = metaData[HsqlProperties.indexClass];
890 
891             t.insertSys(session, store, row);
892         }
893 
894         return t;
895     }
896 
897     /**
898      * Retrieves a <code>Table</code> object describing attributes
899      * for the calling session context.<p>
900      *
901      * The rows report the following {key,value} pairs:<p>
902      *
903      * <pre class="SqlCodeExample">
904      * KEY (VARCHAR)       VALUE (VARCHAR)
905      * ------------------- ---------------
906      * AUTOCOMMIT          TRUE / FALSE (session is in autocommit mode or not)
907      * CURRENT SCHEMA      the name of current schema
908      * CURRENT STATEMENT   current SQL statement
909      * DATABASE            the name of the database
910      * DATABASE READONLY   TRUE / FALSE (database is in read-only mode or not)
911      * IDENTITY            the last identity value used by calling session
912      * IGNORECASE          IGNORECASE property for new VARCHAR columns
913      * ISOLATION_LEVEL     transaction isolation level of session
914      * SESSION_ID          the id of the calling session
915      * SESSION READONLY    TRUE / FALSE (session is in read-only mode or not)
916      * USER                the name of user connected in the calling session
917      * </pre>
918      *
919      * <b>Note:</b>  This table <em>may</em> become deprecated in a future
920      * release, as the information it reports now duplicates information
921      * reported in the newer SYSTEM_SESSIONS and SYSTEM_PROPERTIES
922      * tables. <p>
923      *
924      * @return a <code>Table</code> object describing the
925      *        attributes of the connection associated
926      *        with the current execution context
927      */
SYSTEM_SESSIONINFO(Session session, PersistentStore store)928     Table SYSTEM_SESSIONINFO(Session session, PersistentStore store) {
929 
930         Table t = sysTables[SYSTEM_SESSIONINFO];
931 
932         if (t == null) {
933             t = createBlankTable(sysTableHsqlNames[SYSTEM_SESSIONINFO]);
934 
935             addColumn(t, "KEY", CHARACTER_DATA);      // not null
936             addColumn(t, "VALUE", CHARACTER_DATA);    // not null
937 
938             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
939                 sysTableHsqlNames[SYSTEM_SESSIONINFO].name, false,
940                 SchemaObject.INDEX);
941 
942             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
943 
944             return t;
945         }
946 
947         Object[] row;
948 
949         row    = t.getEmptyRowData();
950         row[0] = "SESSION ID";
951         row[1] = String.valueOf(session.getId());
952 
953         t.insertSys(session, store, row);
954 
955         row    = t.getEmptyRowData();
956         row[0] = "AUTOCOMMIT";
957         row[1] = session.isAutoCommit() ? Tokens.T_TRUE
958                                         : Tokens.T_FALSE;
959 
960         t.insertSys(session, store, row);
961 
962         row    = t.getEmptyRowData();
963         row[0] = "USER";
964         row[1] = session.getUsername();
965 
966         t.insertSys(session, store, row);
967 
968         row    = t.getEmptyRowData();
969         row[0] = "SESSION READONLY";
970         row[1] = session.isReadOnlyDefault() ? Tokens.T_TRUE
971                                              : Tokens.T_FALSE;
972 
973         t.insertSys(session, store, row);
974 
975         row    = t.getEmptyRowData();
976         row[0] = "DATABASE READONLY";
977         row[1] = database.isReadOnly() ? Tokens.T_TRUE
978                                        : Tokens.T_FALSE;
979 
980         t.insertSys(session, store, row);
981 
982         row    = t.getEmptyRowData();
983         row[0] = "DATABASE";
984         row[1] = database.getURI();
985 
986         t.insertSys(session, store, row);
987 
988         row    = t.getEmptyRowData();
989         row[0] = "IDENTITY";
990         row[1] = String.valueOf(session.getLastIdentity());
991 
992         t.insertSys(session, store, row);
993 
994         row    = t.getEmptyRowData();
995         row[0] = "CURRENT SCHEMA";
996         row[1] = String.valueOf(session.getSchemaName(null));
997 
998         t.insertSys(session, store, row);
999 
1000         row    = t.getEmptyRowData();
1001         row[0] = "ISOLATION LEVEL";
1002         row[1] = String.valueOf(session.getIsolation());
1003 
1004         t.insertSys(session, store, row);
1005 
1006         row    = t.getEmptyRowData();
1007         row[0] = "IGNORECASE";
1008         row[1] = session.isIgnorecase() ? Tokens.T_TRUE
1009                                         : Tokens.T_FALSE;
1010 
1011         t.insertSys(session, store, row);
1012 
1013         row    = t.getEmptyRowData();
1014         row[0] = "CURRENT STATEMENT";
1015         row[1] = "";
1016 
1017         Statement st = session.sessionContext.currentStatement;
1018 
1019         if (st != null) {
1020             row[1] = st.getSQL();
1021         }
1022 
1023         t.insertSys(session, store, row);
1024 
1025         return t;
1026     }
1027 
1028     /**
1029      * Retrieves a <code>Table</code> object describing all visible
1030      * sessions. ADMIN users see *all* sessions
1031      * while non-admin users see only their own session.<p>
1032      *
1033      * Each row is a session state description with the following columns: <p>
1034      *
1035      * <pre class="SqlCodeExample">
1036      * SESSION_ID         BIGINT    session identifier
1037      * CONNECTED          TIMESTAMP time at which session was created
1038      * USER_NAME          VARCHAR   db user name of current session user
1039      * IS_ADMIN           BOOLEAN   is session user an admin user?
1040      * AUTOCOMMIT         BOOLEAN   is session in autocommit mode?
1041      * READONLY           BOOLEAN   is session in read-only mode?
1042      * LAST_IDENTITY      BIGINT    last identity value used by this session
1043      * SCHEMA             VARCHAR   current schema for session
1044      * TRANSACTION        BOOLEAN   is session in a transaction
1045      * TRANSACTION_SIZE   BIGINT    # of undo items in current transaction
1046      * WAITING_FOR_THIS   VARCHAR   comma separated list of sessions waiting for this one
1047      * THIS_WAITING_FOR   VARCHAR   comma separated list of sessions this session is waiting for
1048      * CURRENT_STATEMENT  VARCHAR   SQL statement currently running
1049      * LATCH_COUNT        BIGINT    latch count for session
1050      * </pre> <p>
1051      *
1052      * @return a <code>Table</code> object describing all visible
1053      *      sessions
1054      */
SYSTEM_SESSIONS(Session session, PersistentStore store)1055     Table SYSTEM_SESSIONS(Session session, PersistentStore store) {
1056 
1057         Table t = sysTables[SYSTEM_SESSIONS];
1058 
1059         if (t == null) {
1060             t = createBlankTable(sysTableHsqlNames[SYSTEM_SESSIONS]);
1061 
1062             addColumn(t, "SESSION_ID", CARDINAL_NUMBER);
1063             addColumn(t, "CONNECTED", TIME_STAMP);
1064             addColumn(t, "USER_NAME", SQL_IDENTIFIER);
1065             addColumn(t, "IS_ADMIN", Type.SQL_BOOLEAN);
1066             addColumn(t, "AUTOCOMMIT", Type.SQL_BOOLEAN);
1067             addColumn(t, "READONLY", Type.SQL_BOOLEAN);
1068 
1069             // Note: some sessions may have a NULL LAST_IDENTITY value
1070             addColumn(t, "LAST_IDENTITY", CARDINAL_NUMBER);
1071             addColumn(t, "SCHEMA", SQL_IDENTIFIER);
1072             addColumn(t, "TRANSACTION", Type.SQL_BOOLEAN);
1073             addColumn(t, "TRANSACTION_SIZE", CARDINAL_NUMBER);
1074             addColumn(t, "WAITING_FOR_THIS", CHARACTER_DATA);
1075             addColumn(t, "THIS_WAITING_FOR", CHARACTER_DATA);
1076             addColumn(t, "CURRENT_STATEMENT", CHARACTER_DATA);
1077             addColumn(t, "LATCH_COUNT", CARDINAL_NUMBER);
1078 
1079             // order:  SESSION_ID
1080             // true primary key
1081             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1082                 sysTableHsqlNames[SYSTEM_SESSIONS].name, false,
1083                 SchemaObject.INDEX);
1084 
1085             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
1086 
1087             return t;
1088         }
1089 
1090         // column number mappings
1091         final int isid           = 0;
1092         final int ict            = 1;
1093         final int iuname         = 2;
1094         final int iis_admin      = 3;
1095         final int iautocmt       = 4;
1096         final int ireadonly      = 5;
1097         final int ilast_id       = 6;
1098         final int it_schema      = 7;
1099         final int it_tx          = 8;
1100         final int it_size        = 9;
1101         final int it_waiting     = 10;
1102         final int it_waited      = 11;
1103         final int it_statement   = 12;
1104         final int it_latch_count = 13;
1105 
1106         //
1107         // intermediate holders
1108         Session[] sessions;
1109         Session   s;
1110         Object[]  row;
1111 
1112         // Initialisation
1113         sessions = database.sessionManager.getVisibleSessions(session);
1114 
1115         // Do it.
1116         for (int i = 0; i < sessions.length; i++) {
1117             if (sessions[i].isClosed()) {
1118                 continue;
1119             }
1120 
1121             s              = sessions[i];
1122             row            = t.getEmptyRowData();
1123             row[isid]      = ValuePool.getLong(s.getId());
1124             row[ict]       = new TimestampData(s.getConnectTime() / 1000);
1125             row[iuname]    = s.getUsername();
1126             row[iis_admin] = s.isAdmin() ? Boolean.TRUE
1127                                          : Boolean.FALSE;
1128             row[iautocmt]  = Boolean.valueOf(s.sessionContext.isAutoCommit);
1129             row[ireadonly] = Boolean.valueOf(s.isReadOnlyDefault);
1130 
1131             Number lastId = s.getLastIdentity();
1132 
1133             if (lastId != null) {
1134                 row[ilast_id] = ValuePool.getLong(lastId.longValue());
1135             }
1136 
1137             row[it_tx]   = s.isInMidTransaction() ? Boolean.TRUE
1138                                                   : Boolean.FALSE;
1139             row[it_size] = ValuePool.getLong(s.getTransactionSize());
1140 
1141             HsqlName name = s.getCurrentSchemaHsqlName();
1142 
1143             if (name != null) {
1144                 row[it_schema] = name.name;
1145             }
1146 
1147             row[it_waiting] = "";
1148             row[it_waited]  = "";
1149 
1150             if (s.waitingSessions.size() > 0) {
1151                 StringBuffer sb    = new StringBuffer();
1152                 Session[]    array = new Session[s.waitingSessions.size()];
1153 
1154                 s.waitingSessions.toArray(array);
1155 
1156                 for (int j = 0; j < array.length; j++) {
1157                     if (j > 0) {
1158                         sb.append(',');
1159                     }
1160 
1161                     sb.append(array[j].getId());
1162                 }
1163 
1164                 row[it_waiting] = sb.toString();
1165             }
1166 
1167             if (s.waitedSessions.size() > 0) {
1168                 StringBuffer sb    = new StringBuffer();
1169                 Session[]    array = new Session[s.waitedSessions.size()];
1170 
1171                 s.waitedSessions.toArray(array);
1172 
1173                 for (int j = 0; j < array.length; j++) {
1174                     if (j > 0) {
1175                         sb.append(',');
1176                     }
1177 
1178                     sb.append(array[j].getId());
1179                 }
1180 
1181                 row[it_waited] = sb.toString();
1182             }
1183 
1184             Statement st = s.sessionContext.currentStatement;
1185 
1186             row[it_statement]   = st == null ? ""
1187                                              : st.getSQL();
1188             row[it_latch_count] = new Long(s.latch.getCount());
1189 
1190             t.insertSys(session, store, row);
1191         }
1192 
1193         return t;
1194     }
1195 
SYSTEM_SYNONYMS(Session session, PersistentStore store)1196     Table SYSTEM_SYNONYMS(Session session, PersistentStore store) {
1197 
1198         Table t = sysTables[SYSTEM_SYNONYMS];
1199 
1200         if (t == null) {
1201             t = createBlankTable(sysTableHsqlNames[SYSTEM_SYNONYMS]);
1202 
1203             addColumn(t, "SYNONYM_CATALOG", SQL_IDENTIFIER);
1204             addColumn(t, "SYNONYM_SCHEMA", SQL_IDENTIFIER);
1205             addColumn(t, "SYNONYM_NAME", SQL_IDENTIFIER);    // not null
1206             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
1207             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
1208             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);     // not null
1209             addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
1210 
1211             // ------------------------------------------------------------
1212             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1213                 sysTableHsqlNames[SYSTEM_SYNONYMS].name, false,
1214                 SchemaObject.INDEX);
1215 
1216             t.createPrimaryKeyConstraint(name, new int[] {
1217                 0, 1, 2,
1218             }, false);
1219 
1220             return t;
1221         }
1222 
1223         // column number mappings
1224         final int isynonym_cat   = 0;
1225         final int isynonym_schem = 1;
1226         final int isynonym_name  = 2;
1227         final int object_catalog = 3;
1228         final int object_schema  = 4;
1229         final int object_name    = 5;
1230         final int object_type    = 6;
1231 
1232         //
1233         // intermediate holders
1234         Iterator        objects;
1235         ReferenceObject synonym;
1236         Object[]        row;
1237 
1238         if (!session.isAdmin()) {
1239             return t;
1240         }
1241 
1242         // Initialization
1243         objects = database.schemaManager.databaseObjectIterator(
1244             SchemaObject.REFERENCE);
1245 
1246         // Do it.
1247         while (objects.hasNext()) {
1248             synonym             = (ReferenceObject) objects.next();
1249             row                 = t.getEmptyRowData();
1250             row[isynonym_cat]   = database.getCatalogName().name;
1251             row[isynonym_schem] = synonym.getSchemaName().name;
1252             row[isynonym_name]  = synonym.getName().name;
1253             row[object_catalog] = database.getCatalogName().name;
1254             row[object_schema]  = synonym.getTarget().schema.name;
1255             row[object_name]    = synonym.getTarget().name;
1256 
1257             switch (synonym.getTarget().type) {
1258 
1259                 case SchemaObject.TABLE :
1260                     row[object_type] = "TABLE";
1261                     break;
1262 
1263                 case SchemaObject.VIEW :
1264                     row[object_type] = "VIEW";
1265                     break;
1266 
1267                 case SchemaObject.SEQUENCE :
1268                     row[object_type] = "SEQUENCE";
1269                     break;
1270 
1271                 case SchemaObject.ROUTINE :
1272                     row[object_type] = "ROUTINE";
1273                     break;
1274 
1275                 case SchemaObject.FUNCTION :
1276                     row[object_type] = "FUNCTION";
1277                     break;
1278 
1279                 case SchemaObject.PROCEDURE :
1280                     row[object_type] = "PROCEDURE";
1281                     break;
1282             }
1283 
1284             t.insertSys(session, store, row);
1285         }
1286 
1287         return t;
1288     }
1289 
1290     /**
1291      * Retrieves a <code>Table</code> object describing the TEXT TABLE objects
1292      * defined within this database. The table contains one row for each row
1293      * in the SYSTEM_TABLES table with a HSQLDB_TYPE of  TEXT . <p>
1294      *
1295      * Each row is a description of the attributes that defines its TEXT TABLE,
1296      * with the following columns:
1297      *
1298      * <pre class="SqlCodeExample">
1299      * TABLE_CAT                 VARCHAR   table's catalog name
1300      * TABLE_SCHEM               VARCHAR   table's simple schema name
1301      * TABLE_NAME                VARCHAR   table's simple name
1302      * DATA_SOURCE_DEFINITION    VARCHAR   the "spec" proption of the table's
1303      *                                     SET TABLE ... SOURCE DDL declaration
1304      * FILE_PATH                 VARCHAR   absolute file path.
1305      * FILE_ENCODING             VARCHAR   endcoding of table's text file
1306      * FIELD_SEPARATOR           VARCHAR   default field separator
1307      * VARCHAR_SEPARATOR         VARCAHR   varchar field separator
1308      * LONGVARCHAR_SEPARATOR     VARCHAR   longvarchar field separator
1309      * IS_IGNORE_FIRST           BOOLEAN   ignores first line of file?
1310      * IS_QUOTED                 BOOLEAN   fields are quoted if necessary?
1311      * IS_ALL_QUOTED             BOOLEAN   all fields are quoted?
1312      * IS_DESC                   BOOLEAN   read rows starting at end of file?
1313      * </pre> <p>
1314      *
1315      * @return a <code>Table</code> object describing the text attributes
1316      * of the accessible text tables defined within this database
1317      *
1318      */
SYSTEM_TEXTTABLES(Session session, PersistentStore store)1319     Table SYSTEM_TEXTTABLES(Session session, PersistentStore store) {
1320 
1321         Table t = sysTables[SYSTEM_TEXTTABLES];
1322 
1323         if (t == null) {
1324             t = createBlankTable(sysTableHsqlNames[SYSTEM_TEXTTABLES]);
1325 
1326             addColumn(t, "TABLE_CAT", SQL_IDENTIFIER);
1327             addColumn(t, "TABLE_SCHEM", SQL_IDENTIFIER);
1328             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);    // not null
1329             addColumn(t, "DATA_SOURCE_DEFINTION", CHARACTER_DATA);
1330             addColumn(t, "FILE_PATH", CHARACTER_DATA);
1331             addColumn(t, "FILE_ENCODING", CHARACTER_DATA);
1332             addColumn(t, "FIELD_SEPARATOR", CHARACTER_DATA);
1333             addColumn(t, "VARCHAR_SEPARATOR", CHARACTER_DATA);
1334             addColumn(t, "LONGVARCHAR_SEPARATOR", CHARACTER_DATA);
1335             addColumn(t, "IS_IGNORE_FIRST", Type.SQL_BOOLEAN);
1336             addColumn(t, "IS_QUOTED", Type.SQL_BOOLEAN);
1337             addColumn(t, "IS_ALL_QUOTED", Type.SQL_BOOLEAN);
1338             addColumn(t, "IS_DESC", Type.SQL_BOOLEAN);
1339 
1340             // ------------------------------------------------------------
1341             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1342                 sysTableHsqlNames[SYSTEM_TEXTTABLES].name, false,
1343                 SchemaObject.INDEX);
1344 
1345             t.createPrimaryKeyConstraint(name, new int[] {
1346                 0, 1, 2,
1347             }, false);
1348 
1349             return t;
1350         }
1351 
1352         // column number mappings
1353         final int itable_cat   = 0;
1354         final int itable_schem = 1;
1355         final int itable_name  = 2;
1356         final int idsd         = 3;
1357         final int ifile_path   = 4;
1358         final int ifile_enc    = 5;
1359         final int ifs          = 6;
1360         final int ivfs         = 7;
1361         final int ilvfs        = 8;
1362         final int iif          = 9;
1363         final int iiq          = 10;
1364         final int iiaq         = 11;
1365         final int iid          = 12;
1366 
1367         //
1368         // intermediate holders
1369         Iterator tables;
1370         Table    table;
1371         Object[] row;
1372 
1373         if (!session.isAdmin()) {
1374             return t;
1375         }
1376 
1377         // Initialization
1378         tables =
1379             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
1380 
1381         // Do it.
1382         while (tables.hasNext()) {
1383             table = (Table) tables.next();
1384 
1385             if (!table.isText()) {
1386                 continue;
1387             }
1388 
1389             PersistentStore currentStore = table.getRowStore(session);
1390 
1391             row               = t.getEmptyRowData();
1392             row[itable_cat]   = database.getCatalogName().name;
1393             row[itable_schem] = table.getSchemaName().name;
1394             row[itable_name]  = table.getName().name;
1395             row[idsd]         = ((TextTable) table).getDataSource();
1396 
1397             TextCache cache = (TextCache) currentStore.getCache();
1398 
1399             if (cache != null) {
1400                 TextFileSettings textFileSettings =
1401                     cache.getTextFileSettings();
1402 
1403                 row[ifile_path] =
1404                     FileUtil.getFileUtil().canonicalOrAbsolutePath(
1405                         cache.getFileName());
1406                 row[ifile_enc] = textFileSettings.stringEncoding;
1407                 row[ifs]       = textFileSettings.fs;
1408                 row[ivfs]      = textFileSettings.vs;
1409                 row[ilvfs]     = textFileSettings.lvs;
1410                 row[iif]       = textFileSettings.ignoreFirst ? Boolean.TRUE
1411                                                               : Boolean.FALSE;
1412                 row[iiq]       = textFileSettings.isQuoted ? Boolean.TRUE
1413                                                            : Boolean.FALSE;
1414                 row[iiaq]      = textFileSettings.isAllQuoted ? Boolean.TRUE
1415                                                               : Boolean.FALSE;
1416                 row[iid] = ((TextTable) table).isDescDataSource()
1417                            ? Boolean.TRUE
1418                            : Boolean.FALSE;
1419             }
1420 
1421             t.insertSys(session, store, row);
1422         }
1423 
1424         return t;
1425     }
1426 
SYSTEM_TABLESTATS(Session session, PersistentStore store)1427     Table SYSTEM_TABLESTATS(Session session, PersistentStore store) {
1428 
1429         Table t = sysTables[SYSTEM_TABLESTATS];
1430 
1431         if (t == null) {
1432             t = createBlankTable(sysTableHsqlNames[SYSTEM_TABLESTATS]);
1433 
1434             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
1435             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
1436             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
1437             addColumn(t, "TABLE_TYPE", SQL_IDENTIFIER);
1438             addColumn(t, "CARDINALITY", CARDINAL_NUMBER);
1439             addColumn(t, "SPACE_ID", CARDINAL_NUMBER);
1440             addColumn(t, "USED_SPACE", CARDINAL_NUMBER);
1441             addColumn(t, "ALLOCATED_SPACE", CARDINAL_NUMBER);
1442             addColumn(t, "USED_MEMORY", CARDINAL_NUMBER);
1443 
1444             //
1445             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1446                 sysTableHsqlNames[SYSTEM_TABLESTATS].name, false,
1447                 SchemaObject.INDEX);
1448 
1449             t.createPrimaryKeyConstraint(name, new int[] {
1450                 0, 1, 2,
1451             }, false);
1452 
1453             return t;
1454         }
1455 
1456         // intermediate holders
1457         Iterator  tables;
1458         Table     table;
1459         Object[]  row;
1460         final int table_catalog = 0;
1461         final int table_schema  = 1;
1462         final int table_name    = 2;
1463         final int table_type    = 3;
1464         final int cardinality   = 4;
1465         final int space_id      = 5;
1466         final int used_space    = 6;
1467         final int alloc_space   = 7;
1468         final int used_memory   = 8;
1469 
1470         if (!session.isAdmin()) {
1471             return t;
1472         }
1473 
1474         DataSpaceManager spaceManager = null;
1475         DirectoryBlockCachedObject[] directoryList =
1476             new DirectoryBlockCachedObject[0];
1477         int     cacheScale    = database.logger.getDataFileScale();
1478         int     fileBlockSize = 1024 * 1024 * cacheScale / 16;
1479         boolean hasCache      = database.logger.hasCache();
1480 
1481         if (hasCache) {
1482             DataFileCache cache = database.logger.getCache();
1483 
1484             spaceManager  = cache.spaceManager;
1485             directoryList = cache.spaceManager.getDirectoryList();
1486             cacheScale    = cache.getDataFileScale();
1487             fileBlockSize = spaceManager.getFileBlockSize();
1488         }
1489 
1490         // Initialization
1491         tables = allTables();
1492 
1493         // Do it.
1494         while (tables.hasNext()) {
1495             table              = (Table) tables.next();
1496             row                = t.getEmptyRowData();
1497             row[table_catalog] = database.getCatalogName().name;
1498             row[table_schema]  = table.getSchemaName().name;
1499             row[table_name]    = table.getName().name;
1500             row[table_type]    = table.getTableTypeString();
1501 
1502             switch (table.getTableType()) {
1503 
1504                 case TableBase.MEMORY_TABLE :
1505                 case TableBase.CACHED_TABLE :
1506                 case TableBase.TEXT_TABLE :
1507                     break;
1508 
1509                 default :
1510                     continue;
1511             }
1512 
1513             PersistentStore tableStore = table.getRowStore(session);
1514 
1515             row[cardinality] = Long.valueOf(tableStore.elementCount());
1516 
1517             if (table.isCached()) {
1518                 int spaceId = table.getSpaceID();
1519 
1520                 row[space_id]    = Long.valueOf(spaceId);
1521                 row[alloc_space] = null;
1522                 row[used_space]  = null;
1523                 row[used_memory] = null;
1524 
1525                 if (hasCache && spaceManager.isMultiSpace()
1526                         && spaceId != DataSpaceManager.tableIdDefault) {
1527                     long allocated = 0;
1528                     long used      = 0;
1529 
1530                     for (int i = 0; i < directoryList.length; i++) {
1531                         int[] tableIdList = directoryList[i].getTableIdArray();
1532                         char[] freeSpaceList =
1533                             directoryList[i].getFreeSpaceArray();
1534 
1535                         for (int j = 0; j < tableIdList.length; j++) {
1536                             if (tableIdList[j] == spaceId) {
1537                                 allocated += fileBlockSize;
1538                                 used += fileBlockSize
1539                                         - freeSpaceList[j] * cacheScale;
1540                             }
1541                         }
1542                     }
1543 
1544                     if (allocated > 0) {
1545                         TableSpaceManager tableSpace =
1546                             tableStore.getSpaceManager();
1547 
1548                         used -= tableSpace.getLostBlocksSize();
1549                     }
1550 
1551                     row[alloc_space] = Long.valueOf(allocated);
1552                     row[used_space]  = Long.valueOf(used);
1553                 }
1554             }
1555 
1556             t.insertSys(session, store, row);
1557         }
1558 
1559         long allocated = 0;
1560         long used      = 0;
1561         long empty     = 0;
1562         long system    = 0;
1563 
1564         for (int i = 0; i < directoryList.length; i++) {
1565             int[]  tableIdList   = directoryList[i].getTableIdArray();
1566             char[] freeSpaceList = directoryList[i].getFreeSpaceArray();
1567             int[]  bitMapList    = directoryList[i].getBitmapAddressArray();
1568 
1569             for (int j = 0; j < tableIdList.length; j++) {
1570                 if (tableIdList[j] == DataSpaceManager.tableIdDefault) {
1571                     allocated += fileBlockSize;
1572                     used      += fileBlockSize - freeSpaceList[j] * cacheScale;
1573                 } else if (tableIdList[j] == DataSpaceManager.tableIdEmpty
1574                            && bitMapList[j] != 0) {
1575                     empty += fileBlockSize;
1576                 } else if (tableIdList[j]
1577                            == DataSpaceManager.tableIdDirectory) {
1578                     system += fileBlockSize;
1579                 }
1580             }
1581         }
1582 
1583         if (hasCache) {
1584             row              = t.getEmptyRowData();
1585             row[table_name]  = "UNUSED_SPACE";
1586             row[alloc_space] = Long.valueOf(empty);
1587             row[used_space]  = Long.valueOf(0);
1588             row[space_id]    = Long.valueOf(DataSpaceManager.tableIdEmpty);
1589 
1590             t.insertSys(session, store, row);
1591 
1592             row              = t.getEmptyRowData();
1593             row[table_name]  = "COMMON_SPACE";
1594             row[alloc_space] = Long.valueOf(allocated);
1595             row[used_space]  = Long.valueOf(used);
1596             row[space_id]    = Long.valueOf(DataSpaceManager.tableIdDefault);
1597 
1598             t.insertSys(session, store, row);
1599 
1600             row              = t.getEmptyRowData();
1601             row[table_name]  = "SYSTEM_SPACE";
1602             row[alloc_space] = Long.valueOf(system);
1603             row[used_space]  = Long.valueOf(system);
1604             row[space_id]    = Long.valueOf(DataSpaceManager.tableIdDirectory);
1605 
1606             t.insertSys(session, store, row);
1607         }
1608 
1609         return t;
1610     }
1611 
1612     /**
1613      * Retrieves a <code>Table</code> object describing the visible
1614      * <code>Index</code> objects for each accessible table defined
1615      * within this database.<p>
1616      *
1617      * Each row is an index column description with the following
1618      * columns: <p>
1619      *
1620      * <pre class="SqlCodeExample">
1621      * TABLE_CATALOG    VARCHAR   table's catalog
1622      * TABLE_SCHEMA     VARCHAR   simple name of table's schema
1623      * TABLE_NAME       VARCHAR   simple name of the table using the index
1624      * INDEX_NAME       VARCHAR   simple name of the index
1625      * CARDINALITY      BIGINT    total number of rows
1626      * ALLOCATED_ROWS   BIGINT    allocated row count
1627      * ALLOCATED_SPACE  BIGINT    allocated bytes
1628      * USED_SPACE       BIGINT    used bytes
1629      * </pre> <p>
1630      *
1631      * @return a <code>Table</code> object describing the visible
1632      *        <code>Index</code> objects for each accessible
1633      *        table defined within this database.
1634      */
SYSTEM_INDEXSTATS(Session session, PersistentStore store)1635     final Table SYSTEM_INDEXSTATS(Session session, PersistentStore store) {
1636 
1637         Table t = sysTables[SYSTEM_INDEXSTATS];
1638 
1639         if (t == null) {
1640             t = createBlankTable(sysTableHsqlNames[SYSTEM_INDEXSTATS]);
1641 
1642             // JDBC
1643             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
1644             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
1645             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);    // NOT NULL
1646             addColumn(t, "TABLE_TYPE", SQL_IDENTIFIER);    // NOT NULL
1647             addColumn(t, "INDEX_NAME", SQL_IDENTIFIER);
1648             addColumn(t, "CARDINALITY", CARDINAL_NUMBER);
1649             addColumn(t, "ALLOCATED_ROWS", CARDINAL_NUMBER);
1650             addColumn(t, "USED_SPACE", CARDINAL_NUMBER);
1651             addColumn(t, "ALLOCATED_SPACE", CARDINAL_NUMBER);
1652             addColumn(t, "SPACE_ID", CARDINAL_NUMBER);
1653             addColumn(t, "BASE_SPACE", CARDINAL_NUMBER);
1654 
1655             // order: NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
1656             // added for unique: INDEX_QUALIFIER, TABLE_NAME
1657             // false PK, as INDEX_QUALIFIER may be null
1658             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1659                 sysTableHsqlNames[SYSTEM_INDEXSTATS].name, false,
1660                 SchemaObject.INDEX);
1661 
1662             t.createPrimaryKeyConstraint(name, new int[] {
1663                 0, 1, 2, 4
1664             }, false);
1665 
1666             return t;
1667         }
1668 
1669         // calculated column values
1670         String tableCatalog;
1671         String tableSchema;
1672         String tableName;
1673         String tableType;
1674         String indexName;
1675 
1676         // Intermediate holders
1677         Iterator tables;
1678         Table    table;
1679         int      indexCount;
1680         Object[] row;
1681 
1682         // column number mappings
1683         final int itable_cat   = 0;
1684         final int itable_schem = 1;
1685         final int itable_name  = 2;
1686         final int itable_type  = 3;
1687         final int iindex_name  = 4;
1688 
1689         // Initialization
1690         tables =
1691             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
1692 
1693         // Do it.
1694         while (tables.hasNext()) {
1695             table = (Table) tables.next();
1696 
1697             if (table.isView() || !isAccessibleTable(session, table)) {
1698                 continue;
1699             }
1700 
1701             tableCatalog = table.getCatalogName().name;
1702             tableSchema  = table.getSchemaName().name;
1703             tableName    = table.getName().name;
1704             tableType    = table.getTableTypeString();
1705             indexCount   = table.getIndexCount();
1706 
1707             // process all of the visible indices for this table
1708             for (int i = 0; i < indexCount; i++) {
1709                 Index index = table.getIndex(i);
1710 
1711                 indexName         = index.getName().name;
1712                 row               = t.getEmptyRowData();
1713                 row[itable_cat]   = tableCatalog;
1714                 row[itable_schem] = tableSchema;
1715                 row[itable_name]  = tableName;
1716                 row[itable_type]  = tableType;
1717                 row[iindex_name]  = indexName;
1718 
1719                 t.insertSys(session, store, row);
1720             }
1721         }
1722 
1723         return t;
1724     }
1725 
1726 //------------------------------------------------------------------------------
1727 // SQL SCHEMATA VIEWS
1728 
1729     /**
1730      * SQL:2008 VIEW<p>
1731      *
1732      * ADMINISTRABLE_ROLE_AUTHORIZATIONS<p>
1733      *
1734      * Returns roles that are grantable by an admin user, which means all the
1735      * roles.
1736      *
1737      * @return Table
1738      */
ADMINISTRABLE_ROLE_AUTHORIZATIONS(Session session, PersistentStore store)1739     Table ADMINISTRABLE_ROLE_AUTHORIZATIONS(Session session,
1740             PersistentStore store) {
1741 
1742         Table t = sysTables[ADMINISTRABLE_ROLE_AUTHORIZATIONS];
1743 
1744         if (t == null) {
1745             t = createBlankTable(
1746                 sysTableHsqlNames[ADMINISTRABLE_ROLE_AUTHORIZATIONS]);
1747 
1748             addColumn(t, "GRANTEE", SQL_IDENTIFIER);
1749             addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
1750             addColumn(t, "IS_GRANTABLE", SQL_IDENTIFIER);
1751 
1752             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1753                 sysTableHsqlNames[ADMINISTRABLE_ROLE_AUTHORIZATIONS].name,
1754                 false, SchemaObject.INDEX);
1755 
1756             t.createPrimaryKeyConstraint(name, new int[] {
1757                 0, 1, 2
1758             }, false);
1759 
1760             return t;
1761         }
1762 
1763         if (session.isAdmin()) {
1764             insertRoles(session, t, session.getGrantee(), true);
1765         }
1766 
1767         return t;
1768     }
1769 
1770     /**
1771      * SQL:2008 VIEW<p>
1772      *
1773      * APPLICABLE_ROLES<p>
1774      *
1775      * Identifies the applicable roles for the current user.<p>
1776      *
1777      * <b>Definition</b><p>
1778      *
1779      * <pre class="SqlCodeExample">
1780      * CREATE RECURSIVE VIEW APPLICABLE_ROLES ( GRANTEE, ROLE_NAME, IS_GRANTABLE ) AS
1781      *      ( ( SELECT GRANTEE, ROLE_NAME, IS_GRANTABLE
1782      *            FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS
1783      *           WHERE ( GRANTEE IN ( CURRENT_USER, 'PUBLIC' )
1784      *                OR GRANTEE IN ( SELECT ROLE_NAME
1785      *                                  FROM ENABLED_ROLES ) ) )
1786      *      UNION
1787      *      ( SELECT RAD.GRANTEE, RAD.ROLE_NAME, RAD.IS_GRANTABLE
1788      *          FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS RAD
1789      *          JOIN APPLICABLE_ROLES R
1790      *            ON RAD.GRANTEE = R.ROLE_NAME ) );
1791      *
1792      * GRANT SELECT ON TABLE APPLICABLE_ROLES
1793      *    TO PUBLIC WITH GRANT OPTION;
1794      * </pre>
1795      */
APPLICABLE_ROLES(Session session, PersistentStore store)1796     Table APPLICABLE_ROLES(Session session, PersistentStore store) {
1797 
1798         Table t = sysTables[APPLICABLE_ROLES];
1799 
1800         if (t == null) {
1801             t = createBlankTable(sysTableHsqlNames[APPLICABLE_ROLES]);
1802 
1803             addColumn(t, "GRANTEE", SQL_IDENTIFIER);
1804             addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
1805             addColumn(t, "IS_GRANTABLE", SQL_IDENTIFIER);
1806 
1807             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1808                 sysTableHsqlNames[APPLICABLE_ROLES].name, false,
1809                 SchemaObject.INDEX);
1810 
1811             t.createPrimaryKeyConstraint(name, new int[] {
1812                 0, 1, 2
1813             }, false);
1814 
1815             return t;
1816         }
1817 
1818         insertRoles(session, t, session.getGrantee(), session.isAdmin());
1819 
1820         return t;
1821     }
1822 
insertRoles(Session session, Table t, Grantee role, boolean isGrantable)1823     private void insertRoles(Session session, Table t, Grantee role,
1824                              boolean isGrantable) {
1825 
1826         final int       grantee      = 0;
1827         final int       role_name    = 1;
1828         final int       is_grantable = 2;
1829         PersistentStore store        = t.getRowStore(session);
1830 
1831         if (isGrantable) {
1832             Set      roles = database.getGranteeManager().getRoleNames();
1833             Iterator it    = roles.iterator();
1834 
1835             while (it.hasNext()) {
1836                 String   roleName = (String) it.next();
1837                 Object[] row      = t.getEmptyRowData();
1838 
1839                 row[grantee]      = role.getName().getNameString();
1840                 row[role_name]    = roleName;
1841                 row[is_grantable] = Tokens.T_YES;
1842 
1843                 t.insertSys(session, store, row);
1844             }
1845         } else {
1846             OrderedHashSet roles = role.getDirectRoles();
1847 
1848             for (int i = 0; i < roles.size(); i++) {
1849                 Grantee  currentRole = (Grantee) roles.get(i);
1850                 String   roleName    = currentRole.getName().getNameString();
1851                 Object[] row         = t.getEmptyRowData();
1852 
1853                 row[grantee]      = role.getName().getNameString();
1854                 row[role_name]    = roleName;
1855                 row[is_grantable] = Tokens.T_NO;
1856 
1857                 t.insertSys(session, store, row);
1858 
1859                 role = database.getGranteeManager().getRole(roleName);
1860 
1861                 insertRoles(session, t, role, isGrantable);
1862             }
1863         }
1864     }
1865 
1866     /**
1867      * SQL:2008 VIEW<p>
1868      *
1869      * The ASSERTIONS view is empty.<p>
1870      *
1871      */
ASSERTIONS(Session session, PersistentStore store)1872     Table ASSERTIONS(Session session, PersistentStore store) {
1873 
1874         Table t = sysTables[ASSERTIONS];
1875 
1876         if (t == null) {
1877             t = createBlankTable(sysTableHsqlNames[ASSERTIONS]);
1878 
1879             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
1880             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
1881             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
1882             addColumn(t, "IS_DEFERRABLE", YES_OR_NO);
1883             addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);
1884 
1885             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1886                 sysTableHsqlNames[ASSERTIONS].name, false, SchemaObject.INDEX);
1887 
1888             t.createPrimaryKeyConstraint(name, new int[] {
1889                 0, 1, 2
1890             }, false);
1891 
1892             return t;
1893         }
1894 
1895         final int constraint_catalog = 0;
1896         final int constraint_schema  = 1;
1897         final int constraint_name    = 2;
1898         final int is_deferrable      = 3;
1899         final int initially_deferred = 4;
1900 
1901         return t;
1902     }
1903 
1904     /**
1905      * SQL:2008 VIEW<p>
1906      *
1907      *  SYSTEM_AUTHORIZATIONS<p>
1908      *
1909      *  The AUTHORIZATIONS table has one row for each &lt;role name&gt; and
1910      *  one row for each &lt;authorization identifier &gt; referenced in the
1911      *  Information Schema. These are the &lt;role name&gt;s and
1912      *  &lt;authorization identifier&gt;s that may grant privileges as well as
1913      *  those that may create a schema, or currently own a schema created
1914      *  through a &lt;schema definition&gt;. <p>
1915      *
1916      *  <b>Definition</b><p>
1917      *
1918      *  <pre class="SqlCodeExample">
1919      *  CREATE TABLE AUTHORIZATIONS (
1920      *       AUTHORIZATION_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
1921      *       AUTHORIZATION_TYPE INFORMATION_SCHEMA.CHARACTER_DATA
1922      *           CONSTRAINT AUTHORIZATIONS_AUTHORIZATION_TYPE_NOT_NULL
1923      *               NOT NULL
1924      *           CONSTRAINT AUTHORIZATIONS_AUTHORIZATION_TYPE_CHECK
1925      *               CHECK ( AUTHORIZATION_TYPE IN ( 'USER', 'ROLE' ) ),
1926      *           CONSTRAINT AUTHORIZATIONS_PRIMARY_KEY
1927      *               PRIMARY KEY (AUTHORIZATION_NAME)
1928      *       )
1929      *  </pre>
1930      *
1931      *  <b>Description</b><p>
1932      *
1933      *  <ol>
1934      *  <li> The values of AUTHORIZATION_TYPE have the following meanings:<p>
1935      *
1936      *  <table border cellpadding="3">
1937      *       <tr>
1938      *           <td nowrap>USER</td>
1939      *           <td nowrap>The value of AUTHORIZATION_NAME is a known
1940      *                      &lt;user identifier&gt;.</td>
1941      *       <tr>
1942      *       <tr>
1943      *           <td nowrap>NO</td>
1944      *           <td nowrap>The value of AUTHORIZATION_NAME is a &lt;role
1945      *                      name&gt; defined by a &lt;role definition&gt;.</td>
1946      *       <tr>
1947      *  </table> <p>
1948      *  </ol>
1949      *
1950      * @return Table
1951      */
AUTHORIZATIONS(Session session, PersistentStore store)1952     Table AUTHORIZATIONS(Session session, PersistentStore store) {
1953 
1954         Table t = sysTables[AUTHORIZATIONS];
1955 
1956         if (t == null) {
1957             t = createBlankTable(sysTableHsqlNames[AUTHORIZATIONS]);
1958 
1959             addColumn(t, "AUTHORIZATION_NAME", SQL_IDENTIFIER);    // not null
1960             addColumn(t, "AUTHORIZATION_TYPE", SQL_IDENTIFIER);    // not null
1961 
1962             // true PK
1963             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
1964                 sysTableHsqlNames[AUTHORIZATIONS].name, false,
1965                 SchemaObject.INDEX);
1966 
1967             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
1968 
1969             return t;
1970         }
1971 
1972         // Intermediate holders
1973         Iterator grantees;
1974         Grantee  grantee;
1975         Object[] row;
1976 
1977         // initialization
1978         grantees = session.getGrantee().visibleGrantees().iterator();
1979 
1980         // Do it.
1981         while (grantees.hasNext()) {
1982             grantee = (Grantee) grantees.next();
1983             row     = t.getEmptyRowData();
1984             row[0]  = grantee.getName().getNameString();
1985             row[1]  = grantee.isRole() ? "ROLE"
1986                                        : "USER";
1987 
1988             t.insertSys(session, store, row);
1989         }
1990 
1991         return t;
1992     }
1993 
CHARACTER_SETS(Session session, PersistentStore store)1994     Table CHARACTER_SETS(Session session, PersistentStore store) {
1995 
1996         Table t = sysTables[CHARACTER_SETS];
1997 
1998         if (t == null) {
1999             t = createBlankTable(sysTableHsqlNames[CHARACTER_SETS]);
2000 
2001             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
2002             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
2003             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
2004             addColumn(t, "CHARACTER_REPERTOIRE", SQL_IDENTIFIER);
2005             addColumn(t, "FORM_OF_USE", SQL_IDENTIFIER);
2006             addColumn(t, "DEFAULT_COLLATE_CATALOG", SQL_IDENTIFIER);
2007             addColumn(t, "DEFAULT_COLLATE_SCHEMA", SQL_IDENTIFIER);
2008             addColumn(t, "DEFAULT_COLLATE_NAME", SQL_IDENTIFIER);
2009 
2010             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2011                 sysTableHsqlNames[CHARACTER_SETS].name, false,
2012                 SchemaObject.INDEX);
2013 
2014             t.createPrimaryKeyConstraint(name, new int[] {
2015                 0, 1, 2
2016             }, false);
2017 
2018             return t;
2019         }
2020 
2021         final int character_set_catalog   = 0;
2022         final int character_set_schema    = 1;
2023         final int character_set_name      = 2;
2024         final int character_repertoire    = 3;
2025         final int form_of_use             = 4;
2026         final int default_collate_catalog = 5;
2027         final int default_collate_schema  = 6;
2028         final int default_collate_name    = 7;
2029 
2030         //
2031         Iterator it = database.schemaManager.databaseObjectIterator(
2032             SchemaObject.CHARSET);
2033 
2034         while (it.hasNext()) {
2035             Charset charset = (Charset) it.next();
2036 
2037             if (!session.getGrantee().isAccessible(charset)) {
2038                 continue;
2039             }
2040 
2041             Object[] data = t.getEmptyRowData();
2042 
2043             data[character_set_catalog]   = database.getCatalogName().name;
2044             data[character_set_schema]    = charset.getSchemaName().name;
2045             data[character_set_name]      = charset.getName().name;
2046             data[character_repertoire]    = "UCS";
2047             data[form_of_use]             = "UTF16";
2048             data[default_collate_catalog] = data[character_set_catalog];
2049 
2050             if (charset.base == null) {
2051                 data[default_collate_schema] = data[character_set_schema];
2052                 data[default_collate_name]   = data[character_set_name];
2053             } else {
2054                 data[default_collate_schema] = charset.base.schema.name;
2055                 data[default_collate_name]   = charset.base.name;
2056             }
2057 
2058             t.insertSys(session, store, data);
2059         }
2060 
2061         return t;
2062     }
2063 
2064     /**
2065      * SQL:2008 VIEW<p>
2066      *
2067      * The CHECK_CONSTRAINT_ROUTINE_USAGE view has one row for each
2068      * SQL-invoked routine identified as the subject routine of either a
2069      * &lt;routine invocation&gt;, a &lt;method reference&gt;, a
2070      * &lt;method invocation&gt;, or a &lt;static method invocation&gt;
2071      * contained in an &lt;assertion definition&gt;, a &lt;domain
2072      * constraint&gt;, or a &lt;table constraint definition&gt;. <p>
2073      *
2074      * <b>Definition:</b> <p>
2075      *
2076      * <pre class="SqlCodeExample">
2077      * CREATE TABLE SYSTEM_CHECK_ROUTINE_USAGE (
2078      *      CONSTRAINT_CATALOG      VARCHAR NULL,
2079      *      CONSTRAINT_SCHEMA       VARCHAR NULL,
2080      *      CONSTRAINT_NAME         VARCHAR NOT NULL,
2081      *      SPECIFIC_CATALOG        VARCHAR NULL,
2082      *      SPECIFIC_SCHEMA         VARCHAR NULL,
2083      *      SPECIFIC_NAME           VARCHAR NOT NULL,
2084      *      UNIQUE( CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME,
2085      *              SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME )
2086      * )
2087      * </pre>
2088      *
2089      * <b>Description:</b> <p>
2090      *
2091      * <ol>
2092      * <li> The CHECK_ROUTINE_USAGE table has one row for each
2093      *      SQL-invoked routine R identified as the subject routine of either a
2094      *      &lt;routine invocation&gt;, a &lt;method reference&gt;, a &lt;method
2095      *      invocation&gt;, or a &lt;static method invocation&gt; contained in
2096      *      an &lt;assertion definition&gt; or in the &lt;check constraint
2097      *      definition&gt; contained in either a &lt;domain constraint&gt; or a
2098      *      &lt;table constraint definition&gt;. <p>
2099      *
2100      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
2101      *      CONSTRAINT_NAME are the catalog name, schema name, and
2102      *      identifier, respectively, of the assertion or check
2103      *      constraint being described. <p>
2104      *
2105      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA, and SPECIFIC_NAME
2106      *      are the catalog name, schema name, and qualified
2107      *      identifier, respectively, of the specific name of R. <p>
2108      *
2109      * <1i> Routines are reported only if the user or one of its roles is
2110      *      the authorization (owner) of the routine.
2111      *
2112      * </ol>
2113      *
2114      * @return Table
2115      */
CHECK_CONSTRAINT_ROUTINE_USAGE(Session session, PersistentStore store)2116     Table CHECK_CONSTRAINT_ROUTINE_USAGE(Session session,
2117                                          PersistentStore store) {
2118 
2119         Table t = sysTables[CHECK_CONSTRAINT_ROUTINE_USAGE];
2120 
2121         if (t == null) {
2122             t = createBlankTable(
2123                 sysTableHsqlNames[CHECK_CONSTRAINT_ROUTINE_USAGE]);
2124 
2125             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
2126             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
2127             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
2128             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
2129             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
2130             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);      // not null
2131 
2132             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2133                 sysTableHsqlNames[CHECK_CONSTRAINT_ROUTINE_USAGE].name, false,
2134                 SchemaObject.INDEX);
2135 
2136             t.createPrimaryKeyConstraint(name, new int[] {
2137                 0, 1, 2, 3, 4, 5
2138             }, false);
2139 
2140             return t;
2141         }
2142 
2143         // column number mappings
2144         final int constraint_catalog = 0;
2145         final int constraint_schema  = 1;
2146         final int constraint_name    = 2;
2147         final int specific_catalog   = 3;
2148         final int specific_schema    = 4;
2149         final int specific_name      = 5;
2150 
2151         //
2152         // Intermediate holders
2153         Iterator       constraints;
2154         Constraint     constraint;
2155         OrderedHashSet references;
2156         Object[]       row;
2157 
2158         constraints = database.schemaManager.databaseObjectIterator(
2159             SchemaObject.CONSTRAINT);
2160 
2161         while (constraints.hasNext()) {
2162             HsqlName constraintName = (HsqlName) constraints.next();
2163 
2164             if (constraintName.parent == null) {
2165                 continue;
2166             }
2167 
2168             switch (constraintName.parent.type) {
2169 
2170                 case SchemaObject.TABLE : {
2171                     Table table;
2172 
2173                     try {
2174                         table = (Table) database.schemaManager.getSchemaObject(
2175                             constraintName.parent.name,
2176                             constraintName.parent.schema.name,
2177                             SchemaObject.TABLE);
2178                     } catch (Exception e) {
2179                         continue;
2180                     }
2181 
2182                     constraint = table.getConstraint(constraintName.name);
2183 
2184                     if (constraint.getConstraintType()
2185                             != SchemaObject.ConstraintTypes.CHECK) {
2186                         continue;
2187                     }
2188 
2189                     break;
2190                 }
2191                 case SchemaObject.DOMAIN : {
2192                     Type domain;
2193 
2194                     try {
2195                         domain = (Type) database.schemaManager.getSchemaObject(
2196                             constraintName.parent.name,
2197                             constraintName.parent.schema.name,
2198                             SchemaObject.DOMAIN);
2199                     } catch (Exception e) {
2200                         continue;
2201                     }
2202 
2203                     constraint = domain.userTypeModifier.getConstraint(
2204                         constraintName.name);
2205                 }
2206                 default :
2207                     continue;
2208             }
2209 
2210             references = constraint.getReferences();
2211 
2212             for (int i = 0; i < references.size(); i++) {
2213                 HsqlName name = (HsqlName) references.get(i);
2214 
2215                 if (name.type != SchemaObject.SPECIFIC_ROUTINE) {
2216                     continue;
2217                 }
2218 
2219                 if (!session.getGrantee().isFullyAccessibleByRole(name)) {
2220                     continue;
2221                 }
2222 
2223                 row                     = t.getEmptyRowData();
2224                 row[constraint_catalog] = database.getCatalogName().name;
2225                 row[constraint_schema]  = constraint.getSchemaName().name;
2226                 row[constraint_name]    = constraint.getName().name;
2227                 row[specific_catalog]   = database.getCatalogName().name;
2228                 row[specific_schema]    = name.schema.name;
2229                 row[specific_name]      = name.name;
2230 
2231                 t.insertSys(session, store, row);
2232             }
2233         }
2234 
2235         return t;
2236     }
2237 
2238     /**
2239      * SQL:2008 VIEW<p>
2240      *
2241      * The CHECK_CONSTRAINTS view has one row for each domain
2242      * constraint, table check constraint, and assertion. <p>
2243      *
2244      * <b>Definition:</b><p>
2245      *
2246      * <pre class="SqlCodeExample">
2247      *      CONSTRAINT_CATALOG  VARCHAR NULL,
2248      *      CONSTRAINT_SCHEMA   VARCHAR NULL,
2249      *      CONSTRAINT_NAME     VARCHAR NOT NULL,
2250      *      CHECK_CLAUSE        VARCHAR NOT NULL,
2251      * </pre>
2252      *
2253      * <b>Description:</b><p>
2254      *
2255      * <ol>
2256      * <li> A constraint is shown in this view if the authorization for the
2257      *      schema that contains the constraint is the current user or is a role
2258      *      assigned to the current user. <p>
2259      *
2260      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA and
2261      *      CONSTRAINT_NAME are the catalog name, schema name,
2262      *      and identifier, respectively, of the constraint being
2263      *      described. <p>
2264      *
2265      * <li> the value of CHECK_CLAUSE is that character representation of
2266      *      the search condition contained in the check constraint.
2267      *
2268      * <1i> Constraints are reported only if the user or one of its roles is
2269      *      the authorization (owner) of the table.
2270      * </ol>
2271      *
2272      * @return Table
2273      */
CHECK_CONSTRAINTS(Session session, PersistentStore store)2274     Table CHECK_CONSTRAINTS(Session session, PersistentStore store) {
2275 
2276         Table t = sysTables[CHECK_CONSTRAINTS];
2277 
2278         if (t == null) {
2279             t = createBlankTable(sysTableHsqlNames[CHECK_CONSTRAINTS]);
2280 
2281             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
2282             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
2283             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
2284             addColumn(t, "CHECK_CLAUSE", CHARACTER_DATA);       // not null
2285 
2286             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2287                 sysTableHsqlNames[CHECK_CONSTRAINTS].name, false,
2288                 SchemaObject.INDEX);
2289 
2290             t.createPrimaryKeyConstraint(name, new int[] {
2291                 2, 1, 0
2292             }, false);
2293 
2294             return t;
2295         }
2296 
2297         // column number mappings
2298         final int constraint_catalog = 0;
2299         final int constraint_schema  = 1;
2300         final int constraint_name    = 2;
2301         final int check_clause       = 3;
2302 
2303         //
2304         // calculated column values
2305         // Intermediate holders
2306         Iterator     tables;
2307         Table        table;
2308         Constraint[] tableConstraints;
2309         int          constraintCount;
2310         Constraint   constraint;
2311         Object[]     row;
2312 
2313         //
2314         tables =
2315             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
2316 
2317         while (tables.hasNext()) {
2318             table = (Table) tables.next();
2319 
2320             if (table.isView()
2321                     || !session.getGrantee().isFullyAccessibleByRole(
2322                         table.getName())) {
2323                 continue;
2324             }
2325 
2326             tableConstraints = table.getConstraints();
2327             constraintCount  = tableConstraints.length;
2328 
2329             for (int i = 0; i < constraintCount; i++) {
2330                 constraint = tableConstraints[i];
2331 
2332                 if (constraint.getConstraintType()
2333                         != SchemaObject.ConstraintTypes.CHECK) {
2334                     continue;
2335                 }
2336 
2337                 row                     = t.getEmptyRowData();
2338                 row[constraint_catalog] = database.getCatalogName().name;
2339                 row[constraint_schema]  = table.getSchemaName().name;
2340                 row[constraint_name]    = constraint.getName().name;
2341 
2342                 try {
2343                     row[check_clause] = constraint.getCheckSQL();
2344                 } catch (Exception e) {}
2345 
2346                 t.insertSys(session, store, row);
2347             }
2348         }
2349 
2350         Iterator it =
2351             database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
2352 
2353         while (it.hasNext()) {
2354             Type domain = (Type) it.next();
2355 
2356             if (!domain.isDomainType()) {
2357                 continue;
2358             }
2359 
2360             if (!session.getGrantee().isFullyAccessibleByRole(
2361                     domain.getName())) {
2362                 continue;
2363             }
2364 
2365             tableConstraints = domain.userTypeModifier.getConstraints();
2366             constraintCount  = tableConstraints.length;
2367 
2368             for (int i = 0; i < constraintCount; i++) {
2369                 constraint              = tableConstraints[i];
2370                 row                     = t.getEmptyRowData();
2371                 row[constraint_catalog] = database.getCatalogName().name;
2372                 row[constraint_schema]  = domain.getSchemaName().name;
2373                 row[constraint_name]    = constraint.getName().name;
2374 
2375                 try {
2376                     row[check_clause] = constraint.getCheckSQL();
2377                 } catch (Exception e) {}
2378 
2379                 t.insertSys(session, store, row);
2380             }
2381         }
2382 
2383         return t;
2384     }
2385 
2386     /**
2387      * SQL:2008 VIEW<p>
2388      *
2389      * COLLATIONS<p>
2390      *
2391      * The COLLATIONS view has one row for each character collation
2392      * descriptor. <p>
2393      *
2394      * <b>Definition</b>
2395      *
2396      * <pre class="SqlCodeExample">
2397      * CREATE TABLE COLLATIONS (
2398      *      COLLATION_CATALOG INFORMATION_SCHEMA.SQL_IDENTIFIER,
2399      *      COLLATION_SCHEMA INFORMATION_SCHEMA.SQL_IDENTIFIER,
2400      *      COLLATION_NAME INFORMATION_SCHEMA.SQL_IDENTIFIER,
2401      *      PAD_ATTRIBUTE INFORMATION_SCHEMA.CHARACTER_DATA
2402      *          CONSTRAINT COLLATIONS_PAD_ATTRIBUTE_CHECK
2403      *              CHECK ( PAD_ATTRIBUTE IN
2404      *                  ( 'NO PAD', 'PAD SPACE' ) )
2405      * )
2406      * </pre>
2407      *
2408      * <b>Description</b><p>
2409      *
2410      * <ol>
2411      *      <li>The values of COLLATION_CATALOG, COLLATION_SCHEMA, and
2412      *          COLLATION_NAME are the catalog name, schema name,
2413      *          and identifier, respectively, of the collation being
2414      *          described.<p>
2415      *
2416      *      <li>The values of PAD_ATTRIBUTE have the following meanings:<p>
2417      *
2418      *      <table border cellpadding="3">
2419      *          <tr>
2420      *              <td nowrap>NO PAD</td>
2421      *              <td nowrap>The collation being described has the NO PAD
2422      *                  characteristic.</td>
2423      *          <tr>
2424      *          <tr>
2425      *              <td nowrap>PAD</td>
2426      *              <td nowrap>The collation being described has the PAD SPACE
2427      *                         characteristic.</td>
2428      *          <tr>
2429      *      </table> <p>
2430      * </ol>
2431      *
2432      * @return Table
2433      */
COLLATIONS(Session session, PersistentStore store)2434     Table COLLATIONS(Session session, PersistentStore store) {
2435 
2436         Table t = sysTables[COLLATIONS];
2437 
2438         if (t == null) {
2439             t = createBlankTable(sysTableHsqlNames[COLLATIONS]);
2440 
2441             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
2442             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);    // not null
2443             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);      // not null
2444             addColumn(t, "PAD_ATTRIBUTE", CHARACTER_DATA);
2445 
2446             // false PK, as rows may have NULL COLLATION_CATALOG
2447             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2448                 sysTableHsqlNames[COLLATIONS].name, false, SchemaObject.INDEX);
2449 
2450             t.createPrimaryKeyConstraint(name, new int[] {
2451                 0, 1, 2
2452             }, false);
2453 
2454             return t;
2455         }
2456 
2457         // Column number mappings
2458         final int collation_catalog = 0;
2459         final int collation_schema  = 1;
2460         final int collation_name    = 2;
2461         final int pad_attribute     = 3;
2462 
2463         //
2464         // Intermediate holders
2465         Iterator  collations;
2466         Collation collation;
2467         String    collationName;
2468         String    collationSchema;
2469         String    padAttribute = "PAD SPACE";
2470         Object[]  row;
2471 
2472         collations = database.schemaManager.databaseObjectIterator(
2473             SchemaObject.COLLATION);
2474 
2475         while (collations.hasNext()) {
2476             row                    = t.getEmptyRowData();
2477             collation              = (Collation) collations.next();
2478             collationSchema        = collation.getSchemaName().name;
2479             collationName          = collation.getName().name;
2480             row[collation_catalog] = database.getCatalogName().name;
2481             row[collation_schema]  = collationSchema;
2482             row[collation_name]    = collationName;
2483             row[pad_attribute]     = collation.isPadSpace() ? "PAD SPACE"
2484                                                             : "NO PAD";
2485 
2486             t.insertSys(session, store, row);
2487         }
2488 
2489         // Initialization
2490         collations = Collation.nameToJavaName.keySet().iterator();
2491 
2492         // Do it.
2493         while (collations.hasNext()) {
2494             row                    = t.getEmptyRowData();
2495             collationSchema        = "INFORMATION_SCHEMA";
2496             collationName          = (String) collations.next();
2497             row[collation_catalog] = database.getCatalogName().name;
2498             row[collation_schema]  = collationSchema;
2499             row[collation_name]    = collationName;
2500             row[pad_attribute]     = padAttribute;
2501 
2502             t.insertSys(session, store, row);
2503         }
2504 
2505         return t;
2506     }
2507 
2508     /**
2509      * SQL:2008 VIEW<p>
2510      * The COLUMN_COLUMN_USAGE view has one row for each column referenced by
2511      * a GENERATED column.<p>
2512      *
2513      * <b>Definition:</b><p>
2514      *
2515      *      TABLE_CATALOG       VARCHAR
2516      *      TABLE_SCHEMA        VARCHAR
2517      *      TABLE_NAME          VARCHAR
2518      *      COLUMN_NAME         VARCHAR
2519      *      DEPENDENT_COLUMN    VARCHAR
2520      *
2521      * </pre>
2522      *
2523      * <b>Description:</b> <p>
2524      *
2525      * <ol>
2526      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
2527      *      COLUMN_NAME are the catalog name, schema name,
2528      *      identifier, and column name, respectively, of a column
2529      *      defined as GENERATED ALWAYS..
2530      *
2531      * <li> The value of DEPENDENT_COLUMN is the name of generated column. The value
2532      *      of COLUMN_NAME is the name of a column referenced by the generated
2533      *      column. There may be multiple rows for each generated column.
2534      *
2535      * <1i> Columns are reported only if the user or one of its roles is
2536      *      the authorization (owner) of the table.
2537      * </ol>
2538      * <p>
2539      *
2540      * @return Table
2541      */
COLUMN_COLUMN_USAGE(Session session, PersistentStore store)2542     Table COLUMN_COLUMN_USAGE(Session session, PersistentStore store) {
2543 
2544         Table t = sysTables[COLUMN_COLUMN_USAGE];
2545 
2546         if (t == null) {
2547             t = createBlankTable(sysTableHsqlNames[COLUMN_COLUMN_USAGE]);
2548 
2549             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
2550             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
2551             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
2552             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
2553             addColumn(t, "DEPENDENT_COLUMN", SQL_IDENTIFIER);
2554 
2555             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2556                 sysTableHsqlNames[COLUMN_COLUMN_USAGE].name, false,
2557                 SchemaObject.INDEX);
2558 
2559             t.createPrimaryKeyConstraint(name, new int[] {
2560                 0, 1, 2, 3, 4
2561             }, false);
2562 
2563             return t;
2564         }
2565 
2566         final int table_catalog    = 0;
2567         final int table_schema     = 1;
2568         final int table_name       = 2;
2569         final int column_name      = 3;
2570         final int dependent_column = 4;
2571 
2572         //
2573         Iterator tables;
2574         Table    table;
2575         Object[] row;
2576 
2577         tables =
2578             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
2579 
2580         while (tables.hasNext()) {
2581             table = (Table) tables.next();
2582 
2583             if (table.isView()
2584                     || !session.getGrantee().isFullyAccessibleByRole(
2585                         table.getName())) {
2586                 continue;
2587             }
2588 
2589             if (!table.hasGeneratedColumn()) {
2590                 continue;
2591             }
2592 
2593             HsqlName name = table.getName();
2594 
2595             for (int i = 0; i < table.getColumnCount(); i++) {
2596                 ColumnSchema column = table.getColumn(i);
2597 
2598                 if (!column.isGenerated()) {
2599                     continue;
2600                 }
2601 
2602                 OrderedHashSet set = column.getGeneratedColumnReferences();
2603 
2604                 if (set != null) {
2605                     for (int j = 0; j < set.size(); j++) {
2606                         row                   = t.getEmptyRowData();
2607                         row[table_catalog]    = database.getCatalogName().name;
2608                         row[table_schema]     = name.schema.name;
2609                         row[table_name]       = name.name;
2610                         row[column_name]      = ((HsqlName) set.get(j)).name;
2611                         row[dependent_column] = column.getName().name;
2612 
2613                         t.insertSys(session, store, row);
2614                     }
2615                 }
2616             }
2617         }
2618 
2619         return t;
2620     }
2621 
2622     /**
2623      * SQL:2008 VIEW<p>
2624      * The COLUMN_DOMAIN_USAGE view has one row for each column defined with a
2625      * a DOMAIN data type.<p>
2626      *
2627      * <b>Definition:</b><p>
2628      *
2629      *      DOMAIN_CATALOG      VARCHAR
2630      *      DOMAIN_SCHEMA       VARCHAR
2631      *      DOMAIN_NAME         VARCHAR
2632      *      TABLE_CATALOG       VARCHAR
2633      *      TABLE_SCHEMA        VARCHAR
2634      *      TABLE_NAME          VARCHAR
2635      *      COLUMN_NAME         VARCHAR
2636      *
2637      * </pre>
2638      *
2639      * <b>Description:</b> <p>
2640      *
2641      * <ol>
2642      * <li> The values of DOMAIN_CATALOG, DOMAIN_SCHEMA and DOMAIN_NAME
2643      *      are the catalog name, schema name,
2644      *      name, respectively, of a DOMAIN data type.
2645      *
2646      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
2647      *      COLUMN_NAME are the catalog name, schema name,
2648      *      identifier, and column name, respectively, of a column
2649      *      defined with a DOMAIN data type.
2650      *
2651      * <1i> Columns are reported only if the user or one of its roles is
2652      *      the authorization (owner) of the DOMAIN.
2653      * </ol>
2654      * <p>
2655      *
2656      * @return Table
2657      */
COLUMN_DOMAIN_USAGE(Session session, PersistentStore store)2658     Table COLUMN_DOMAIN_USAGE(Session session, PersistentStore store) {
2659 
2660         Table t = sysTables[COLUMN_DOMAIN_USAGE];
2661 
2662         if (t == null) {
2663             t = createBlankTable(sysTableHsqlNames[COLUMN_DOMAIN_USAGE]);
2664 
2665             addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
2666             addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
2667             addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
2668             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
2669             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
2670             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);     // not null
2671             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);    // not null
2672 
2673             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2674                 sysTableHsqlNames[COLUMN_DOMAIN_USAGE].name, false,
2675                 SchemaObject.INDEX);
2676 
2677             t.createPrimaryKeyConstraint(name, new int[] {
2678                 0, 1, 2, 3, 4, 5, 6
2679             }, false);
2680 
2681             return t;
2682         }
2683 
2684         // column number mappings
2685         final int domain_catalog = 0;
2686         final int domain_schema  = 1;
2687         final int domain_name    = 2;
2688         final int table_catalog  = 3;
2689         final int table_schema   = 4;
2690         final int table_name     = 5;
2691         final int column_name    = 6;
2692 
2693         // intermediate holders
2694         int      columnCount;
2695         Iterator tables;
2696         Table    table;
2697         Object[] row;
2698         Type     type;
2699         HsqlName tableName;
2700 
2701         // Initialization
2702         tables = allTables();
2703 
2704         Grantee grantee = session.getGrantee();
2705 
2706         while (tables.hasNext()) {
2707             table       = (Table) tables.next();
2708             columnCount = table.getColumnCount();
2709             tableName   = table.getName();
2710 
2711             for (int i = 0; i < columnCount; i++) {
2712                 ColumnSchema column = table.getColumn(i);
2713 
2714                 type = column.getDataType();
2715 
2716                 if (!type.isDomainType()) {
2717                     continue;
2718                 }
2719 
2720                 if (!grantee.isFullyAccessibleByRole(type.getName())) {
2721                     continue;
2722                 }
2723 
2724                 row                 = t.getEmptyRowData();
2725                 row[domain_catalog] = database.getCatalogName().name;
2726                 row[domain_schema]  = type.getSchemaName().name;
2727                 row[domain_name]    = type.getName().name;
2728                 row[table_catalog]  = database.getCatalogName().name;
2729                 row[table_schema]   = tableName.schema.name;
2730                 row[table_name]     = tableName.name;
2731                 row[column_name]    = column.getNameString();
2732 
2733                 t.insertSys(session, store, row);
2734             }
2735         }
2736 
2737         return t;
2738     }
2739 
2740     /**
2741      * SQL:2008 VIEW<p>
2742      * The COLUMN_DOMAIN_USAGE view has one row for each column defined with a
2743      * a DOMAIN data type.<p>
2744      *
2745      * <b>Definition:</b><p>
2746      *
2747      *      UDT_CATALOG      VARCHAR
2748      *      UDT_SCHEMA       VARCHAR
2749      *      UDT_NAME         VARCHAR
2750      *      TABLE_CATALOG    VARCHAR
2751      *      TABLE_SCHEMA     VARCHAR
2752      *      TABLE_NAME       VARCHAR
2753      *      COLUMN_NAME      VARCHAR
2754      *
2755      * </pre>
2756      *
2757      * <b>Description:</b> <p>
2758      *
2759      * <ol>
2760      * <li> The values of UDT_CATALOG, UDT_SCHEMA and UDT_NAME
2761      *      are the catalog name, schema name,
2762      *      name, respectively, of a DISTINCT TYPE data type.
2763      *
2764      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
2765      *      COLUMN_NAME are the catalog name, schema name,
2766      *      identifier, and column name, respectively, of a column
2767      *      defined with a DICTINCT TYPE data type.
2768      *
2769      * <1i> Columns are reported only if the user or one of its roles is
2770      *      the authorization (owner) of the DISTINCT TYPE.
2771      * </ol>
2772      * <p>
2773      *
2774      * @return Table
2775      */
COLUMN_UDT_USAGE(Session session, PersistentStore store)2776     Table COLUMN_UDT_USAGE(Session session, PersistentStore store) {
2777 
2778         Table t = sysTables[COLUMN_UDT_USAGE];
2779 
2780         if (t == null) {
2781             t = createBlankTable(sysTableHsqlNames[COLUMN_UDT_USAGE]);
2782 
2783             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
2784             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
2785             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
2786             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
2787             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
2788             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);     // not null
2789             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);    // not null
2790 
2791             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2792                 sysTableHsqlNames[COLUMN_UDT_USAGE].name, false,
2793                 SchemaObject.INDEX);
2794 
2795             t.createPrimaryKeyConstraint(name, new int[] {
2796                 0, 1, 2, 3, 4, 5, 6
2797             }, false);
2798 
2799             return t;
2800         }
2801 
2802         // column number mappings
2803         final int udt_catalog   = 0;
2804         final int udt_schema    = 1;
2805         final int udt_name      = 2;
2806         final int table_catalog = 3;
2807         final int table_schema  = 4;
2808         final int table_name    = 5;
2809         final int column_name   = 6;
2810 
2811         // intermediate holders
2812         int      columnCount;
2813         Iterator tables;
2814         Table    table;
2815         Object[] row;
2816         Type     type;
2817         HsqlName tableName;
2818 
2819         // Initialization
2820         tables = allTables();
2821 
2822         Grantee grantee = session.getGrantee();
2823 
2824         while (tables.hasNext()) {
2825             table       = (Table) tables.next();
2826             columnCount = table.getColumnCount();
2827             tableName   = table.getName();
2828 
2829             for (int i = 0; i < columnCount; i++) {
2830                 ColumnSchema column = table.getColumn(i);
2831 
2832                 type = column.getDataType();
2833 
2834                 if (!type.isDistinctType()) {
2835                     continue;
2836                 }
2837 
2838                 if (!grantee.isFullyAccessibleByRole(type.getName())) {
2839                     continue;
2840                 }
2841 
2842                 row                = t.getEmptyRowData();
2843                 row[udt_catalog]   = database.getCatalogName().name;
2844                 row[udt_schema]    = type.getSchemaName().name;
2845                 row[udt_name]      = type.getName().name;
2846                 row[table_catalog] = database.getCatalogName().name;
2847                 row[table_schema]  = tableName.schema.name;
2848                 row[table_name]    = tableName.name;
2849                 row[column_name]   = column.getNameString();
2850 
2851                 t.insertSys(session, store, row);
2852             }
2853         }
2854 
2855         return t;
2856     }
2857 
2858     /**
2859      * SQL:2008 VIEW<p>
2860      * The COLUMNS view has one row for each column of each table or view.
2861      * The column, its data type characteristics, together with its
2862      * IDENTITY or GENERATED characteristics are reported in this view.<p>
2863      * <ol>
2864      * <1i> Columns are reported only if the user or one of its roles is
2865      *      the authorization (owner) of the table, or is granted any privilege
2866      *      on the table or the column.
2867      *
2868      * </ol>
2869      *
2870      */
COLUMNS(Session session, PersistentStore store)2871     Table COLUMNS(Session session, PersistentStore store) {
2872 
2873         Table t = sysTables[COLUMNS];
2874 
2875         if (t == null) {
2876             t = createBlankTable(sysTableHsqlNames[COLUMNS]);
2877 
2878             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);           //0
2879             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
2880             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
2881             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
2882             addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);
2883             addColumn(t, "COLUMN_DEFAULT", CHARACTER_DATA);
2884             addColumn(t, "IS_NULLABLE", YES_OR_NO);
2885             addColumn(t, "DATA_TYPE", CHARACTER_DATA);
2886             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
2887             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
2888             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);      //10
2889             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
2890             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
2891             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
2892             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
2893             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
2894             addColumn(t, "CHARACTER_SET_CATALOG", CHARACTER_DATA);
2895             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
2896             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
2897             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
2898             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);        //20
2899             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
2900             addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
2901             addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
2902             addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
2903             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
2904             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
2905             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
2906             addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
2907             addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
2908             addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);              //30
2909             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);    // (only for array tyes)
2910             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
2911             addColumn(t, "IS_SELF_REFERENCING", YES_OR_NO);
2912             addColumn(t, "IS_IDENTITY", YES_OR_NO);
2913             addColumn(t, "IDENTITY_GENERATION", CHARACTER_DATA);     // ALWAYS / BY DEFAULT
2914             addColumn(t, "IDENTITY_START", CHARACTER_DATA);
2915             addColumn(t, "IDENTITY_INCREMENT", CHARACTER_DATA);
2916             addColumn(t, "IDENTITY_MAXIMUM", CHARACTER_DATA);
2917             addColumn(t, "IDENTITY_MINIMUM", CHARACTER_DATA);
2918             addColumn(t, "IDENTITY_CYCLE", YES_OR_NO);               //40
2919             addColumn(t, "IS_GENERATED", CHARACTER_DATA);            // ALWAYS / NEVER
2920             addColumn(t, "GENERATION_EXPRESSION", CHARACTER_DATA);
2921             addColumn(t, "IS_UPDATABLE", YES_OR_NO);
2922             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
2923             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
2924             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
2925 
2926             // order: TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION
2927             // added for unique: TABLE_CAT
2928             // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
2929             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
2930                 sysTableHsqlNames[COLUMNS].name, false, SchemaObject.INDEX);
2931 
2932             t.createPrimaryKeyConstraint(name, new int[] {
2933                 3, 2, 1, 4
2934             }, false);
2935 
2936             return t;
2937         }
2938 
2939         // column number mappings
2940         final int table_cat                  = 0;
2941         final int table_schem                = 1;
2942         final int table_name                 = 2;
2943         final int column_name                = 3;
2944         final int ordinal_position           = 4;
2945         final int column_default             = 5;
2946         final int is_nullable                = 6;
2947         final int data_type                  = 7;
2948         final int character_maximum_length   = 8;
2949         final int character_octet_length     = 9;
2950         final int numeric_precision          = 10;
2951         final int numeric_precision_radix    = 11;
2952         final int numeric_scale              = 12;
2953         final int datetime_precision         = 13;
2954         final int interval_type              = 14;
2955         final int interval_precision         = 15;
2956         final int character_set_catalog      = 16;
2957         final int character_set_schema       = 17;
2958         final int character_set_name         = 18;
2959         final int collation_catalog          = 19;
2960         final int collation_schema           = 20;
2961         final int collation_name             = 21;
2962         final int domain_catalog             = 22;
2963         final int domain_schema              = 23;
2964         final int domain_name                = 24;
2965         final int udt_catalog                = 25;
2966         final int udt_schema                 = 26;
2967         final int udt_name                   = 27;
2968         final int scope_catalog              = 28;
2969         final int scope_schema               = 29;
2970         final int scope_name                 = 30;
2971         final int maximum_cardinality        = 31;
2972         final int dtd_identifier             = 32;
2973         final int is_self_referencing        = 33;
2974         final int is_identity                = 34;
2975         final int identity_generation        = 35;
2976         final int identity_start             = 36;
2977         final int identity_increment         = 37;
2978         final int identity_maximum           = 38;
2979         final int identity_minimum           = 39;
2980         final int identity_cycle             = 40;
2981         final int is_generated               = 41;
2982         final int generation_expression      = 42;
2983         final int is_updatable               = 43;
2984         final int declared_data_type         = 44;
2985         final int declared_numeric_precision = 45;
2986         final int declared_numeric_scale     = 46;
2987 
2988         //
2989         // intermediate holders
2990         int            columnCount;
2991         Iterator       tables;
2992         Table          table;
2993         Object[]       row;
2994         OrderedHashSet columnList;
2995         Type           type;
2996 
2997         // Initialization
2998         tables = allTables();
2999 
3000         while (tables.hasNext()) {
3001             table = (Table) tables.next();
3002             columnList =
3003                 session.getGrantee().getColumnsForAllPrivileges(table);
3004 
3005             if (columnList.isEmpty()) {
3006                 continue;
3007             }
3008 
3009             columnCount = table.getColumnCount();
3010 
3011             for (int i = 0; i < columnCount; i++) {
3012                 ColumnSchema column = table.getColumn(i);
3013 
3014                 type = column.getDataType();
3015 
3016                 if (!columnList.contains(column.getName())) {
3017                     continue;
3018                 }
3019 
3020                 row                   = t.getEmptyRowData();
3021                 row[table_cat]        = database.getCatalogName().name;
3022                 row[table_schem]      = table.getSchemaName().name;
3023                 row[table_name]       = table.getName().name;
3024                 row[column_name]      = column.getName().name;
3025                 row[ordinal_position] = ValuePool.getLong(i + 1);
3026                 row[column_default]   = column.getDefaultSQL();
3027                 row[is_nullable]      = column.isNullable() ? "YES"
3028                                                             : "NO";
3029                 row[data_type]        = type.getFullNameString();
3030 
3031                 // common type block
3032                 if (type.isCharacterType()) {
3033                     row[character_maximum_length] =
3034                         ValuePool.getLong(type.precision);
3035                     row[character_octet_length] =
3036                         ValuePool.getLong(type.precision * 2);
3037                     row[character_set_catalog] =
3038                         database.getCatalogName().name;
3039                     row[character_set_schema] =
3040                         type.getCharacterSet().getSchemaName().name;
3041                     row[character_set_name] =
3042                         type.getCharacterSet().getName().name;
3043                     row[collation_catalog] = database.getCatalogName().name;
3044                     row[collation_schema] =
3045                         type.getCollation().getSchemaName().name;
3046                     row[collation_name] = type.getCollation().getName().name;
3047                 } else if (type.isNumberType()) {
3048                     row[numeric_precision] = ValuePool.getLong(
3049                         ((NumberType) type).getNumericPrecisionInRadix());
3050                     row[declared_numeric_precision] = ValuePool.getLong(
3051                         ((NumberType) type).getNumericPrecisionInRadix());
3052 
3053                     if (type.isExactNumberType()) {
3054                         row[numeric_scale] = row[declared_numeric_scale] =
3055                             ValuePool.getLong(type.scale);
3056                     }
3057 
3058                     row[numeric_precision_radix] =
3059                         ValuePool.getLong(type.getPrecisionRadix());
3060                 } else if (type.isBooleanType()) {
3061 
3062                     //
3063                 } else if (type.isDateTimeType()) {
3064                     row[datetime_precision] = ValuePool.getLong(type.scale);
3065                 } else if (type.isIntervalType()) {
3066                     row[data_type] = "INTERVAL";
3067                     row[interval_type] =
3068                         IntervalType.getQualifier(type.typeCode);
3069                     row[interval_precision] =
3070                         ValuePool.getLong(type.precision);
3071                     row[datetime_precision] = ValuePool.getLong(type.scale);
3072                 } else if (type.isBinaryType()) {
3073                     row[character_maximum_length] =
3074                         ValuePool.getLong(type.precision);
3075                     row[character_octet_length] =
3076                         ValuePool.getLong(type.precision);
3077                 } else if (type.isBitType()) {
3078                     row[character_maximum_length] =
3079                         ValuePool.getLong(type.precision);
3080                     row[character_octet_length] =
3081                         ValuePool.getLong(type.precision);
3082                 } else if (type.isArrayType()) {
3083                     row[maximum_cardinality] =
3084                         ValuePool.getLong(type.arrayLimitCardinality());
3085                     row[data_type] = "ARRAY";
3086                 }
3087 
3088                 if (type.isDomainType()) {
3089                     row[domain_catalog] = database.getCatalogName().name;
3090                     row[domain_schema]  = type.getSchemaName().name;
3091                     row[domain_name]    = type.getName().name;
3092                 }
3093 
3094                 if (type.isDistinctType()) {
3095                     row[udt_catalog] = database.getCatalogName().name;
3096                     row[udt_schema]  = type.getSchemaName().name;
3097                     row[udt_name]    = type.getName().name;
3098                 }
3099 
3100                 row[scope_catalog]       = null;
3101                 row[scope_schema]        = null;
3102                 row[scope_name]          = null;
3103                 row[dtd_identifier]      = type.getDefinition();
3104                 row[is_self_referencing] = null;
3105                 row[is_identity]         = column.isIdentity() ? "YES"
3106                                                                : "NO";
3107 
3108                 if (column.isIdentity()) {
3109                     NumberSequence sequence = column.getIdentitySequence();
3110 
3111                     row[identity_generation] = sequence.isAlways() ? "ALWAYS"
3112                                                                    : "BY DEFAULT";
3113                     row[identity_start] =
3114                         Long.toString(sequence.getStartValue());
3115                     row[identity_increment] =
3116                         Long.toString(sequence.getIncrement());
3117                     row[identity_maximum] =
3118                         Long.toString(sequence.getMaxValue());
3119                     row[identity_minimum] =
3120                         Long.toString(sequence.getMinValue());
3121                     row[identity_cycle] = sequence.isCycle() ? "YES"
3122                                                              : "NO";
3123                 }
3124 
3125                 row[is_generated] = "NEVER";
3126 
3127                 if (column.isGenerated()) {
3128                     row[is_generated] = "ALWAYS";
3129                     row[generation_expression] =
3130                         column.getGeneratingExpression().getSQL();
3131                 }
3132 
3133                 row[is_updatable]       = table.isWritable() ? "YES"
3134                                                              : "NO";
3135                 row[declared_data_type] = row[data_type];
3136 
3137                 if (type.isNumberType()) {
3138                     row[declared_numeric_precision] = row[numeric_precision];
3139                     row[declared_numeric_scale]     = row[numeric_scale];
3140                 }
3141 
3142                 t.insertSys(session, store, row);
3143             }
3144         }
3145 
3146         return t;
3147     }
3148 
3149     /**
3150      * SQL:2008 VIEW<p>
3151      *
3152      * The CONSTRAINT_COLUMN_USAGE view has one row for each column identified by
3153      * a table constraint or assertion.<p>
3154      *
3155      * <b>Definition:</b><p>
3156      *
3157      *      TABLE_CATALOG       VARCHAR
3158      *      TABLE_SCHEMA        VARCHAR
3159      *      TABLE_NAME          VARCHAR
3160      *      COLUMN_NAME         VARCHAR
3161      *      CONSTRAINT_CATALOG  VARCHAR
3162      *      CONSTRAINT_SCHEMA   VARCHAR
3163      *      CONSTRAINT_NAME     VARCHAR
3164      *
3165      * </pre>
3166      *
3167      * <b>Description:</b> <p>
3168      *
3169      * <ol>
3170      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
3171      *      COLUMN_NAME are the catalog name, schema name,
3172      *      identifier, and column name, respectively, of a column
3173      *      identified by a &lt;column reference&gt; explicitly or implicitly
3174      *      contained in the &lt;search condition&gt; of the constraint
3175      *      being described.
3176      *
3177      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
3178      *      CONSTRAINT_NAME are the catalog name, schema name,
3179      *      and identifier, respectively, of the constraint being
3180      *      described. <p>
3181      *
3182      * <li> For FOREIGN KEY constraints, the columns of the UNIQUE constraint
3183      *      in the referenced table are also included in this view.
3184      *
3185      * <1i> Columns are reported only if the user or one of its roles is
3186      *      the authorization (owner) of the table.
3187      *
3188      * </ol>
3189      *
3190      * @return Table
3191      */
CONSTRAINT_COLUMN_USAGE(Session session, PersistentStore store)3192     Table CONSTRAINT_COLUMN_USAGE(Session session, PersistentStore store) {
3193 
3194         Table t = sysTables[CONSTRAINT_COLUMN_USAGE];
3195 
3196         if (t == null) {
3197             t = createBlankTable(sysTableHsqlNames[CONSTRAINT_COLUMN_USAGE]);
3198 
3199             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
3200             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
3201             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
3202             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);        // not null
3203             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
3204             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
3205             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
3206 
3207             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3208                 sysTableHsqlNames[CONSTRAINT_COLUMN_USAGE].name, false,
3209                 SchemaObject.INDEX);
3210 
3211             t.createPrimaryKeyConstraint(name, new int[] {
3212                 0, 1, 2, 3, 4, 5, 6
3213             }, false);
3214 
3215             return t;
3216         }
3217 
3218         // column number mappings
3219         final int table_catalog      = 0;
3220         final int table_schema       = 1;
3221         final int table_name         = 2;
3222         final int column_name        = 3;
3223         final int constraint_catalog = 4;
3224         final int constraint_schema  = 5;
3225         final int constraint_name    = 6;
3226 
3227         //
3228         // calculated column values
3229         String constraintCatalog;
3230         String constraintSchema;
3231         String constraintName;
3232 
3233         // Intermediate holders
3234         Iterator     tables;
3235         Table        table;
3236         Constraint[] constraints;
3237         int          constraintCount;
3238         Constraint   constraint;
3239         Iterator     iterator;
3240         Object[]     row;
3241 
3242         // Initialization
3243         tables =
3244             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
3245 
3246         // Do it.
3247         while (tables.hasNext()) {
3248             table = (Table) tables.next();
3249 
3250             if (table.isView()
3251                     || !session.getGrantee().isFullyAccessibleByRole(
3252                         table.getName())) {
3253                 continue;
3254             }
3255 
3256             constraints       = table.getConstraints();
3257             constraintCount   = constraints.length;
3258             constraintCatalog = database.getCatalogName().name;
3259             constraintSchema  = table.getSchemaName().name;
3260 
3261             // process constraints
3262             for (int i = 0; i < constraintCount; i++) {
3263                 constraint     = constraints[i];
3264                 constraintName = constraint.getName().name;
3265 
3266                 switch (constraint.getConstraintType()) {
3267 
3268                     case SchemaObject.ConstraintTypes.CHECK : {
3269                         OrderedHashSet expressions =
3270                             constraint.getCheckColumnExpressions();
3271 
3272                         if (expressions == null) {
3273                             break;
3274                         }
3275 
3276                         iterator = expressions.iterator();
3277 
3278                         // calculate distinct column references
3279                         while (iterator.hasNext()) {
3280                             ExpressionColumn expr =
3281                                 (ExpressionColumn) iterator.next();
3282                             HsqlName name = expr.getColumn().getName();
3283 
3284                             if (name.type != SchemaObject.COLUMN) {
3285                                 continue;
3286                             }
3287 
3288                             row = t.getEmptyRowData();
3289                             row[table_catalog] =
3290                                 database.getCatalogName().name;
3291                             row[table_schema]       = name.schema.name;
3292                             row[table_name]         = name.parent.name;
3293                             row[column_name]        = name.name;
3294                             row[constraint_catalog] = constraintCatalog;
3295                             row[constraint_schema]  = constraintSchema;
3296                             row[constraint_name]    = constraintName;
3297 
3298                             try {
3299                                 t.insertSys(session, store, row);
3300                             } catch (HsqlException e) {}
3301                         }
3302 
3303                         break;
3304                     }
3305                     case SchemaObject.ConstraintTypes.UNIQUE :
3306                     case SchemaObject.ConstraintTypes.PRIMARY_KEY :
3307                     case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
3308                         Table target = table;
3309                         int[] cols   = constraint.getMainColumns();
3310 
3311                         if (constraint.getConstraintType()
3312                                 == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
3313                             cols = constraint.getRefColumns();
3314                         }
3315 
3316                         for (int j = 0; j < cols.length; j++) {
3317                             row = t.getEmptyRowData();
3318                             row[table_catalog] =
3319                                 database.getCatalogName().name;
3320                             row[table_schema] = constraintSchema;
3321                             row[table_name]   = target.getName().name;
3322                             row[column_name] =
3323                                 target.getColumn(cols[j]).getName().name;
3324                             row[constraint_catalog] = constraintCatalog;
3325                             row[constraint_schema]  = constraintSchema;
3326                             row[constraint_name]    = constraintName;
3327 
3328                             try {
3329                                 t.insertSys(session, store, row);
3330                             } catch (HsqlException e) {}
3331                         }
3332                     }
3333                 }
3334             }
3335         }
3336 
3337         return t;
3338     }
3339 
3340     /**
3341      * SQL:2008 VIEW<p>
3342      *
3343      * The CONSTRAINT_TABLE_USAGE view has one row for each table identified by a
3344      * &lt;table name&gt; simply contained in a &lt;table reference&gt;
3345      * contained in the &lt;search condition&gt; of a check constraint,
3346      * domain constraint, or assertion. It has one row for each table
3347      * containing / referenced by each PRIMARY KEY, UNIQUE and FOREIGN KEY
3348      * constraint<p>
3349      *
3350      * <b>Definition:</b> <p>
3351      *
3352      * <pre class="SqlCodeExample">
3353      *      TABLE_CATALOG           VARCHAR
3354      *      TABLE_SCHEMA            VARCHAR
3355      *      TABLE_NAME              VARCHAR
3356      *      CONSTRAINT_CATALOG      VARCHAR
3357      *      CONSTRAINT_SCHEMA       VARCHAR
3358      *      CONSTRAINT_NAME         VARCHAR
3359      * </pre>
3360      *
3361      * <b>Description:</b> <p>
3362      *
3363      * <ol>
3364      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
3365      *      CONSTRAINT_NAME are the catalog name, schema name,
3366      *       and identifier, respectively, of the constraint being
3367      *      described. <p>
3368      *
3369      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
3370      *      catalog name, schema name, and identifier,
3371      *      respectively, of a table identified by a &lt;table name&gt;
3372      *      simply contained in a &lt;table reference&gt; contained in the
3373      *      *lt;search condition&gt; of the constraint being described, or
3374      *      its columns.
3375      *
3376      * <1i> Tables are reported only if the user or one of its roles is
3377      *      the authorization (owner) of the table.
3378      * </ol>
3379      *
3380      * @return Table
3381      */
CONSTRAINT_TABLE_USAGE(Session session, PersistentStore store)3382     Table CONSTRAINT_TABLE_USAGE(Session session, PersistentStore store) {
3383 
3384         Table t = sysTables[CONSTRAINT_TABLE_USAGE];
3385 
3386         if (t == null) {
3387             t = createBlankTable(sysTableHsqlNames[CONSTRAINT_TABLE_USAGE]);
3388 
3389             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
3390             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
3391             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
3392             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
3393             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
3394             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
3395 
3396             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3397                 sysTableHsqlNames[CONSTRAINT_TABLE_USAGE].name, false,
3398                 SchemaObject.INDEX);
3399 
3400             t.createPrimaryKeyConstraint(name, new int[] {
3401                 0, 1, 2, 3, 4, 5
3402             }, false);
3403 
3404             return t;
3405         }
3406 
3407         //
3408         Session sys = database.sessionManager.newSysSession(
3409             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
3410         Result rs = sys.executeDirectStatement(
3411             "select DISTINCT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, "
3412             + "CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME "
3413             + "from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE");
3414 
3415         t.insertSys(session, store, rs);
3416         sys.close();
3417 
3418         return t;
3419     }
3420 
3421     /**
3422      * SQL:2008 VIEW<p>
3423      *
3424      * The DATA_TYPE_PRIVILEGES view has one row for each use of a data type.
3425      * Currently this view does not report the DTD_IDENTIFIER column.
3426      * <b>Definition:</b> <p>
3427      *
3428      * <pre class="SqlCodeExample">
3429      *      OBJECT_CATALOG      VARCHAR
3430      *      OBJECT_SCHEMA       VARCHAR
3431      *      OBJECT_NAME         VARCHAR
3432      *      OBJECT_TYPE         VARCHAR
3433      *      DTD_IDENTIFIER      VARCHAR
3434      * </pre>
3435      *
3436      * <b>Description:</b> <p>
3437      *
3438      * <ol>
3439      * <li> The values of OBJECT_CATALOG, OBJECT_SCHEMA, and
3440      *      OBJECT_NAME are the catalog name, schema name,
3441      *       and identifier, respectively, of the object. <p>
3442      *
3443      * <li> The value of OBJECT_TYPE is the type of the object, for example
3444      *      'TABLE'.
3445      *
3446      * <1i> Tables are reported only if the user or one of its roles is
3447      *      the authorization (owner) of the table.
3448      * </ol>
3449      *
3450      * @return Table
3451      */
DATA_TYPE_PRIVILEGES(Session session, PersistentStore store)3452     Table DATA_TYPE_PRIVILEGES(Session session, PersistentStore store) {
3453 
3454         Table t = sysTables[DATA_TYPE_PRIVILEGES];
3455 
3456         if (t == null) {
3457             t = createBlankTable(sysTableHsqlNames[DATA_TYPE_PRIVILEGES]);
3458 
3459             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
3460             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
3461             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
3462             addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
3463             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
3464 
3465             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3466                 sysTableHsqlNames[DATA_TYPE_PRIVILEGES].name, false,
3467                 SchemaObject.INDEX);
3468 
3469             t.createPrimaryKeyConstraint(name, new int[] {
3470                 0, 1, 2, 3, 4
3471             }, false);
3472 
3473             return t;
3474         }
3475 
3476         //
3477         Session sys = database.sessionManager.newSysSession(
3478             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
3479         String sql = (String) statementMap.get("/*data_type_privileges*/");
3480         Result rs  = sys.executeDirectStatement(sql);
3481 
3482         t.insertSys(session, store, rs);
3483         sys.close();
3484 
3485         return t;
3486     }
3487 
3488     /**
3489      * a DEFINITION_SCHEMA table. Not in the INFORMATION_SCHEMA list
3490      */
3491 /*
3492     Table DATA_TYPE_DESCRIPTOR() {
3493 
3494         Table t = sysTables[DATA_TYPE_DESCRIPTOR];
3495 
3496         if (t == null) {
3497             t = createBlankTable(sysTableHsqlNames[DATA_TYPE_DESCRIPTOR]);
3498 
3499             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
3500             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
3501             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);
3502             addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);
3503             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
3504             addColumn(t, "DATA_TYPE", CHARACTER_DATA);
3505             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
3506             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
3507             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
3508             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
3509             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
3510             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
3511             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
3512             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
3513             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
3514             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
3515             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
3516             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
3517             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
3518             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
3519             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
3520             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
3521             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
3522             addColumn(t, "USER_DEFINED_TYPE_CATALOG", SQL_IDENTIFIER);
3523             addColumn(t, "USER_DEFINED_TYPE_SCHEMA", SQL_IDENTIFIER);
3524             addColumn(t, "USER_DEFINED_TYPE_NAME", SQL_IDENTIFIER);
3525             addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
3526             addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
3527             addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);
3528             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
3529             t.createPrimaryKeyConstraint(null, new int[] {
3530                 0, 1, 2, 4, 5, 6
3531             }, false);
3532 
3533             return t;
3534         }
3535 
3536         PersistentStore store =  session.sessionData.getRowStore(t);
3537         final int       object_catalog             = 0;
3538         final int       object_schema              = 1;
3539         final int       object_name                = 2;
3540         final int       object_type                = 3;
3541         final int       dtd_identifier             = 4;
3542         final int       data_type                  = 5;
3543         final int       character_set_catalog      = 6;
3544         final int       character_set_schema       = 7;
3545         final int       character_set_name         = 8;
3546         final int       character_maximum_length   = 9;
3547         final int       character_octet_length     = 10;
3548         final int       collation_catalog          = 11;
3549         final int       collation_schema           = 12;
3550         final int       collation_name             = 13;
3551         final int       numeric_precision          = 14;
3552         final int       numeric_precision_radix    = 15;
3553         final int       numeric_scale              = 16;
3554         final int       declared_data_type         = 17;
3555         final int       declared_numeric_precision = 18;
3556         final int       declared_numeric_scale     = 19;
3557         final int       datetime_precision         = 20;
3558         final int       interval_type              = 21;
3559         final int       interval_precision         = 22;
3560         final int       user_defined_type_catalog  = 23;
3561         final int       user_defined_type_schema   = 24;
3562         final int       user_defined_type_name     = 25;
3563         final int       scope_catalog              = 26;
3564         final int       scope_schema               = 27;
3565         final int       scope_name                 = 28;
3566         final int       maximum_cardinality        = 29;
3567         return t;
3568     }
3569 */
3570 
3571     /**
3572      * SQL:2008 VIEW<p>
3573      *
3574      * The DOMAIN_CONSTRAINTS view has one row for each domain
3575      * constraint. <p>
3576      *
3577      * <b>Definition:</b><p>
3578      *
3579      * <pre class="SqlCodeExample">
3580      *      CONSTRAINT_CATALOG  VARCHAR NULL,
3581      *      CONSTRAINT_SCHEMA   VARCHAR NULL,
3582      *      CONSTRAINT_NAME     VARCHAR NOT NULL,
3583      *      DOMAIN_CATALOG      VARCHAR
3584      *      DOMAIN_SCHEMA       VARCHAR
3585      *      DOMAIN_NAME         VARCHAR
3586      *      IS_DEFERABLE        VARCHAR NOT NULL,
3587      *      INITIALLY_DEFERRED  VARCHAR NOT NULL,
3588      * </pre>
3589      *
3590      * <b>Description:</b><p>
3591      *
3592      * <ol>
3593      * <li> A constraint is shown in this view if the authorization for the
3594      *      DOMAIN that contains the constraint is the current user or is a role
3595      *      assigned to the current user. <p>
3596      *
3597      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA and
3598      *      CONSTRAINT_NAME are the catalog name, schema name,
3599      *      and identifier, respectively, of the constraint being
3600      *      described. <p>
3601      *
3602      * <1i> Constraints are reported only if the user or one of its roles is
3603      *      the authorization (owner) of the DOMAIN.
3604      * </ol>
3605      *
3606      * @return Table
3607      */
DOMAIN_CONSTRAINTS(Session session, PersistentStore store)3608     Table DOMAIN_CONSTRAINTS(Session session, PersistentStore store) {
3609 
3610         Table t = sysTables[DOMAIN_CONSTRAINTS];
3611 
3612         if (t == null) {
3613             t = createBlankTable(sysTableHsqlNames[DOMAIN_CONSTRAINTS]);
3614 
3615             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
3616             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
3617             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
3618             addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
3619             addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
3620             addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
3621             addColumn(t, "IS_DEFERRABLE", YES_OR_NO);
3622             addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);
3623 
3624             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3625                 sysTableHsqlNames[DOMAIN_CONSTRAINTS].name, false,
3626                 SchemaObject.INDEX);
3627 
3628             t.createPrimaryKeyConstraint(name, new int[] {
3629                 0, 1, 2, 4, 5, 6
3630             }, false);
3631 
3632             return t;
3633         }
3634 
3635         final int constraint_catalog = 0;
3636         final int constraint_schema  = 1;
3637         final int constraint_name    = 2;
3638         final int domain_catalog     = 3;
3639         final int domain_schema      = 4;
3640         final int domain_name        = 5;
3641         final int is_deferrable      = 6;
3642         final int initially_deferred = 7;
3643 
3644         //
3645         //
3646         Iterator it =
3647             database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
3648 
3649         while (it.hasNext()) {
3650             Type domain = (Type) it.next();
3651 
3652             if (!domain.isDomainType()) {
3653                 continue;
3654             }
3655 
3656             if (!session.getGrantee().isFullyAccessibleByRole(
3657                     domain.getName())) {
3658                 continue;
3659             }
3660 
3661             Constraint[] constraints =
3662                 domain.userTypeModifier.getConstraints();
3663 
3664             for (int i = 0; i < constraints.length; i++) {
3665                 Object[] data = t.getEmptyRowData();
3666 
3667                 data[constraint_catalog] = data[domain_catalog] =
3668                     database.getCatalogName().name;
3669                 data[constraint_schema] = data[domain_schema] =
3670                     domain.getSchemaName().name;
3671                 data[constraint_name]    = constraints[i].getName().name;
3672                 data[domain_name]        = domain.getName().name;
3673                 data[is_deferrable]      = Tokens.T_NO;
3674                 data[initially_deferred] = Tokens.T_NO;
3675 
3676                 t.insertSys(session, store, data);
3677             }
3678         }
3679 
3680         return t;
3681     }
3682 
3683     /**
3684      * SQL:2008 VIEW<p>
3685      *
3686      * The DOMAINS view has one row for each domain. <p>
3687      *
3688      * @return Table
3689      */
DOMAINS(Session session, PersistentStore store)3690     Table DOMAINS(Session session, PersistentStore store) {
3691 
3692         Table t = sysTables[DOMAINS];
3693 
3694         if (t == null) {
3695             t = createBlankTable(sysTableHsqlNames[DOMAINS]);
3696 
3697             addColumn(t, "DOMAIN_CATALOG", SQL_IDENTIFIER);
3698             addColumn(t, "DOMAIN_SCHEMA", SQL_IDENTIFIER);
3699             addColumn(t, "DOMAIN_NAME", SQL_IDENTIFIER);
3700             addColumn(t, "DATA_TYPE", SQL_IDENTIFIER);
3701             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
3702             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
3703             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
3704             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
3705             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
3706             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
3707             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
3708             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
3709             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
3710             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
3711             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
3712             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
3713             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
3714             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
3715             addColumn(t, "DOMAIN_DEFAULT", CHARACTER_DATA);
3716             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
3717             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
3718             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
3719             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
3720             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
3721 
3722             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3723                 sysTableHsqlNames[DOMAINS].name, false, SchemaObject.INDEX);
3724 
3725             t.createPrimaryKeyConstraint(name, new int[] {
3726                 0, 1, 2, 4, 5, 6
3727             }, false);
3728 
3729             return t;
3730         }
3731 
3732         final int domain_catalog             = 0;
3733         final int domain_schema              = 1;
3734         final int domain_name                = 2;
3735         final int data_type                  = 3;
3736         final int character_maximum_length   = 4;
3737         final int character_octet_length     = 5;
3738         final int character_set_catalog      = 6;
3739         final int character_set_schema       = 7;
3740         final int character_set_name         = 8;
3741         final int collation_catalog          = 9;
3742         final int collation_schema           = 10;
3743         final int collation_name             = 11;
3744         final int numeric_precision          = 12;
3745         final int numeric_precision_radix    = 13;
3746         final int numeric_scale              = 14;
3747         final int datetime_precision         = 15;
3748         final int interval_type              = 16;
3749         final int interval_precision         = 17;
3750         final int domain_default             = 18;
3751         final int maximum_cardinality        = 19;
3752         final int dtd_identifier             = 20;
3753         final int declared_data_type         = 21;
3754         final int declared_numeric_precision = 22;
3755         final int declared_numeric_scale     = 23;
3756 
3757         //
3758         //
3759         Iterator it =
3760             database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
3761 
3762         while (it.hasNext()) {
3763             Type type = (Type) it.next();
3764 
3765             if (!type.isDomainType()) {
3766                 continue;
3767             }
3768 
3769             if (!session.getGrantee().isAccessible(type)) {
3770                 continue;
3771             }
3772 
3773             Object[] row = t.getEmptyRowData();
3774 
3775             row[domain_catalog] = database.getCatalogName().name;
3776             row[domain_schema]  = type.getSchemaName().name;
3777             row[domain_name]    = type.getName().name;
3778             row[data_type]      = type.getFullNameString();
3779 
3780             // common type block
3781             if (type.isCharacterType()) {
3782                 row[character_maximum_length] =
3783                     ValuePool.getLong(type.precision);
3784                 row[character_octet_length] = ValuePool.getLong(type.precision
3785                         * 2);
3786                 row[character_set_catalog] = database.getCatalogName().name;
3787                 row[character_set_schema] =
3788                     type.getCharacterSet().getSchemaName().name;
3789                 row[character_set_name] =
3790                     type.getCharacterSet().getName().name;
3791                 row[collation_catalog] = database.getCatalogName().name;
3792                 row[collation_schema] =
3793                     type.getCollation().getSchemaName().name;
3794                 row[collation_name] = type.getCollation().getName().name;
3795             } else if (type.isNumberType()) {
3796                 row[numeric_precision] = ValuePool.getLong(
3797                     ((NumberType) type).getNumericPrecisionInRadix());
3798                 row[declared_numeric_precision] = ValuePool.getLong(
3799                     ((NumberType) type).getNumericPrecisionInRadix());
3800 
3801                 if (type.isExactNumberType()) {
3802                     row[numeric_scale] = row[declared_numeric_scale] =
3803                         ValuePool.getLong(type.scale);
3804                 }
3805 
3806                 row[numeric_precision_radix] =
3807                     ValuePool.getLong(type.getPrecisionRadix());
3808             } else if (type.isBooleanType()) {
3809 
3810                 //
3811             } else if (type.isDateTimeType()) {
3812                 row[datetime_precision] = ValuePool.getLong(type.scale);
3813             } else if (type.isIntervalType()) {
3814                 row[data_type]          = "INTERVAL";
3815                 row[interval_type] = IntervalType.getQualifier(type.typeCode);
3816                 row[interval_precision] = ValuePool.getLong(type.precision);
3817                 row[datetime_precision] = ValuePool.getLong(type.scale);
3818             } else if (type.isBinaryType()) {
3819                 row[character_maximum_length] =
3820                     ValuePool.getLong(type.precision);
3821                 row[character_octet_length] =
3822                     ValuePool.getLong(type.precision);
3823             } else if (type.isBitType()) {
3824                 row[character_maximum_length] =
3825                     ValuePool.getLong(type.precision);
3826                 row[character_octet_length] =
3827                     ValuePool.getLong(type.precision);
3828             } else if (type.isArrayType()) {
3829                 row[maximum_cardinality] =
3830                     ValuePool.getLong(type.arrayLimitCardinality());
3831                 row[data_type] = "ARRAY";
3832             }
3833 
3834             row[dtd_identifier]     = type.getDefinition();
3835             row[declared_data_type] = row[data_type];
3836 
3837             // end common block
3838             Expression defaultExpression =
3839                 type.userTypeModifier.getDefaultClause();
3840 
3841             if (defaultExpression != null) {
3842                 row[domain_default] = defaultExpression.getSQL();
3843             }
3844 
3845             t.insertSys(session, store, row);
3846         }
3847 
3848         return t;
3849     }
3850 
3851     /**
3852      * SQL:2008 VIEW<p>
3853      *
3854      * The type attributes of elements of array. <p>
3855      *
3856      * The ELEMENT_TYPES view is empty.<p>
3857      *
3858      * @return Table
3859      */
ELEMENT_TYPES(Session session, PersistentStore store)3860     Table ELEMENT_TYPES(Session session, PersistentStore store) {
3861 
3862         Table t = sysTables[ELEMENT_TYPES];
3863 
3864         if (t == null) {
3865             t = createBlankTable(sysTableHsqlNames[ELEMENT_TYPES]);
3866 
3867             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
3868             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
3869             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);
3870             addColumn(t, "OBJECT_TYPE", SQL_IDENTIFIER);
3871             addColumn(t, "COLLECTION_TYPE_IDENTIFIER", SQL_IDENTIFIER);
3872             addColumn(t, "DATA_TYPE", SQL_IDENTIFIER);
3873             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
3874             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
3875             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
3876             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
3877             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
3878             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
3879             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
3880             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
3881             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
3882             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
3883             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
3884             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
3885             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
3886             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
3887             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
3888             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
3889             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
3890             addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
3891             addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
3892             addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);
3893             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
3894             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
3895             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
3896             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
3897             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
3898 
3899             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
3900                 sysTableHsqlNames[ELEMENT_TYPES].name, false,
3901                 SchemaObject.INDEX);
3902 
3903             t.createPrimaryKeyConstraint(name, new int[] {
3904                 0, 1, 2, 4, 5, 27
3905             }, true);
3906 
3907             return t;
3908         }
3909 
3910         final int object_catalog             = 0;
3911         final int object_schema              = 1;
3912         final int object_name                = 2;
3913         final int object_type                = 3;
3914         final int collection_type_identifier = 4;
3915 
3916         //
3917         final int udt_catalog   = 20;
3918         final int udt_schema    = 21;
3919         final int udt_name      = 22;
3920         final int scope_catalog = 23;
3921         final int scope_schema  = 24;
3922         final int scope_name    = 25;
3923 
3924         //
3925         // intermediate holders
3926         int            columnCount;
3927         Iterator       tables;
3928         Table          table;
3929         Object[]       row;
3930         OrderedHashSet columnList;
3931         Type           type;
3932 
3933         // Initialization
3934         tables = allTables();
3935 
3936         while (tables.hasNext()) {
3937             table = (Table) tables.next();
3938             columnList =
3939                 session.getGrantee().getColumnsForAllPrivileges(table);
3940 
3941             if (columnList.isEmpty()) {
3942                 continue;
3943             }
3944 
3945             columnCount = table.getColumnCount();
3946 
3947             for (int i = 0; i < columnCount; i++) {
3948                 ColumnSchema column = table.getColumn(i);
3949 
3950                 if (!columnList.contains(column.getName())) {
3951                     continue;
3952                 }
3953 
3954                 type = column.getDataType();
3955 
3956                 if (type.isDistinctType() || type.isDomainType()
3957                         || !type.isArrayType()) {
3958                     continue;
3959                 }
3960 
3961                 row                             = t.getEmptyRowData();
3962                 row[object_catalog] = database.getCatalogName().name;
3963                 row[object_schema]              = table.getSchemaName().name;
3964                 row[object_name]                = table.getName().name;
3965                 row[object_type]                = "TABLE";
3966                 row[collection_type_identifier] = type.getDefinition();
3967 
3968                 addTypeInfo(row, type.collectionBaseType());
3969 
3970                 try {
3971                     t.insertSys(session, store, row);
3972                 } catch (HsqlException e) {}
3973             }
3974         }
3975 
3976         Iterator it =
3977             database.schemaManager.databaseObjectIterator(SchemaObject.DOMAIN);
3978 
3979         while (it.hasNext()) {
3980             type = (Type) it.next();
3981 
3982             if (!type.isDomainType() || !type.isArrayType()) {
3983                 continue;
3984             }
3985 
3986             if (!session.getGrantee().isAccessible(type)) {
3987                 continue;
3988             }
3989 
3990             row                             = t.getEmptyRowData();
3991             row[object_catalog]             = database.getCatalogName().name;
3992             row[object_schema]              = type.getSchemaName().name;
3993             row[object_name]                = type.getName().name;
3994             row[object_type]                = "DOMAIN";
3995             row[collection_type_identifier] = type.getDefinition();
3996 
3997             addTypeInfo(row, type.collectionBaseType());
3998             t.insertSys(session, store, row);
3999         }
4000 
4001         it = database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
4002 
4003         while (it.hasNext()) {
4004             type = (Type) it.next();
4005 
4006             if (!type.isDistinctType() || !type.isArrayType()) {
4007                 continue;
4008             }
4009 
4010             if (!session.getGrantee().isAccessible(type)) {
4011                 continue;
4012             }
4013 
4014             row                             = t.getEmptyRowData();
4015             row[object_catalog]             = database.getCatalogName().name;
4016             row[object_schema]              = type.getSchemaName().name;
4017             row[object_name]                = type.getName().name;
4018             row[object_type]                = "USER-DEFINED TYPE";
4019             row[collection_type_identifier] = type.getDefinition();
4020 
4021             addTypeInfo(row, type.collectionBaseType());
4022 
4023             try {
4024                 t.insertSys(session, store, row);
4025             } catch (HsqlException e) {}
4026         }
4027 
4028         it = database.schemaManager.databaseObjectIterator(
4029             SchemaObject.SPECIFIC_ROUTINE);
4030 
4031         while (it.hasNext()) {
4032             Routine routine = (Routine) it.next();
4033 
4034             if (!session.getGrantee().isAccessible(routine)) {
4035                 continue;
4036             }
4037 
4038             type = routine.isProcedure() ? null
4039                                          : routine.getReturnType();
4040 
4041             if (type == null || type.isDistinctType() || type.isDomainType()
4042                     || !type.isArrayType()) {
4043 
4044                 //
4045             } else {
4046                 row                             = t.getEmptyRowData();
4047                 row[object_catalog] = database.getCatalogName().name;
4048                 row[object_schema]              = routine.getSchemaName().name;
4049                 row[object_name]                = routine.getName().name;
4050                 row[object_type]                = "ROUTINE";
4051                 row[collection_type_identifier] = type.getDefinition();
4052 
4053                 addTypeInfo(row, type.collectionBaseType());
4054 
4055                 try {
4056                     t.insertSys(session, store, row);
4057                 } catch (HsqlException e) {}
4058             }
4059 
4060             Type returnType = type;
4061             int  paramCount = routine.getParameterCount();
4062 
4063             for (int i = 0; i < paramCount; i++) {
4064                 ColumnSchema param = routine.getParameter(i);
4065 
4066                 type = param.getDataType();
4067 
4068                 if (type.isDistinctType() || type.isDomainType()
4069                         || !type.isArrayType()) {
4070                     continue;
4071                 }
4072 
4073                 if (type.equals(returnType)) {
4074                     continue;
4075                 }
4076 
4077                 row                             = t.getEmptyRowData();
4078                 row[object_catalog] = database.getCatalogName().name;
4079                 row[object_schema]              = routine.getSchemaName().name;
4080                 row[object_name]                = routine.getName().name;
4081                 row[object_type]                = "ROUTINE";
4082                 row[collection_type_identifier] = type.getDefinition();
4083 
4084                 addTypeInfo(row, type.collectionBaseType());
4085 
4086                 try {
4087                     t.insertSys(session, store, row);
4088                 } catch (HsqlException e) {}
4089             }
4090         }
4091 
4092         return t;
4093     }
4094 
addTypeInfo(Object[] row, Type type)4095     void addTypeInfo(Object[] row, Type type) {
4096 
4097         final int data_type                = 5;
4098         final int character_maximum_length = 6;
4099         final int character_octet_length   = 7;
4100         final int character_set_catalog    = 8;
4101         final int character_set_schema     = 9;
4102         final int character_set_name       = 10;
4103         final int collation_catalog        = 11;
4104         final int collation_schema         = 12;
4105         final int collation_name           = 13;
4106         final int numeric_precision        = 14;
4107         final int numeric_precision_radix  = 15;
4108         final int numeric_scale            = 16;
4109         final int datetime_precision       = 17;
4110         final int interval_type            = 18;
4111         final int interval_precision       = 19;
4112 
4113         //
4114         final int maximum_cardinality        = 26;
4115         final int dtd_identifier             = 27;
4116         final int declared_data_type         = 28;
4117         final int declared_numeric_precision = 29;
4118         final int declared_numeric_scale     = 30;
4119 
4120         row[data_type] = type.getFullNameString();
4121 
4122         if (type.isCharacterType()) {
4123             row[character_maximum_length] = ValuePool.getLong(type.precision);
4124             row[character_octet_length] = ValuePool.getLong(type.precision
4125                     * 2);
4126             row[character_set_catalog] = database.getCatalogName().name;
4127             row[character_set_schema] =
4128                 type.getCharacterSet().getSchemaName().name;
4129             row[character_set_name] = type.getCharacterSet().getName().name;
4130             row[collation_catalog]  = database.getCatalogName().name;
4131             row[collation_schema]   = type.getCollation().getSchemaName().name;
4132             row[collation_name]     = type.getCollation().getName().name;
4133         } else if (type.isNumberType()) {
4134             row[numeric_precision] = ValuePool.getLong(
4135                 ((NumberType) type).getNumericPrecisionInRadix());
4136             row[declared_numeric_precision] = ValuePool.getLong(
4137                 ((NumberType) type).getNumericPrecisionInRadix());
4138 
4139             if (type.isExactNumberType()) {
4140                 row[numeric_scale] = row[declared_numeric_scale] =
4141                     ValuePool.getLong(type.scale);
4142             }
4143 
4144             row[numeric_precision_radix] =
4145                 ValuePool.getLong(type.getPrecisionRadix());
4146         } else if (type.isBooleanType()) {
4147 
4148             //
4149         } else if (type.isDateTimeType()) {
4150             row[datetime_precision] = ValuePool.getLong(type.scale);
4151         } else if (type.isIntervalType()) {
4152             row[data_type]          = "INTERVAL";
4153             row[interval_type]      = IntervalType.getQualifier(type.typeCode);
4154             row[interval_precision] = ValuePool.getLong(type.precision);
4155             row[datetime_precision] = ValuePool.getLong(type.scale);
4156         } else if (type.isBinaryType()) {
4157             row[character_maximum_length] = ValuePool.getLong(type.precision);
4158             row[character_octet_length]   = ValuePool.getLong(type.precision);
4159         } else if (type.isBitType()) {
4160             row[character_maximum_length] = ValuePool.getLong(type.precision);
4161             row[character_octet_length]   = ValuePool.getLong(type.precision);
4162         } else if (type.isArrayType()) {
4163             row[maximum_cardinality] =
4164                 ValuePool.getLong(type.arrayLimitCardinality());
4165         }
4166 
4167         row[dtd_identifier]     = type.getDefinition();
4168         row[declared_data_type] = row[data_type];
4169     }
4170 
4171     /**
4172      * SQL:2008 VIEW<p>
4173      *
4174      * ENABLED_ROLES<p>
4175      *
4176      * Identify the enabled roles for the current SQL-session.<p>
4177      *
4178      * Definition<p>
4179      *
4180      * <pre class="SqlCodeExample">
4181      * CREATE RECURSIVE VIEW ENABLED_ROLES ( ROLE_NAME ) AS
4182      *      VALUES ( CURRENT_ROLE )
4183      *      UNION
4184      *      SELECT RAD.ROLE_NAME
4185      *        FROM DEFINITION_SCHEMA.ROLE_AUTHORIZATION_DESCRIPTORS RAD
4186      *        JOIN ENABLED_ROLES R
4187      *          ON RAD.GRANTEE = R.ROLE_NAME;
4188      *
4189      * GRANT SELECT ON TABLE ENABLED_ROLES
4190      *    TO PUBLIC WITH GRANT OPTION;
4191      * </pre>
4192      */
ENABLED_ROLES(Session session, PersistentStore store)4193     Table ENABLED_ROLES(Session session, PersistentStore store) {
4194 
4195         Table t = sysTables[ENABLED_ROLES];
4196 
4197         if (t == null) {
4198             t = createBlankTable(sysTableHsqlNames[ENABLED_ROLES]);
4199 
4200             addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);
4201 
4202             // true PK
4203             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4204                 sysTableHsqlNames[ENABLED_ROLES].name, false,
4205                 SchemaObject.INDEX);
4206 
4207             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, true);
4208 
4209             return t;
4210         }
4211 
4212         // Intermediate holders
4213         Iterator grantees;
4214         Grantee  grantee;
4215         Object[] row;
4216 
4217         // initialization
4218         grantees = session.getGrantee().getAllRoles().iterator();
4219 
4220         while (grantees.hasNext()) {
4221             grantee = (Grantee) grantees.next();
4222             row     = t.getEmptyRowData();
4223             row[0]  = grantee.getName().getNameString();
4224 
4225             t.insertSys(session, store, row);
4226         }
4227 
4228         return t;
4229     }
4230 
4231     /**
4232      * SQL:2008 VIEW<p>
4233      *
4234      * The JAR_JAR_USAGE view is empty.<p>
4235      *
4236      */
JAR_JAR_USAGE(Session session, PersistentStore store)4237     Table JAR_JAR_USAGE(Session session, PersistentStore store) {
4238 
4239         Table t = sysTables[JAR_JAR_USAGE];
4240 
4241         if (t == null) {
4242             t = createBlankTable(sysTableHsqlNames[JAR_JAR_USAGE]);
4243 
4244             addColumn(t, "PATH_JAR_CATALOG", SQL_IDENTIFIER);
4245             addColumn(t, "PATH_JAR_SCHAMA", SQL_IDENTIFIER);
4246             addColumn(t, "PATH_JAR_NAME", SQL_IDENTIFIER);
4247             addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
4248             addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
4249             addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
4250 
4251             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4252                 sysTableHsqlNames[JAR_JAR_USAGE].name, false,
4253                 SchemaObject.INDEX);
4254 
4255             t.createPrimaryKeyConstraint(name, new int[] {
4256                 0, 1, 2, 3, 4, 5
4257             }, false);
4258 
4259             return t;
4260         }
4261 
4262         // column number mappings
4263         final int path_jar_catalog = 0;
4264         final int path_jar_schema  = 1;
4265         final int path_jar_name    = 2;
4266         final int jar_catalog      = 3;
4267         final int jar_schema       = 4;
4268         final int jar_name         = 5;
4269 
4270         //
4271         Iterator it;
4272         Object[] row;
4273 
4274         return t;
4275     }
4276 
4277     /**
4278      * SQL:2008 VIEW<p>
4279      *
4280      * The JARS view is empty.<p>
4281      *
4282      */
JARS(Session session, PersistentStore store)4283     Table JARS(Session session, PersistentStore store) {
4284 
4285         Table t = sysTables[JARS];
4286 
4287         if (t == null) {
4288             t = createBlankTable(sysTableHsqlNames[JARS]);
4289 
4290             addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
4291             addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
4292             addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
4293             addColumn(t, "JAR_PATH", CHARACTER_DATA);
4294 
4295             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4296                 sysTableHsqlNames[JARS].name, false, SchemaObject.INDEX);
4297 
4298             t.createPrimaryKeyConstraint(name, new int[] {
4299                 0, 1, 2, 3
4300             }, false);
4301 
4302             return t;
4303         }
4304 
4305         // column number mappings
4306         final int jar_catalog = 0;
4307         final int jar_schema  = 1;
4308         final int jar_name    = 2;
4309         final int jar_path    = 3;
4310 
4311         //
4312         Iterator it;
4313         Object[] row;
4314 
4315         return t;
4316     }
4317 
4318     /**
4319      * SQL:2008 VIEW<p>
4320      *
4321      * The KEY_COLUMN_USAGE view describes the columns of
4322      * PRIMARY KEY, UNIQUE, FOREIGN KEY, and CHECK  constraint of each accessible table
4323      * defined within this database. <p>
4324      *
4325      * Each row is a PRIMARY KEY or UNIQUE column description with the following
4326      * columns: <p>
4327      *
4328      * <pre class="SqlCodeExample">
4329      * CONSTRAINT_CATALOG              VARCHAR NULL,
4330      * CONSTRAINT_SCHEMA               VARCHAR NULL,
4331      * CONSTRAINT_NAME                 VARCHAR NOT NULL,
4332      * TABLE_CATALOG                   VARCHAR   table catalog
4333      * TABLE_SCHEMA                    VARCHAR   table schema
4334      * TABLE_NAME                      VARCHAR   table name
4335      * COLUMN_NAME                     VARCHAR   column name
4336      * ORDINAL_POSITION                BIGINT
4337      * POSITION_IN_UNIQUE_CONSTRAINT   BIGINT
4338      * </pre> <p>
4339      *
4340      * The ORDINAL_POSITION column refers to the position of the column in the
4341      * definition of the UNIQUE or FOREIGN KEY constraints.<p>
4342      * The POSITION_IN_UNIQUE_CONSTRAINT column is defined for FOREIGN KEY constraints
4343      * only. It refers to the position of the referenced column in the UNIQUE
4344      * constraint in the reference table.<p>
4345      * A column is included in this view if the user has some privilege on al
4346      * the columns of the constraint.<p>
4347      *
4348      * @return a <code>Table</code> object describing the visible
4349      *        primary key and unique columns of each accessible table
4350      *        defined within this database.
4351      */
KEY_COLUMN_USAGE(Session session, PersistentStore store)4352     Table KEY_COLUMN_USAGE(Session session, PersistentStore store) {
4353 
4354         Table t = sysTables[KEY_COLUMN_USAGE];
4355 
4356         if (t == null) {
4357             t = createBlankTable(sysTableHsqlNames[KEY_COLUMN_USAGE]);
4358 
4359             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
4360             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
4361             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);                   // not null
4362             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
4363             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
4364             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);                        // not null
4365             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);                       // not null
4366             addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);                 // not null
4367             addColumn(t, "POSITION_IN_UNIQUE_CONSTRAINT", CARDINAL_NUMBER);    // not null
4368 
4369             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4370                 sysTableHsqlNames[KEY_COLUMN_USAGE].name, false,
4371                 SchemaObject.INDEX);
4372 
4373             t.createPrimaryKeyConstraint(name, new int[] {
4374                 2, 1, 0, 6, 7
4375             }, false);
4376 
4377             return t;
4378         }
4379 
4380         // Intermediate holders
4381         Iterator tables;
4382         Object[] row;
4383 
4384         // column number mappings
4385         final int constraint_catalog            = 0;
4386         final int constraint_schema             = 1;
4387         final int constraint_name               = 2;
4388         final int table_catalog                 = 3;
4389         final int table_schema                  = 4;
4390         final int table_name                    = 5;
4391         final int column_name                   = 6;
4392         final int ordinal_position              = 7;
4393         final int position_in_unique_constraint = 8;
4394 
4395         // Initialization
4396         tables =
4397             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
4398 
4399         while (tables.hasNext()) {
4400             Table    table        = (Table) tables.next();
4401             String   tableCatalog = database.getCatalogName().name;
4402             HsqlName tableName    = table.getName();
4403 
4404             if (table.isView()) {
4405                 continue;
4406             }
4407 
4408             if (!session.getGrantee().isAccessible(tableName)) {
4409                 continue;
4410             }
4411 
4412             Constraint[] constraints = table.getConstraints();
4413 
4414             for (int i = 0; i < constraints.length; i++) {
4415                 Constraint constraint = constraints[i];
4416 
4417                 if (constraint.getConstraintType() == SchemaObject
4418                         .ConstraintTypes.PRIMARY_KEY || constraint
4419                         .getConstraintType() == SchemaObject.ConstraintTypes
4420                         .UNIQUE || constraint
4421                         .getConstraintType() == SchemaObject.ConstraintTypes
4422                         .FOREIGN_KEY) {
4423                     String constraintName = constraint.getName().name;
4424                     int[]  cols           = constraint.getMainColumns();
4425                     int[]  uniqueColMap   = null;
4426 
4427                     if (constraint.getConstraintType()
4428                             == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
4429                         Table uniqueConstTable = constraint.getMain();
4430                         Constraint uniqueConstraint =
4431                             uniqueConstTable.getConstraint(
4432                                 constraint.getUniqueName().name);
4433                         int[] uniqueConstIndexes =
4434                             uniqueConstraint.getMainColumns();
4435 
4436                         uniqueColMap = new int[cols.length];
4437 
4438                         for (int j = 0; j < cols.length; j++) {
4439                             uniqueColMap[j] =
4440                                 ArrayUtil.find(uniqueConstIndexes, cols[j]);
4441                         }
4442 
4443                         cols = constraint.getRefColumns();
4444                     }
4445 
4446                     if (!session.getGrantee().hasColumnRights(table, cols)) {
4447                         continue;
4448                     }
4449 
4450                     for (int j = 0; j < cols.length; j++) {
4451                         row                     = t.getEmptyRowData();
4452                         row[constraint_catalog] = tableCatalog;
4453                         row[constraint_schema]  = tableName.schema.name;
4454                         row[constraint_name]    = constraintName;
4455                         row[table_catalog]      = tableCatalog;
4456                         row[table_schema]       = tableName.schema.name;
4457                         row[table_name]         = tableName.name;
4458                         row[column_name] =
4459                             table.getColumn(cols[j]).getName().name;
4460                         row[ordinal_position] = ValuePool.getLong(j + 1);
4461 
4462                         if (constraint.getConstraintType()
4463                                 == SchemaObject.ConstraintTypes.FOREIGN_KEY) {
4464                             row[position_in_unique_constraint] =
4465                                 ValuePool.getInt(uniqueColMap[j] + 1);
4466                         }
4467 
4468                         t.insertSys(session, store, row);
4469                     }
4470                 }
4471             }
4472         }
4473 
4474         return t;
4475     }
4476 
4477     /**
4478      * SQL:2008 VIEW<p>
4479      *
4480      * The METHOD_SPECIFICATION_PARAMETERS view is not implemented.<p>
4481      *
4482      */
METHOD_SPECIFICATION_PARAMETERS(Session session, PersistentStore store)4483     Table METHOD_SPECIFICATION_PARAMETERS(Session session,
4484                                           PersistentStore store) {
4485         return null;
4486     }
4487 
4488     /**
4489      * SQL:2008 VIEW<p>
4490      *
4491      * The METHOD_SPECIFICATIONS view is not implemented.<p>
4492      *
4493      */
METHOD_SPECIFICATIONS(Session session, PersistentStore store)4494     Table METHOD_SPECIFICATIONS(Session session, PersistentStore store) {
4495         return null;
4496     }
4497 
4498     /**
4499      * SQL:2008 VIEW<p>
4500      *
4501      * The MODULE_COLUMN_USAGE view is not implemented.<p>
4502      *
4503      */
MODULE_COLUMN_USAGE(Session session, PersistentStore store)4504     Table MODULE_COLUMN_USAGE(Session session, PersistentStore store) {
4505         return null;
4506     }
4507 
4508     /**
4509      * SQL:2008 VIEW<p>
4510      *
4511      * The MODULE_PRIVILEGES view is not implemented.<p>
4512      *
4513      */
MODULE_PRIVILEGES(Session session, PersistentStore store)4514     Table MODULE_PRIVILEGES(Session session, PersistentStore store) {
4515         return null;
4516     }
4517 
4518     /**
4519      * SQL:2008 VIEW<p>
4520      *
4521      * The MODULE_TABLE_USAGE view is not implemented.<p>
4522      *
4523      */
MODULE_TABLE_USAGE(Session session, PersistentStore store)4524     Table MODULE_TABLE_USAGE(Session session, PersistentStore store) {
4525         return null;
4526     }
4527 
4528     /**
4529      * SQL:2008 VIEW<p>
4530      *
4531      * The MODULES view is not implemented.<p>
4532      *
4533      */
MODULES(Session session, PersistentStore store)4534     Table MODULES(Session session, PersistentStore store) {
4535         return null;
4536     }
4537 
4538     /**
4539      * SQL:2008 VIEW<p>
4540      *
4541      * The PARAMETERS view has one row for each parameter of a user defined
4542      * routine.<p>
4543      *
4544      * <pre class="SqlCodeExample">
4545      *      OBJECT_CATALOG      VARCHAR
4546      *      OBJECT_SCHEMA       VARCHAR
4547      *      OBJECT_NAME         VARCHAR
4548      *      OBJECT_TYPE         VARCHAR
4549      *      DTD_IDENTIFIER      VARCHAR
4550      * </pre>
4551      *
4552      * <b>Description:</b> <p>
4553      *
4554      * <ol>
4555      * <li> The values of OBJECT_CATALOG, OBJECT_SCHEMA, and
4556      *      OBJECT_NAME are the catalog name, schema name,
4557      *       and identifier, respectively, of the object. <p>
4558      *
4559      * <li> The value of OBJECT_TYPE is the type of the object, for example
4560      *      'TABLE'.
4561      *
4562      * <1i> Tables are reported only if the user or one of its roles is
4563      *      the authorization (owner) of the table.
4564      * </ol>
4565      *
4566      * @return Table
4567      */
PARAMETERS(Session session, PersistentStore store)4568     Table PARAMETERS(Session session, PersistentStore store) {
4569 
4570         Table t = sysTables[PARAMETERS];
4571 
4572         if (t == null) {
4573             t = createBlankTable(sysTableHsqlNames[PARAMETERS]);
4574 
4575             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
4576             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
4577             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
4578             addColumn(t, "ORDINAL_POSITION", CARDINAL_NUMBER);
4579             addColumn(t, "PARAMETER_MODE", CHARACTER_DATA);
4580             addColumn(t, "IS_RESULT", YES_OR_NO);
4581             addColumn(t, "AS_LOCATOR", YES_OR_NO);
4582             addColumn(t, "PARAMETER_NAME", SQL_IDENTIFIER);
4583 
4584             //
4585             addColumn(t, "FROM_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
4586             addColumn(t, "FROM_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);
4587             addColumn(t, "FROM_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
4588 
4589             //
4590             addColumn(t, "TO_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
4591             addColumn(t, "TO_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);
4592             addColumn(t, "TO_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
4593 
4594             //
4595             addColumn(t, "DATA_TYPE", CHARACTER_DATA);
4596             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
4597             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
4598             addColumn(t, "CHARACTER_SET_CATALOG", CHARACTER_DATA);
4599             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
4600             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
4601             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
4602             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
4603             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
4604             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
4605             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
4606             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
4607             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
4608             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
4609             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
4610             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
4611             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
4612             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
4613             addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
4614             addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
4615             addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);
4616             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
4617             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
4618             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
4619             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
4620             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
4621 
4622             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4623                 sysTableHsqlNames[PARAMETERS].name, false, SchemaObject.INDEX);
4624 
4625             t.createPrimaryKeyConstraint(name, new int[] {
4626                 0, 1, 2, 3
4627             }, false);
4628 
4629             return t;
4630         }
4631 
4632         // column number mappings
4633         final int specific_cat             = 0;
4634         final int specific_schem           = 1;
4635         final int specific_name            = 2;
4636         final int ordinal_position         = 3;
4637         final int parameter_mode           = 4;
4638         final int is_result                = 5;
4639         final int as_locator               = 6;
4640         final int parameter_name           = 7;
4641         final int from_specific_catalog    = 8;
4642         final int from_specific_schema     = 9;
4643         final int from_specific_name       = 10;
4644         final int to_specific_catalog      = 11;
4645         final int to_specific_schema       = 12;
4646         final int to_specific_name         = 13;
4647         final int data_type                = 14;
4648         final int character_maximum_length = 15;
4649         final int character_octet_length   = 16;
4650         final int character_set_catalog    = 17;
4651         final int character_set_schema     = 18;
4652         final int character_set_name       = 19;
4653         final int collation_catalog        = 20;
4654         final int collation_schema         = 21;
4655         final int collation_name           = 22;
4656         final int numeric_precision        = 23;
4657         final int numeric_precision_radix  = 24;
4658         final int numeric_scale            = 25;
4659         final int datetime_precision       = 26;
4660         final int interval_type            = 27;
4661         final int interval_precision       = 28;
4662         final int udt_catalog              = 29;
4663         final int udt_schema               = 30;
4664         final int udt_name                 = 31;
4665         final int scope_catalog            = 32;
4666         final int scope_schema             = 33;
4667         final int scope_name               = 34;
4668         final int maximum_cardinality      = 35;
4669         final int dtd_identifier           = 36;
4670 
4671         // intermediate holders
4672         int           columnCount;
4673         Iterator      routines;
4674         RoutineSchema routineSchema;
4675         Routine       routine;
4676         Object[]      row;
4677         Type          type;
4678 
4679         // Initialization
4680         routines = database.schemaManager.databaseObjectIterator(
4681             SchemaObject.ROUTINE);
4682 
4683         while (routines.hasNext()) {
4684             routineSchema = (RoutineSchema) routines.next();
4685 
4686             if (!session.getGrantee().isAccessible(routineSchema)) {
4687                 continue;
4688             }
4689 
4690             Routine[] specifics = routineSchema.getSpecificRoutines();
4691 
4692             for (int i = 0; i < specifics.length; i++) {
4693                 routine     = specifics[i];
4694                 columnCount = routine.getParameterCount();
4695 
4696                 for (int j = 0; j < columnCount; j++) {
4697                     ColumnSchema column = routine.getParameter(j);
4698 
4699                     type                  = column.getDataType();
4700                     row                   = t.getEmptyRowData();
4701                     row[specific_cat]     = database.getCatalogName().name;
4702                     row[specific_schem]   = routine.getSchemaName().name;
4703                     row[specific_name]    = routine.getSpecificName().name;
4704                     row[parameter_name]   = column.getName().name;
4705                     row[ordinal_position] = ValuePool.getLong(j + 1);
4706 
4707                     switch (column.getParameterMode()) {
4708 
4709                         case SchemaObject.ParameterModes.PARAM_IN :
4710                             row[parameter_mode] = "IN";
4711                             break;
4712 
4713                         case SchemaObject.ParameterModes.PARAM_OUT :
4714                             row[parameter_mode] = "OUT";
4715                             break;
4716 
4717                         case SchemaObject.ParameterModes.PARAM_INOUT :
4718                             row[parameter_mode] = "INOUT";
4719                             break;
4720                     }
4721 
4722                     row[is_result]  = "NO";
4723                     row[as_locator] = "NO";
4724                     row[data_type]  = type.getFullNameString();
4725 
4726                     // common type block
4727                     if (type.isCharacterType()) {
4728                         row[character_maximum_length] =
4729                             ValuePool.getLong(type.precision);
4730                         row[character_octet_length] =
4731                             ValuePool.getLong(type.precision * 2);
4732                         row[character_set_catalog] =
4733                             database.getCatalogName().name;
4734                         row[character_set_schema] =
4735                             type.getCharacterSet().getSchemaName().name;
4736                         row[character_set_name] =
4737                             type.getCharacterSet().getName().name;
4738                         row[collation_catalog] =
4739                             database.getCatalogName().name;
4740                         row[collation_schema] =
4741                             type.getCollation().getSchemaName().name;
4742                         row[collation_name] =
4743                             type.getCollation().getName().name;
4744                     } else if (type.isNumberType()) {
4745                         row[numeric_precision] = ValuePool.getLong(
4746                             ((NumberType) type).getNumericPrecisionInRadix());
4747                         row[numeric_precision_radix] =
4748                             ValuePool.getLong(type.getPrecisionRadix());
4749                     } else if (type.isBooleanType()) {
4750 
4751                         //
4752                     } else if (type.isDateTimeType()) {
4753                         row[datetime_precision] =
4754                             ValuePool.getLong(type.scale);
4755                     } else if (type.isIntervalType()) {
4756                         row[data_type] = "INTERVAL";
4757                         row[interval_type] =
4758                             IntervalType.getQualifier(type.typeCode);
4759                         row[interval_precision] =
4760                             ValuePool.getLong(type.precision);
4761                         row[datetime_precision] =
4762                             ValuePool.getLong(type.scale);
4763                     } else if (type.isBinaryType()) {
4764                         row[character_maximum_length] =
4765                             ValuePool.getLong(type.precision);
4766                         row[character_octet_length] =
4767                             ValuePool.getLong(type.precision);
4768                     } else if (type.isBitType()) {
4769                         row[character_maximum_length] =
4770                             ValuePool.getLong(type.precision);
4771                         row[character_octet_length] =
4772                             ValuePool.getLong(type.precision);
4773                     } else if (type.isArrayType()) {
4774                         row[maximum_cardinality] =
4775                             ValuePool.getLong(type.arrayLimitCardinality());
4776                         row[data_type] = "ARRAY";
4777                     }
4778 
4779                     if (type.isDistinctType()) {
4780                         row[udt_catalog] = database.getCatalogName().name;
4781                         row[udt_schema]  = type.getSchemaName().name;
4782                         row[udt_name]    = type.getName().name;
4783                     }
4784 
4785                     row[dtd_identifier] = type.getDefinition();
4786 
4787                     // end common block
4788                     t.insertSys(session, store, row);
4789                 }
4790             }
4791         }
4792 
4793         return t;
4794     }
4795 
4796     /**
4797      * SQL:2008 VIEW<p>
4798      *
4799      * The REFERENTIAL_CONSTRAINTS view has one row for each FOREIGN KEY
4800      * constraint. <p>
4801      *
4802      * <b>Definition:</b><p>
4803      *
4804      * <pre class="SqlCodeExample">
4805      *      CONSTRAINT_CATALOG             VARCHAR ,
4806      *      CONSTRAINT_SCHEMA              VARCHAR ,
4807      *      CONSTRAINT_NAME                VARCHAR ,
4808      *      UNIQUE_CONSTRAINT_CATALOG      VARCHAR ,
4809      *      UNIQUE_CONSTRAINT_SCHEMA       VARCHAR ,
4810      *      UNIQUE_CONSTRAINT_NAME         VARCHAR ,
4811      *      MATCH_OPTION                   VARCHAR ,
4812      *      UPDATE_RULE                    VARCHAR ,
4813      *      DELETE_RULE                    VARCHAR ,
4814      * </pre>
4815      *
4816      * <b>Description:</b><p>
4817      *
4818      * <ol>
4819      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA and
4820      *      CONSTRAINT_NAME are the catalog name, schema name,
4821      *      and identifier, respectively, of the constraint being
4822      *      described. <p>
4823      *
4824      * <li> The values of UNIQUE_CONSTRAINT_CATALOG, UNIQUE_CONSTRAINT_SCHEMA and
4825      *      UNIQUE_CONSTRAINT_NAME are the catalog name, schema name,
4826      *      and identifier, respectively, of the referenced UNIQUE constraint. <p>
4827      *
4828      * <li> A constraint is shown in this view if the user has table level
4829      *      privilege of at lease one of the types, INSERT, UPDATE, DELETE,
4830      *      REFERENCES or TRIGGER.
4831      * </ol>
4832      *
4833      * @return Table
4834      */
REFERENTIAL_CONSTRAINTS(Session session, PersistentStore store)4835     Table REFERENTIAL_CONSTRAINTS(Session session, PersistentStore store) {
4836 
4837         Table t = sysTables[REFERENTIAL_CONSTRAINTS];
4838 
4839         if (t == null) {
4840             t = createBlankTable(sysTableHsqlNames[REFERENTIAL_CONSTRAINTS]);
4841 
4842             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
4843             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
4844             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);              // not null
4845             addColumn(t, "UNIQUE_CONSTRAINT_CATALOG", SQL_IDENTIFIER);    // not null
4846             addColumn(t, "UNIQUE_CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
4847             addColumn(t, "UNIQUE_CONSTRAINT_NAME", SQL_IDENTIFIER);
4848             addColumn(t, "MATCH_OPTION", CHARACTER_DATA);                 // not null
4849             addColumn(t, "UPDATE_RULE", CHARACTER_DATA);                  // not null
4850             addColumn(t, "DELETE_RULE", CHARACTER_DATA);                  // not null
4851 
4852             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4853                 sysTableHsqlNames[REFERENTIAL_CONSTRAINTS].name, false,
4854                 SchemaObject.INDEX);
4855 
4856             t.createPrimaryKeyConstraint(name, new int[] {
4857                 0, 1, 2,
4858             }, false);
4859 
4860             return t;
4861         }
4862 
4863         // column number mappings
4864         final int constraint_catalog        = 0;
4865         final int constraint_schema         = 1;
4866         final int constraint_name           = 2;
4867         final int unique_constraint_catalog = 3;
4868         final int unique_constraint_schema  = 4;
4869         final int unique_constraint_name    = 5;
4870         final int match_option              = 6;
4871         final int update_rule               = 7;
4872         final int delete_rule               = 8;
4873 
4874         //
4875         Iterator     tables;
4876         Table        table;
4877         Constraint[] constraints;
4878         Constraint   constraint;
4879         Object[]     row;
4880 
4881         tables =
4882             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
4883 
4884         while (tables.hasNext()) {
4885             table = (Table) tables.next();
4886 
4887             if (table.isView()
4888                     || !session.getGrantee().hasNonSelectTableRight(table)) {
4889                 continue;
4890             }
4891 
4892             constraints = table.getConstraints();
4893 
4894             for (int i = 0; i < constraints.length; i++) {
4895                 constraint = constraints[i];
4896 
4897                 if (constraint.getConstraintType()
4898                         != SchemaObject.ConstraintTypes.FOREIGN_KEY) {
4899                     continue;
4900                 }
4901 
4902                 HsqlName uniqueName = constraint.getUniqueName();
4903 
4904                 row                     = t.getEmptyRowData();
4905                 row[constraint_catalog] = database.getCatalogName().name;
4906                 row[constraint_schema]  = constraint.getSchemaName().name;
4907                 row[constraint_name]    = constraint.getName().name;
4908 
4909                 if (isAccessibleTable(session, constraint.getMain())) {
4910                     row[unique_constraint_catalog] =
4911                         database.getCatalogName().name;
4912                     row[unique_constraint_schema] = uniqueName.schema.name;
4913                     row[unique_constraint_name]   = uniqueName.name;
4914                 }
4915 
4916                 row[match_option] = Tokens.T_NONE;
4917                 row[update_rule]  = constraint.getUpdateActionString();
4918                 row[delete_rule]  = constraint.getDeleteActionString();
4919 
4920                 t.insertSys(session, store, row);
4921             }
4922         }
4923 
4924         return t;
4925     }
4926 
4927     /**
4928      * SQL:2008 VIEW<p>
4929      *
4930      * The ROLE_COLUMN_GRANTS view has one row for each privilege granted to each
4931      * ROLE on each column. <p>
4932      *
4933      * <b>Definition:</b><p>
4934      *
4935      * <pre class="SqlCodeExample">
4936      *      GRANTOR                        VARCHAR ,
4937      *      GRANTEE                        VARCHAR ,
4938      *      TABLE_CATALOG                  VARCHAR ,
4939      *      TABLE_SCHEMA                   VARCHAR ,
4940      *      TABLE_NAME                     VARCHAR ,
4941      *      COLUMN_NAME                    VARCHAR ,
4942      *      PRIVILEGE_TYPE                 VARCHAR ,
4943      *      IS_GRANTABLE                   VARCHAR ,
4944      * </pre>
4945      *
4946      * <b>Description:</b><p>
4947      *
4948      * <ol>
4949      * <li> The values of GRANTOR is the grantor of the privilege. The value of
4950      *      GRANTEE is the name of the ROLE.
4951      *
4952      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA,
4953      *      TABLE_NAME and COLUMN_NAME are the catalog name, schema name,
4954      *      table name and column identifier, respectively, of the column grant being
4955      *      described. <p>
4956      *
4957      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
4958      *      'SELECT', 'UPDATE', 'INSERT', 'REFERENCES' and 'TRIGGER'.
4959      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
4960      * </ol>
4961      *
4962      * @return Table
4963      */
ROLE_COLUMN_GRANTS(Session session, PersistentStore store)4964     Table ROLE_COLUMN_GRANTS(Session session, PersistentStore store) {
4965 
4966         Table t = sysTables[ROLE_COLUMN_GRANTS];
4967 
4968         if (t == null) {
4969             t = createBlankTable(sysTableHsqlNames[ROLE_COLUMN_GRANTS]);
4970 
4971             addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
4972             addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
4973             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
4974             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
4975             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
4976             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);       // not null
4977             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
4978             addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
4979 
4980             // order: COLUMN_NAME, PRIVILEGE
4981             // for unique: GRANTEE, GRANTOR, TABLE_NAME, TABLE_SCHEMA, TABLE_CAT
4982             // false PK, as TABLE_SCHEMA and/or TABLE_CAT may be null
4983             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
4984                 sysTableHsqlNames[ROLE_COLUMN_GRANTS].name, false,
4985                 SchemaObject.INDEX);
4986 
4987             t.createPrimaryKeyConstraint(name, new int[] {
4988                 5, 6, 1, 0, 4, 3, 2
4989             }, false);
4990 
4991             return t;
4992         }
4993 
4994         Session sys = database.sessionManager.newSysSession(
4995             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
4996         Result rs = sys.executeDirectStatement(
4997             "SELECT C.GRANTOR, C.GRANTEE, C.TABLE_CATALOG, C.TABLE_SCHEMA, C.TABLE_NAME, C.COLUMN_NAME, C.PRIVILEGE_TYPE, C.IS_GRANTABLE "
4998             + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES C "
4999             + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON C.GRANTEE = ROLE_NAME;");
5000 
5001         t.insertSys(session, store, rs);
5002         sys.close();
5003 
5004         return t;
5005     }
5006 
5007     /**
5008      * SQL:2008 VIEW<p>
5009      *
5010      * The ROLE_ROUTINE_GRANTS view has one row for each privilege granted to each
5011      * ROLE on each specific routine. <p>
5012      *
5013      * <b>Definition:</b><p>
5014      *
5015      * <pre class="SqlCodeExample">
5016      *      GRANTOR                        VARCHAR ,
5017      *      GRANTEE                        VARCHAR ,
5018      *      SPECIFIC_CATALOG               VARCHAR ,
5019      *      SPECIFIC_SCHEMA                VARCHAR ,
5020      *      SPECIFIC_NAME                  VARCHAR ,
5021      *      ROUTINE_CATALOG                VARCHAR ,
5022      *      ROUTINE_SCHEMA                 VARCHAR ,
5023      *      ROUTINE_NAME                   VARCHAR ,
5024      *      PRIVILEGE_TYPE                 VARCHAR ,
5025      *      IS_GRANTABLE                   VARCHAR ,
5026      * </pre>
5027      *
5028      * <b>Description:</b><p>
5029      *
5030      * <ol>
5031      * <li> The values of GRANTOR is the grantor of the privilege. The value of
5032      *      GRANTEE is the name of the ROLE.
5033      *
5034      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5035      *      SPECIFIC_NAME are the catalog name, schema name,
5036      *      routine identifier, respectively, of the grant being
5037      *      described. <p>
5038      *
5039      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including
5040      *      'EXECUTE'.
5041      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
5042      * </ol>
5043      *
5044      * @return Table
5045      */
ROLE_ROUTINE_GRANTS(Session session, PersistentStore store)5046     Table ROLE_ROUTINE_GRANTS(Session session, PersistentStore store) {
5047 
5048         Table t = sysTables[ROLE_ROUTINE_GRANTS];
5049 
5050         if (t == null) {
5051             t = createBlankTable(sysTableHsqlNames[ROLE_ROUTINE_GRANTS]);
5052 
5053             addColumn(t, "GRANTOR", SQL_IDENTIFIER);          // not null
5054             addColumn(t, "GRANTEE", SQL_IDENTIFIER);          // not null
5055             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5056             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5057             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);    // not null
5058             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
5059             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
5060             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
5061             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
5062             addColumn(t, "IS_GRANTABLE", YES_OR_NO);
5063 
5064             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5065                 sysTableHsqlNames[ROLE_ROUTINE_GRANTS].name, false,
5066                 SchemaObject.INDEX);
5067 
5068             t.createPrimaryKeyConstraint(name, new int[] {
5069                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
5070             }, false);
5071 
5072             return t;
5073         }
5074 
5075         Session sys = database.sessionManager.newSysSession(
5076             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
5077         Result rs = sys.executeDirectStatement(
5078             "SELECT R.GRANTOR, R.GRANTEE, R.SPECIFIC_CATALOG, R.SPECIFIC_SCHEMA, "
5079             + "R.SPECIFIC_NAME, R.ROUTINE_CATALOG, R.ROUTINE_SCHEMA, R.ROUTINE_NAME, "
5080             + "R.PRIVILEGE_TYPE, R.IS_GRANTABLE "
5081             + "FROM INFORMATION_SCHEMA.ROUTINE_PRIVILEGES R "
5082             + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON R.GRANTEE = ROLE_NAME;");
5083 
5084         t.insertSys(session, store, rs);
5085         sys.close();
5086 
5087         // Column number mappings
5088         final int grantor          = 0;
5089         final int grantee          = 1;
5090         final int table_name       = 2;
5091         final int specific_catalog = 3;
5092         final int specific_schema  = 4;
5093         final int specific_name    = 5;
5094         final int routine_catalog  = 6;
5095         final int routine_schema   = 7;
5096         final int routine_name     = 8;
5097         final int privilege_type   = 9;
5098         final int is_grantable     = 10;
5099 
5100         //
5101         return t;
5102     }
5103 
5104     /**
5105      * SQL:2008 VIEW<p>
5106      *
5107      * The ROLE_ROUTINE_GRANTS view has one row for each privilege granted to each
5108      * ROLE on each table. <p>
5109      *
5110      * <b>Definition:</b><p>
5111      *
5112      * <pre class="SqlCodeExample">
5113      *      GRANTOR                        VARCHAR ,
5114      *      GRANTEE                        VARCHAR ,
5115      *      TABLE_CATALOG                  VARCHAR ,
5116      *      TABLE_SCHEMA                   VARCHAR ,
5117      *      TABLE_NAME                     VARCHAR ,
5118      *      PRIVILEGE_TYPE                 VARCHAR ,
5119      *      IS_GRANTABLE                   VARCHAR ,
5120      *      WITH_HIERARCHY                 VARCHAR ,
5121      * </pre>
5122      *
5123      * <b>Description:</b><p>
5124      *
5125      * <ol>
5126      * <li> The values of GRANTOR is the grantor of the privilege. The value of
5127      *      GRANTEE is the name of the ROLE.
5128      *
5129      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA and
5130      *      TABLE_NAME are the catalog name, schema name and
5131      *      table name, respectively, of the table level grant being
5132      *      described. <p>
5133      *
5134      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
5135      *      'DELETE', 'SELECT', 'UPDATE', 'INSERT', 'REFERENCES' and 'TRIGGER'.
5136      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
5137      * </ol>
5138      *
5139      * @return Table
5140      */
ROLE_TABLE_GRANTS(Session session, PersistentStore store)5141     Table ROLE_TABLE_GRANTS(Session session, PersistentStore store) {
5142 
5143         Table t = sysTables[ROLE_TABLE_GRANTS];
5144 
5145         if (t == null) {
5146             t = createBlankTable(sysTableHsqlNames[ROLE_TABLE_GRANTS]);
5147 
5148             addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
5149             addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
5150             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
5151             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
5152             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);        // not null
5153             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
5154             addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
5155             addColumn(t, "WITH_HIERARCHY", YES_OR_NO);
5156 
5157             // order:  TABLE_SCHEM, TABLE_NAME, and PRIVILEGE,
5158             // added for unique:  GRANTEE, GRANTOR,
5159             // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
5160             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5161                 sysTableHsqlNames[ROLE_TABLE_GRANTS].name, false,
5162                 SchemaObject.INDEX);
5163 
5164             t.createPrimaryKeyConstraint(name, new int[] {
5165                 3, 4, 5, 0, 1
5166             }, false);
5167 
5168             return t;
5169         }
5170 
5171         Session sys = database.sessionManager.newSysSession(
5172             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
5173         Result rs = sys.executeDirectStatement(
5174             "SELECT T.GRANTOR, T.GRANTEE, T.TABLE_CATALOG, T.TABLE_SCHEMA, T.TABLE_NAME, "
5175             + "T.PRIVILEGE_TYPE, T.IS_GRANTABLE, 'NO' "
5176             + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES T "
5177             + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON T.GRANTEE = ROLE_NAME;");
5178 
5179         t.insertSys(session, store, rs);
5180         sys.close();
5181 
5182         return t;
5183     }
5184 
5185     /**
5186      * SQL:2008 VIEW<p>
5187      *
5188      * The ROLE_UDT_GRANT view has one row for each privilege granted to each
5189      * user defined type. <p>
5190      *
5191      * <b>Definition:</b><p>
5192      *
5193      * <pre class="SqlCodeExample">
5194      *      GRANTOR                        VARCHAR ,
5195      *      GRANTEE                        VARCHAR ,
5196      *      UDT_CATALOG                    VARCHAR ,
5197      *      UDT_SCHEMA                     VARCHAR ,
5198      *      UDT_NAME                       VARCHAR ,
5199      *      PRIVILEGE_TYPE                 VARCHAR ,
5200      *      IS_GRANTABLE                   VARCHAR ,
5201      * </pre>
5202      *
5203      * <b>Description:</b><p>
5204      *
5205      * <ol>
5206      * <li> The values of GRANTOR is the grantor of the privilege. The value of
5207      *      GRANTEE is the name of the ROLE.
5208      *
5209      * <li> The values of UDT_CATALOG, UDT_SCHEMA and
5210      *      UDT_NAME are the catalog name, schema name and
5211      *      table name, respectively, of the table level grant being
5212      *      described. <p>
5213      *
5214      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
5215      *      'USAGE'.
5216      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
5217      * </ol>
5218      *
5219      * @return Table
5220      */
ROLE_UDT_GRANTS(Session session, PersistentStore store)5221     Table ROLE_UDT_GRANTS(Session session, PersistentStore store) {
5222 
5223         Table t = sysTables[ROLE_UDT_GRANTS];
5224 
5225         if (t == null) {
5226             t = createBlankTable(sysTableHsqlNames[ROLE_UDT_GRANTS]);
5227 
5228             addColumn(t, "GRANTOR", SQL_IDENTIFIER);     // not null
5229             addColumn(t, "GRANTEE", SQL_IDENTIFIER);     // not null
5230             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
5231             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
5232             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);    // not null
5233             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
5234             addColumn(t, "IS_GRANTABLE", YES_OR_NO);     // not null
5235 
5236             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5237                 sysTableHsqlNames[ROLE_UDT_GRANTS].name, false,
5238                 SchemaObject.INDEX);
5239 
5240             t.createPrimaryKeyConstraint(name, null, false);
5241 
5242             return t;
5243         }
5244 
5245         Session sys = database.sessionManager.newSysSession(
5246             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
5247         Result rs = sys.executeDirectStatement(
5248             "SELECT U.GRANTOR, U.GRANTEE, U.UDT_CATALOG, U.UDT_SCHEMA, U.UDT_NAME, "
5249             + "U.PRIVILEGE_TYPE, U.IS_GRANTABLE "
5250             + "FROM INFORMATION_SCHEMA.UDT_PRIVILEGES U "
5251             + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES ON U.GRANTEE = ROLE_NAME;");
5252 
5253         t.insertSys(session, store, rs);
5254         sys.close();
5255 
5256         return t;
5257     }
5258 
5259     /**
5260      * SQL:2008 VIEW<p>
5261      *
5262      * The ROLE_USAGE_GRANTS view has one row for each privilege granted to each
5263      * ROLE on each table. <p>
5264      *
5265      * <b>Definition:</b><p>
5266      *
5267      * <pre class="SqlCodeExample">
5268      *      GRANTOR                        VARCHAR ,
5269      *      GRANTEE                        VARCHAR ,
5270      *      OBJECT_CATALOG                 VARCHAR ,
5271      *      OBJECT_SCHEMA                  VARCHAR ,
5272      *      OBJECT_NAME                    VARCHAR ,
5273      *      OBJECT_TYPE                    VARCHAR ,
5274      *      PRIVILEGE_TYPE                 VARCHAR ,
5275      *      IS_GRANTABLE                   VARCHAR ,
5276      * </pre>
5277      *
5278      * <b>Description:</b><p>
5279      *
5280      * <ol>
5281      * <li> The values of GRANTOR is the grantor of the privilege. The value of
5282      *      GRANTEE is the name of the ROLE.
5283      *
5284      * <li> The values of OBJECT_CATALOG, OBJECT_SCHEMA and
5285      *      OBJECT_NAME are the catalog name, schema name and
5286      *      table name, respectively, of the object being
5287      *      described. <p>
5288      * <li> The value of OBJECT_TYPE is they type of object, including 'DOMAIN', 'CHARACTER SET',
5289      *      'COLLATION', 'TRANSLATION' and 'SEQUENCE'.
5290      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
5291      *      'USAGE'.
5292      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
5293      * </ol>
5294      *
5295      * @return Table
5296      */
ROLE_USAGE_GRANTS(Session session, PersistentStore store)5297     Table ROLE_USAGE_GRANTS(Session session, PersistentStore store) {
5298 
5299         Table t = sysTables[ROLE_USAGE_GRANTS];
5300 
5301         if (t == null) {
5302             t = createBlankTable(sysTableHsqlNames[ROLE_USAGE_GRANTS]);
5303 
5304             addColumn(t, "GRANTOR", SQL_IDENTIFIER);        // not null
5305             addColumn(t, "GRANTEE", SQL_IDENTIFIER);        // not null
5306             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
5307             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
5308             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
5309             addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);    // not null
5310             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
5311             addColumn(t, "IS_GRANTABLE", YES_OR_NO);        // not null
5312 
5313             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5314                 sysTableHsqlNames[ROLE_USAGE_GRANTS].name, false,
5315                 SchemaObject.INDEX);
5316 
5317             t.createPrimaryKeyConstraint(name, new int[] {
5318                 0, 1, 2, 3, 4, 5, 6, 7
5319             }, false);
5320 
5321             return t;
5322         }
5323 
5324         Session sys = database.sessionManager.newSysSession(
5325             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
5326         Result rs = sys.executeDirectStatement(
5327             "SELECT U.GRANTOR, U.GRANTEE, U.OBJECT_CATALOG, U.OBJECT_SCHEMA, U.OBJECT_NAME, "
5328             + "U.OBJECT_TYPE, U.PRIVILEGE_TYPE, U.IS_GRANTABLE "
5329             + "FROM INFORMATION_SCHEMA.USAGE_PRIVILEGES U "
5330             + "JOIN INFORMATION_SCHEMA.APPLICABLE_ROLES A ON U.GRANTEE = A.ROLE_NAME;");
5331 
5332         t.insertSys(session, store, rs);
5333         sys.close();
5334 
5335         return t;
5336     }
5337 
5338     /**
5339      * SQL:2008 VIEW<p>
5340      *
5341      * The ROUTINE_COLUMN_USAGE view has one row for each column
5342      * referenced in the body of a routine.<p>
5343      *
5344      * <b>Definition:</b><p>
5345      *
5346      *      SPECIFIC_CATALOG    VARCHAR ,
5347      *      SPECIFIC_SCHEMA     VARCHAR ,
5348      *      SPECIFIC_NAME       VARCHAR ,
5349      *      ROUTINE_CATALOG     VARCHAR ,
5350      *      ROUTINE_SCHEMA      VARCHAR ,
5351      *      ROUTINE_NAME        VARCHAR ,
5352      *      TABLE_CATALOG       VARCHAR ,
5353      *      TABLE_SCHEMA        VARCHAR ,
5354      *      TABLE_NAME          VARCHAR ,
5355      *      COLUMN_NAME         VARCHAR ,
5356      *
5357      * </pre>
5358      *
5359      * <b>Description:</b> <p>
5360      *
5361      * <ol>
5362      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5363      *      SPECIFIC_NAME are the catalog name, schema name,
5364      *      specific routine identifier, respectively, of the grant being
5365      *      described. <p>
5366      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
5367      *      COLUMN_NAME are the catalog name, schema name,
5368      *      identifier, and column name, respectively, of a column
5369      *      reference in the routine body.<>
5370      *
5371      * <1i> Columns are reported only if the user or one of its roles is
5372      *      the authorization (owner) of the table.
5373      *
5374      * </ol>
5375      *
5376      * @return Table
5377      */
ROUTINE_COLUMN_USAGE(Session session, PersistentStore store)5378     Table ROUTINE_COLUMN_USAGE(Session session, PersistentStore store) {
5379 
5380         Table t = sysTables[ROUTINE_COLUMN_USAGE];
5381 
5382         if (t == null) {
5383             t = createBlankTable(sysTableHsqlNames[ROUTINE_COLUMN_USAGE]);
5384 
5385             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5386             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5387             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
5388             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
5389             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
5390             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
5391             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
5392             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
5393             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
5394             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
5395 
5396             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5397                 sysTableHsqlNames[ROUTINE_COLUMN_USAGE].name, false,
5398                 SchemaObject.INDEX);
5399 
5400             t.createPrimaryKeyConstraint(name, new int[] {
5401                 3, 4, 5, 0, 1, 2, 6, 7, 8, 9
5402             }, false);
5403 
5404             return t;
5405         }
5406 
5407         // column number mappings
5408         final int specific_catalog = 0;
5409         final int specific_schema  = 1;
5410         final int specific_name    = 2;
5411         final int routine_catalog  = 3;
5412         final int routine_schema   = 4;
5413         final int routine_name     = 5;
5414         final int table_catalog    = 6;
5415         final int table_schema     = 7;
5416         final int table_name       = 8;
5417         final int column_name      = 9;
5418 
5419         //
5420         Iterator it;
5421         Object[] row;
5422 
5423         it = database.schemaManager.databaseObjectIterator(
5424             SchemaObject.SPECIFIC_ROUTINE);
5425 
5426         while (it.hasNext()) {
5427             Routine        routine = (Routine) it.next();
5428             OrderedHashSet set     = routine.getReferences();
5429 
5430             for (int i = 0; i < set.size(); i++) {
5431                 HsqlName refName = (HsqlName) set.get(i);
5432 
5433                 if (refName.type != SchemaObject.COLUMN) {
5434                     continue;
5435                 }
5436 
5437                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
5438                     continue;
5439                 }
5440 
5441                 row = t.getEmptyRowData();
5442 
5443                 //
5444                 row[specific_catalog] = database.getCatalogName().name;
5445                 row[specific_schema]  = routine.getSchemaName().name;
5446                 row[specific_name]    = routine.getSpecificName().name;
5447                 row[routine_catalog]  = database.getCatalogName().name;
5448                 row[routine_schema]   = routine.getSchemaName().name;
5449                 row[routine_name]     = routine.getName().name;
5450                 row[table_catalog]    = database.getCatalogName().name;
5451                 row[table_schema]     = refName.parent.schema.name;
5452                 row[table_name]       = refName.parent.name;
5453                 row[column_name]      = refName.name;
5454 
5455                 try {
5456                     t.insertSys(session, store, row);
5457                 } catch (HsqlException e) {}
5458             }
5459         }
5460 
5461         return t;
5462     }
5463 
5464     /**
5465      * SQL:2008 VIEW<p>
5466      *
5467      * The ROUTINE_PRIVILEGES view has one row for each privilege granted on
5468      * a PROCEDURE or CATALOG.
5469      *
5470      * <pre class="SqlCodeExample">
5471      *      GRANTOR               VARCHAR ,
5472      *      GRANTEE               VARCHAR ,
5473      *      SPECIFIC_CATALOG      VARCHAR ,
5474      *      SPECIFIC_SCHEMA       VARCHAR ,
5475      *      SPECIFIC_NAME         VARCHAR ,
5476      *      ROUTINE_CATALOG       VARCHAR ,
5477      *      ROUTINE_SCHEMA        VARCHAR ,
5478      *      ROUTINE_NAME          VARCHAR ,
5479      *      PRIVILEGE_TYPE        VARCHAR ,
5480      *      IS_GRANTABLE          VARCHAR ,
5481      * </pre>
5482      *
5483      * <b>Description:</b> <p>
5484      *
5485      * <ol>
5486      * <li> The values of GRANTOR is the grantor of the privilege. The value of
5487      *      GRANTEE is the name of the grantee.
5488      *
5489      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5490      *      SPECIFIC_NAME are the catalog name, schema name
5491      *      and identifier, respectively, of the specific ROUTINE. <p>
5492      *
5493      * <li> The values of ROUTINE_CATALOG, ROUTINE_SCHEMA and
5494      *      ROUTINE_NAME are the catalog name, schema name
5495      *      and identifier, respectively, of the ROUTINE. <p>
5496      *
5497      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
5498      *      'EXECUTE'
5499      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
5500      * </ol>
5501      *
5502      * @return Table
5503      */
ROUTINE_PRIVILEGES(Session session, PersistentStore store)5504     Table ROUTINE_PRIVILEGES(Session session, PersistentStore store) {
5505 
5506         Table t = sysTables[ROUTINE_PRIVILEGES];
5507 
5508         if (t == null) {
5509             t = createBlankTable(sysTableHsqlNames[ROUTINE_PRIVILEGES]);
5510 
5511             addColumn(t, "GRANTOR", SQL_IDENTIFIER);           // not null
5512             addColumn(t, "GRANTEE", SQL_IDENTIFIER);           // not null
5513             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5514             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5515             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);     // not null
5516             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
5517             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
5518             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);      // not null
5519             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);    // not null
5520             addColumn(t, "IS_GRANTABLE", YES_OR_NO);           // not null
5521 
5522             //
5523             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5524                 sysTableHsqlNames[ROUTINE_PRIVILEGES].name, false,
5525                 SchemaObject.INDEX);
5526 
5527             t.createPrimaryKeyConstraint(name, new int[] {
5528                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
5529             }, false);
5530 
5531             return t;
5532         }
5533 
5534         // column number mappings
5535         final int grantor          = 0;
5536         final int grantee          = 1;
5537         final int specific_catalog = 2;
5538         final int specific_schema  = 3;
5539         final int specific_name    = 4;
5540         final int routine_catalog  = 5;
5541         final int routine_schema   = 6;
5542         final int routine_name     = 7;
5543         final int privilege_type   = 8;
5544         final int is_grantable     = 9;
5545 
5546         //
5547         // calculated column values
5548         Grantee granteeObject;
5549         String  privilege;
5550 
5551         // intermediate holders
5552         Iterator       routines;
5553         Routine        routine;
5554         Object[]       row;
5555         OrderedHashSet grantees = session.getGrantee().visibleGrantees();
5556 
5557         routines = database.schemaManager.databaseObjectIterator(
5558             SchemaObject.SPECIFIC_ROUTINE);
5559 
5560         while (routines.hasNext()) {
5561             routine = (Routine) routines.next();
5562 
5563             for (int i = 0; i < grantees.size(); i++) {
5564                 granteeObject = (Grantee) grantees.get(i);
5565 
5566                 OrderedHashSet rights =
5567                     granteeObject.getAllDirectPrivileges(routine);
5568                 OrderedHashSet grants =
5569                     granteeObject.getAllGrantedPrivileges(routine);
5570 
5571                 if (!grants.isEmpty()) {
5572                     grants.addAll(rights);
5573 
5574                     rights = grants;
5575                 }
5576 
5577                 for (int j = 0; j < rights.size(); j++) {
5578                     Right right          = (Right) rights.get(j);
5579                     Right grantableRight = right.getGrantableRights();
5580 
5581                     if (!right.canAccessFully(GrantConstants.EXECUTE)) {
5582                         continue;
5583                     }
5584 
5585                     privilege = Tokens.T_EXECUTE;
5586                     row       = t.getEmptyRowData();
5587 
5588                     //
5589                     row[grantor]          = right.getGrantor().getName().name;
5590                     row[grantee]          = right.getGrantee().getName().name;
5591                     row[specific_catalog] = database.getCatalogName().name;
5592                     row[specific_schema]  = routine.getSchemaName().name;
5593                     row[specific_name]    = routine.getSpecificName().name;
5594                     row[routine_catalog]  = database.getCatalogName().name;
5595                     row[routine_schema]   = routine.getSchemaName().name;
5596                     row[routine_name]     = routine.getName().name;
5597                     row[privilege_type]   = privilege;
5598                     row[is_grantable] =
5599                         right.getGrantee() == routine.getOwner()
5600                         || grantableRight.canAccessFully(
5601                             GrantConstants.EXECUTE) ? "YES"
5602                                                     : "NO";
5603 
5604                     try {
5605                         t.insertSys(session, store, row);
5606                     } catch (HsqlException e) {}
5607                 }
5608             }
5609         }
5610 
5611         return t;
5612     }
5613 
5614     /**
5615      * SQL:2008 VIEW<p>
5616      *
5617      * The ROUTINE_JAR_USAGE view has one row for each jar archive
5618      * referenced in the body of a Java routine.<p>
5619      *
5620      * <b>Definition:</b><p>
5621      *
5622      *      SPECIFIC_CATALOG    VARCHAR ,
5623      *      SPECIFIC_SCHEMA     VARCHAR ,
5624      *      SPECIFIC_NAME       VARCHAR ,
5625      *      JAR_CATALOG         VARCHAR ,
5626      *      JAR_SCHEMA          VARCHAR ,
5627      *      JAR_NAME            VARCHAR ,
5628      *
5629      * </pre>
5630      *
5631      * <b>Description:</b> <p>
5632      *
5633      * <ol>
5634      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5635      *      SPECIFIC_NAME are the catalog name, schema name,
5636      *      specific routine identifier, respectively. <p>
5637      *
5638      * <li> The values of JAR_CATALOG, JAR_SCHEMA and JAR_NAME are
5639      *      the catalog name, schema name,
5640      *      identifier, and column name, respectively, of a jar
5641      *      reference in the routine body.<>
5642      *
5643      * <1i> Currently 'CLASSPATH' is reported for all entries.
5644      *
5645      * </ol>
5646      *
5647      * @return Table
5648      */
ROUTINE_JAR_USAGE(Session session, PersistentStore store)5649     Table ROUTINE_JAR_USAGE(Session session, PersistentStore store) {
5650 
5651         Table t = sysTables[ROUTINE_JAR_USAGE];
5652 
5653         if (t == null) {
5654             t = createBlankTable(sysTableHsqlNames[ROUTINE_JAR_USAGE]);
5655 
5656             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5657             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5658             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
5659             addColumn(t, "JAR_CATALOG", SQL_IDENTIFIER);
5660             addColumn(t, "JAR_SCHEMA", SQL_IDENTIFIER);
5661             addColumn(t, "JAR_NAME", SQL_IDENTIFIER);
5662 
5663             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5664                 sysTableHsqlNames[ROUTINE_JAR_USAGE].name, false,
5665                 SchemaObject.INDEX);
5666 
5667             t.createPrimaryKeyConstraint(name, new int[] {
5668                 0, 1, 2, 3, 4, 5
5669             }, false);
5670 
5671             return t;
5672         }
5673 
5674         // column number mappings
5675         final int specific_catalog = 0;
5676         final int specific_schema  = 1;
5677         final int specific_name    = 2;
5678         final int jar_catalog      = 3;
5679         final int jar_schema       = 4;
5680         final int jar_name         = 5;
5681 
5682         //
5683         Iterator it;
5684         Object[] row;
5685 
5686         if (!session.isAdmin()) {
5687             return t;
5688         }
5689 
5690         it = database.schemaManager.databaseObjectIterator(
5691             SchemaObject.SPECIFIC_ROUTINE);
5692 
5693         while (it.hasNext()) {
5694             Routine routine = (Routine) it.next();
5695 
5696             if (routine.getLanguage() != Routine.LANGUAGE_JAVA) {
5697                 continue;
5698             }
5699 
5700             row                   = t.getEmptyRowData();
5701             row[specific_catalog] = database.getCatalogName().name;
5702             row[specific_schema]  = routine.getSchemaName().name;
5703             row[specific_name]    = routine.getSpecificName().name;
5704             row[jar_catalog]      = database.getCatalogName().name;
5705             row[jar_schema] =
5706                 database.schemaManager.getSQLJSchemaHsqlName().name;
5707             row[jar_name] = "CLASSPATH";
5708 
5709             t.insertSys(session, store, row);
5710         }
5711 
5712         return t;
5713     }
5714 
5715     /**
5716      * SQL:2008 VIEW<p>
5717      *
5718      * The ROUTINE_ROUTINE_USAGE view has one row for each routine
5719      * referenced in the body of a routine.<p>
5720      *
5721      * <b>Definition:</b><p>
5722      *
5723      *      SPECIFIC_CATALOG    VARCHAR ,
5724      *      SPECIFIC_SCHEMA     VARCHAR ,
5725      *      SPECIFIC_NAME       VARCHAR ,
5726      *      ROUTINE_CATALOG     VARCHAR ,
5727      *      ROUTINE_SCHEMA      VARCHAR ,
5728      *      ROUTINE_NAME        VARCHAR ,
5729      *
5730      * </pre>
5731      *
5732      * <b>Description:</b> <p>
5733      *
5734      * <ol>
5735      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5736      *      SPECIFIC_NAME are the catalog name, schema name,
5737      *      specific routine identifier, respectively, of the routine
5738      *      which contains the reference. <p>
5739      * <li> The values of ROUTINE_CATALOG, ROUTINE_SCHEMA and ROUTINE_NAME
5740      *      are the catalog name, schema name and
5741      *      identifier, respectively, of the routine that is referenced.<p>
5742      *
5743      * <1i> Referenced routines are reported only if the user or one of its roles is
5744      *      the authorization (owner) of the referenced routine.
5745      *
5746      * </ol>
5747      *
5748      * @return Table
5749      */
ROUTINE_ROUTINE_USAGE(Session session, PersistentStore store)5750     Table ROUTINE_ROUTINE_USAGE(Session session, PersistentStore store) {
5751 
5752         Table t = sysTables[ROUTINE_ROUTINE_USAGE];
5753 
5754         if (t == null) {
5755             t = createBlankTable(sysTableHsqlNames[ROUTINE_ROUTINE_USAGE]);
5756 
5757             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5758             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5759             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
5760             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
5761             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
5762             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
5763 
5764             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5765                 sysTableHsqlNames[ROUTINE_ROUTINE_USAGE].name, false,
5766                 SchemaObject.INDEX);
5767 
5768             t.createPrimaryKeyConstraint(name, new int[] {
5769                 0, 1, 2, 3, 4, 5
5770             }, false);
5771 
5772             return t;
5773         }
5774 
5775         // column number mappings
5776         final int specific_catalog = 0;
5777         final int specific_schema  = 1;
5778         final int specific_name    = 2;
5779         final int routine_catalog  = 3;
5780         final int routine_schema   = 4;
5781         final int routine_name     = 5;
5782 
5783         //
5784         Iterator it;
5785         Object[] row;
5786 
5787         it = database.schemaManager.databaseObjectIterator(
5788             SchemaObject.SPECIFIC_ROUTINE);
5789 
5790         while (it.hasNext()) {
5791             Routine        routine = (Routine) it.next();
5792             OrderedHashSet set     = routine.getReferences();
5793 
5794             for (int i = 0; i < set.size(); i++) {
5795                 HsqlName refName = (HsqlName) set.get(i);
5796 
5797                 if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
5798                     continue;
5799                 }
5800 
5801                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
5802                     continue;
5803                 }
5804 
5805                 row                   = t.getEmptyRowData();
5806                 row[specific_catalog] = database.getCatalogName().name;
5807                 row[specific_schema]  = routine.getSchemaName().name;
5808                 row[specific_name]    = routine.getSpecificName().name;
5809                 row[routine_catalog]  = database.getCatalogName().name;
5810                 row[routine_schema]   = refName.schema.name;
5811                 row[routine_name]     = refName.name;
5812 
5813                 try {
5814                     t.insertSys(session, store, row);
5815                 } catch (HsqlException e) {}
5816             }
5817         }
5818 
5819         return t;
5820     }
5821 
5822     /**
5823      * SQL:2008 VIEW<p>
5824      *
5825      * The ROUTINE_SEQUENCE_USAGE view has one row for each SEQUENCE
5826      * referenced in the body of a routine.<p>
5827      *
5828      * <b>Definition:</b><p>
5829      *
5830      *      SPECIFIC_CATALOG    VARCHAR ,
5831      *      SPECIFIC_SCHEMA     VARCHAR ,
5832      *      SPECIFIC_NAME       VARCHAR ,
5833      *      SEQUENCE_CATALOG    VARCHAR ,
5834      *      SEQUENCE_SCHEMA     VARCHAR ,
5835      *      SEQUENCE_NAME       VARCHAR ,
5836      *
5837      * </pre>
5838      *
5839      * <b>Description:</b> <p>
5840      *
5841      * <ol>
5842      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5843      *      SPECIFIC_NAME are the catalog name, schema name,
5844      *      specific routine identifier, respectively, of the routine. <p>
5845      * <li> The values of SEQUENCE_CATALOG, SEQUENCE_SCHEMA and SEQUENCE_NAME
5846      *      are the catalog name, schema name and
5847      *      identifier, respectively, of a SEQUENCE
5848      *      reference in the routine body.<>
5849      *
5850      * <1i> Referenced sequences are reported only if the user or one of its roles is
5851      *      the authorization (owner) of the SEQUENCE.
5852      *
5853      * </ol>
5854      *
5855      * @return Table
5856      */
ROUTINE_SEQUENCE_USAGE(Session session, PersistentStore store)5857     Table ROUTINE_SEQUENCE_USAGE(Session session, PersistentStore store) {
5858 
5859         Table t = sysTables[ROUTINE_SEQUENCE_USAGE];
5860 
5861         if (t == null) {
5862             t = createBlankTable(sysTableHsqlNames[ROUTINE_SEQUENCE_USAGE]);
5863 
5864             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5865             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5866             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
5867             addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
5868             addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
5869             addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);
5870 
5871             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5872                 sysTableHsqlNames[ROUTINE_SEQUENCE_USAGE].name, false,
5873                 SchemaObject.INDEX);
5874 
5875             t.createPrimaryKeyConstraint(name, new int[] {
5876                 0, 1, 2, 3, 4, 5
5877             }, false);
5878 
5879             return t;
5880         }
5881 
5882         // column number mappings
5883         final int specific_catalog = 0;
5884         final int specific_schema  = 1;
5885         final int specific_name    = 2;
5886         final int sequence_catalog = 3;
5887         final int sequence_schema  = 4;
5888         final int sequence_name    = 5;
5889 
5890         //
5891         Iterator it;
5892         Object[] row;
5893 
5894         it = database.schemaManager.databaseObjectIterator(
5895             SchemaObject.SPECIFIC_ROUTINE);
5896 
5897         while (it.hasNext()) {
5898             Routine        routine = (Routine) it.next();
5899             OrderedHashSet set     = routine.getReferences();
5900 
5901             for (int i = 0; i < set.size(); i++) {
5902                 HsqlName refName = (HsqlName) set.get(i);
5903 
5904                 if (refName.type != SchemaObject.SEQUENCE) {
5905                     continue;
5906                 }
5907 
5908                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
5909                     continue;
5910                 }
5911 
5912                 row                   = t.getEmptyRowData();
5913                 row[specific_catalog] = database.getCatalogName().name;
5914                 row[specific_schema]  = routine.getSchemaName().name;
5915                 row[specific_name]    = routine.getSpecificName().name;
5916                 row[sequence_catalog] = database.getCatalogName().name;
5917                 row[sequence_schema]  = refName.schema.name;
5918                 row[sequence_name]    = refName.name;
5919 
5920                 try {
5921                     t.insertSys(session, store, row);
5922                 } catch (HsqlException e) {}
5923             }
5924         }
5925 
5926         return t;
5927     }
5928 
5929     /**
5930      * SQL:2008 VIEW<p>
5931      *
5932      * The ROUTINE_TABLE_USAGE view has one row for each TABLE
5933      * referenced in the body of a routine.<p>
5934      *
5935      * <b>Definition:</b><p>
5936      *
5937      *      SPECIFIC_CATALOG    VARCHAR ,
5938      *      SPECIFIC_SCHEMA     VARCHAR ,
5939      *      SPECIFIC_NAME       VARCHAR ,
5940      *      ROUTINE_CATALOG     VARCHAR ,
5941      *      ROUTINE_SCHEMA      VARCHAR ,
5942      *      ROUTINE_NAME        VARCHAR ,
5943      *      TABLE_CATALOG       VARCHAR ,
5944      *      TABLE_SCHEMA        VARCHAR ,
5945      *      TABLE_NAME          VARCHAR ,
5946      *
5947      * </pre>
5948      *
5949      * <b>Description:</b> <p>
5950      *
5951      * <ol>
5952      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
5953      *      SPECIFIC_NAME are the catalog name, schema name,
5954      *      specific routine identifier, respectively, of the routine. <p>
5955      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA and TABLE_NAME
5956      *      are the catalog name, schema name and
5957      *      identifier, respectively, of a TABLE
5958      *      reference in the routine body.<>
5959      *
5960      * <1i> Tables are reported only if the user or one of its roles is
5961      *      the authorization (owner) of the TABLE.
5962      *
5963      * </ol>
5964      *
5965      * @return Table
5966      */
ROUTINE_TABLE_USAGE(Session session, PersistentStore store)5967     Table ROUTINE_TABLE_USAGE(Session session, PersistentStore store) {
5968 
5969         Table t = sysTables[ROUTINE_TABLE_USAGE];
5970 
5971         if (t == null) {
5972             t = createBlankTable(sysTableHsqlNames[ROUTINE_TABLE_USAGE]);
5973 
5974             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
5975             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
5976             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
5977             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
5978             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
5979             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
5980             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
5981             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
5982             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
5983 
5984             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
5985                 sysTableHsqlNames[ROUTINE_TABLE_USAGE].name, false,
5986                 SchemaObject.INDEX);
5987 
5988             t.createPrimaryKeyConstraint(name, new int[] {
5989                 3, 4, 5, 0, 1, 2, 6, 7, 8
5990             }, false);
5991 
5992             return t;
5993         }
5994 
5995         // column number mappings
5996         final int specific_catalog = 0;
5997         final int specific_schema  = 1;
5998         final int specific_name    = 2;
5999         final int routine_catalog  = 3;
6000         final int routine_schema   = 4;
6001         final int routine_name     = 5;
6002         final int table_catalog    = 6;
6003         final int table_schema     = 7;
6004         final int table_name       = 8;
6005 
6006         //
6007         Iterator it;
6008         Object[] row;
6009 
6010         it = database.schemaManager.databaseObjectIterator(
6011             SchemaObject.SPECIFIC_ROUTINE);
6012 
6013         while (it.hasNext()) {
6014             Routine        routine = (Routine) it.next();
6015             OrderedHashSet set     = routine.getReferences();
6016 
6017             for (int i = 0; i < set.size(); i++) {
6018                 HsqlName refName = (HsqlName) set.get(i);
6019 
6020                 if (refName.type != SchemaObject.TABLE
6021                         && refName.type != SchemaObject.VIEW) {
6022                     continue;
6023                 }
6024 
6025                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
6026                     continue;
6027                 }
6028 
6029                 row                   = t.getEmptyRowData();
6030                 row[specific_catalog] = database.getCatalogName().name;
6031                 row[specific_schema]  = routine.getSchemaName().name;
6032                 row[specific_name]    = routine.getSpecificName().name;
6033                 row[routine_catalog]  = database.getCatalogName().name;
6034                 row[routine_schema]   = routine.getSchemaName().name;
6035                 row[routine_name]     = routine.getName().name;
6036                 row[table_catalog]    = database.getCatalogName().name;
6037                 row[table_schema]     = refName.schema.name;
6038                 row[table_name]       = refName.name;
6039 
6040                 try {
6041                     t.insertSys(session, store, row);
6042                 } catch (HsqlException e) {}
6043             }
6044         }
6045 
6046         return t;
6047     }
6048 
6049     /**
6050      * SQL:2008 VIEW<p>
6051      *
6052      * The ROUTINES view has one row for each PROCEDURE and FUNCTION.<p>
6053      *
6054      */
ROUTINES(Session session, PersistentStore store)6055     Table ROUTINES(Session session, PersistentStore store) {
6056 
6057         Table t = sysTables[ROUTINES];
6058 
6059         if (t == null) {
6060             t = createBlankTable(sysTableHsqlNames[ROUTINES]);
6061 
6062             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
6063             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
6064             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
6065             addColumn(t, "ROUTINE_CATALOG", SQL_IDENTIFIER);
6066             addColumn(t, "ROUTINE_SCHEMA", SQL_IDENTIFIER);
6067             addColumn(t, "ROUTINE_NAME", SQL_IDENTIFIER);
6068             addColumn(t, "ROUTINE_TYPE", CHARACTER_DATA);
6069             addColumn(t, "MODULE_CATALOG", SQL_IDENTIFIER);
6070             addColumn(t, "MODULE_SCHEMA", SQL_IDENTIFIER);
6071             addColumn(t, "MODULE_NAME", SQL_IDENTIFIER);
6072             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
6073             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
6074             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
6075             addColumn(t, "DATA_TYPE", CHARACTER_DATA);
6076             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
6077             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
6078             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
6079             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
6080             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
6081             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
6082             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);          //
6083             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
6084             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);        //
6085             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
6086             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
6087             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
6088             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
6089             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
6090             addColumn(t, "TYPE_UDT_CATALOG", SQL_IDENTIFIER);
6091             addColumn(t, "TYPE_UDT_SCHEMA", SQL_IDENTIFIER);
6092             addColumn(t, "TYPE_UDT_NAME", SQL_IDENTIFIER);
6093             addColumn(t, "SCOPE_CATALOG", SQL_IDENTIFIER);
6094             addColumn(t, "SCOPE_SCHEMA", SQL_IDENTIFIER);
6095             addColumn(t, "SCOPE_NAME", SQL_IDENTIFIER);                //
6096             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);      // (only for array tyes)
6097             addColumn(t, "DTD_IDENTIFIER", SQL_IDENTIFIER);
6098             addColumn(t, "ROUTINE_BODY", CHARACTER_DATA);
6099             addColumn(t, "ROUTINE_DEFINITION", CHARACTER_DATA);
6100             addColumn(t, "EXTERNAL_NAME", CHARACTER_DATA);
6101             addColumn(t, "EXTERNAL_LANGUAGE", CHARACTER_DATA);
6102             addColumn(t, "PARAMETER_STYLE", CHARACTER_DATA);
6103             addColumn(t, "IS_DETERMINISTIC", YES_OR_NO);
6104             addColumn(t, "SQL_DATA_ACCESS", CHARACTER_DATA);
6105             addColumn(t, "IS_NULL_CALL", YES_OR_NO);
6106             addColumn(t, "SQL_PATH", CHARACTER_DATA);
6107             addColumn(t, "SCHEMA_LEVEL_ROUTINE", YES_OR_NO);           //
6108             addColumn(t, "MAX_DYNAMIC_RESULT_SETS", CARDINAL_NUMBER);
6109             addColumn(t, "IS_USER_DEFINED_CAST", YES_OR_NO);
6110             addColumn(t, "IS_IMPLICITLY_INVOCABLE", YES_OR_NO);
6111             addColumn(t, "SECURITY_TYPE", CHARACTER_DATA);
6112             addColumn(t, "TO_SQL_SPECIFIC_CATALOG", SQL_IDENTIFIER);
6113             addColumn(t, "TO_SQL_SPECIFIC_SCHEMA", SQL_IDENTIFIER);    //
6114             addColumn(t, "TO_SQL_SPECIFIC_NAME", SQL_IDENTIFIER);
6115             addColumn(t, "AS_LOCATOR", YES_OR_NO);
6116             addColumn(t, "CREATED", TIME_STAMP);
6117             addColumn(t, "LAST_ALTERED", TIME_STAMP);
6118             addColumn(t, "NEW_SAVEPOINT_LEVEL", YES_OR_NO);
6119             addColumn(t, "IS_UDT_DEPENDENT", YES_OR_NO);
6120             addColumn(t, "RESULT_CAST_FROM_DATA_TYPE", CHARACTER_DATA);
6121             addColumn(t, "RESULT_CAST_AS_LOCATOR", YES_OR_NO);
6122             addColumn(t, "RESULT_CAST_CHAR_MAX_LENGTH", CARDINAL_NUMBER);
6123             addColumn(t, "RESULT_CAST_CHAR_OCTET_LENGTH", CARDINAL_NUMBER);
6124             addColumn(t, "RESULT_CAST_CHAR_SET_CATALOG", CHARACTER_DATA);
6125             addColumn(t, "RESULT_CAST_CHAR_SET_SCHEMA", SQL_IDENTIFIER);
6126             addColumn(t, "RESULT_CAST_CHARACTER_SET_NAME", SQL_IDENTIFIER);
6127             addColumn(t, "RESULT_CAST_COLLATION_CATALOG", SQL_IDENTIFIER);
6128             addColumn(t, "RESULT_CAST_COLLATION_SCHEMA", SQL_IDENTIFIER);
6129             addColumn(t, "RESULT_CAST_COLLATION_NAME", SQL_IDENTIFIER);
6130             addColumn(t, "RESULT_CAST_NUMERIC_PRECISION", CARDINAL_NUMBER);
6131             addColumn(t, "RESULT_CAST_NUMERIC_RADIX", CARDINAL_NUMBER);
6132             addColumn(t, "RESULT_CAST_NUMERIC_SCALE", CARDINAL_NUMBER);
6133             addColumn(t, "RESULT_CAST_DATETIME_PRECISION", CARDINAL_NUMBER);
6134             addColumn(t, "RESULT_CAST_INTERVAL_TYPE", CHARACTER_DATA);
6135             addColumn(t, "RESULT_CAST_INTERVAL_PRECISION", CARDINAL_NUMBER);
6136             addColumn(t, "RESULT_CAST_TYPE_UDT_CATALOG", SQL_IDENTIFIER);
6137             addColumn(t, "RESULT_CAST_TYPE_UDT_SCHEMA", SQL_IDENTIFIER);
6138             addColumn(t, "RESULT_CAST_TYPE_UDT_NAME", SQL_IDENTIFIER);
6139             addColumn(t, "RESULT_CAST_SCOPE_CATALOG", SQL_IDENTIFIER);
6140             addColumn(t, "RESULT_CAST_SCOPE_SCHEMA", SQL_IDENTIFIER);
6141             addColumn(t, "RESULT_CAST_SCOPE_NAME", SQL_IDENTIFIER);
6142             addColumn(t, "RESULT_CAST_MAX_CARDINALITY", CARDINAL_NUMBER);
6143             addColumn(t, "RESULT_CAST_DTD_IDENTIFIER", CHARACTER_DATA);
6144             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
6145             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
6146             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
6147             addColumn(t, "RESULT_CAST_FROM_DECLARED_DATA_TYPE",
6148                       CHARACTER_DATA);
6149             addColumn(t, "RESULT_CAST_DECLARED_NUMERIC_PRECISION",
6150                       CARDINAL_NUMBER);
6151             addColumn(t, "RESULT_CAST_DECLARED_NUMERIC_SCALE",
6152                       CARDINAL_NUMBER);
6153 
6154             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6155                 sysTableHsqlNames[ROUTINES].name, false, SchemaObject.INDEX);
6156 
6157             t.createPrimaryKeyConstraint(name, new int[] {
6158                 3, 4, 5, 0, 1, 2
6159             }, false);
6160 
6161             return t;
6162         }
6163 
6164         // column number mappings
6165         final int specific_catalog                       = 0;
6166         final int specific_schema                        = 1;
6167         final int specific_name                          = 2;
6168         final int routine_catalog                        = 3;
6169         final int routine_schema                         = 4;
6170         final int routine_name                           = 5;
6171         final int routine_type                           = 6;
6172         final int module_catalog                         = 7;
6173         final int module_schema                          = 8;
6174         final int module_name                            = 9;
6175         final int udt_catalog                            = 10;
6176         final int udt_schema                             = 11;
6177         final int udt_name                               = 12;
6178         final int data_type                              = 13;
6179         final int character_maximum_length               = 14;
6180         final int character_octet_length                 = 15;
6181         final int character_set_catalog                  = 16;
6182         final int character_set_schema                   = 17;
6183         final int character_set_name                     = 18;
6184         final int collation_catalog                      = 19;
6185         final int collation_schema                       = 20;
6186         final int collation_name                         = 21;
6187         final int numeric_precision                      = 22;
6188         final int numeric_precision_radix                = 23;
6189         final int numeric_scale                          = 24;
6190         final int datetime_precision                     = 25;
6191         final int interval_type                          = 26;
6192         final int interval_precision                     = 27;
6193         final int type_udt_catalog                       = 28;
6194         final int type_udt_schema                        = 29;
6195         final int type_udt_name                          = 30;
6196         final int scope_catalog                          = 31;
6197         final int scope_schema                           = 32;
6198         final int scope_name                             = 33;
6199         final int maximum_cardinality                    = 34;
6200         final int dtd_identifier                         = 35;
6201         final int routine_body                           = 36;
6202         final int routine_definition                     = 37;
6203         final int external_name                          = 38;
6204         final int external_language                      = 39;
6205         final int parameter_style                        = 40;
6206         final int is_deterministic                       = 41;
6207         final int sql_data_access                        = 42;
6208         final int is_null_call                           = 43;
6209         final int sql_path                               = 44;
6210         final int schema_level_routine                   = 45;
6211         final int max_dynamic_result_sets                = 46;
6212         final int is_user_defined_cast                   = 47;
6213         final int is_implicitly_invocable                = 48;
6214         final int security_type                          = 49;
6215         final int to_sql_specific_catalog                = 50;
6216         final int to_sql_specific_schema                 = 51;
6217         final int to_sql_specific_name                   = 52;
6218         final int as_locator                             = 53;
6219         final int created                                = 54;
6220         final int last_altered                           = 55;
6221         final int new_savepoint_level                    = 56;
6222         final int is_udt_dependent                       = 57;
6223         final int result_cast_from_data_type             = 58;
6224         final int result_cast_as_locator                 = 59;
6225         final int result_cast_char_max_length            = 60;
6226         final int result_cast_char_octet_length          = 61;
6227         final int result_cast_char_set_catalog           = 62;
6228         final int result_cast_char_set_schema            = 63;
6229         final int result_cast_character_set_name         = 64;
6230         final int result_cast_collation_catalog          = 65;
6231         final int result_cast_collation_schema           = 66;
6232         final int result_cast_collation_name             = 67;
6233         final int result_cast_numeric_precision          = 68;
6234         final int result_cast_numeric_radix              = 69;
6235         final int result_cast_numeric_scale              = 70;
6236         final int result_cast_datetime_precision         = 71;
6237         final int result_cast_interval_type              = 72;
6238         final int result_cast_interval_precision         = 73;
6239         final int result_cast_type_udt_catalog           = 74;
6240         final int result_cast_type_udt_schema            = 75;
6241         final int result_cast_type_udt_name              = 76;
6242         final int result_cast_scope_catalog              = 77;
6243         final int result_cast_scope_schema               = 78;
6244         final int result_cast_scope_name                 = 79;
6245         final int result_cast_max_cardinality            = 80;
6246         final int result_cast_dtd_identifier             = 81;
6247         final int declared_data_type                     = 82;
6248         final int declared_numeric_precision             = 83;
6249         final int declared_numeric_scale                 = 84;
6250         final int result_cast_from_declared_data_type    = 85;
6251         final int result_cast_declared_numeric_precision = 86;
6252         final int result_cast_declared_numeric_scale     = 87;
6253 
6254         //
6255         Iterator it;
6256         Object[] row;
6257 
6258         it = database.schemaManager.databaseObjectIterator(
6259             SchemaObject.SPECIFIC_ROUTINE);
6260 
6261         while (it.hasNext()) {
6262             Routine routine = (Routine) it.next();
6263             boolean isFullyAccessible;
6264 
6265             if (!session.getGrantee().isAccessible(routine)) {
6266                 continue;
6267             }
6268 
6269             isFullyAccessible = session.getGrantee().isFullyAccessibleByRole(
6270                 routine.getName());
6271             row = t.getEmptyRowData();
6272 
6273             Type type = routine.isProcedure() ? null
6274                                               : routine.getReturnType();
6275 
6276             //
6277             row[specific_catalog] = database.getCatalogName().name;
6278             row[specific_schema]  = routine.getSchemaName().name;
6279             row[specific_name]    = routine.getSpecificName().name;
6280             row[routine_catalog]  = database.getCatalogName().name;
6281             row[routine_schema]   = routine.getSchemaName().name;
6282             row[routine_name]     = routine.getName().name;
6283             row[routine_type]     = routine.isProcedure() ? Tokens.T_PROCEDURE
6284                                                           : Tokens.T_FUNCTION;
6285             row[module_catalog]   = null;
6286             row[module_schema]    = null;
6287             row[module_name]      = null;
6288             row[udt_catalog]      = null;
6289             row[udt_schema]       = null;
6290             row[udt_name]         = null;
6291             row[data_type]        = type == null ? null
6292                                                  : type.getNameString();
6293 
6294             if (type != null) {
6295 
6296                 // common type block
6297                 if (type.isCharacterType()) {
6298                     row[character_maximum_length] =
6299                         ValuePool.getLong(type.precision);
6300                     row[character_octet_length] =
6301                         ValuePool.getLong(type.precision * 2);
6302                     row[character_set_catalog] =
6303                         database.getCatalogName().name;
6304                     row[character_set_schema] =
6305                         type.getCharacterSet().getSchemaName().name;
6306                     row[character_set_name] =
6307                         type.getCharacterSet().getName().name;
6308                     row[collation_catalog] = database.getCatalogName().name;
6309                     row[collation_schema] =
6310                         type.getCollation().getSchemaName().name;
6311                     row[collation_name] = type.getCollation().getName().name;
6312                 } else if (type.isNumberType()) {
6313                     row[numeric_precision] = ValuePool.getLong(
6314                         ((NumberType) type).getNumericPrecisionInRadix());
6315                     row[declared_numeric_precision] = ValuePool.getLong(
6316                         ((NumberType) type).getNumericPrecisionInRadix());
6317 
6318                     if (type.isExactNumberType()) {
6319                         row[numeric_scale] = row[declared_numeric_scale] =
6320                             ValuePool.getLong(type.scale);
6321                     }
6322 
6323                     row[numeric_precision_radix] =
6324                         ValuePool.getLong(type.getPrecisionRadix());
6325                 } else if (type.isBooleanType()) {
6326 
6327                     //
6328                 } else if (type.isDateTimeType()) {
6329                     row[datetime_precision] = ValuePool.getLong(type.scale);
6330                 } else if (type.isIntervalType()) {
6331                     row[data_type] = "INTERVAL";
6332                     row[interval_type] =
6333                         IntervalType.getQualifier(type.typeCode);
6334                     row[interval_precision] =
6335                         ValuePool.getLong(type.precision);
6336                     row[datetime_precision] = ValuePool.getLong(type.scale);
6337                 } else if (type.isBinaryType()) {
6338                     row[character_maximum_length] =
6339                         ValuePool.getLong(type.precision);
6340                     row[character_octet_length] =
6341                         ValuePool.getLong(type.precision);
6342                 } else if (type.isBitType()) {
6343                     row[character_maximum_length] =
6344                         ValuePool.getLong(type.precision);
6345                     row[character_octet_length] =
6346                         ValuePool.getLong(type.precision);
6347                 } else if (type.isArrayType()) {
6348                     row[maximum_cardinality] =
6349                         ValuePool.getLong(type.arrayLimitCardinality());
6350                     row[data_type] = "ARRAY";
6351                 }
6352 
6353                 row[dtd_identifier]     = type.getDefinition();
6354                 row[declared_data_type] = row[data_type];
6355 
6356                 // end common block
6357             }
6358 
6359             row[type_udt_catalog] = null;
6360             row[type_udt_schema]  = null;
6361             row[type_udt_name]    = null;
6362             row[scope_catalog]    = null;
6363             row[scope_schema]     = null;
6364             row[scope_name]       = null;
6365             row[routine_body] = routine.getLanguage() == Routine.LANGUAGE_JAVA
6366                                 ? "EXTERNAL"
6367                                 : "SQL";
6368             row[routine_definition] = isFullyAccessible ? routine.getSQL()
6369                                                         : null;
6370             row[external_name]      = routine.getExternalName();
6371             row[external_language] = routine.getLanguage()
6372                                      == Routine.LANGUAGE_JAVA ? "JAVA"
6373                                                               : null;
6374             row[parameter_style] = routine.getLanguage()
6375                                    == Routine.LANGUAGE_JAVA ? "JAVA"
6376                                                             : null;
6377             row[is_deterministic] = routine.isDeterministic() ? "YES"
6378                                                               : "NO";
6379             row[sql_data_access]  = routine.getDataImpactString();
6380             row[is_null_call]     = type == null ? null
6381                                                  : routine.isNullInputOutput()
6382                                                    ? "YES"
6383                                                    : "NO";
6384             row[sql_path]                               = null;
6385             row[schema_level_routine]                   = "YES";
6386             row[max_dynamic_result_sets]                = ValuePool.getLong(0);
6387             row[is_user_defined_cast]                   = type == null ? null
6388                                                                        : "NO";
6389             row[is_implicitly_invocable]                = null;
6390             row[security_type]                          = "DEFINER";
6391             row[to_sql_specific_catalog]                = null;
6392             row[to_sql_specific_schema]                 = null;
6393             row[to_sql_specific_name]                   = null;
6394             row[as_locator]                             = type == null ? null
6395                                                                        : "NO";
6396             row[created]                                = null;
6397             row[last_altered]                           = null;
6398             row[new_savepoint_level]                    = "YES";
6399             row[is_udt_dependent]                       = null;
6400             row[result_cast_from_data_type]             = null;
6401             row[result_cast_as_locator]                 = null;
6402             row[result_cast_char_max_length]            = null;
6403             row[result_cast_char_octet_length]          = null;
6404             row[result_cast_char_set_catalog]           = null;
6405             row[result_cast_char_set_schema]            = null;
6406             row[result_cast_character_set_name]         = null;
6407             row[result_cast_collation_catalog]          = null;
6408             row[result_cast_collation_schema]           = null;
6409             row[result_cast_collation_name]             = null;
6410             row[result_cast_numeric_precision]          = null;
6411             row[result_cast_numeric_radix]              = null;
6412             row[result_cast_numeric_scale]              = null;
6413             row[result_cast_datetime_precision]         = null;
6414             row[result_cast_interval_type]              = null;
6415             row[result_cast_interval_precision]         = null;
6416             row[result_cast_type_udt_catalog]           = null;
6417             row[result_cast_type_udt_schema]            = null;
6418             row[result_cast_type_udt_name]              = null;
6419             row[result_cast_scope_catalog]              = null;
6420             row[result_cast_scope_schema]               = null;
6421             row[result_cast_scope_name]                 = null;
6422             row[result_cast_max_cardinality]            = null;
6423             row[result_cast_dtd_identifier]             = null;
6424             row[declared_data_type]                     = row[data_type];
6425             row[declared_numeric_precision] = row[numeric_precision];
6426             row[declared_numeric_scale]                 = row[numeric_scale];
6427             row[result_cast_from_declared_data_type]    = null;
6428             row[result_cast_declared_numeric_precision] = null;
6429             row[result_cast_declared_numeric_scale]     = null;
6430 
6431             t.insertSys(session, store, row);
6432         }
6433 
6434         return t;
6435     }
6436 
6437     /**
6438      * SQL:2008 VIEW<p>
6439      *
6440      * The SCHEMATA view has one row for each accessible schema. <p>
6441      *
6442      * <b>Definition:</b><p>
6443      *
6444      *      CATALOG_NAME                       VARCHAR ,
6445      *      SCHEMA_NAME                        VARCHAR ,
6446      *      SCHEMA_OWNER                       VARCHAR ,
6447      *      DEFAULT_CHARACTER_SET_CATALOG      VARCHAR ,
6448      *      DEFAULT_CHARACTER_SET_SCHEMA       VARCHAR ,
6449      *      DEFAULT_CHARACTER_SET_NAME         VARCHAR ,
6450      *      SQL_PATH                           VARCHAR ,
6451      *
6452      * </pre>
6453      *
6454      * <b>Description</b><p>
6455      *
6456      * <ol>
6457      *      <li>The value of CATALOG_NAME is the name of the catalog of the
6458      *          schema described by this row.<p>
6459      *
6460      *      <li>The value of SCHEMA_NAME is the schema name of
6461      *          the schema described by this row.<p>
6462      *
6463      *      <li>The values of SCHEMA_OWNER are the authorization identifiers
6464      *          that own the schemata.<p>
6465      *
6466      *      <li>The values of DEFAULT_CHARACTER_SET_CATALOG,
6467      *          DEFAULT_CHARACTER_SET_SCHEMA, and DEFAULT_CHARACTER_SET_NAME
6468      *          are the catalog name, schema name, and qualified
6469      *          identifier, respectively, of the default character set for
6470      *          columns and domains in the schemata.<p>
6471      *
6472      *      <li>Case:<p>
6473      *          <ul>
6474      *              <li>If &lt;schema path specification&gt; was specified in
6475      *                  the &lt;schema definition&gt; that defined the schema
6476      *                  described by this row and the character representation
6477      *                  of the &lt;schema path specification&gt; can be
6478      *                  represented without truncation, then the value of
6479      *                  SQL_PATH is that character representation.<p>
6480      *
6481      *              <li>Otherwise, the value of SQL_PATH is the null value.
6482      *         </ul>
6483      * </ol>
6484      *
6485      * @return Table
6486      */
SCHEMATA(Session session, PersistentStore store)6487     Table SCHEMATA(Session session, PersistentStore store) {
6488 
6489         Table t = sysTables[SCHEMATA];
6490 
6491         if (t == null) {
6492             t = createBlankTable(sysTableHsqlNames[SCHEMATA]);
6493 
6494             addColumn(t, "CATALOG_NAME", SQL_IDENTIFIER);
6495             addColumn(t, "SCHEMA_NAME", SQL_IDENTIFIER);
6496             addColumn(t, "SCHEMA_OWNER", SQL_IDENTIFIER);
6497             addColumn(t, "DEFAULT_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
6498             addColumn(t, "DEFAULT_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
6499             addColumn(t, "DEFAULT_CHARACTER_SET_NAME", SQL_IDENTIFIER);
6500             addColumn(t, "SQL_PATH", CHARACTER_DATA);
6501 
6502             // order: CATALOG_NAME, SCHEMA_NAME
6503             // false PK, as rows may have NULL CATALOG_NAME
6504             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6505                 sysTableHsqlNames[SCHEMATA].name, false, SchemaObject.INDEX);
6506 
6507             t.createPrimaryKeyConstraint(name, new int[] {
6508                 0, 1
6509             }, false);
6510 
6511             return t;
6512         }
6513 
6514         // Intermediate holders
6515         Schema[] schemas;
6516         Schema   schema;
6517         String   dcsSchema = SqlInvariants.INFORMATION_SCHEMA;
6518         String   dcsName   = "SQL_TEXT";
6519         String   sqlPath   = null;
6520         Grantee  user      = session.getGrantee();
6521         Object[] row;
6522 
6523         // column number mappings
6524         final int schema_catalog                = 0;
6525         final int schema_name                   = 1;
6526         final int schema_owner                  = 2;
6527         final int default_character_set_catalog = 3;
6528         final int default_character_set_schema  = 4;
6529         final int default_character_set_name    = 5;
6530         final int sql_path                      = 6;
6531 
6532         // Initialization
6533         schemas = database.schemaManager.getAllSchemas();
6534 
6535         // Do it.
6536         for (int i = 0; i < schemas.length; i++) {
6537             schema = schemas[i];
6538 
6539             if (!user.hasSchemaUpdateOrGrantRights(
6540                     schema.getName().getNameString())) {
6541                 continue;
6542             }
6543 
6544             row                 = t.getEmptyRowData();
6545             row[schema_catalog] = database.getCatalogName().name;
6546             row[schema_name]    = schema.getName().getNameString();
6547             row[schema_owner]   = schema.getOwner().getName().getNameString();
6548             row[default_character_set_catalog] =
6549                 database.getCatalogName().name;
6550             row[default_character_set_schema] = dcsSchema;
6551             row[default_character_set_name]   = dcsName;
6552             row[sql_path]                     = sqlPath;
6553 
6554             t.insertSys(session, store, row);
6555         }
6556 
6557         return t;
6558     }
6559 
6560     /**
6561      * SQL:2008 VIEW<p>
6562      *
6563      * The SQL_FEATURES view lists the individual features of the SQL Standard
6564      * supported by HyperSQL.<p>
6565      *
6566      */
SQL_FEATURES(Session session, PersistentStore store)6567     Table SQL_FEATURES(Session session, PersistentStore store) {
6568 
6569         Table t = sysTables[SQL_FEATURES];
6570 
6571         if (t == null) {
6572             t = createBlankTable(sysTableHsqlNames[SQL_FEATURES]);
6573 
6574             addColumn(t, "FEATURE_ID", CHARACTER_DATA);
6575             addColumn(t, "FEATURE_NAME", CHARACTER_DATA);
6576             addColumn(t, "SUB_FEATURE_ID", CHARACTER_DATA);
6577             addColumn(t, "SUB_FEATURE_NAME", CHARACTER_DATA);
6578             addColumn(t, "IS_SUPPORTED", YES_OR_NO);
6579             addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
6580             addColumn(t, "COMMENTS", CHARACTER_DATA);
6581 
6582             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6583                 sysTableHsqlNames[SQL_FEATURES].name, false,
6584                 SchemaObject.INDEX);
6585 
6586             t.createPrimaryKeyConstraint(name, new int[] {
6587                 0, 2
6588             }, false);
6589 
6590             return t;
6591         }
6592 
6593         Session sys = database.sessionManager.newSysSession(
6594             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
6595         String sql = (String) statementMap.get("/*sql_features*/");
6596         Result rs  = sys.executeDirectStatement(sql);
6597 
6598         t.insertSys(session, store, rs);
6599 
6600         return t;
6601     }
6602 
6603     /**
6604      * SQL:2008 VIEW<p>
6605      *
6606      * The SQL_IMPLEMENTATION_INFO shows some properties and capabilities
6607      * of the database engine .<p>
6608      *
6609      */
SQL_IMPLEMENTATION_INFO(Session session, PersistentStore store)6610     Table SQL_IMPLEMENTATION_INFO(Session session, PersistentStore store) {
6611 
6612         Table t = sysTables[SQL_IMPLEMENTATION_INFO];
6613 
6614         if (t == null) {
6615             t = createBlankTable(sysTableHsqlNames[SQL_IMPLEMENTATION_INFO]);
6616 
6617             addColumn(t, "IMPLEMENTATION_INFO_ID", CARDINAL_NUMBER);
6618             addColumn(t, "IMPLEMENTATION_INFO_NAME", CHARACTER_DATA);
6619             addColumn(t, "INTEGER_VALUE", CARDINAL_NUMBER);
6620             addColumn(t, "CHARACTER_VALUE", CHARACTER_DATA);
6621             addColumn(t, "COMMENTS", CHARACTER_DATA);
6622 
6623             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6624                 sysTableHsqlNames[SQL_IMPLEMENTATION_INFO].name, false,
6625                 SchemaObject.INDEX);
6626 
6627             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
6628 
6629             return t;
6630         }
6631 
6632         Session sys = database.sessionManager.newSysSession(
6633             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
6634         String sql = (String) statementMap.get("/*sql_implementation_info*/");
6635         Result rs  = sys.executeDirectStatement(sql);
6636 
6637         t.insertSys(session, store, rs);
6638 
6639         return t;
6640     }
6641 
6642     /**
6643      * SQL:2008 VIEW<p>
6644      *
6645      * The SQL_PACHAGES view lists the packages of the SQL Standard supported by
6646      * HyperSQL.<p>
6647      *
6648      */
SQL_PACKAGES(Session session, PersistentStore store)6649     Table SQL_PACKAGES(Session session, PersistentStore store) {
6650 
6651         Table t = sysTables[SQL_PACKAGES];
6652 
6653         if (t == null) {
6654             t = createBlankTable(sysTableHsqlNames[SQL_PACKAGES]);
6655 
6656             addColumn(t, "ID", CHARACTER_DATA);
6657             addColumn(t, "NAME", CHARACTER_DATA);
6658             addColumn(t, "IS_SUPPORTED", YES_OR_NO);
6659             addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
6660             addColumn(t, "COMMENTS", CHARACTER_DATA);
6661 
6662             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6663                 sysTableHsqlNames[SQL_PACKAGES].name, false,
6664                 SchemaObject.INDEX);
6665 
6666             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
6667 
6668             return t;
6669         }
6670 
6671         Session sys = database.sessionManager.newSysSession(
6672             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
6673         String sql = (String) statementMap.get("/*sql_packages*/");
6674         Result rs  = sys.executeDirectStatement(sql);
6675 
6676         t.insertSys(session, store, rs);
6677 
6678         return t;
6679     }
6680 
6681     /**
6682      * SQL:2008 VIEW<p>
6683      *
6684      * The SQL_PARTS view lists the parts of the SQL Standard supported by
6685      * HyperSQL.<p>
6686      *
6687      */
SQL_PARTS(Session session, PersistentStore store)6688     Table SQL_PARTS(Session session, PersistentStore store) {
6689 
6690         Table t = sysTables[SQL_PARTS];
6691 
6692         if (t == null) {
6693             t = createBlankTable(sysTableHsqlNames[SQL_PARTS]);
6694 
6695             addColumn(t, "PART", CHARACTER_DATA);
6696             addColumn(t, "NAME", CHARACTER_DATA);
6697             addColumn(t, "IS_SUPPORTED", YES_OR_NO);
6698             addColumn(t, "IS_VERIFIED_BY", CHARACTER_DATA);
6699             addColumn(t, "COMMENTS", CHARACTER_DATA);
6700 
6701             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6702                 sysTableHsqlNames[SQL_PARTS].name, false, SchemaObject.INDEX);
6703 
6704             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
6705 
6706             return t;
6707         }
6708 
6709         Session sys = database.sessionManager.newSysSession(
6710             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
6711         String sql = (String) statementMap.get("/*sql_parts*/");
6712         Result rs  = sys.executeDirectStatement(sql);
6713 
6714         t.insertSys(session, store, rs);
6715 
6716         return t;
6717     }
6718 
6719     /**
6720      * SQL:2008 VIEW<p>
6721      *
6722      * The SQL_SIZING view has one row for the maximum size of each built in
6723      * type supported by HyperSQL.<p>
6724      *
6725      */
SQL_SIZING(Session session, PersistentStore store)6726     Table SQL_SIZING(Session session, PersistentStore store) {
6727 
6728         Table t = sysTables[SQL_SIZING];
6729 
6730         if (t == null) {
6731             t = createBlankTable(sysTableHsqlNames[SQL_SIZING]);
6732 
6733             addColumn(t, "SIZING_ID", CARDINAL_NUMBER);
6734             addColumn(t, "SIZING_NAME", CHARACTER_DATA);
6735             addColumn(t, "SUPPORTED_VALUE", CARDINAL_NUMBER);
6736             addColumn(t, "COMMENTS", CHARACTER_DATA);
6737 
6738             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6739                 sysTableHsqlNames[SQL_SIZING].name, false, SchemaObject.INDEX);
6740 
6741             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
6742 
6743             return t;
6744         }
6745 
6746         Session sys = database.sessionManager.newSysSession(
6747             SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, session.getUser());
6748         String sql = (String) statementMap.get("/*sql_sizing*/");
6749         Result rs  = sys.executeDirectStatement(sql);
6750 
6751         t.insertSys(session, store, rs);
6752 
6753         return t;
6754     }
6755 
6756     /**
6757      * SQL:2008 VIEW<p>
6758      *
6759      * The SQL_SIZING_PROFILES is empty.<p>
6760      *
6761      */
SQL_SIZING_PROFILES(Session session, PersistentStore store)6762     Table SQL_SIZING_PROFILES(Session session, PersistentStore store) {
6763 
6764         Table t = sysTables[SQL_SIZING_PROFILES];
6765 
6766         if (t == null) {
6767             t = createBlankTable(sysTableHsqlNames[SQL_SIZING_PROFILES]);
6768 
6769             addColumn(t, "SIZING_ID", CARDINAL_NUMBER);
6770             addColumn(t, "SIZING_NAME", CHARACTER_DATA);
6771             addColumn(t, "PROFILE_ID", CARDINAL_NUMBER);
6772             addColumn(t, "PROFILE_NAME", CHARACTER_DATA);
6773             addColumn(t, "REQUIRED_VALUE", CARDINAL_NUMBER);
6774             addColumn(t, "COMMENTS", CHARACTER_DATA);
6775 
6776             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6777                 sysTableHsqlNames[SQL_SIZING_PROFILES].name, false,
6778                 SchemaObject.INDEX);
6779 
6780             t.createPrimaryKeyConstraint(name, new int[]{ 0 }, false);
6781 
6782             return t;
6783         }
6784 
6785         return t;
6786     }
6787 
6788     /**
6789      * The TABLE_CONSTRAINTS table has one row for each table constraint
6790      * associated with a table.  <p>
6791      *
6792      * It effectively contains a representation of the table constraint
6793      * descriptors. <p>
6794      *
6795      * <b>Definition:</b> <p>
6796      *
6797      * <pre class="SqlCodeExample">
6798      * CREATE TABLE SYSTEM_TABLE_CONSTRAINTS (
6799      *      CONSTRAINT_CATALOG      VARCHAR NULL,
6800      *      CONSTRAINT_SCHEMA       VARCHAR NULL,
6801      *      CONSTRAINT_NAME         VARCHAR NOT NULL,
6802      *      CONSTRAINT_TYPE         VARCHAR NOT NULL,
6803      *      TABLE_CATALOG           VARCHAR NULL,
6804      *      TABLE_SCHEMA            VARCHAR NULL,
6805      *      TABLE_NAME              VARCHAR NOT NULL,
6806      *      IS_DEFERRABLE           VARCHAR NOT NULL,
6807      *      INITIALLY_DEFERRED      VARCHAR NOT NULL,
6808      *
6809      *      CHECK ( CONSTRAINT_TYPE IN
6810      *                      ( 'UNIQUE', 'PRIMARY KEY',
6811      *                        'FOREIGN KEY', 'CHECK' ) ),
6812      *
6813      *      CHECK ( ( IS_DEFERRABLE, INITIALLY_DEFERRED ) IN
6814      *              ( VALUES ( 'NO',  'NO'  ),
6815      *                       ( 'YES', 'NO'  ),
6816      *                       ( 'YES', 'YES' ) ) )
6817      * )
6818      * </pre>
6819      *
6820      * <b>Description:</b> <p>
6821      *
6822      * <ol>
6823      * <li> The values of CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, and
6824      *      CONSTRAINT_NAME are the catalog name, schema
6825      *      name, and identifier, respectively, of the
6826      *      constraint being described. If the &lt;table constraint
6827      *      definition&gt; or &lt;add table constraint definition&gt;
6828      *      that defined the constraint did not specify a
6829      *      &lt;constraint name&gt;, then the values of CONSTRAINT_CATALOG,
6830      *      CONSTRAINT_SCHEMA, and CONSTRAINT_NAME are
6831      *      implementation-defined. <p>
6832      *
6833      * <li> The values of CONSTRAINT_TYPE have the following meanings: <p>
6834      *  <table border cellpadding="3">
6835      *  <tr>
6836      *      <td nowrap>FOREIGN KEY</td>
6837      *      <td nowrap>The constraint being described is a
6838      *                 foreign key constraint.</td>
6839      *  </tr>
6840      *  <tr>
6841      *      <td nowrap>UNIQUE</td>
6842      *      <td nowrap>The constraint being described is a
6843      *                 unique constraint.</td>
6844      *  </tr>
6845      *  <tr>
6846      *      <td nowrap>PRIMARY KEY</td>
6847      *      <td nowrap>The constraint being described is a
6848      *                 primary key constraint.</td>
6849      *  </tr>
6850      *  <tr>
6851      *      <td nowrap>CHECK</td>
6852      *      <td nowrap>The constraint being described is a
6853      *                 check constraint.</td>
6854      *  </tr>
6855      * </table> <p>
6856      *
6857      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are
6858      *      the catalog name, the schema name, and the
6859      *      name of the table to which the
6860      *      table constraint being described applies. <p>
6861      *
6862      * <li> The values of IS_DEFERRABLE have the following meanings: <p>
6863      *
6864      *  <table>
6865      *      <tr>
6866      *          <td nowrap>YES</td>
6867      *          <td nowrap>The table constraint is deferrable.</td>
6868      *      </tr>
6869      *      <tr>
6870      *          <td nowrap>NO</td>
6871      *          <td nowrap>The table constraint is not deferrable.</td>
6872      *      </tr>
6873      *  </table> <p>
6874      *
6875      * <li> The values of INITIALLY_DEFERRED have the following meanings: <p>
6876      *
6877      *  <table>
6878      *      <tr>
6879      *          <td nowrap>YES</td>
6880      *          <td nowrap>The table constraint is initially deferred.</td>
6881      *      </tr>
6882      *      <tr>
6883      *          <td nowrap>NO</td>
6884      *          <td nowrap>The table constraint is initially immediate.</td>
6885      *      </tr>
6886      *  </table> <p>
6887      * </ol>
6888      *
6889      * @return Table
6890      */
TABLE_CONSTRAINTS(Session session, PersistentStore store)6891     Table TABLE_CONSTRAINTS(Session session, PersistentStore store) {
6892 
6893         Table t = sysTables[TABLE_CONSTRAINTS];
6894 
6895         if (t == null) {
6896             t = createBlankTable(sysTableHsqlNames[TABLE_CONSTRAINTS]);
6897 
6898             addColumn(t, "CONSTRAINT_CATALOG", SQL_IDENTIFIER);
6899             addColumn(t, "CONSTRAINT_SCHEMA", SQL_IDENTIFIER);
6900             addColumn(t, "CONSTRAINT_NAME", SQL_IDENTIFIER);    // not null
6901             addColumn(t, "CONSTRAINT_TYPE", CHARACTER_DATA);    // not null
6902             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
6903             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
6904             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);         // not null
6905             addColumn(t, "IS_DEFERRABLE", YES_OR_NO);           // not null
6906             addColumn(t, "INITIALLY_DEFERRED", YES_OR_NO);      // not null
6907 
6908             // false PK, as CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA,
6909             // TABLE_CATALOG and/or TABLE_SCHEMA may be null
6910             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
6911                 sysTableHsqlNames[TABLE_CONSTRAINTS].name, false,
6912                 SchemaObject.INDEX);
6913 
6914             t.createPrimaryKeyConstraint(name, new int[] {
6915                 0, 1, 2, 4, 5, 6
6916             }, false);
6917 
6918             return t;
6919         }
6920 
6921         // Intermediate holders
6922         Iterator     tables;
6923         Table        table;
6924         Constraint[] constraints;
6925         int          constraintCount;
6926         Constraint   constraint;
6927         String       cat;
6928         String       schem;
6929         Object[]     row;
6930 
6931         // column number mappings
6932         final int constraint_catalog = 0;
6933         final int constraint_schema  = 1;
6934         final int constraint_name    = 2;
6935         final int constraint_type    = 3;
6936         final int table_catalog      = 4;
6937         final int table_schema       = 5;
6938         final int table_name         = 6;
6939         final int is_deferable       = 7;
6940         final int initially_deferred = 8;
6941 
6942         // initialization
6943         tables =
6944             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
6945         table = null;    // else compiler complains
6946 
6947         // do it
6948         while (tables.hasNext()) {
6949             table = (Table) tables.next();
6950 
6951             /** requires any INSERT or UPDATE or DELETE or REFERENCES or TRIGGER, (not SELECT) right */
6952             if (table.isView()
6953                     || !session.getGrantee().hasNonSelectTableRight(table)) {
6954                 continue;
6955             }
6956 
6957             constraints     = table.getConstraints();
6958             constraintCount = constraints.length;
6959 
6960             for (int i = 0; i < constraintCount; i++) {
6961                 constraint = constraints[i];
6962                 row        = t.getEmptyRowData();
6963 
6964                 switch (constraint.getConstraintType()) {
6965 
6966                     case SchemaObject.ConstraintTypes.CHECK : {
6967                         row[constraint_type] = "CHECK";
6968 
6969                         break;
6970                     }
6971                     case SchemaObject.ConstraintTypes.UNIQUE : {
6972                         row[constraint_type] = "UNIQUE";
6973 
6974                         break;
6975                     }
6976                     case SchemaObject.ConstraintTypes.FOREIGN_KEY : {
6977                         row[constraint_type] = "FOREIGN KEY";
6978                         table                = constraint.getRef();
6979 
6980                         break;
6981                     }
6982                     case SchemaObject.ConstraintTypes.PRIMARY_KEY : {
6983                         row[constraint_type] = "PRIMARY KEY";
6984 
6985                         break;
6986                     }
6987                     case SchemaObject.ConstraintTypes.MAIN :
6988                     default : {
6989                         continue;
6990                     }
6991                 }
6992 
6993                 cat                     = database.getCatalogName().name;
6994                 schem                   = table.getSchemaName().name;
6995                 row[constraint_catalog] = cat;
6996                 row[constraint_schema]  = schem;
6997                 row[constraint_name]    = constraint.getName().name;
6998                 row[table_catalog]      = cat;
6999                 row[table_schema]       = schem;
7000                 row[table_name]         = table.getName().name;
7001                 row[is_deferable]       = Tokens.T_NO;
7002                 row[initially_deferred] = Tokens.T_NO;
7003 
7004                 t.insertSys(session, store, row);
7005             }
7006         }
7007 
7008         return t;
7009     }
7010 
7011     /**
7012      * SQL:2008 VIEW<p>
7013      *
7014      * The TRANSLATIONS view has one row for each translation between two
7015      * character sets.<p>
7016      *
7017      */
TRANSLATIONS(Session session, PersistentStore store)7018     Table TRANSLATIONS(Session session, PersistentStore store) {
7019 
7020         Table t = sysTables[TRANSLATIONS];
7021 
7022         if (t == null) {
7023             t = createBlankTable(sysTableHsqlNames[TRANSLATIONS]);
7024 
7025             addColumn(t, "TRANSLATION_CATALOG", SQL_IDENTIFIER);
7026             addColumn(t, "TRANSLATION_SCHEMA", SQL_IDENTIFIER);
7027             addColumn(t, "TRANSLATION_NAME", SQL_IDENTIFIER);
7028             addColumn(t, "SOURCE_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
7029             addColumn(t, "SOURCE_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
7030             addColumn(t, "SOURCE_CHARACTER_SET_NAME", SQL_IDENTIFIER);
7031             addColumn(t, "TARGET_CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
7032             addColumn(t, "TARGET_CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
7033             addColumn(t, "TARGET_CHARACTER_SET_NAME", SQL_IDENTIFIER);
7034             addColumn(t, "TRANSLATION_SOURCE_CATALOG", SQL_IDENTIFIER);
7035             addColumn(t, "TRANSLATION_SOURCE_SCHEMA", SQL_IDENTIFIER);
7036             addColumn(t, "TRANSLATION_SOURCE_NAME", SQL_IDENTIFIER);
7037 
7038             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7039                 sysTableHsqlNames[TRANSLATIONS].name, false,
7040                 SchemaObject.INDEX);
7041 
7042             t.createPrimaryKeyConstraint(name, new int[] {
7043                 0, 1, 2
7044             }, false);
7045 
7046             return t;
7047         }
7048 
7049         return t;
7050     }
7051 
7052     /**
7053      * SQL:2008 VIEW<p>
7054      *
7055      * The TRIGGER_COLUMN_USAGE view has one row for each column
7056      * referenced in the body of a trigger.<p>
7057      *
7058      * <b>Definition:</b><p>
7059      *
7060      *      TRIGGER_CATALOG     VARCHAR ,
7061      *      TRIGGER_SCHEMA      VARCHAR ,
7062      *      TRIGGER_NAME        VARCHAR ,
7063      *      TABLE_CATALOG       VARCHAR ,
7064      *      TABLE_SCHEMA        VARCHAR ,
7065      *      TABLE_NAME          VARCHAR ,
7066      *      COLUMN_NAME         VARCHAR ,
7067      *
7068      * </pre>
7069      *
7070      * <b>Description:</b> <p>
7071      *
7072      * <ol>
7073      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and
7074      *      TRIGGER_NAME are the catalog name, schema name and
7075      *      identifier, respectively, of the trigger. <p>
7076      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
7077      *      COLUMN_NAME are the catalog name, schema name,
7078      *      identifier, and column name, respectively, of a column
7079      *      reference in the trigger body.<>
7080      *
7081      * <1i> Columns are reported only if the user or one of its roles is
7082      *      the authorization (owner) of the TRIGGER.
7083      *
7084      * </ol>
7085      *
7086      * @return Table
7087      */
TRIGGER_COLUMN_USAGE(Session session, PersistentStore store)7088     Table TRIGGER_COLUMN_USAGE(Session session, PersistentStore store) {
7089 
7090         Table t = sysTables[TRIGGER_COLUMN_USAGE];
7091 
7092         if (t == null) {
7093             t = createBlankTable(sysTableHsqlNames[TRIGGER_COLUMN_USAGE]);
7094 
7095             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7096             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7097             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);    // not null
7098             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
7099             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
7100             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);      // not null
7101             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);     // not null
7102 
7103             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7104                 sysTableHsqlNames[TRIGGER_COLUMN_USAGE].name, false,
7105                 SchemaObject.INDEX);
7106 
7107             t.createPrimaryKeyConstraint(name, new int[] {
7108                 0, 1, 2, 3, 4, 5, 6
7109             }, false);
7110 
7111             return t;
7112         }
7113 
7114         // column number mappings
7115         final int trigger_catalog = 0;
7116         final int trigger_schema  = 1;
7117         final int trigger_name    = 2;
7118         final int table_catalog   = 3;
7119         final int table_schema    = 4;
7120         final int table_name      = 5;
7121         final int column_name     = 6;
7122 
7123         //
7124         Iterator it;
7125         Object[] row;
7126 
7127         it = database.schemaManager.databaseObjectIterator(
7128             SchemaObject.TRIGGER);
7129 
7130         while (it.hasNext()) {
7131             TriggerDef trigger = (TriggerDef) it.next();
7132 
7133             if (!session.getGrantee().isFullyAccessibleByRole(
7134                     trigger.getName())) {
7135                 continue;
7136             }
7137 
7138             OrderedHashSet set = trigger.getReferences();
7139 
7140             for (int i = 0; i < set.size(); i++) {
7141                 HsqlName refName = (HsqlName) set.get(i);
7142 
7143                 if (refName.type != SchemaObject.COLUMN) {
7144                     continue;
7145                 }
7146 
7147                 if (!session.getGrantee().isAccessible(refName)) {
7148                     continue;
7149                 }
7150 
7151                 row = t.getEmptyRowData();
7152 
7153                 //
7154                 row[trigger_catalog] = database.getCatalogName().name;
7155                 row[trigger_schema]  = trigger.getSchemaName().name;
7156                 row[trigger_name]    = trigger.getName().name;
7157                 row[table_catalog]   = database.getCatalogName().name;
7158                 row[table_schema]    = refName.parent.schema.name;
7159                 row[table_name]      = refName.parent.name;
7160                 row[column_name]     = refName.name;
7161 
7162                 try {
7163                     t.insertSys(session, store, row);
7164                 } catch (HsqlException e) {}
7165             }
7166         }
7167 
7168         // Initialization
7169         return t;
7170     }
7171 
7172     /**
7173      * SQL:2008 VIEW<p>
7174      *
7175      * The TRIGGER_ROUTINE_USAGE view has one row for each routine
7176      * referenced in the body of a trigger.<p>
7177      *
7178      * <b>Definition:</b><p>
7179      *
7180      *      TRIGGER_CATALOG     VARCHAR ,
7181      *      TRIGGER_SCHEMA      VARCHAR ,
7182      *      TRIGGER_NAME        VARCHAR ,
7183      *      SPECIFIC_CATALOG    VARCHAR ,
7184      *      SPECIFIC_SCHEMA     VARCHAR ,
7185      *      SPECIFIC_NAME       VARCHAR ,
7186      *
7187      * </pre>
7188      *
7189      * <b>Description:</b> <p>
7190      *
7191      * <ol>
7192      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and TRIGGER_NAME
7193      *      are the catalog name, schema name and
7194      *      identifier, respectively, of the TRIGGER.<p>
7195      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA and
7196      *      SPECIFIC_NAME are the catalog name, schema name,
7197      *      specific routine identifier, respectively, of the routine
7198      *      that is referenced. <p>
7199      *
7200      * <1i> Referenced routines are reported only if the user or one of its roles is
7201      *      the authorization (owner) of the TRIGGER.
7202      *
7203      * </ol>
7204      *
7205      * @return Table
7206      */
TRIGGER_ROUTINE_USAGE(Session session, PersistentStore store)7207     Table TRIGGER_ROUTINE_USAGE(Session session, PersistentStore store) {
7208 
7209         Table t = sysTables[TRIGGER_ROUTINE_USAGE];
7210 
7211         if (t == null) {
7212             t = createBlankTable(sysTableHsqlNames[TRIGGER_ROUTINE_USAGE]);
7213 
7214             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7215             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7216             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);     // not null
7217             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
7218             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
7219             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);    // not null
7220 
7221             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7222                 sysTableHsqlNames[TRIGGER_ROUTINE_USAGE].name, false,
7223                 SchemaObject.INDEX);
7224 
7225             t.createPrimaryKeyConstraint(name, new int[] {
7226                 0, 1, 2, 3, 4, 5
7227             }, false);
7228 
7229             return t;
7230         }
7231 
7232         // column number mappings
7233         final int trigger_catalog  = 0;
7234         final int trigger_schema   = 1;
7235         final int trigger_name     = 2;
7236         final int specific_catalog = 3;
7237         final int specific_schema  = 4;
7238         final int specific_name    = 5;
7239 
7240         //
7241         Iterator it;
7242         Object[] row;
7243 
7244         it = database.schemaManager.databaseObjectIterator(
7245             SchemaObject.TRIGGER);
7246 
7247         while (it.hasNext()) {
7248             TriggerDef trigger = (TriggerDef) it.next();
7249 
7250             if (!session.getGrantee().isFullyAccessibleByRole(
7251                     trigger.getName())) {
7252                 continue;
7253             }
7254 
7255             OrderedHashSet set = trigger.getReferences();
7256 
7257             for (int i = 0; i < set.size(); i++) {
7258                 HsqlName refName = (HsqlName) set.get(i);
7259 
7260                 if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
7261                     continue;
7262                 }
7263 
7264                 row                   = t.getEmptyRowData();
7265                 row[trigger_catalog]  = database.getCatalogName().name;
7266                 row[trigger_schema]   = trigger.getSchemaName().name;
7267                 row[trigger_name]     = trigger.getName().name;
7268                 row[specific_catalog] = database.getCatalogName().name;
7269                 row[specific_schema]  = refName.schema.name;
7270                 row[specific_name]    = refName.name;
7271 
7272                 try {
7273                     t.insertSys(session, store, row);
7274                 } catch (HsqlException e) {}
7275             }
7276         }
7277 
7278         return t;
7279     }
7280 
7281     /**
7282      * SQL:2008 VIEW<p>
7283      *
7284      * The TRIGGER_SEQUENCE_USAGE view has one row for each SEQUENCE
7285      * referenced in the body of a trigger.<p>
7286      *
7287      * <b>Definition:</b><p>
7288      *
7289      *      TRIGGER_CATALOG     VARCHAR ,
7290      *      TRIGGER_SCHEMA      VARCHAR ,
7291      *      TRIGGER_NAME        VARCHAR ,
7292      *      SEQUENCE_CATALOG    VARCHAR ,
7293      *      SEQUENCE_SCHEMA     VARCHAR ,
7294      *      SEQUENCE_NAME       VARCHAR ,
7295      *
7296      * </pre>
7297      *
7298      * <b>Description:</b> <p>
7299      *
7300      * <ol>
7301      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and TRIGGER_NAME
7302      *      are the catalog name, schema name and
7303      *      identifier, respectively, of the TRIGGER.<p>
7304      * <li> The values of SEQUENCE_CATALOG, SEQUENCE_SCHEMA and
7305      *      SEQUENCE_NAME are the catalog name, schema name and
7306      *      identifier, respectively, of the SEQUENCE
7307      *      that is referenced. <p>
7308      *
7309      * <1i> Referenced sequences are reported only if the user or one of its roles is
7310      *      the authorization (owner) of the TRIGGER.
7311      *
7312      * </ol>
7313      *
7314      * @return Table
7315      */
TRIGGER_SEQUENCE_USAGE(Session session, PersistentStore store)7316     Table TRIGGER_SEQUENCE_USAGE(Session session, PersistentStore store) {
7317 
7318         Table t = sysTables[TRIGGER_SEQUENCE_USAGE];
7319 
7320         if (t == null) {
7321             t = createBlankTable(sysTableHsqlNames[TRIGGER_SEQUENCE_USAGE]);
7322 
7323             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7324             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7325             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);     // not null
7326             addColumn(t, "SEQUENCE_CATALOG", SQL_IDENTIFIER);
7327             addColumn(t, "SEQUENCE_SCHEMA", SQL_IDENTIFIER);
7328             addColumn(t, "SEQUENCE_NAME", SQL_IDENTIFIER);    // not null
7329 
7330             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7331                 sysTableHsqlNames[TRIGGER_SEQUENCE_USAGE].name, false,
7332                 SchemaObject.INDEX);
7333 
7334             t.createPrimaryKeyConstraint(name, new int[] {
7335                 0, 1, 2, 3, 4, 5
7336             }, false);
7337 
7338             return t;
7339         }
7340 
7341         // column number mappings
7342         final int trigger_catalog  = 0;
7343         final int trigger_schema   = 1;
7344         final int trigger_name     = 2;
7345         final int sequence_catalog = 3;
7346         final int sequence_schema  = 4;
7347         final int sequence_name    = 5;
7348 
7349         //
7350         Iterator it;
7351         Object[] row;
7352 
7353         it = database.schemaManager.databaseObjectIterator(
7354             SchemaObject.TRIGGER);
7355 
7356         while (it.hasNext()) {
7357             TriggerDef trigger = (TriggerDef) it.next();
7358 
7359             if (!session.getGrantee().isFullyAccessibleByRole(
7360                     trigger.getName())) {
7361                 continue;
7362             }
7363 
7364             OrderedHashSet set = trigger.getReferences();
7365 
7366             for (int i = 0; i < set.size(); i++) {
7367                 HsqlName refName = (HsqlName) set.get(i);
7368 
7369                 if (refName.type != SchemaObject.SEQUENCE) {
7370                     continue;
7371                 }
7372 
7373                 row                   = t.getEmptyRowData();
7374                 row[trigger_catalog]  = database.getCatalogName().name;
7375                 row[trigger_schema]   = trigger.getSchemaName().name;
7376                 row[trigger_name]     = trigger.getName().name;
7377                 row[sequence_catalog] = database.getCatalogName().name;
7378                 row[sequence_schema]  = refName.schema.name;
7379                 row[sequence_name]    = refName.name;
7380 
7381                 try {
7382                     t.insertSys(session, store, row);
7383                 } catch (HsqlException e) {}
7384             }
7385         }
7386 
7387         // Initialization
7388         return t;
7389     }
7390 
7391     /**
7392      * SQL:2008 VIEW<p>
7393      *
7394      * The TRIGGER_TABLE_USAGE view has one row for each TABLE
7395      * referenced in the body of a trigger.<p>
7396      *
7397      * <b>Definition:</b><p>
7398      *
7399      *      TRIGGER_CATALOG     VARCHAR ,
7400      *      TRIGGER_SCHEMA      VARCHAR ,
7401      *      TRIGGER_NAME        VARCHAR ,
7402      *      TABLE_CATALOG       VARCHAR ,
7403      *      TABLE_SCHEMA        VARCHAR ,
7404      *      TABLE_NAME          VARCHAR ,
7405      *
7406      * </pre>
7407      *
7408      * <b>Description:</b> <p>
7409      *
7410      * <ol>
7411      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and TRIGGER_NAME
7412      *      are the catalog name, schema name and
7413      *      identifier, respectively, of the TRIGGER.<p>
7414      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA and
7415      *      TABLE_NAME are the catalog name, schema name and
7416      *      identifier, respectively, of the TABLE
7417      *      that is referenced. <p>
7418      *
7419      * <1i> Referenced tables are reported only if the user or one of its roles is
7420      *      the authorization (owner) of the TRIGGER.
7421      *
7422      * </ol>
7423      *
7424      * @return Table
7425      */
TRIGGER_TABLE_USAGE(Session session, PersistentStore store)7426     Table TRIGGER_TABLE_USAGE(Session session, PersistentStore store) {
7427 
7428         Table t = sysTables[TRIGGER_TABLE_USAGE];
7429 
7430         if (t == null) {
7431             t = createBlankTable(sysTableHsqlNames[TRIGGER_TABLE_USAGE]);
7432 
7433             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7434             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7435             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);    // not null
7436             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
7437             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
7438             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);      // not null
7439 
7440             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7441                 sysTableHsqlNames[TRIGGER_TABLE_USAGE].name, false,
7442                 SchemaObject.INDEX);
7443 
7444             t.createPrimaryKeyConstraint(name, new int[] {
7445                 0, 1, 2, 3, 4, 5
7446             }, false);
7447 
7448             return t;
7449         }
7450 
7451         // column number mappings
7452         final int trigger_catalog = 0;
7453         final int trigger_schema  = 1;
7454         final int trigger_name    = 2;
7455         final int table_catalog   = 3;
7456         final int table_schema    = 4;
7457         final int table_name      = 5;
7458 
7459         //
7460         Iterator it;
7461         Object[] row;
7462 
7463         it = database.schemaManager.databaseObjectIterator(
7464             SchemaObject.TRIGGER);
7465 
7466         while (it.hasNext()) {
7467             TriggerDef trigger = (TriggerDef) it.next();
7468 
7469             if (!session.getGrantee().isFullyAccessibleByRole(
7470                     trigger.getName())) {
7471                 continue;
7472             }
7473 
7474             OrderedHashSet set = trigger.getReferences();
7475 
7476             for (int i = 0; i < set.size(); i++) {
7477                 HsqlName refName = (HsqlName) set.get(i);
7478 
7479                 if (refName.type != SchemaObject.TABLE
7480                         && refName.type != SchemaObject.VIEW) {
7481                     continue;
7482                 }
7483 
7484                 row                  = t.getEmptyRowData();
7485                 row[trigger_catalog] = database.getCatalogName().name;
7486                 row[trigger_schema]  = trigger.getSchemaName().name;
7487                 row[trigger_name]    = trigger.getName().name;
7488                 row[table_catalog]   = database.getCatalogName().name;
7489                 row[table_schema]    = refName.schema.name;
7490                 row[table_name]      = refName.name;
7491 
7492                 try {
7493                     t.insertSys(session, store, row);
7494                 } catch (HsqlException e) {}
7495             }
7496         }
7497 
7498         // Initialization
7499         return t;
7500     }
7501 
7502     /**
7503      * SQL:2008 VIEW<p>
7504      *
7505      * The TRIGGERS view has one row for each TRIGGER.<p>
7506      *
7507      * <b>Definition:</b><p>
7508      *
7509      *      TRIGGER_CATALOG               VARCHAR ,
7510      *      TRIGGER_SCHEMA                VARCHAR ,
7511      *      TRIGGER_NAME                  VARCHAR ,
7512      *      EVENT_MANIPULATION            VARCHAR ,
7513      *      EVENT_OBJECT_CATALOG          VARCHAR ,
7514      *      EVENT_OBJECT_SCHEMA           VARCHAR ,
7515      *      EVENT_OBJECT_TABLE            VARCHAR ,
7516      *      ACTION_ORDER                  VARCHAR ,
7517      *      ACTION_CONDITION              VARCHAR ,
7518      *      ACTION_STATEMENT              VARCHAR ,
7519      *      ACTION_ORIENTATION            VARCHAR ,
7520      *      ACTION_TIMING_                VARCHAR ,
7521      *      ACTION_REFERENCE_OLD_TABLE    VARCHAR ,
7522      *      ACTION_REFERENCE_NEW_TABLE    VARCHAR ,
7523      *      ACTION_REFERENCE_OLD_ROW      VARCHAR ,
7524      *      ACTION_REFERENCE_NEW_ROW      VARCHAR ,
7525      *      CREATED                       VARCHAR ,
7526      *
7527      * </pre>
7528      *
7529      * <b>Description:</b> <p>
7530      *
7531      * <ol>
7532      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and TRIGGER_NAME
7533      *      are the catalog name, schema name and
7534      *      identifier, respectively, of the TRIGGER.<p>
7535      * <li> The value of EVENT_MANUPULATION indicates for which action the
7536      *      trigger is fired: 'INSERT', 'UPDATE' or 'DELETE'.
7537      * <li> The values of EVENT_OBJECT_CATALOG, EVENT_OBJECT_SCHEMA and
7538      *      EVENT_OBJECT_NAME are the catalog name, schema name and
7539      *      identifier, respectively, of the trigger TABLE. <p>
7540      * <li> The value of ACTION_ORDER indicates the ordinal position of the
7541      *      trigger is firing event, among all the triggers of the same
7542      *      ACTION_ORIENTATION and ACTION_TIMING.
7543      * <li> The value of ACTION_CONDITION is the text of the SQL expression in
7544      *     t he optional WHEN condition.
7545      * <li> The value of ACTION_STATEMENT is the text of the SQL statement(s)
7546      *      executed by the trigger.
7547      * <li> The value of ACTION_ORIENTATION indicates whether the trigger is
7548      *      fired once per each 'STATEMENT' or per each 'ROW'.
7549      * <li> The value of ACTION_TIMING indicates when the trigger is
7550      *      trigger is fired: 'BEFORE', 'AFTER' or 'INSTEAD OF'.
7551      * <li> The value of ACTION_REFERENCING_OLD_TABLE contains the name of the
7552      *      OLD TABLE transition table.
7553      * <li> The value of ACTION_REFERENCING_NEW_TABLE contains the name of the
7554      *      NEW TABLE transition table.
7555      * <li> The value of ACTION_REFERENCING_OLD_ROW contains the name of the
7556      *      OLD ROW.
7557      * <li> The value of ACTION_REFERENCING_NEW_ROW contains the name of the
7558      *      NEW ROW.
7559      * <li> The value of CREATED contains the timestamp of the creation of the
7560      *      trigger. Currently NULL.
7561      * <1i> Triggers are reported only if the user or one of its roles has
7562      *      some privilege on at least one column of the trigger table.
7563      * <li> The ACTION_CONDITION and ACTION_STATEMENT columns show the SQL only
7564      *      if the user or one of its roles is the authorization (owner) of the
7565      *      trigger table.
7566      * </ol>
7567      *
7568      * @return Table
7569      */
TRIGGERS(Session session, PersistentStore store)7570     Table TRIGGERS(Session session, PersistentStore store) {
7571 
7572         Table t = sysTables[TRIGGERS];
7573 
7574         if (t == null) {
7575             t = createBlankTable(sysTableHsqlNames[TRIGGERS]);
7576 
7577             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7578             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7579             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);
7580             addColumn(t, "EVENT_MANIPULATION", SQL_IDENTIFIER);
7581             addColumn(t, "EVENT_OBJECT_CATALOG", SQL_IDENTIFIER);
7582             addColumn(t, "EVENT_OBJECT_SCHEMA", SQL_IDENTIFIER);
7583             addColumn(t, "EVENT_OBJECT_TABLE", SQL_IDENTIFIER);
7584             addColumn(t, "ACTION_ORDER", CARDINAL_NUMBER);
7585             addColumn(t, "ACTION_CONDITION", CHARACTER_DATA);
7586             addColumn(t, "ACTION_STATEMENT", CHARACTER_DATA);
7587             addColumn(t, "ACTION_ORIENTATION", CHARACTER_DATA);
7588             addColumn(t, "ACTION_TIMING", CHARACTER_DATA);
7589             addColumn(t, "ACTION_REFERENCE_OLD_TABLE", SQL_IDENTIFIER);
7590             addColumn(t, "ACTION_REFERENCE_NEW_TABLE", SQL_IDENTIFIER);
7591             addColumn(t, "ACTION_REFERENCE_OLD_ROW", SQL_IDENTIFIER);
7592             addColumn(t, "ACTION_REFERENCE_NEW_ROW", SQL_IDENTIFIER);
7593             addColumn(t, "CREATED", TIME_STAMP);
7594 
7595             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7596                 sysTableHsqlNames[TRIGGERS].name, false, SchemaObject.INDEX);
7597 
7598             t.createPrimaryKeyConstraint(name, new int[] {
7599                 0, 1, 2
7600             }, false);
7601 
7602             return t;
7603         }
7604 
7605         // column number mappings
7606         final int trigger_catalog            = 0;
7607         final int trigger_schema             = 1;
7608         final int trigger_name               = 2;
7609         final int event_manipulation         = 3;
7610         final int event_object_catalog       = 4;
7611         final int event_object_schema        = 5;
7612         final int event_object_table         = 6;
7613         final int action_order               = 7;
7614         final int action_condition           = 8;
7615         final int action_statement           = 9;
7616         final int action_orientation         = 10;
7617         final int action_timing              = 11;
7618         final int action_reference_old_table = 12;
7619         final int action_reference_new_table = 13;
7620         final int action_reference_old_row   = 14;
7621         final int action_reference_new_row   = 15;
7622         final int created                    = 16;
7623 
7624         //
7625         Iterator it;
7626         Object[] row;
7627 
7628         it = database.schemaManager.databaseObjectIterator(
7629             SchemaObject.TRIGGER);
7630 
7631         while (it.hasNext()) {
7632             TriggerDef trigger = (TriggerDef) it.next();
7633             boolean isFullAccess =
7634                 session.getGrantee().isFullyAccessibleByRole(
7635                     trigger.getName());
7636 
7637             if (!session.getGrantee().hasNonSelectTableRight(
7638                     trigger.getTable())) {
7639                 continue;
7640             }
7641 
7642             row                       = t.getEmptyRowData();
7643             row[trigger_catalog]      = database.getCatalogName().name;
7644             row[trigger_schema]       = trigger.getSchemaName().name;
7645             row[trigger_name]         = trigger.getName().name;
7646             row[event_manipulation]   = trigger.getEventTypeString();
7647             row[event_object_catalog] = database.getCatalogName().name;
7648             row[event_object_schema] = trigger.getTable().getSchemaName().name;
7649             row[event_object_table]   = trigger.getTable().getName().name;
7650 
7651             int order =
7652                 trigger.getTable().getTriggerIndex(trigger.getName().name);
7653 
7654             row[action_order]       = ValuePool.getLong(order);
7655             row[action_condition]   = isFullAccess ? trigger.getConditionSQL()
7656                                                    : null;
7657             row[action_statement]   = isFullAccess ? trigger.getProcedureSQL()
7658                                                    : null;
7659             row[action_orientation] = trigger.getActionOrientationString();
7660             row[action_timing]      = trigger.getActionTimingString();
7661             row[action_reference_old_table] =
7662                 trigger.getOldTransitionTableName();
7663             row[action_reference_new_table] =
7664                 trigger.getNewTransitionTableName();
7665             row[action_reference_old_row] = trigger.getOldTransitionRowName();
7666             row[action_reference_new_row] = trigger.getNewTransitionRowName();
7667             row[created]                  = null;
7668 
7669             t.insertSys(session, store, row);
7670         }
7671 
7672         // Initialization
7673         return t;
7674     }
7675 
7676     /**
7677      * SQL:2008 VIEW<p>
7678      *
7679      * The TRIGGERED_UPDATE_COLUMNS view has one row for each column
7680      * referenced in the optional column list of a UPDATE trigger.<p>
7681      *
7682      * <b>Definition:</b><p>
7683      *
7684      *      TRIGGER_CATALOG            VARCHAR ,
7685      *      TRIGGER_SCHEMA             VARCHAR ,
7686      *      TRIGGER_NAME               VARCHAR ,
7687      *      EVENT_OBJECT_CATALOG       VARCHAR ,
7688      *      EVENT_OBJECT_SCHEMA        VARCHAR ,
7689      *      EVENT_OBJECT_NAME          VARCHAR ,
7690      *
7691      * </pre>
7692      *
7693      * <b>Description:</b> <p>
7694      *
7695      * <ol>
7696      * <li> The values of TRIGGER_CATALOG, TRIGGER_SCHEMA and TRIGGER_NAME
7697      *      are the catalog name, schema name and
7698      *      identifier, respectively, of the TRIGGER.<p>
7699      * <li> The values of EVENT_OBJECT_CATALOG, EVENT_OBJECT_SCHEMA and
7700      *      EVENT_OBJECT_NAME are the catalog name, schema name and
7701      *      identifier, respectively, of the COLUMN
7702      *      that is referenced. <p>
7703      * </ol>
7704      *
7705      * @return Table
7706      */
TRIGGERED_UPDATE_COLUMNS(Session session, PersistentStore store)7707     Table TRIGGERED_UPDATE_COLUMNS(Session session, PersistentStore store) {
7708 
7709         Table t = sysTables[TRIGGERED_UPDATE_COLUMNS];
7710 
7711         if (t == null) {
7712             t = createBlankTable(sysTableHsqlNames[TRIGGERED_UPDATE_COLUMNS]);
7713 
7714             addColumn(t, "TRIGGER_CATALOG", SQL_IDENTIFIER);
7715             addColumn(t, "TRIGGER_SCHEMA", SQL_IDENTIFIER);
7716             addColumn(t, "TRIGGER_NAME", SQL_IDENTIFIER);            // not null
7717             addColumn(t, "EVENT_OBJECT_CATALOG", SQL_IDENTIFIER);    // not null
7718             addColumn(t, "EVENT_OBJECT_SCHEMA", SQL_IDENTIFIER);
7719             addColumn(t, "EVENT_OBJECT_TABLE", SQL_IDENTIFIER);
7720             addColumn(t, "EVENT_OBJECT_COLUMN", SQL_IDENTIFIER);     // not null
7721 
7722             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7723                 sysTableHsqlNames[TRIGGERED_UPDATE_COLUMNS].name, false,
7724                 SchemaObject.INDEX);
7725 
7726             t.createPrimaryKeyConstraint(name, new int[] {
7727                 0, 1, 2, 3, 4, 5, 6
7728             }, false);
7729 
7730             return t;
7731         }
7732 
7733         // column number mappings
7734         final int trigger_catalog      = 0;
7735         final int trigger_schema       = 1;
7736         final int trigger_name         = 2;
7737         final int event_object_catalog = 3;
7738         final int event_object_schema  = 4;
7739         final int event_object_table   = 5;
7740         final int event_object_column  = 6;
7741 
7742         //
7743         Iterator it;
7744         Object[] row;
7745 
7746         it = database.schemaManager.databaseObjectIterator(
7747             SchemaObject.TRIGGER);
7748 
7749         while (it.hasNext()) {
7750             TriggerDef trigger = (TriggerDef) it.next();
7751 
7752             if (!session.getGrantee().isAccessible(trigger)) {
7753                 continue;
7754             }
7755 
7756             int[] colIndexes = trigger.getUpdateColumnIndexes();
7757 
7758             if (colIndexes == null) {
7759                 continue;
7760             }
7761 
7762             for (int i = 0; i < colIndexes.length; i++) {
7763                 ColumnSchema column =
7764                     trigger.getTable().getColumn(colIndexes[i]);
7765 
7766                 row                       = t.getEmptyRowData();
7767                 row[trigger_catalog]      = database.getCatalogName().name;
7768                 row[trigger_schema]       = trigger.getSchemaName().name;
7769                 row[trigger_name]         = trigger.getName().name;
7770                 row[event_object_catalog] = database.getCatalogName().name;
7771                 row[event_object_schema] =
7772                     trigger.getTable().getSchemaName().name;
7773                 row[event_object_table]  = trigger.getTable().getName().name;
7774                 row[event_object_column] = column.getNameString();
7775 
7776                 t.insertSys(session, store, row);
7777             }
7778         }
7779 
7780         // Initialization
7781         return t;
7782     }
7783 
7784     /**
7785      * SQL:2008 VIEW<p>
7786      *
7787      * The UDT_PRIVILEGES view has one row for each privilege granted on
7788      * a DISTINCT TYPE.
7789      *
7790      * <pre class="SqlCodeExample">
7791      *      GRANTOR               VARCHAR
7792      *      GRANTEE               VARCHAR
7793      *      UDT_CATALOG           VARCHAR
7794      *      UDT_SCHEMA            VARCHAR
7795      *      UDT_NAME              VARCHAR
7796      *      PRIVILEGE_TYPE        VARCHAR
7797      *      IS_GRANTABLE          VARCHAR
7798      * </pre>
7799      *
7800      * <b>Description:</b> <p>
7801      *
7802      * <ol>
7803      * <li> The values of GRANTOR is the grantor of the privilege. The value of
7804      *      GRANTEE is the name of the grantee.
7805      *
7806      * <li> The values of UDT_CATALOG, UDT_SCHEMA and
7807      *      UDT_NAME are the catalog name, schema name
7808      *      and identifier, respectively, of the user defined type
7809      *      described. <p>
7810      *
7811      * <li> The value of PRIVILEGE_TYPE is the type of the privilege, including,
7812      *      'USAGE'
7813      *      The value IS_GRANTABLE is 'YES' if the privilege is grantable. <p>
7814      * </ol>
7815      *
7816      * @return Table
7817      */
UDT_PRIVILEGES(Session session, PersistentStore store)7818     Table UDT_PRIVILEGES(Session session, PersistentStore store) {
7819 
7820         Table t = sysTables[UDT_PRIVILEGES];
7821 
7822         if (t == null) {
7823             t = createBlankTable(sysTableHsqlNames[UDT_PRIVILEGES]);
7824 
7825             addColumn(t, "GRANTOR", SQL_IDENTIFIER);
7826             addColumn(t, "GRANTEE", SQL_IDENTIFIER);
7827             addColumn(t, "UDT_CATALOG", SQL_IDENTIFIER);
7828             addColumn(t, "UDT_SCHEMA", SQL_IDENTIFIER);
7829             addColumn(t, "UDT_NAME", SQL_IDENTIFIER);
7830             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
7831             addColumn(t, "IS_GRANTABLE", YES_OR_NO);
7832 
7833             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
7834                 sysTableHsqlNames[UDT_PRIVILEGES].name, false,
7835                 SchemaObject.INDEX);
7836 
7837             t.createPrimaryKeyConstraint(name, new int[] {
7838                 0, 1, 2, 3, 4
7839             }, false);
7840 
7841             return t;
7842         }
7843 
7844         final int grantor        = 0;
7845         final int grantee        = 1;
7846         final int udt_catalog    = 2;
7847         final int udt_schema     = 3;
7848         final int udt_name       = 4;
7849         final int privilege_type = 5;
7850         final int is_grantable   = 6;
7851 
7852         //
7853         Iterator objects =
7854             database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
7855         OrderedHashSet grantees =
7856             session.getGrantee().getGranteeAndAllRolesWithPublic();
7857 
7858         while (objects.hasNext()) {
7859             SchemaObject object = (SchemaObject) objects.next();
7860 
7861             if (object.getType() != SchemaObject.TYPE) {
7862                 continue;
7863             }
7864 
7865             for (int i = 0; i < grantees.size(); i++) {
7866                 Grantee granteeObject = (Grantee) grantees.get(i);
7867                 OrderedHashSet rights =
7868                     granteeObject.getAllDirectPrivileges(object);
7869                 OrderedHashSet grants =
7870                     granteeObject.getAllGrantedPrivileges(object);
7871 
7872                 if (!grants.isEmpty()) {
7873                     grants.addAll(rights);
7874 
7875                     rights = grants;
7876                 }
7877 
7878                 for (int j = 0; j < rights.size(); j++) {
7879                     Right    right          = (Right) rights.get(j);
7880                     Right    grantableRight = right.getGrantableRights();
7881                     Object[] row;
7882 
7883                     row                 = t.getEmptyRowData();
7884                     row[grantor]        = right.getGrantor().getName().name;
7885                     row[grantee]        = right.getGrantee().getName().name;
7886                     row[udt_catalog]    = database.getCatalogName().name;
7887                     row[udt_schema]     = object.getSchemaName().name;
7888                     row[udt_name]       = object.getName().name;
7889                     row[privilege_type] = Tokens.T_USAGE;
7890                     row[is_grantable] =
7891                         right.getGrantee() == object.getOwner()
7892                         || grantableRight.isFull() ? Tokens.T_YES
7893                                                    : Tokens.T_NO;
7894 
7895                     try {
7896                         t.insertSys(session, store, row);
7897                     } catch (HsqlException e) {}
7898                 }
7899             }
7900         }
7901 
7902         return t;
7903     }
7904 
7905     /**
7906      * SQL:2008 VIEW<p>
7907      *
7908      * The USAGE_PRIVILEGES view has one row for each usage privilege
7909      * descriptor. <p>
7910      *
7911      * It effectively contains a representation of the usage privilege
7912      * descriptors. <p>
7913      *
7914      * <b>Definition:</b> <p>
7915      *
7916      * <pre class="SqlCodeExample">
7917      * CREATE TABLE SYSTEM_USAGE_PRIVILEGES (
7918      *      GRANTOR         VARCHAR NOT NULL,
7919      *      GRANTEE         VARCHAR NOT NULL,
7920      *      OBJECT_CATALOG  VARCHAR NULL,
7921      *      OBJECT_SCHEMA   VARCHAR NULL,
7922      *      OBJECT_NAME     VARCHAR NOT NULL,
7923      *      OBJECT_TYPE     VARCHAR NOT NULL
7924      *      PRIVILEGE_TYPE  VARCHAR NOT NULL
7925      *      IS_GRANTABLE    VARCHAR NOT NULL
7926      * )
7927      * </pre>
7928      *
7929      * <b>Description:</b><p>
7930      *
7931      * <ol>
7932      * <li> The value of GRANTOR is the &lt;authorization identifier&gt; of the
7933      *      user or role who granted usage privileges on the object of the type
7934      *      identified by OBJECT_TYPE that is identified by OBJECT_CATALOG,
7935      *      OBJECT_SCHEMA, and OBJECT_NAME, to the user or role identified by the
7936      *      value of GRANTEE for the usage privilege being described. <p>
7937      *
7938      * <li> The value of GRANTEE is the &lt;authorization identifier&gt; of some
7939      *      user or role, or PUBLIC to indicate all users, to whom the usage
7940      *      privilege being described is granted. <p>
7941      *
7942      * <li> The values of OBJECT_CATALOG, OBJECT_SCHEMA, and OBJECT_NAME are the
7943      *      catalog name, schema name, and identifier,
7944      *      respectively, of the object to which the privilege applies. <p>
7945      *
7946      * <li> The values of OBJECT_TYPE have the following meanings: <p>
7947      *
7948      *      <table border cellpadding="3">
7949      *          <tr>
7950      *              <td nowrap>DOMAIN</td>
7951      *              <td nowrap>The object to which the privilege applies is
7952      *                         a domain.</td>
7953      *          <tr>
7954      *          <tr>
7955      *              <td nowrap>CHARACTER SET</td>
7956      *              <td nowrap>The object to which the privilege applies is a
7957      *                         character set.</td>
7958      *          <tr>
7959      *          <tr>
7960      *              <td nowrap>COLLATION</td>
7961      *              <td nowrap>The object to which the privilege applies is a
7962      *                         collation.</td>
7963      *          <tr>
7964      *          <tr>
7965      *              <td nowrap>TRANSLATION</td>
7966      *              <td nowrap>The object to which the privilege applies is a
7967      *                         transliteration.</td>
7968      *          <tr>
7969      *          <tr>
7970      *              <td nowrap>SEQUENCE</td>
7971      *              <td nowrap>The object to which the privilege applies is a
7972      *                         sequence generator.</td>
7973      *          <tr>
7974      *      </table> <p>
7975      *
7976      * <li> The values of IS_GRANTABLE have the following meanings: <p>
7977      *
7978      *      <table border cellpadding="3">
7979      *          <tr>
7980      *              <td nowrap>YES</td>
7981      *              <td nowrap>The privilege being described was granted
7982      *                         WITH GRANT OPTION and is thus grantable.</td>
7983      *          <tr>
7984      *          <tr>
7985      *              <td nowrap>NO</td>
7986      *              <td nowrap>The privilege being described was not granted
7987      *                  WITH GRANT OPTION and is thus not grantable.</td>
7988      *          <tr>
7989      *      </table> <p>
7990      * <ol>
7991      *
7992      * @return Table
7993      */
USAGE_PRIVILEGES(Session session, PersistentStore store)7994     Table USAGE_PRIVILEGES(Session session, PersistentStore store) {
7995 
7996         Table t = sysTables[USAGE_PRIVILEGES];
7997 
7998         if (t == null) {
7999             t = createBlankTable(sysTableHsqlNames[USAGE_PRIVILEGES]);
8000 
8001             addColumn(t, "GRANTOR", SQL_IDENTIFIER);        // not null
8002             addColumn(t, "GRANTEE", SQL_IDENTIFIER);        // not null
8003             addColumn(t, "OBJECT_CATALOG", SQL_IDENTIFIER);
8004             addColumn(t, "OBJECT_SCHEMA", SQL_IDENTIFIER);
8005             addColumn(t, "OBJECT_NAME", SQL_IDENTIFIER);    // not null
8006             addColumn(t, "OBJECT_TYPE", CHARACTER_DATA);    // not null
8007             addColumn(t, "PRIVILEGE_TYPE", CHARACTER_DATA);
8008             addColumn(t, "IS_GRANTABLE", YES_OR_NO);        // not null
8009 
8010             // order: COLUMN_NAME, PRIVILEGE
8011             // for unique: GRANTEE, GRANTOR, TABLE_NAME, TABLE_SCHEM, TABLE_CAT
8012             // false PK, as TABLE_SCHEM and/or TABLE_CAT may be null
8013             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8014                 sysTableHsqlNames[USAGE_PRIVILEGES].name, false,
8015                 SchemaObject.INDEX);
8016 
8017             t.createPrimaryKeyConstraint(name, new int[] {
8018                 0, 1, 2, 3, 4, 5, 6, 7
8019             }, false);
8020 
8021             return t;
8022         }
8023 
8024         //
8025         Object[] row;
8026 
8027         //
8028         final int grantor        = 0;
8029         final int grantee        = 1;
8030         final int object_catalog = 2;
8031         final int object_schema  = 3;
8032         final int object_name    = 4;
8033         final int object_type    = 5;
8034         final int privilege_type = 6;
8035         final int is_grantable   = 7;
8036 
8037         //
8038         Iterator objects =
8039             new WrapperIterator(database.schemaManager
8040                 .databaseObjectIterator(SchemaObject.SEQUENCE), database
8041                 .schemaManager.databaseObjectIterator(SchemaObject.COLLATION));
8042 
8043         objects = new WrapperIterator(
8044             objects,
8045             database.schemaManager.databaseObjectIterator(
8046                 SchemaObject.CHARSET));
8047         objects = new WrapperIterator(
8048             objects,
8049             database.schemaManager.databaseObjectIterator(
8050                 SchemaObject.DOMAIN));
8051 
8052         // TYPE objects are covered in separate UDT_PRIVILEGES view
8053         OrderedHashSet grantees =
8054             session.getGrantee().getGranteeAndAllRolesWithPublic();
8055 
8056         while (objects.hasNext()) {
8057             SchemaObject object = (SchemaObject) objects.next();
8058 
8059             for (int i = 0; i < grantees.size(); i++) {
8060                 Grantee granteeObject = (Grantee) grantees.get(i);
8061                 OrderedHashSet rights =
8062                     granteeObject.getAllDirectPrivileges(object);
8063                 OrderedHashSet grants =
8064                     granteeObject.getAllGrantedPrivileges(object);
8065 
8066                 if (!grants.isEmpty()) {
8067                     grants.addAll(rights);
8068 
8069                     rights = grants;
8070                 }
8071 
8072                 for (int j = 0; j < rights.size(); j++) {
8073                     Right right          = (Right) rights.get(j);
8074                     Right grantableRight = right.getGrantableRights();
8075 
8076                     row                 = t.getEmptyRowData();
8077                     row[grantor]        = right.getGrantor().getName().name;
8078                     row[grantee]        = right.getGrantee().getName().name;
8079                     row[object_catalog] = database.getCatalogName().name;
8080                     row[object_schema]  = object.getSchemaName().name;
8081                     row[object_name]    = object.getName().name;
8082                     row[object_type] =
8083                         SchemaObjectSet.getName(object.getName().type);
8084                     row[privilege_type] = Tokens.T_USAGE;
8085                     row[is_grantable] =
8086                         right.getGrantee() == object.getOwner()
8087                         || grantableRight.isFull() ? Tokens.T_YES
8088                                                    : Tokens.T_NO;
8089 
8090                     try {
8091                         t.insertSys(session, store, row);
8092                     } catch (HsqlException e) {}
8093                 }
8094             }
8095         }
8096 
8097         return t;
8098     }
8099 
8100     /**
8101      * SQL:2008 VIEW<p>
8102      *
8103      * The USER_DEFINED_TYPES view has one row for each user defined type.
8104      * Only DICTINCT TYPE user defined types are currently supported. <p>
8105      *
8106      * <b>Definition:</b> <p>
8107      *
8108      * <pre class="SqlCodeExample">
8109      *      VIEW_CATALOG    VARCHAR NULL,
8110      *      VIEW_SCHEMA     VARCHAR NULL,
8111      *      VIEW_NAME       VARCHAR NOT NULL,
8112      *      TABLE_CATALOG   VARCHAR NULL,
8113      *      TABLE_SCHEMA    VARCHAR NULL,
8114      *      TABLE_NAME      VARCHAR NOT NULL,
8115      *      COLUMN_NAME     VARCHAR NOT NULL,
8116      * </pre>
8117      *
8118      * <b>Description:</b> <p>
8119      *
8120      * <ol>
8121      * <li> The values of VIEW_CATALOG, VIEW_SCHEMA, and VIEW_NAME are the
8122      *      catalog name, schema name, and identifier,
8123      *      respectively, of the view being described. <p>
8124      *
8125      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
8126      *      COLUMN_NAME are the catalog name, schema name,
8127      *      table name, and column name, respectively, of a column
8128      *      of a table that is explicitly or implicitly referenced in the
8129      *      &lt;query expression&gt; of the view being described.
8130      * <1i> Referenced routines are reported only if the user or one of its roles is
8131      *      the authorization (owner) of the referenced ROUTINE
8132      * </ol>
8133      *
8134      * @return Table
8135      */
USER_DEFINED_TYPES(Session session, PersistentStore store)8136     Table USER_DEFINED_TYPES(Session session, PersistentStore store) {
8137 
8138         Table t = sysTables[USER_DEFINED_TYPES];
8139 
8140         if (t == null) {
8141             t = createBlankTable(sysTableHsqlNames[USER_DEFINED_TYPES]);
8142 
8143             addColumn(t, "USER_DEFINED_TYPE_CATALOG", SQL_IDENTIFIER);
8144             addColumn(t, "USER_DEFINED_TYPE_SCHEMA", SQL_IDENTIFIER);
8145             addColumn(t, "USER_DEFINED_TYPE_NAME", SQL_IDENTIFIER);
8146             addColumn(t, "USER_DEFINED_TYPE_CATEGORY", SQL_IDENTIFIER);
8147             addColumn(t, "IS_INSTANTIABLE", YES_OR_NO);
8148             addColumn(t, "IS_FINAL", YES_OR_NO);
8149             addColumn(t, "ORDERING_FORM", SQL_IDENTIFIER);
8150             addColumn(t, "ORDERING_CATEGORY", SQL_IDENTIFIER);
8151             addColumn(t, "ORDERING_ROUTINE_CATALOG", SQL_IDENTIFIER);
8152             addColumn(t, "ORDERING_ROUTINE_SCHEMA", SQL_IDENTIFIER);
8153             addColumn(t, "ORDERING_ROUTINE_NAME", SQL_IDENTIFIER);
8154             addColumn(t, "REFERENCE_TYPE", SQL_IDENTIFIER);
8155             addColumn(t, "DATA_TYPE", CHARACTER_DATA);
8156             addColumn(t, "CHARACTER_MAXIMUM_LENGTH", CARDINAL_NUMBER);
8157             addColumn(t, "CHARACTER_OCTET_LENGTH", CARDINAL_NUMBER);
8158             addColumn(t, "CHARACTER_SET_CATALOG", SQL_IDENTIFIER);
8159             addColumn(t, "CHARACTER_SET_SCHEMA", SQL_IDENTIFIER);
8160             addColumn(t, "CHARACTER_SET_NAME", SQL_IDENTIFIER);
8161             addColumn(t, "COLLATION_CATALOG", SQL_IDENTIFIER);
8162             addColumn(t, "COLLATION_SCHEMA", SQL_IDENTIFIER);
8163             addColumn(t, "COLLATION_NAME", SQL_IDENTIFIER);
8164             addColumn(t, "NUMERIC_PRECISION", CARDINAL_NUMBER);
8165             addColumn(t, "NUMERIC_PRECISION_RADIX", CARDINAL_NUMBER);
8166             addColumn(t, "NUMERIC_SCALE", CARDINAL_NUMBER);
8167             addColumn(t, "DATETIME_PRECISION", CARDINAL_NUMBER);
8168             addColumn(t, "INTERVAL_TYPE", CHARACTER_DATA);
8169             addColumn(t, "INTERVAL_PRECISION", CARDINAL_NUMBER);
8170             addColumn(t, "SOURCE_DTD_IDENTIFIER", CHARACTER_DATA);
8171             addColumn(t, "REF_DTD_IDENTIFIER", CHARACTER_DATA);
8172             addColumn(t, "DECLARED_DATA_TYPE", CHARACTER_DATA);
8173             addColumn(t, "DECLARED_NUMERIC_PRECISION", CARDINAL_NUMBER);
8174             addColumn(t, "DECLARED_NUMERIC_SCALE", CARDINAL_NUMBER);
8175             addColumn(t, "MAXIMUM_CARDINALITY", CARDINAL_NUMBER);
8176             addColumn(t, "EXTERNAL_NAME", CHARACTER_DATA);
8177             addColumn(t, "EXTERNAL_LANGUAGE", CHARACTER_DATA);
8178             addColumn(t, "JAVA_INTERFACE", CHARACTER_DATA);
8179 
8180             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8181                 sysTableHsqlNames[USER_DEFINED_TYPES].name, false,
8182                 SchemaObject.INDEX);
8183 
8184             t.createPrimaryKeyConstraint(name, new int[] {
8185                 0, 1, 2, 4, 5, 6
8186             }, false);
8187 
8188             return t;
8189         }
8190 
8191         final int user_defined_type_catalog  = 0;
8192         final int user_defined_type_schema   = 1;
8193         final int user_defined_type_name     = 2;
8194         final int user_defined_type_category = 3;
8195         final int is_instantiable            = 4;
8196         final int is_final                   = 5;
8197         final int ordering_form              = 6;
8198         final int ordering_category          = 7;
8199         final int ordering_routine_catalog   = 8;
8200         final int ordering_routine_schema    = 9;
8201         final int ordering_routine_name      = 10;
8202         final int reference_type             = 11;
8203         final int data_type                  = 12;
8204         final int character_maximum_length   = 13;
8205         final int character_octet_length     = 14;
8206         final int character_set_catalog      = 15;
8207         final int character_set_schema       = 16;
8208         final int character_set_name         = 17;
8209         final int collation_catalog          = 18;
8210         final int collation_schema           = 19;
8211         final int collation_name             = 20;
8212         final int numeric_precision          = 21;
8213         final int numeric_precision_radix    = 22;
8214         final int numeric_scale              = 23;
8215         final int datetime_precision         = 24;
8216         final int interval_type              = 25;
8217         final int interval_precision         = 26;
8218         final int source_dtd_identifier      = 27;
8219         final int ref_dtd_identifier         = 28;
8220         final int declared_data_type         = 29;
8221         final int declared_numeric_precision = 30;
8222         final int declared_numeric_scale     = 31;
8223         final int maximum_cardinality        = 32;
8224 
8225         //
8226         Iterator it =
8227             database.schemaManager.databaseObjectIterator(SchemaObject.TYPE);
8228 
8229         while (it.hasNext()) {
8230             Type type = (Type) it.next();
8231 
8232             if (!type.isDistinctType()) {
8233                 continue;
8234             }
8235 
8236             Object[] row = t.getEmptyRowData();
8237 
8238             row[user_defined_type_catalog]  = database.getCatalogName().name;
8239             row[user_defined_type_schema]   = type.getSchemaName().name;
8240             row[user_defined_type_name]     = type.getName().name;
8241             row[data_type]                  = type.getFullNameString();
8242             row[user_defined_type_category] = "DISTINCT";
8243             row[is_instantiable]            = "YES";
8244             row[is_final]                   = "YES";
8245             row[ordering_form]              = "FULL";
8246 
8247             // common type block
8248             if (type.isCharacterType()) {
8249                 row[character_maximum_length] =
8250                     ValuePool.getLong(type.precision);
8251                 row[character_octet_length] = ValuePool.getLong(type.precision
8252                         * 2);
8253                 row[character_set_catalog] = database.getCatalogName().name;
8254                 row[character_set_schema] =
8255                     type.getCharacterSet().getSchemaName().name;
8256                 row[character_set_name] =
8257                     type.getCharacterSet().getName().name;
8258                 row[collation_catalog] = database.getCatalogName().name;
8259                 row[collation_schema] =
8260                     type.getCollation().getSchemaName().name;
8261                 row[collation_name] = type.getCollation().getName().name;
8262             } else if (type.isNumberType()) {
8263                 row[numeric_precision] = ValuePool.getLong(
8264                     ((NumberType) type).getNumericPrecisionInRadix());
8265                 row[declared_numeric_precision] = ValuePool.getLong(
8266                     ((NumberType) type).getNumericPrecisionInRadix());
8267 
8268                 if (type.isExactNumberType()) {
8269                     row[numeric_scale] = row[declared_numeric_scale] =
8270                         ValuePool.getLong(type.scale);
8271                 }
8272 
8273                 row[numeric_precision_radix] =
8274                     ValuePool.getLong(type.getPrecisionRadix());
8275             } else if (type.isBooleanType()) {}
8276             else if (type.isDateTimeType()) {
8277                 row[datetime_precision] = ValuePool.getLong(type.scale);
8278             } else if (type.isIntervalType()) {
8279                 row[data_type]          = "INTERVAL";
8280                 row[interval_type] = IntervalType.getQualifier(type.typeCode);
8281                 row[interval_precision] = ValuePool.getLong(type.precision);
8282                 row[datetime_precision] = ValuePool.getLong(type.scale);
8283             } else if (type.isBinaryType()) {
8284                 row[character_maximum_length] =
8285                     ValuePool.getLong(type.precision);
8286                 row[character_octet_length] =
8287                     ValuePool.getLong(type.precision);
8288             } else if (type.isBitType()) {
8289                 row[character_maximum_length] =
8290                     ValuePool.getLong(type.precision);
8291                 row[character_octet_length] =
8292                     ValuePool.getLong(type.precision);
8293             } else if (type.isArrayType()) {
8294                 row[maximum_cardinality] =
8295                     ValuePool.getLong(type.arrayLimitCardinality());
8296                 row[data_type] = "ARRAY";
8297             }
8298 
8299             // end common block
8300             row[source_dtd_identifier] = type.getDefinition();
8301             row[declared_data_type]    = row[data_type];
8302 
8303             t.insertSys(session, store, row);
8304         }
8305 
8306         return t;
8307     }
8308 
8309     /**
8310      * SQL:2008 VIEW<p>
8311      *
8312      * The VIEW_COLUMN_USAGE view has one row for each column of a
8313      * table that is explicitly or implicitly referenced in the
8314      * &lt;query expression&gt; of the view being described. <p>
8315      *
8316      * <b>Definition:</b> <p>
8317      *
8318      * <pre class="SqlCodeExample">
8319      *      VIEW_CATALOG    VARCHAR NULL,
8320      *      VIEW_SCHEMA     VARCHAR NULL,
8321      *      VIEW_NAME       VARCHAR NOT NULL,
8322      *      TABLE_CATALOG   VARCHAR NULL,
8323      *      TABLE_SCHEMA    VARCHAR NULL,
8324      *      TABLE_NAME      VARCHAR NOT NULL,
8325      *      COLUMN_NAME     VARCHAR NOT NULL,
8326      * </pre>
8327      *
8328      * <b>Description:</b> <p>
8329      *
8330      * <ol>
8331      * <li> The values of VIEW_CATALOG, VIEW_SCHEMA, and VIEW_NAME are the
8332      *      catalog name, schema name, and identifier,
8333      *      respectively, of the view being described. <p>
8334      *
8335      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and
8336      *      COLUMN_NAME are the catalog name, schema name,
8337      *      table name, and column name, respectively, of a column
8338      *      of a table that is explicitly or implicitly referenced in the
8339      *      &lt;query expression&gt; of the view being described.
8340      * <1i> Referenced routines are reported only if the user or one of its roles is
8341      *      the authorization (owner) of the referenced ROUTINE
8342      * </ol>
8343      *
8344      * @return Table
8345      */
VIEW_COLUMN_USAGE(Session session, PersistentStore store)8346     Table VIEW_COLUMN_USAGE(Session session, PersistentStore store) {
8347 
8348         Table t = sysTables[VIEW_COLUMN_USAGE];
8349 
8350         if (t == null) {
8351             t = createBlankTable(sysTableHsqlNames[VIEW_COLUMN_USAGE]);
8352 
8353             addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
8354             addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
8355             addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);
8356             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
8357             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
8358             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);
8359             addColumn(t, "COLUMN_NAME", SQL_IDENTIFIER);
8360 
8361             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8362                 sysTableHsqlNames[VIEW_COLUMN_USAGE].name, false,
8363                 SchemaObject.INDEX);
8364 
8365             t.createPrimaryKeyConstraint(name, new int[] {
8366                 0, 1, 2, 3, 4, 5, 6
8367             }, false);
8368 
8369             return t;
8370         }
8371 
8372         // Calculated column values
8373         String viewCatalog;
8374         String viewSchema;
8375         String viewName;
8376 
8377         // Intermediate holders
8378         Iterator tables;
8379         View     view;
8380         Table    table;
8381         Object[] row;
8382         Iterator iterator;
8383 
8384         // Column number mappings
8385         final int view_catalog  = 0;
8386         final int view_schema   = 1;
8387         final int view_name     = 2;
8388         final int table_catalog = 3;
8389         final int table_schema  = 4;
8390         final int table_name    = 5;
8391         final int column_name   = 6;
8392 
8393         // Initialization
8394         tables =
8395             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
8396 
8397         // Do it.
8398         while (tables.hasNext()) {
8399             table = (Table) tables.next();
8400 
8401             if (table.isView()
8402                     && session.getGrantee().isFullyAccessibleByRole(
8403                         table.getName())) {
8404 
8405                 // fall through
8406             } else {
8407                 continue;
8408             }
8409 
8410             viewCatalog = database.getCatalogName().name;
8411             viewSchema  = table.getSchemaName().name;
8412             viewName    = table.getName().name;
8413             view        = (View) table;
8414 
8415             OrderedHashSet references = view.getReferences();
8416 
8417             iterator = references.iterator();
8418 
8419             while (iterator.hasNext()) {
8420                 HsqlName refName = (HsqlName) iterator.next();
8421 
8422                 if (refName.type != SchemaObject.COLUMN) {
8423                     continue;
8424                 }
8425 
8426                 row                = t.getEmptyRowData();
8427                 row[view_catalog]  = viewCatalog;
8428                 row[view_schema]   = viewSchema;
8429                 row[view_name]     = viewName;
8430                 row[table_catalog] = viewCatalog;
8431                 row[table_schema]  = refName.parent.schema.name;
8432                 row[table_name]    = refName.parent.name;
8433                 row[column_name]   = refName.name;
8434 
8435                 try {
8436                     t.insertSys(session, store, row);
8437                 } catch (HsqlException e) {}
8438             }
8439         }
8440 
8441         return t;
8442     }
8443 
8444     /**
8445      * SQL:2008 VIEW<p>
8446      *
8447      * The VIEW_ROUTINE_USAGE view has one row for each SQL-invoked
8448      * routine identified as the subject routine of either a &lt;routine
8449      * invocation&gt;, a &lt;method reference&gt;, a &lt;method invocation&gt;,
8450      * or a &lt;static method invocation&gt; contained in a &lt;view
8451      * definition&gt;. <p>
8452      *
8453      * <b>Definition</b><p>
8454      *
8455      * <pre class="SqlCodeExample">
8456      *      TABLE_CATALOG       VARCHAR NULL,
8457      *      TABLE_SCHEMA        VARCHAR NULL,
8458      *      TABLE_NAME          VARCHAR NOT NULL,
8459      *      SPECIFIC_CATALOG    VARCHAR NULL,
8460      *      SPECIFIC_SCHEMA     VARCHAR NULL,
8461      *      SPECIFIC_NAME       VARCHAR NOT NULL,
8462      * </pre>
8463      *
8464      * <b>Description</b><p>
8465      *
8466      * <ol>
8467      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
8468      *      catalog name, schema name, and identifier,
8469      *      respectively, of the viewed table being described.
8470      *
8471      * <li> The values of SPECIFIC_CATALOG, SPECIFIC_SCHEMA, and SPECIFIC_NAME are
8472      *      the catalog name, schema name, and identifier,
8473      *      respectively, of the specific name of R.
8474      * <1i> Referenced routines are reported only if the user or one of its roles is
8475      *      the authorization (owner) of the referenced ROUTINE.
8476      * </ol>
8477      *
8478      * @return Table
8479      */
VIEW_ROUTINE_USAGE(Session session, PersistentStore store)8480     Table VIEW_ROUTINE_USAGE(Session session, PersistentStore store) {
8481 
8482         Table t = sysTables[VIEW_ROUTINE_USAGE];
8483 
8484         if (t == null) {
8485             t = createBlankTable(sysTableHsqlNames[VIEW_ROUTINE_USAGE]);
8486 
8487             addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
8488             addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
8489             addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);
8490             addColumn(t, "SPECIFIC_CATALOG", SQL_IDENTIFIER);
8491             addColumn(t, "SPECIFIC_SCHEMA", SQL_IDENTIFIER);
8492             addColumn(t, "SPECIFIC_NAME", SQL_IDENTIFIER);
8493 
8494             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8495                 sysTableHsqlNames[VIEW_ROUTINE_USAGE].name, false,
8496                 SchemaObject.INDEX);
8497 
8498             t.createPrimaryKeyConstraint(name, new int[] {
8499                 0, 1, 2, 3, 4, 5
8500             }, false);
8501 
8502             return t;
8503         }
8504 
8505         // Intermediate holders
8506         Iterator tables;
8507         Table    table;
8508         Object[] row;
8509 
8510         // Column number mappings
8511         final int view_catalog     = 0;
8512         final int view_schema      = 1;
8513         final int view_name        = 2;
8514         final int specific_catalog = 3;
8515         final int specific_schema  = 4;
8516         final int specific_name    = 5;
8517 
8518         // Initialization
8519         tables =
8520             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
8521 
8522         // Do it.
8523         while (tables.hasNext()) {
8524             table = (Table) tables.next();
8525 
8526             if (!table.isView()) {
8527                 continue;
8528             }
8529 
8530             OrderedHashSet set = table.getReferences();
8531 
8532             for (int i = 0; i < set.size(); i++) {
8533                 HsqlName refName = (HsqlName) set.get(i);
8534 
8535                 if (refName.type != SchemaObject.SPECIFIC_ROUTINE) {
8536                     continue;
8537                 }
8538 
8539                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
8540                     continue;
8541                 }
8542 
8543                 row                   = t.getEmptyRowData();
8544                 row[view_catalog]     = database.getCatalogName().name;
8545                 row[view_schema]      = table.getSchemaName().name;
8546                 row[view_name]        = table.getName().name;
8547                 row[specific_catalog] = database.getCatalogName().name;
8548                 row[specific_schema]  = refName.schema.name;
8549                 row[specific_name]    = refName.name;
8550 
8551                 try {
8552                     t.insertSys(session, store, row);
8553                 } catch (HsqlException e) {}
8554             }
8555         }
8556 
8557         return t;
8558     }
8559 
8560     /**
8561      * SQL:2008 VIEW<p>
8562      *
8563      * The VIEW_TABLE_USAGE view has one row for each table identified
8564      * by a &lt;table name&gt; simply contained in a &lt;table reference&gt;
8565      * that is contained in the &lt;query expression&gt; of a view. <p>
8566      *
8567      * <b>Definition</b><p>
8568      *
8569      * <pre class="SqlCodeExample">
8570      *      VIEW_CATALOG    VARCHAR NULL,
8571      *      VIEW_SCHEMA     VARCHAR NULL,
8572      *      VIEW_NAME       VARCHAR NULL,
8573      *      TABLE_CATALOG   VARCHAR NULL,
8574      *      TABLE_SCHEMA    VARCHAR NULL,
8575      *      TABLE_NAME      VARCHAR NULL,
8576      * </pre>
8577      *
8578      * <b>Description:</b><p>
8579      *
8580      * <ol>
8581      * <li> The values of VIEW_CATALOG, VIEW_SCHEMA, and VIEW_NAME are the
8582      *      catalog name, schema name, and identifier,
8583      *      respectively, of the view being described. <p>
8584      *
8585      * <li> The values of TABLE_CATALOG, TABLE_SCHEMA, and TABLE_NAME are the
8586      *      catalog name, schema name, and identifier,
8587      *      respectively, of a table identified by a &lt;table name&gt;
8588      *      simply contained in a &lt;table reference&gt; that is contained in
8589      *      the &lt;query expression&gt; of the view being described.
8590      * <1i> Referenced tables are reported only if the user or one of its roles is
8591      *      the authorization (owner) of the referenced TABLE
8592      * </ol>
8593      *
8594      * @return Table
8595      */
VIEW_TABLE_USAGE(Session session, PersistentStore store)8596     Table VIEW_TABLE_USAGE(Session session, PersistentStore store) {
8597 
8598         Table t = sysTables[VIEW_TABLE_USAGE];
8599 
8600         if (t == null) {
8601             t = createBlankTable(sysTableHsqlNames[VIEW_TABLE_USAGE]);
8602 
8603             addColumn(t, "VIEW_CATALOG", SQL_IDENTIFIER);
8604             addColumn(t, "VIEW_SCHEMA", SQL_IDENTIFIER);
8605             addColumn(t, "VIEW_NAME", SQL_IDENTIFIER);     // not null
8606             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
8607             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
8608             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);    // not null
8609 
8610             // false PK, as VIEW_CATALOG, VIEW_SCHEMA, TABLE_CATALOG, and/or
8611             // TABLE_SCHEMA may be NULL
8612             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8613                 sysTableHsqlNames[VIEW_TABLE_USAGE].name, false,
8614                 SchemaObject.INDEX);
8615 
8616             t.createPrimaryKeyConstraint(name, new int[] {
8617                 0, 1, 2, 3, 4, 5
8618             }, false);
8619 
8620             return t;
8621         }
8622 
8623         // Column number mappings
8624         final int view_catalog  = 0;
8625         final int view_schema   = 1;
8626         final int view_name     = 2;
8627         final int table_catalog = 3;
8628         final int table_schema  = 4;
8629         final int table_name    = 5;
8630 
8631         //
8632         Iterator tables;
8633         Table    table;
8634         Object[] row;
8635 
8636         // Initialization
8637         tables =
8638             database.schemaManager.databaseObjectIterator(SchemaObject.TABLE);
8639 
8640         // Do it.
8641         while (tables.hasNext()) {
8642             table = (Table) tables.next();
8643 
8644             if (!table.isView()) {
8645                 continue;
8646             }
8647 
8648             OrderedHashSet references = table.getReferences();
8649 
8650             for (int i = 0; i < references.size(); i++) {
8651                 HsqlName refName = (HsqlName) references.get(i);
8652 
8653                 if (refName.type != SchemaObject.TABLE
8654                         && refName.type != SchemaObject.VIEW) {
8655                     continue;
8656                 }
8657 
8658                 if (!session.getGrantee().isFullyAccessibleByRole(refName)) {
8659                     continue;
8660                 }
8661 
8662                 row                = t.getEmptyRowData();
8663                 row[view_catalog]  = database.getCatalogName().name;
8664                 row[view_schema]   = table.getSchemaName().name;
8665                 row[view_name]     = table.getName().name;
8666                 row[table_catalog] = database.getCatalogName().name;
8667                 row[table_schema]  = refName.schema.name;
8668                 row[table_name]    = refName.name;
8669 
8670                 try {
8671                     t.insertSys(session, store, row);
8672                 } catch (HsqlException e) {}
8673             }
8674         }
8675 
8676         return t;
8677     }
8678 
8679     /**
8680      * SQL:2008 VIEW<p>
8681      *
8682      * The VIEWS view contains one row for each VIEW definition. <p>
8683      *
8684      * Each row is a description of the query expression that defines its view,
8685      * with the following columns:
8686      *
8687      * <pre class="SqlCodeExample">
8688      *      TABLE_CATALOG    VARCHAR     name of view's defining catalog.
8689      *      TABLE_SCHEMA     VARCHAR     name of view's defining schema.
8690      *      TABLE_NAME       VARCHAR     the simple name of the view.
8691      *      VIEW_DEFINITION  VARCHAR     the character representation of the
8692      *                                   &lt;query expression&gt; contained in the
8693      *                                   corresponding &lt;view descriptor&gt;.
8694      *      CHECK_OPTION     VARCHAR     {"CASCADED" | "LOCAL" | "NONE"}
8695      *      IS_UPDATABLE     VARCHAR     {"YES" | "NO"}
8696      *      INSERTABLE_INTO VARCHAR      {"YES" | "NO"}
8697      *      IS_TRIGGER_UPDATABLE        VARCHAR  {"YES" | "NO"}
8698      *      IS_TRIGGER_DELETEABLE       VARCHAR  {"YES" | "NO"}
8699      *      IS_TRIGGER_INSERTABLE_INTO  VARCHAR  {"YES" | "NO"}
8700      * </pre> <p>
8701      *
8702      * @return a tabular description of the text source of all
8703      *        <code>View</code> objects accessible to
8704      *        the user.
8705      */
VIEWS(Session session, PersistentStore store)8706     Table VIEWS(Session session, PersistentStore store) {
8707 
8708         Table t = sysTables[VIEWS];
8709 
8710         if (t == null) {
8711             t = createBlankTable(sysTableHsqlNames[VIEWS]);
8712 
8713             addColumn(t, "TABLE_CATALOG", SQL_IDENTIFIER);
8714             addColumn(t, "TABLE_SCHEMA", SQL_IDENTIFIER);
8715             addColumn(t, "TABLE_NAME", SQL_IDENTIFIER);               // not null
8716             addColumn(t, "VIEW_DEFINITION", CHARACTER_DATA);          // not null
8717             addColumn(t, "CHECK_OPTION", CHARACTER_DATA);             // not null
8718             addColumn(t, "IS_UPDATABLE", YES_OR_NO);                  // not null
8719             addColumn(t, "INSERTABLE_INTO", YES_OR_NO);               // not null
8720             addColumn(t, "IS_TRIGGER_UPDATABLE", YES_OR_NO);          // not null
8721             addColumn(t, "IS_TRIGGER_DELETABLE", YES_OR_NO);          // not null
8722             addColumn(t, "IS_TRIGGER_INSERTABLE_INTO", YES_OR_NO);    // not null
8723 
8724             // order TABLE_NAME
8725             // added for unique: TABLE_SCHEMA, TABLE_CATALOG
8726             // false PK, as TABLE_SCHEMA and/or TABLE_CATALOG may be null
8727             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8728                 sysTableHsqlNames[VIEWS].name, false, SchemaObject.INDEX);
8729 
8730             t.createPrimaryKeyConstraint(name, new int[] {
8731                 1, 2, 0
8732             }, false);
8733 
8734             return t;
8735         }
8736 
8737         Iterator  tables;
8738         Table     table;
8739         Object[]  row;
8740         final int table_catalog              = 0;
8741         final int table_schema               = 1;
8742         final int table_name                 = 2;
8743         final int view_definition            = 3;
8744         final int check_option               = 4;
8745         final int is_updatable               = 5;
8746         final int insertable_into            = 6;
8747         final int is_trigger_updatable       = 7;
8748         final int is_trigger_deletable       = 8;
8749         final int is_trigger_insertable_into = 9;
8750 
8751         tables = allTables();
8752 
8753         while (tables.hasNext()) {
8754             table = (Table) tables.next();
8755 
8756             if (!table.isView()
8757                     && table.getSchemaName()
8758                        != SqlInvariants.INFORMATION_SCHEMA_HSQLNAME) {
8759                 continue;
8760             }
8761 
8762             if (!isAccessibleTable(session, table)) {
8763                 continue;
8764             }
8765 
8766             row                = t.getEmptyRowData();
8767             row[table_catalog] = database.getCatalogName().name;
8768             row[table_schema]  = table.getSchemaName().name;
8769             row[table_name]    = table.getName().name;
8770 
8771             String check = Tokens.T_NONE;
8772 
8773             if (table instanceof View) {
8774                 if (session.getGrantee().isFullyAccessibleByRole(
8775                         table.getName())) {
8776                     row[view_definition] = ((View) table).getStatement();
8777                 }
8778 
8779                 switch (((View) table).getCheckOption()) {
8780 
8781                     case SchemaObject.ViewCheckModes.CHECK_NONE :
8782                         break;
8783 
8784                     case SchemaObject.ViewCheckModes.CHECK_LOCAL :
8785                         check = Tokens.T_LOCAL;
8786                         break;
8787 
8788                     case SchemaObject.ViewCheckModes.CHECK_CASCADE :
8789                         check = Tokens.T_CASCADED;
8790                         break;
8791                 }
8792             }
8793 
8794             row[check_option]    = check;
8795             row[is_updatable]    = table.isUpdatable() ? Tokens.T_YES
8796                                                        : Tokens.T_NO;
8797             row[insertable_into] = table.isInsertable() ? Tokens.T_YES
8798                                                         : Tokens.T_NO;
8799             row[is_trigger_updatable] = table.isTriggerUpdatable()
8800                                         ? Tokens.T_YES
8801                                         : Tokens.T_NO;
8802             row[is_trigger_deletable] = table.isTriggerDeletable()
8803                                         ? Tokens.T_YES
8804                                         : Tokens.T_NO;
8805             row[is_trigger_insertable_into] = table.isTriggerInsertable()
8806                                               ? Tokens.T_YES
8807                                               : Tokens.T_NO;
8808 
8809             t.insertSys(session, store, row);
8810         }
8811 
8812         return t;
8813     }
8814 
8815 //------------------------------------------------------------------------------
8816 // SQL SCHEMATA BASE TABLES
8817 
8818     /**
8819      * SQL:2008 VIEW<p>
8820      *
8821      * ROLE_AUTHORIZATION_DESCRIPTORS<p>
8822      *
8823      * Contains a representation of the role authorization descriptors.<p>
8824      * <b>Definition</b>
8825      *
8826      * <pre class="SqlCodeExample">
8827      *      ROLE_NAME     VARCHAR     name of view's defining catalog.
8828      *      GRANTEE       VARCHAR     name of view's defining schema.
8829      *      GRANTOR       VARCHAR     the simple name of the view.
8830      *      IS_GRANTABLE  VARCHAR     the character representation of the
8831      * </pre>
8832      *
8833      * <b>Description</b><p>
8834      *
8835      * <ol>
8836      *      <li>The value of ROLE_NAME is the &lt;role name&gt; of some
8837      *          &lt;role granted&gt; by the &lt;grant role statement&gt; or
8838      *          the &lt;role name&gt; of a &lt;role definition&gt;. <p>
8839      *
8840      *      <li>The value of GRANTEE is an &lt;authorization identifier&gt;,
8841      *          possibly PUBLIC, or &lt;role name&gt; specified as a
8842      *          &lt;grantee&gt; contained in a &lt;grant role statement&gt;,
8843      *          or the &lt;authorization identifier&gt; of the current
8844      *          SQLsession when the &lt;role definition&gt; is executed. <p>
8845      *
8846      *      <li>The value of GRANTOR is the &lt;authorization identifier&gt;
8847      *          of the user or role who granted the role identified by
8848      *          ROLE_NAME to the user or role identified by the value of
8849      *          GRANTEE. <p>
8850      *
8851      *      <li>The values of IS_GRANTABLE have the following meanings:<p>
8852      *
8853      *      <table border cellpadding="3">
8854      *          <tr>
8855      *              <td nowrap>YES</td>
8856      *              <td nowrap>The described role is grantable.</td>
8857      *          <tr>
8858      *          <tr>
8859      *              <td nowrap>NO</td>
8860      *              <td nowrap>The described role is not grantable.</td>
8861      *          <tr>
8862      *      </table> <p>
8863      * </ol>
8864      *
8865      * @return Table
8866      */
ROLE_AUTHORIZATION_DESCRIPTORS(Session session, PersistentStore store)8867     Table ROLE_AUTHORIZATION_DESCRIPTORS(Session session,
8868                                          PersistentStore store) {
8869 
8870         Table t = sysTables[ROLE_AUTHORIZATION_DESCRIPTORS];
8871 
8872         if (t == null) {
8873             t = createBlankTable(
8874                 sysTableHsqlNames[ROLE_AUTHORIZATION_DESCRIPTORS]);
8875 
8876             addColumn(t, "ROLE_NAME", SQL_IDENTIFIER);    // not null
8877             addColumn(t, "GRANTEE", SQL_IDENTIFIER);      // not null
8878             addColumn(t, "GRANTOR", SQL_IDENTIFIER);      // not null
8879             addColumn(t, "IS_GRANTABLE", YES_OR_NO);      // not null
8880 
8881             // true PK
8882             HsqlName name = HsqlNameManager.newInfoSchemaObjectName(
8883                 sysTableHsqlNames[ROLE_AUTHORIZATION_DESCRIPTORS].name, false,
8884                 SchemaObject.INDEX);
8885 
8886             t.createPrimaryKeyConstraint(name, new int[] {
8887                 0, 1
8888             }, true);
8889 
8890             return t;
8891         }
8892 
8893         // Intermediate holders
8894         String   grantorName = SqlInvariants.SYSTEM_AUTHORIZATION_NAME;
8895         Iterator grantees;
8896         Grantee  granteeObject;
8897         String   granteeName;
8898         Iterator roles;
8899         String   isGrantable;
8900         Object[] row;
8901 
8902         // Column number mappings
8903         final int role_name    = 0;
8904         final int grantee      = 1;
8905         final int grantor      = 2;
8906         final int is_grantable = 3;
8907 
8908         // Initialization
8909         grantees = session.getGrantee().visibleGrantees().iterator();
8910 
8911         //
8912         while (grantees.hasNext()) {
8913             granteeObject = (Grantee) grantees.next();
8914             granteeName   = granteeObject.getName().getNameString();
8915             roles         = granteeObject.getDirectRoles().iterator();
8916             isGrantable   = granteeObject.isAdmin() ? Tokens.T_YES
8917                                                     : Tokens.T_NO;
8918 
8919             while (roles.hasNext()) {
8920                 Grantee role = (Grantee) roles.next();
8921 
8922                 row               = t.getEmptyRowData();
8923                 row[role_name]    = role.getName().getNameString();
8924                 row[grantee]      = granteeName;
8925                 row[grantor]      = grantorName;
8926                 row[is_grantable] = isGrantable;
8927 
8928                 t.insertSys(session, store, row);
8929             }
8930         }
8931 
8932         return t;
8933     }
8934 }
8935