1 {*********************************************************}
3 { Zeos Database Objects }
4 { Interbase Database Connectivity Classes }
6 { Originally written by Sergey Merkuriev }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
52 unit ZDbcInterbase6Metadata;
59 Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata, ZCompatibility,
60 ZDbcConnection, ZDbcInterbase6, ZURL;
64 // technobot 2008-06-25 - methods moved as is from TZInterbase6DatabaseMetadata:
65 {** Implements Interbase6 Database Information. }
66 IZInterbaseDatabaseInfo = Interface(IZDatabaseInfo)
67 ['{F2895A2A-C427-4984-9356-79349EAAD44F}']
68 function HostIsFireBird: Boolean;
69 procedure CollectServerInformations;
72 TZInterbase6DatabaseInfo = class(TZAbstractDatabaseInfo, IZInterbaseDatabaseInfo)
75 FServerVersion: string;
76 FProductVersion: String;
77 // function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
78 // const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;
80 procedure CollectServerInformations;
81 function HostIsFireBird: Boolean;
82 // database/driver/server info:
83 function GetDatabaseProductName: string; override;
84 function GetDatabaseProductVersion: string; override;
85 function GetDriverName: string; override;
86 // function GetDriverVersion: string; override; -> Same as parent
87 function GetDriverMajorVersion: Integer; override;
88 function GetDriverMinorVersion: Integer; override;
89 function GetServerVersion: string; override;
91 // capabilities (what it can/cannot do):
92 // function AllProceduresAreCallable: Boolean; override; -> Not implemented
93 // function AllTablesAreSelectable: Boolean; override; -> Not implemented
94 function SupportsMixedCaseIdentifiers: Boolean; override;
95 function SupportsMixedCaseQuotedIdentifiers: Boolean; override;
96 // function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented
97 // function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented
98 // function SupportsColumnAliasing: Boolean; override; -> Not implemented
99 // function SupportsConvert: Boolean; override; -> Not implemented
100 // function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):
101 // Boolean; override; -> Not implemented
102 // function SupportsTableCorrelationNames: Boolean; override; -> Not implemented
103 // function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented
104 function SupportsExpressionsInOrderBy: Boolean; override;
105 function SupportsOrderByUnrelated: Boolean; override;
106 function SupportsGroupBy: Boolean; override;
107 function SupportsGroupByUnrelated: Boolean; override;
108 function SupportsGroupByBeyondSelect: Boolean; override;
109 // function SupportsLikeEscapeClause: Boolean; override; -> Not implemented
110 // function SupportsMultipleResultSets: Boolean; override; -> Not implemented
111 // function SupportsMultipleTransactions: Boolean; override; -> Not implemented
112 // function SupportsNonNullableColumns: Boolean; override; -> Not implemented
113 // function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented
114 // function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented
115 // function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented
116 // function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented
117 // function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented
118 // function SupportsANSI92FullSQL: Boolean; override; -> Not implemented
119 function SupportsIntegrityEnhancementFacility: Boolean; override;
120 // function SupportsOuterJoins: Boolean; override; -> Not implemented
121 // function SupportsFullOuterJoins: Boolean; override; -> Not implemented
122 // function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented
123 function SupportsSchemasInDataManipulation: Boolean; override;
124 function SupportsSchemasInProcedureCalls: Boolean; override;
125 function SupportsSchemasInTableDefinitions: Boolean; override;
126 function SupportsSchemasInIndexDefinitions: Boolean; override;
127 function SupportsSchemasInPrivilegeDefinitions: Boolean; override;
128 function SupportsCatalogsInDataManipulation: Boolean; override;
129 function SupportsCatalogsInProcedureCalls: Boolean; override;
130 function SupportsCatalogsInTableDefinitions: Boolean; override;
131 function SupportsCatalogsInIndexDefinitions: Boolean; override;
132 function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;
133 function SupportsPositionedDelete: Boolean; override;
134 function SupportsPositionedUpdate: Boolean; override;
135 function SupportsSelectForUpdate: Boolean; override;
136 function SupportsStoredProcedures: Boolean; override;
137 function SupportsSubqueriesInComparisons: Boolean; override;
138 function SupportsSubqueriesInExists: Boolean; override;
139 function SupportsSubqueriesInIns: Boolean; override;
140 function SupportsSubqueriesInQuantifieds: Boolean; override;
141 function SupportsCorrelatedSubqueries: Boolean; override;
142 function SupportsUnion: Boolean; override;
143 function SupportsUnionAll: Boolean; override;
144 function SupportsOpenCursorsAcrossCommit: Boolean; override;
145 function SupportsOpenCursorsAcrossRollback: Boolean; override;
146 function SupportsOpenStatementsAcrossCommit: Boolean; override;
147 function SupportsOpenStatementsAcrossRollback: Boolean; override;
148 function SupportsTransactions: Boolean; override;
149 function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):
151 function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;
152 function SupportsDataManipulationTransactionsOnly: Boolean; override;
153 function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;
154 function SupportsResultSetConcurrency(_Type: TZResultSetType;
155 Concurrency: TZResultSetConcurrency): Boolean; override;
156 // function SupportsBatchUpdates: Boolean; override; -> Not implemented
159 function GetMaxBinaryLiteralLength: Integer; override;
160 function GetMaxCharLiteralLength: Integer; override;
161 function GetMaxColumnNameLength: Integer; override;
162 function GetMaxColumnsInGroupBy: Integer; override;
163 function GetMaxColumnsInIndex: Integer; override;
164 function GetMaxColumnsInOrderBy: Integer; override;
165 function GetMaxColumnsInSelect: Integer; override;
166 function GetMaxColumnsInTable: Integer; override;
167 function GetMaxConnections: Integer; override;
168 function GetMaxCursorNameLength: Integer; override;
169 function GetMaxIndexLength: Integer; override;
170 function GetMaxSchemaNameLength: Integer; override;
171 function GetMaxProcedureNameLength: Integer; override;
172 function GetMaxCatalogNameLength: Integer; override;
173 function GetMaxRowSize: Integer; override;
174 function GetMaxStatementLength: Integer; override;
175 function GetMaxStatements: Integer; override;
176 function GetMaxTableNameLength: Integer; override;
177 function GetMaxTablesInSelect: Integer; override;
178 function GetMaxUserNameLength: Integer; override;
180 // policies (how are various data and operations handled):
181 // function IsReadOnly: Boolean; override; -> Not implemented
182 // function IsCatalogAtStart: Boolean; override; -> Not implemented
183 function DoesMaxRowSizeIncludeBlobs: Boolean; override;
184 // function NullsAreSortedHigh: Boolean; override; -> Not implemented
185 // function NullsAreSortedLow: Boolean; override; -> Not implemented
186 // function NullsAreSortedAtStart: Boolean; override; -> Not implemented
187 // function NullsAreSortedAtEnd: Boolean; override; -> Not implemented
188 // function NullPlusNonNullIsNull: Boolean; override; -> Not implemented
189 // function UsesLocalFiles: Boolean; override; -> Not implemented
190 function UsesLocalFilePerTable: Boolean; override;
191 function StoresUpperCaseIdentifiers: Boolean; override;
192 function StoresLowerCaseIdentifiers: Boolean; override;
193 function StoresMixedCaseIdentifiers: Boolean; override;
194 function StoresUpperCaseQuotedIdentifiers: Boolean; override;
195 function StoresLowerCaseQuotedIdentifiers: Boolean; override;
196 function StoresMixedCaseQuotedIdentifiers: Boolean; override;
197 function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;
198 function DataDefinitionCausesTransactionCommit: Boolean; override;
199 function DataDefinitionIgnoredInTransactions: Boolean; override;
201 // interface details (terms, keywords, etc):
202 function GetSchemaTerm: string; override;
203 function GetProcedureTerm: string; override;
204 function GetCatalogTerm: string; override;
205 function GetCatalogSeparator: string; override;
206 function GetSQLKeywords: string; override;
207 function GetNumericFunctions: string; override;
208 function GetStringFunctions: string; override;
209 function GetSystemFunctions: string; override;
210 function GetTimeDateFunctions: string; override;
211 function GetSearchStringEscape: string; override;
212 function GetExtraNameCharacters: string; override;
215 {** Implements Interbase6 Database Metadata. }
216 TZInterbase6DatabaseMetadata = class(TZAbstractDatabaseMetadata)
218 function GetPrivilege(Privilege: string): string;
220 function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-25
221 function ConstructNameCondition(Pattern: string; Column: string): string; override;
223 function UncachedGetTables(const Catalog: string; const SchemaPattern: string;
224 const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;
225 // function UncachedGetSchemas: IZResultSet; override; -> Not implemented
226 // function UncachedGetCatalogs: IZResultSet; override; -> Not Implemented
227 function UncachedGetTableTypes: IZResultSet; override;
228 function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;
229 const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;
230 function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;
231 const TableNamePattern: string): IZResultSet; override;
232 function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;
233 const Table: string; const ColumnNamePattern: string): IZResultSet; override;
234 function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;
235 const Table: string): IZResultSet; override;
236 function UncachedGetImportedKeys(const Catalog: string; const Schema: string;
237 const Table: string): IZResultSet; override;
238 function UncachedGetExportedKeys(const Catalog: string; const Schema: string;
239 const Table: string): IZResultSet; override;
240 function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;
241 const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
242 const ForeignTable: string): IZResultSet; override;
243 function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;
244 Unique: Boolean; Approximate: Boolean): IZResultSet; override;
245 function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;
246 const SequenceNamePattern: string): IZResultSet; override;
247 function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;
248 const ProcedureNamePattern: string): IZResultSet; override;
249 function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;
250 const ProcedureNamePattern: string; const ColumnNamePattern: string):
251 IZResultSet; override;
252 function UncachedGetVersionColumns(const Catalog: string; const Schema: string;
253 const Table: string): IZResultSet; override;
254 function UncachedGetTypeInfo: IZResultSet; override;
255 function UncachedGetTriggers(const Catalog: string;
256 const SchemaPattern: string; const TableNamePattern: string;
257 const TriggerNamePattern: string): IZResultSet; override; //EgonHugesit
258 function UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,
259 TableNamePattern, ColumnNamePattern: string): IZResultSet; override; //EgonHugeist
260 function UncachedGetCharacterSets: IZResultSet; override; //EgonHugeist
262 property ConSettings;
267 uses ZMessages, ZDbcInterbase6Utils, ZPlainFirebirdInterbaseConstants;
270 DBProvider: array[Boolean] of String = ('Interbase', 'Firebird');
272 { TZInterbase6DatabaseInfo }
274 //----------------------------------------------------------------------
275 // First, a variety of minor information about the target database.
277 procedure TZInterbase6DatabaseInfo.CollectServerInformations;
279 FIBConnection: IZInterbase6Connection;
281 if FServerVersion = '' then
283 FIBConnection := Metadata.GetConnection as IZInterbase6Connection;
284 FServerVersion := String(GetVersion(FIBConnection.GetPlainDriver,
285 FIBConnection.GetDBHandle));
286 FIsFireBird := Pos('Firebird', FServerVersion) > 0;
287 FProductVersion := Copy(FServerVersion, Pos(DBProvider[FIsFireBird],
288 FServerVersion)+8+Ord(not FIsFireBird)+1, Length(FServerVersion));
292 function TZInterbase6DatabaseInfo.HostIsFireBird: Boolean;
294 Result := FIsFireBird;
298 What's the name of this database product?
299 @return database product name
301 function TZInterbase6DatabaseInfo.GetDatabaseProductName: string;
303 Result := DBProvider[FIsFireBird];
307 What's the version of this database product?
308 @return database version
310 function TZInterbase6DatabaseInfo.GetDatabaseProductVersion: string;
312 Result := FProductVersion;
316 What's the name of this JDBC driver?
317 @return JDBC driver name
319 function TZInterbase6DatabaseInfo.GetDriverName: string;
321 Result := 'Zeos Database Connectivity Driver for Interbase and Firebird';
325 What's this JDBC driver's major version number?
326 @return JDBC driver major version
328 function TZInterbase6DatabaseInfo.GetDriverMajorVersion: Integer;
334 What's this JDBC driver's minor version number?
335 @return JDBC driver minor version number
337 function TZInterbase6DatabaseInfo.GetDriverMinorVersion: Integer;
343 Gets the version of the server.
344 @returns the version of the server.
346 function TZInterbase6DatabaseInfo.GetServerVersion: string;
348 if FServerVersion = '' then
350 FServerVersion := String(GetVersion((Metadata.GetConnection as IZInterbase6Connection).GetPlainDriver,
351 (Metadata.GetConnection as IZInterbase6Connection).GetDBHandle));
353 Result := FServerVersion;
357 Does the database use a file for each table?
358 @return true if the database uses a local file for each table
360 function TZInterbase6DatabaseInfo.UsesLocalFilePerTable: Boolean;
366 Does the database treat mixed case unquoted SQL identifiers as
367 case sensitive and as a result store them in mixed case?
368 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.
369 @return <code>true</code> if so; <code>false</code> otherwise
371 function TZInterbase6DatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;
377 Does the database treat mixed case unquoted SQL identifiers as
378 case insensitive and store them in upper case?
379 @return <code>true</code> if so; <code>false</code> otherwise
381 function TZInterbase6DatabaseInfo.StoresUpperCaseIdentifiers: Boolean;
387 Does the database treat mixed case unquoted SQL identifiers as
388 case insensitive and store them in lower case?
389 @return <code>true</code> if so; <code>false</code> otherwise
391 function TZInterbase6DatabaseInfo.StoresLowerCaseIdentifiers: Boolean;
397 Does the database treat mixed case unquoted SQL identifiers as
398 case insensitive and store them in mixed case?
399 @return <code>true</code> if so; <code>false</code> otherwise
401 function TZInterbase6DatabaseInfo.StoresMixedCaseIdentifiers: Boolean;
407 Does the database treat mixed case quoted SQL identifiers as
408 case sensitive and as a result store them in mixed case?
409 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.
410 @return <code>true</code> if so; <code>false</code> otherwise
412 function TZInterbase6DatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;
418 Does the database treat mixed case quoted SQL identifiers as
419 case insensitive and store them in upper case?
420 @return <code>true</code> if so; <code>false</code> otherwise
422 function TZInterbase6DatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;
428 Does the database treat mixed case quoted SQL identifiers as
429 case insensitive and store them in lower case?
430 @return <code>true</code> if so; <code>false</code> otherwise
432 function TZInterbase6DatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;
438 Does the database treat mixed case quoted SQL identifiers as
439 case insensitive and store them in mixed case?
440 @return <code>true</code> if so; <code>false</code> otherwise
442 function TZInterbase6DatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;
448 Gets a comma-separated list of all a database's SQL keywords
449 that are NOT also SQL92 keywords.
452 function TZInterbase6DatabaseInfo.GetSQLKeywords: string;
454 Result := 'ACTIVE,AFTER,ASCENDING,BASE_NAME,BEFORE,BLOB,' +
455 'CACHE,CHECK_POINT_LENGTH,COMPUTED,CONDITIONAL,CONTAINING,' +
456 'CSTRING,DATABASE,RDB$DB_KEY,DEBUG,DESCENDING,DO,ENTRY_POINT,' +
457 'EXIT,FILE,FILTER,FUNCTION,GDSCODE,GENERATOR,GEN_ID,' +
458 'GROUP_COMMIT_WAIT_TIME,IF,INACTIVE,INPUT_TYPE,INDEX,' +
459 'LOGFILE,LOG_BUFFER_SIZE,MANUAL,MAXIMUM_SEGMENT,MERGE, MESSAGE,' +
460 'MODULE_NAME,NCHAR,NUM_LOG_BUFFERS,OUTPUT_TYPE,OVERFLOW,PAGE,' +
461 'PAGES,PAGE_SIZE,PARAMETER,PASSWORD,PLAN,POST_EVENT,PROTECTED,' +
462 'RAW_PARTITIONS,RESERV,RESERVING,RETAIN,RETURNING_VALUES,RETURNS,' +
463 'SEGMENT,SHADOW,SHARED,SINGULAR,SNAPSHOT,SORT,STABILITY,STARTS,' +
464 'STARTING,STATISTICS,SUB_TYPE,SUSPEND,TRIGGER,VARIABLE,RECORD_VERSION,' +
465 'WAIT,WHILE,WORK,VALUE,POSITION,USER,CURRENCY,OPTION,DATE,START,END,USER,' +
467 {Ticket #63: http://sourceforge.net/p/zeoslib/tickets/62/}
470 ',DETERMINISTIC,OVER,RETURN,SCROLL,SQLSTATE';
474 Gets a comma-separated list of math functions. These are the
475 X/Open CLI math function names used in the JDBC function escape
479 function TZInterbase6DatabaseInfo.GetNumericFunctions: string;
485 Gets a comma-separated list of string functions. These are the
486 X/Open CLI string function names used in the JDBC function escape
490 function TZInterbase6DatabaseInfo.GetStringFunctions: string;
496 Gets a comma-separated list of system functions. These are the
497 X/Open CLI system function names used in the JDBC function escape
501 function TZInterbase6DatabaseInfo.GetSystemFunctions: string;
507 Gets a comma-separated list of time and date functions.
510 function TZInterbase6DatabaseInfo.GetTimeDateFunctions: string;
516 Gets the string that can be used to escape wildcard characters.
517 This is the string that can be used to escape '_' or '%' in
518 the string pattern style catalog search parameters.
520 <P>The '_' character represents any single character.
521 <P>The '%' character represents any sequence of zero or
524 @return the string used to escape wildcard characters
526 function TZInterbase6DatabaseInfo.GetSearchStringEscape: string;
532 Gets all the "extra" characters that can be used in unquoted
533 identifier names (those beyond a-z, A-Z, 0-9 and _).
534 @return the string containing the extra characters
536 function TZInterbase6DatabaseInfo.GetExtraNameCharacters: string;
541 //--------------------------------------------------------------------
542 // Functions describing which features are supported.
545 Are expressions in "ORDER BY" lists supported?
546 @return <code>true</code> if so; <code>false</code> otherwise
548 function TZInterbase6DatabaseInfo.SupportsExpressionsInOrderBy: Boolean;
554 Can an "ORDER BY" clause use columns not in the SELECT statement?
555 @return <code>true</code> if so; <code>false</code> otherwise
557 function TZInterbase6DatabaseInfo.SupportsOrderByUnrelated: Boolean;
563 Is some form of "GROUP BY" clause supported?
564 @return <code>true</code> if so; <code>false</code> otherwise
566 function TZInterbase6DatabaseInfo.SupportsGroupBy: Boolean;
572 Can a "GROUP BY" clause use columns not in the SELECT?
573 @return <code>true</code> if so; <code>false</code> otherwise
575 function TZInterbase6DatabaseInfo.SupportsGroupByUnrelated: Boolean;
581 Can a "GROUP BY" clause add columns not in the SELECT
582 provided it specifies all the columns in the SELECT?
583 @return <code>true</code> if so; <code>false</code> otherwise
585 function TZInterbase6DatabaseInfo.SupportsGroupByBeyondSelect: Boolean;
591 Is the SQL Integrity Enhancement Facility supported?
592 @return <code>true</code> if so; <code>false</code> otherwise
594 function TZInterbase6DatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;
600 What's the database vendor's preferred term for "schema"?
601 @return the vendor term
603 function TZInterbase6DatabaseInfo.GetSchemaTerm: string;
609 What's the database vendor's preferred term for "procedure"?
610 @return the vendor term
612 function TZInterbase6DatabaseInfo.GetProcedureTerm: string;
614 Result := 'PROCEDURE';
618 What's the database vendor's preferred term for "catalog"?
619 @return the vendor term
621 function TZInterbase6DatabaseInfo.GetCatalogTerm: string;
627 What's the separator between catalog and table name?
628 @return the separator string
630 function TZInterbase6DatabaseInfo.GetCatalogSeparator: string;
636 Can a schema name be used in a data manipulation statement?
637 @return <code>true</code> if so; <code>false</code> otherwise
639 function TZInterbase6DatabaseInfo.SupportsSchemasInDataManipulation: Boolean;
645 Can a schema name be used in a procedure call statement?
646 @return <code>true</code> if so; <code>false</code> otherwise
648 function TZInterbase6DatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;
654 Can a schema name be used in a table definition statement?
655 @return <code>true</code> if so; <code>false</code> otherwise
657 function TZInterbase6DatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;
663 Can a schema name be used in an index definition statement?
664 @return <code>true</code> if so; <code>false</code> otherwise
666 function TZInterbase6DatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;
672 Can a schema name be used in a privilege definition statement?
673 @return <code>true</code> if so; <code>false</code> otherwise
675 function TZInterbase6DatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;
681 Can a catalog name be used in a data manipulation statement?
682 @return <code>true</code> if so; <code>false</code> otherwise
684 function TZInterbase6DatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;
690 Can a catalog name be used in a procedure call statement?
691 @return <code>true</code> if so; <code>false</code> otherwise
693 function TZInterbase6DatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;
699 Can a catalog name be used in a table definition statement?
700 @return <code>true</code> if so; <code>false</code> otherwise
702 function TZInterbase6DatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;
708 Can a catalog name be used in an index definition statement?
709 @return <code>true</code> if so; <code>false</code> otherwise
711 function TZInterbase6DatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;
717 Can a catalog name be used in a privilege definition statement?
718 @return <code>true</code> if so; <code>false</code> otherwise
720 function TZInterbase6DatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;
726 Is positioned DELETE supported?
727 @return <code>true</code> if so; <code>false</code> otherwise
729 function TZInterbase6DatabaseInfo.SupportsPositionedDelete: Boolean;
735 Is positioned UPDATE supported?
736 @return <code>true</code> if so; <code>false</code> otherwise
738 function TZInterbase6DatabaseInfo.SupportsPositionedUpdate: Boolean;
744 Is SELECT for UPDATE supported?
745 @return <code>true</code> if so; <code>false</code> otherwise
747 function TZInterbase6DatabaseInfo.SupportsSelectForUpdate: Boolean;
753 Are stored procedure calls using the stored procedure escape
755 @return <code>true</code> if so; <code>false</code> otherwise
757 function TZInterbase6DatabaseInfo.SupportsStoredProcedures: Boolean;
763 Are subqueries in comparison expressions supported?
764 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
765 @return <code>true</code> if so; <code>false</code> otherwise
767 function TZInterbase6DatabaseInfo.SupportsSubqueriesInComparisons: Boolean;
773 Are subqueries in 'exists' expressions supported?
774 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
775 @return <code>true</code> if so; <code>false</code> otherwise
777 function TZInterbase6DatabaseInfo.SupportsSubqueriesInExists: Boolean;
783 Are subqueries in 'in' statements supported?
784 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
785 @return <code>true</code> if so; <code>false</code> otherwise
787 function TZInterbase6DatabaseInfo.SupportsSubqueriesInIns: Boolean;
793 Are subqueries in quantified expressions supported?
794 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
795 @return <code>true</code> if so; <code>false</code> otherwise
797 function TZInterbase6DatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;
803 Are correlated subqueries supported?
804 A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
805 @return <code>true</code> if so; <code>false</code> otherwise
807 function TZInterbase6DatabaseInfo.SupportsCorrelatedSubqueries: Boolean;
813 Is SQL UNION supported?
814 @return <code>true</code> if so; <code>false</code> otherwise
816 function TZInterbase6DatabaseInfo.SupportsUnion: Boolean;
822 Is SQL UNION ALL supported?
823 @return <code>true</code> if so; <code>false</code> otherwise
825 function TZInterbase6DatabaseInfo.SupportsUnionAll: Boolean;
831 Can cursors remain open across commits?
832 @return <code>true</code> if cursors always remain open;
833 <code>false</code> if they might not remain open
835 function TZInterbase6DatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;
841 Can cursors remain open across rollbacks?
842 @return <code>true</code> if cursors always remain open;
843 <code>false</code> if they might not remain open
845 function TZInterbase6DatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;
851 Can statements remain open across commits?
852 @return <code>true</code> if statements always remain open;
853 <code>false</code> if they might not remain open
855 function TZInterbase6DatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;
861 Can statements remain open across rollbacks?
862 @return <code>true</code> if statements always remain open;
863 <code>false</code> if they might not remain open
865 function TZInterbase6DatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;
870 //----------------------------------------------------------------------
871 // The following group of methods exposes various limitations
872 // based on the target database with the current driver.
873 // Unless otherwise specified, a result of zero means there is no
874 // limit, or the limit is not known.
877 How many hex characters can you have in an inline binary literal?
878 @return max binary literal length in hex characters;
879 a result of zero means that there is no limit or the limit is not known
881 function TZInterbase6DatabaseInfo.GetMaxBinaryLiteralLength: Integer;
887 What's the max length for a character literal?
888 @return max literal length;
889 a result of zero means that there is no limit or the limit is not known
891 function TZInterbase6DatabaseInfo.GetMaxCharLiteralLength: Integer;
897 What's the limit on column name length?
898 @return max column name length;
899 a result of zero means that there is no limit or the limit is not known
901 function TZInterbase6DatabaseInfo.GetMaxColumnNameLength: Integer;
907 What's the maximum number of columns in a "GROUP BY" clause?
908 @return max number of columns;
909 a result of zero means that there is no limit or the limit is not known
911 function TZInterbase6DatabaseInfo.GetMaxColumnsInGroupBy: Integer;
917 What's the maximum number of columns allowed in an index?
918 @return max number of columns;
919 a result of zero means that there is no limit or the limit is not known
921 function TZInterbase6DatabaseInfo.GetMaxColumnsInIndex: Integer;
927 What's the maximum number of columns in an "ORDER BY" clause?
928 @return max number of columns;
929 a result of zero means that there is no limit or the limit is not known
931 function TZInterbase6DatabaseInfo.GetMaxColumnsInOrderBy: Integer;
937 What's the maximum number of columns in a "SELECT" list?
938 @return max number of columns;
939 a result of zero means that there is no limit or the limit is not known
941 function TZInterbase6DatabaseInfo.GetMaxColumnsInSelect: Integer;
947 What's the maximum number of columns in a table?
948 @return max number of columns;
949 a result of zero means that there is no limit or the limit is not known
951 function TZInterbase6DatabaseInfo.GetMaxColumnsInTable: Integer;
957 How many active connections can we have at a time to this database?
958 @return max number of active connections;
959 a result of zero means that there is no limit or the limit is not known
961 function TZInterbase6DatabaseInfo.GetMaxConnections: Integer;
967 What's the maximum cursor name length?
968 @return max cursor name length in bytes;
969 a result of zero means that there is no limit or the limit is not known
971 function TZInterbase6DatabaseInfo.GetMaxCursorNameLength: Integer;
977 Retrieves the maximum number of bytes for an index, including all
978 of the parts of the index.
979 @return max index length in bytes, which includes the composite of all
980 the constituent parts of the index;
981 a result of zero means that there is no limit or the limit is not known
983 function TZInterbase6DatabaseInfo.GetMaxIndexLength: Integer;
989 What's the maximum length allowed for a schema name?
990 @return max name length in bytes;
991 a result of zero means that there is no limit or the limit is not known
993 function TZInterbase6DatabaseInfo.GetMaxSchemaNameLength: Integer;
999 What's the maximum length of a procedure name?
1000 @return max name length in bytes;
1001 a result of zero means that there is no limit or the limit is not known
1003 function TZInterbase6DatabaseInfo.GetMaxProcedureNameLength: Integer;
1009 What's the maximum length of a catalog name?
1010 @return max name length in bytes;
1011 a result of zero means that there is no limit or the limit is not known
1013 function TZInterbase6DatabaseInfo.GetMaxCatalogNameLength: Integer;
1019 What's the maximum length of a single row?
1020 @return max row size in bytes;
1021 a result of zero means that there is no limit or the limit is not known
1023 function TZInterbase6DatabaseInfo.GetMaxRowSize: Integer;
1029 Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1031 @return <code>true</code> if so; <code>false</code> otherwise
1033 function TZInterbase6DatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;
1039 What's the maximum length of an SQL statement?
1040 @return max length in bytes;
1041 a result of zero means that there is no limit or the limit is not known
1043 function TZInterbase6DatabaseInfo.GetMaxStatementLength: Integer;
1049 How many active statements can we have open at one time to this
1051 @return the maximum number of statements that can be open at one time;
1052 a result of zero means that there is no limit or the limit is not known
1054 function TZInterbase6DatabaseInfo.GetMaxStatements: Integer;
1060 What's the maximum length of a table name?
1061 @return max name length in bytes;
1062 a result of zero means that there is no limit or the limit is not known
1064 function TZInterbase6DatabaseInfo.GetMaxTableNameLength: Integer;
1070 What's the maximum number of tables in a SELECT statement?
1071 @return the maximum number of tables allowed in a SELECT statement;
1072 a result of zero means that there is no limit or the limit is not known
1074 function TZInterbase6DatabaseInfo.GetMaxTablesInSelect: Integer;
1080 What's the maximum length of a user name?
1081 @return max user name length in bytes;
1082 a result of zero means that there is no limit or the limit is not known
1084 function TZInterbase6DatabaseInfo.GetMaxUserNameLength: Integer;
1089 //----------------------------------------------------------------------
1092 What's the database's default transaction isolation level? The
1093 values are defined in <code>java.sql.Connection</code>.
1094 @return the default isolation level
1097 function TZInterbase6DatabaseInfo.GetDefaultTransactionIsolation:
1098 TZTransactIsolationLevel;
1100 Result := tiSerializable;
1104 Are transactions supported? If not, invoking the method
1105 <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.
1106 @return <code>true</code> if transactions are supported; <code>false</code> otherwise
1108 function TZInterbase6DatabaseInfo.SupportsTransactions: Boolean;
1114 Does this database support the given transaction isolation level?
1115 @param level the values are defined in <code>java.sql.Connection</code>
1116 @return <code>true</code> if so; <code>false</code> otherwise
1119 function TZInterbase6DatabaseInfo.SupportsTransactionIsolationLevel(
1120 Level: TZTransactIsolationLevel): Boolean;
1123 tiRepeatableRead, tiReadCommitted, tiSerializable: Result := True;
1124 tiReadUncommitted: Result := False;
1125 tiNone: Result := False; //MAY BE FIX IT
1132 Are both data definition and data manipulation statements
1133 within a transaction supported?
1134 @return <code>true</code> if so; <code>false</code> otherwise
1136 function TZInterbase6DatabaseInfo.
1137 SupportsDataDefinitionAndDataManipulationTransactions: Boolean;
1143 Are only data manipulation statements within a transaction
1145 @return <code>true</code> if so; <code>false</code> otherwise
1147 function TZInterbase6DatabaseInfo.
1148 SupportsDataManipulationTransactionsOnly: Boolean;
1154 Does a data definition statement within a transaction force the
1155 transaction to commit?
1156 @return <code>true</code> if so; <code>false</code> otherwise
1158 function TZInterbase6DatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;
1164 Is a data definition statement within a transaction ignored?
1165 @return <code>true</code> if so; <code>false</code> otherwise
1167 function TZInterbase6DatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;
1173 Does the database support the given result set type?
1174 @param type defined in <code>java.sql.ResultSet</code>
1175 @return <code>true</code> if so; <code>false</code> otherwise
1177 function TZInterbase6DatabaseInfo.SupportsResultSetType(
1178 _Type: TZResultSetType): Boolean;
1180 Result := _Type = rtScrollInsensitive;
1184 Does the database support the concurrency type in combination
1185 with the given result set type?
1187 @param type defined in <code>java.sql.ResultSet</code>
1188 @param concurrency type defined in <code>java.sql.ResultSet</code>
1189 @return <code>true</code> if so; <code>false</code> otherwise
1191 function TZInterbase6DatabaseInfo.SupportsResultSetConcurrency(
1192 _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;
1194 Result := (_Type = rtScrollInsensitive) and (Concurrency = rcReadOnly);
1198 { TZInterbase6DatabaseMetadata }
1201 Constructs a database information object and returns the interface to it. Used
1202 internally by the constructor.
1203 @return the database information object interface
1205 function TZInterbase6DatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;
1207 Result := TZInterbase6DatabaseInfo.Create(Self);
1210 function TZInterbase6DatabaseMetadata.ConstructNameCondition(Pattern: string;
1211 Column: string): string;
1213 if (GetDatabaseInfo as IZInterbaseDatabaseInfo).HostIsFireBird and
1214 (GetConnection.GetHostVersion < 2000000) then
1215 //Old FireBird do NOT support 'trim'
1216 Result := Inherited ConstructnameCondition(Pattern,Column)
1218 Result := Inherited ConstructnameCondition(Pattern,'trim('+Column+')')
1221 function TZInterbase6DatabaseMetadata.UncachedGetTriggers(const Catalog: string;
1222 const SchemaPattern: string; const TableNamePattern: string;
1223 const TriggerNamePattern: string): IZResultSet;
1226 LTriggerNamePattern: string;
1227 LTableNamePattern: string;
1229 Result:=inherited UncachedGetTriggers(Catalog, SchemaPattern, TableNamePattern, TriggerNamePattern);
1231 LTriggerNamePattern := ConstructNameCondition(TriggerNamePattern,
1232 'RDB$TRIGGER_NAME');
1233 LTableNamePattern := ConstructNameCondition(TableNamePattern,
1234 'RDB$RELATION_NAME');
1235 If LTriggerNamePattern <> '' then
1236 LTriggerNamePattern := ' and ' + LTriggerNamePattern;
1237 If LTableNamePattern <> '' then
1238 LTableNamePattern := ' and ' + LTableNamePattern;
1240 SQL := 'SELECT RDB$TRIGGER_NAME, RDB$RELATION_NAME,'
1241 + ' RDB$TRIGGER_TYPE, RDB$TRIGGER_INACTIVE,'
1242 + ' RDB$TRIGGER_SOURCE, RDB$DESCRIPTION FROM RDB$TRIGGERS'
1243 + ' WHERE 1=1' + LTriggerNamePattern + LTableNamePattern;
1245 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1249 Result.MoveToInsertRow;
1250 Result.UpdateNull(1);
1251 Result.UpdateNull(2);
1252 Result.UpdateString(3, GetString(1)); //RDB$TRIGGER_NAME
1253 Result.UpdateString(4, GetString(2)); //RDB$RELATION_NAME
1254 Result.UpdateShort(5, GetShort(3)); //RDB$TRIGGER_TYPE
1255 Result.UpdateShort(6, GetShort(4)); //RDB$TRIGGER_INACTIVE
1256 Result.UpdateString(7, GetString(5)); //RDB$TRIGGER_SOURCE
1257 Result.UpdateString(8, GetString(6)); //RDB$DESCRIPTION
1266 Gets a description of the stored procedures available in a
1269 <P>Only procedure descriptions matching the schema and
1270 procedure name criteria are returned. They are ordered by
1271 PROCEDURE_SCHEM, and PROCEDURE_NAME.
1273 <P>Each procedure description has the the following columns:
1275 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1276 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1277 <LI><B>PROCEDURE_NAME</B> String => procedure name
1278 <LI> reserved for future use
1279 <LI> reserved for future use
1280 <LI> reserved for future use
1281 <LI><B>REMARKS</B> String => explanatory comment on the procedure
1282 <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1284 <LI> procedureResultUnknown - May return a result
1285 <LI> procedureNoResult - Does not return a result
1286 <LI> procedureReturnsResult - Returns a result
1290 @param catalog a catalog name; "" retrieves those without a
1291 catalog; null means drop catalog name from the selection criteria
1292 @param schemaPattern a schema name pattern; "" retrieves those
1294 @param procedureNamePattern a procedure name pattern
1295 @return <code>ResultSet</code> - each row is a procedure description
1296 @see #getSearchStringEscape
1298 function TZInterbase6DatabaseMetadata.UncachedGetProcedures(const Catalog: string;
1299 const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;
1302 LProcedureNamePattern: string;
1304 Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);
1306 LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern,
1307 'RDB$PROCEDURE_NAME');
1308 If LProcedureNamePattern <> '' then
1309 LProcedureNamePattern := ' and ' + LProcedureNamePattern;
1311 SQL := 'SELECT RDB$PROCEDURE_NAME, RDB$PROCEDURE_OUTPUTS,'
1312 + ' RDB$DESCRIPTION FROM RDB$PROCEDURES'
1313 + ' WHERE 1=1' + LProcedureNamePattern;
1315 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1319 Result.MoveToInsertRow;
1320 Result.UpdateNull(1);
1321 Result.UpdateNull(2);
1322 Result.UpdateString(3, GetString(1)); //RDB$PROCEDURE_NAME
1323 Result.UpdateNull(4);
1324 Result.UpdateNull(5);
1325 Result.UpdateNull(6);
1326 Result.UpdateString(7, GetString(3)); //RDB$DESCRIPTION
1327 if IsNull(2) then //RDB$PROCEDURE_OUTPUTS
1328 Result.UpdateInt(8, Ord(prtNoResult))
1329 else Result.UpdateInt(8, Ord(prtReturnsResult));
1337 Gets a description of a catalog's stored procedure parameters
1340 <P>Only descriptions matching the schema, procedure and
1341 parameter name criteria are returned. They are ordered by
1342 PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1343 if any, is first. Next are the parameter descriptions in call
1344 order. The column descriptions follow in column number order.
1346 <P>Each row in the <code>ResultSet</code> is a parameter description or
1347 column description with the following fields:
1349 <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1350 <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1351 <LI><B>PROCEDURE_NAME</B> String => procedure name
1352 <LI><B>COLUMN_NAME</B> String => column/parameter name
1353 <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1355 <LI> procedureColumnUnknown - nobody knows
1356 <LI> procedureColumnIn - IN parameter
1357 <LI> procedureColumnInOut - INOUT parameter
1358 <LI> procedureColumnOut - OUT parameter
1359 <LI> procedureColumnReturn - procedure return value
1360 <LI> procedureColumnResult - result column in <code>ResultSet</code>
1362 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1363 <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
1364 type name is fully qualified
1365 <LI><B>PRECISION</B> int => precision
1366 <LI><B>LENGTH</B> int => length in bytes of data
1367 <LI><B>SCALE</B> short => scale
1368 <LI><B>RADIX</B> short => radix
1369 <LI><B>NULLABLE</B> short => can it contain NULL?
1371 <LI> procedureNoNulls - does not allow NULL values
1372 <LI> procedureNullable - allows NULL values
1373 <LI> procedureNullableUnknown - nullability unknown
1375 <LI><B>REMARKS</B> String => comment describing parameter/column
1378 <P><B>Note:</B> Some databases may not return the column
1379 descriptions for a procedure. Additional columns beyond
1380 REMARKS can be defined by the database.
1382 @param catalog a catalog name; "" retrieves those without a
1383 catalog; null means drop catalog name from the selection criteria
1384 @param schemaPattern a schema name pattern; "" retrieves those
1386 @param procedureNamePattern a procedure name pattern
1387 @param columnNamePattern a column name pattern
1388 @return <code>ResultSet</code> - each row describes a stored procedure parameter or
1390 @see #getSearchStringEscape
1392 function TZInterbase6DatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;
1393 const SchemaPattern: string; const ProcedureNamePattern: string;
1394 const ColumnNamePattern: string): IZResultSet;
1397 LProcedureNamePattern, LColumnNamePattern: string;
1398 TypeName, SubTypeName: Integer;
1399 ColumnIndexes : Array[1..8] of integer;
1401 Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);
1403 LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern,
1404 'P.RDB$PROCEDURE_NAME');
1405 LColumnNamePattern := ConstructNameCondition(ColumnNamePattern,
1406 'PP.RDB$PARAMETER_NAME');
1407 If LProcedureNamePattern <> '' then
1408 LProcedureNamePattern := ' and ' + LProcedureNamePattern;
1409 If LColumnNamePattern <> '' then
1410 LColumnNamePattern := ' and ' + LColumnNamePattern;
1412 if (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'Interbase 5') <> nil)
1413 or (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'V5.') <> nil) then
1415 SQL := ' SELECT P.RDB$PROCEDURE_NAME, PP.RDB$PARAMETER_NAME,'
1416 + ' PP.RDB$PARAMETER_TYPE, F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE,'
1417 + ' F.RDB$FIELD_SCALE, F.RDB$FIELD_LENGTH, F.RDB$NULL_FLAG,'
1418 + ' PP.RDB$DESCRIPTION, F.RDB$FIELD_SCALE as RDB$FIELD_PRECISION,'
1419 + ' F.RDB$NULL_FLAG FROM RDB$PROCEDURES P'
1420 + ' JOIN RDB$PROCEDURE_PARAMETERS PP ON P.RDB$PROCEDURE_NAME'
1421 + '=PP.RDB$PROCEDURE_NAME JOIN RDB$FIELDS F ON PP.RDB$FIELD_SOURCE'
1422 + '=F.RDB$FIELD_NAME '
1423 + ' WHERE 1=1' + LProcedureNamePattern + LColumnNamePattern
1424 + ' ORDER BY P.RDB$PROCEDURE_NAME,'
1425 + ' PP.RDB$PARAMETER_TYPE, PP.RDB$PARAMETER_NUMBER';
1429 SQL := ' SELECT P.RDB$PROCEDURE_NAME, PP.RDB$PARAMETER_NAME,'
1430 + ' PP.RDB$PARAMETER_TYPE, F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE,'
1431 + ' F.RDB$FIELD_SCALE, F.RDB$FIELD_LENGTH, F.RDB$NULL_FLAG,'
1432 + ' PP.RDB$DESCRIPTION, F.RDB$FIELD_PRECISION, F.RDB$NULL_FLAG '
1433 + ' FROM RDB$PROCEDURES P JOIN RDB$PROCEDURE_PARAMETERS PP ON'
1434 + ' P.RDB$PROCEDURE_NAME = PP.RDB$PROCEDURE_NAME '
1435 + ' JOIN RDB$FIELDS F ON PP.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME '
1436 + ' WHERE 1=1' + LProcedureNamePattern + LColumnNamePattern
1437 + ' ORDER BY P.RDB$PROCEDURE_NAME,'
1438 + ' PP.RDB$PARAMETER_TYPE, PP.RDB$PARAMETER_NUMBER';
1441 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1443 ColumnIndexes[1] := FindColumn('RDB$PROCEDURE_NAME');
1444 ColumnIndexes[2] := FindColumn('RDB$PARAMETER_NAME');
1445 ColumnIndexes[3] := FindColumn('RDB$PARAMETER_TYPE');
1446 ColumnIndexes[4] := FindColumn('RDB$FIELD_TYPE');
1447 ColumnIndexes[5] := FindColumn('RDB$FIELD_SUB_TYPE');
1448 ColumnIndexes[6] := FindColumn('RDB$FIELD_PRECISION');
1449 ColumnIndexes[7] := FindColumn('RDB$FIELD_SCALE');
1450 ColumnIndexes[8] := FindColumn('RDB$NULL_FLAG');
1453 TypeName := GetInt(ColumnIndexes[4]);
1454 SubTypeName := GetInt(ColumnIndexes[5]);
1456 Result.MoveToInsertRow;
1457 Result.UpdateNull(1); //PROCEDURE_CAT
1458 Result.UpdateNull(2); //PROCEDURE_SCHEM
1459 Result.UpdateString(3, GetString(ColumnIndexes[1])); //TABLE_NAME
1460 Result.UpdateString(4, GetString(ColumnIndexes[2])); //COLUMN_NAME
1461 case GetInt(ColumnIndexes[3]) of
1462 0: Result.UpdateInt(5, Ord(pctIn));
1463 1: Result.UpdateInt(5, Ord(pctOut));
1465 Result.UpdateInt(5, Ord(pctUnknown));
1469 Ord(ConvertInterbase6ToSqlType(TypeName, SubTypeName,
1470 ConSettings.CPType))); //DATA_TYPE
1471 Result.UpdateString(7,GetString(ColumnIndexes[4])); //TYPE_NAME
1472 Result.UpdateInt(10, GetInt(ColumnIndexes[6]));
1473 Result.UpdateNull(9); //BUFFER_LENGTH
1474 Result.UpdateInt(10, GetInt(ColumnIndexes[7]));
1475 Result.UpdateInt(11, 10);
1476 Result.UpdateInt(12, GetInt(ColumnIndexes[8]));
1477 Result.UpdateString(12, GetString(ColumnIndexes[6]));
1485 Gets a description of tables available in a catalog.
1487 <P>Only table descriptions matching the catalog, schema, table
1488 name and type criteria are returned. They are ordered by
1489 TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1491 <P>Each table description has the following columns:
1493 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1494 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1495 <LI><B>TABLE_NAME</B> String => table name
1496 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1497 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1498 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1499 <LI><B>REMARKS</B> String => explanatory comment on the table
1502 <P><B>Note:</B> Some databases may not return information for
1505 @param catalog a catalog name; "" retrieves those without a
1506 catalog; null means drop catalog name from the selection criteria
1507 @param schemaPattern a schema name pattern; "" retrieves those
1509 @param tableNamePattern a table name pattern
1510 @param types a list of table types to include; null returns all types
1511 @return <code>ResultSet</code> - each row is a table description
1512 @see #getSearchStringEscape
1515 function TZInterbase6DatabaseMetadata.UncachedGetTables(const Catalog: string;
1516 const SchemaPattern: string; const TableNamePattern: string;
1517 const Types: TStringDynArray): IZResultSet;
1519 SQL, TableType: string;
1520 I, SystemFlag: Integer;
1521 TableNameCondition: string;
1524 Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);
1526 TableNameCondition := ConstructNameCondition(TableNamePattern,
1527 'a.RDB$RELATION_NAME');
1528 If TableNameCondition <> '' then
1529 TableNameCondition := ' and ' + TableNameCondition;
1531 SQL := 'SELECT DISTINCT a.RDB$RELATION_NAME, a.RDB$SYSTEM_FLAG, '
1532 + ' a.RDB$VIEW_SOURCE, a.RDB$DESCRIPTION FROM RDB$RELATIONS a'
1533 + ' WHERE 1=1' + TableNameCondition;
1535 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1539 SystemFlag := GetInt(2); //RDB$SYSTEM_FLAG
1541 if SystemFlag = 0 then
1543 if IsNull(3) then //RDB$VIEW_SOURCE
1544 TableType := 'TABLE'
1546 TableType := 'VIEW';
1549 TableType := 'SYSTEM TABLE';
1551 if Length(Types) = 0 then
1553 Result.MoveToInsertRow;
1554 Result.UpdateNull(1);
1555 Result.UpdateNull(2);
1556 Result.UpdateString(3, GetString(1)); //RDB$RELATION_NAME
1557 Result.UpdateString(4, TableType);
1558 Result.UpdateString(5, Copy(GetString(4),1,255)); //RDB$DESCRIPTION
1563 for I := 0 to High(Types) do
1565 if Types[I] = TableType then
1567 Result.MoveToInsertRow;
1568 Result.UpdateNull(1);
1569 Result.UpdateNull(2);
1570 Result.UpdateString(3, GetString(1)); //RDB$RELATION_NAME
1571 Result.UpdateString(4, TableType);
1572 Result.UpdateString(5, Copy(GetString(4),1,255)); //RDB$DESCRIPTION
1584 Gets the table types available in this database. The results
1585 are ordered by table type.
1587 <P>The table type is:
1589 <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1590 "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1591 "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1594 @return <code>ResultSet</code> - each row has a single String column that is a
1597 function TZInterbase6DatabaseMetadata.UncachedGetTableTypes: IZResultSet;
1599 TablesTypes: array [0..2] of String = ('TABLE', 'VIEW', 'SYSTEM TABLE');
1603 Result:=inherited UncachedGetTableTypes;
1607 Result.MoveToInsertRow;
1608 Result.UpdateString(1, TablesTypes[I]);
1614 Gets a description of table columns available in
1615 the specified catalog.
1617 <P>Only column descriptions matching the catalog, schema, table
1618 and column name criteria are returned. They are ordered by
1619 TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1621 <P>Each column description has the following columns:
1623 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1624 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1625 <LI><B>TABLE_NAME</B> String => table name
1626 <LI><B>COLUMN_NAME</B> String => column name
1627 <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1628 <LI><B>TYPE_NAME</B> String => Data source dependent type name,
1629 for a UDT the type name is fully qualified
1630 <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1631 types this is the maximum number of characters, for numeric or
1632 decimal types this is precision.
1633 <LI><B>BUFFER_LENGTH</B> is not used.
1634 <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1635 <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1636 <LI><B>NULLABLE</B> int => is NULL allowed?
1638 <LI> columnNoNulls - might not allow NULL values
1639 <LI> columnNullable - definitely allows NULL values
1640 <LI> columnNullableUnknown - nullability unknown
1642 <LI><B>REMARKS</B> String => comment describing column (may be null)
1643 <LI><B>COLUMN_DEF</B> String => default value (may be null)
1644 <LI><B>SQL_DATA_TYPE</B> int => unused
1645 <LI><B>SQL_DATETIME_SUB</B> int => unused
1646 <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1647 maximum number of bytes in the column
1648 <LI><B>ORDINAL_POSITION</B> int => index of column in table
1650 <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1651 does not allow NULL values; "YES" means the column might
1652 allow NULL values. An empty string means nobody knows.
1655 @param catalog a catalog name; "" retrieves those without a
1656 catalog; null means drop catalog name from the selection criteria
1657 @param schemaPattern a schema name pattern; "" retrieves those
1659 @param tableNamePattern a table name pattern
1660 @param columnNamePattern a column name pattern
1661 @return <code>ResultSet</code> - each row is a column description
1662 @see #getSearchStringEscape
1665 function TZInterbase6DatabaseMetadata.UncachedGetColumns(const Catalog: string;
1666 const SchemaPattern: string; const TableNamePattern: string;
1667 const ColumnNamePattern: string): IZResultSet;
1669 SQL, ColumnName, DefaultValue: String;
1670 TypeName, SubTypeName, FieldScale: integer;
1671 LTableNamePattern, LColumnNamePattern: string;
1672 ColumnIndexes : Array[1..15] of integer;
1675 Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);
1677 LTableNamePattern := ConstructNameCondition(TableNamePattern,
1678 'a.RDB$RELATION_NAME');
1679 LColumnNamePattern := ConstructNameCondition(ColumnNamePattern,
1680 'a.RDB$FIELD_NAME');
1681 If LTableNamePattern <> '' then
1682 LTableNamePattern := ' and ' + LTableNamePattern;
1683 If LColumnNamePattern <> '' then
1684 LColumnNamePattern := ' and ' + LColumnNamePattern;
1686 if (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'Interbase 5') <> nil)
1687 or (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'V5.') <> nil) then
1689 SQL := 'SELECT a.RDB$RELATION_NAME, a.RDB$FIELD_NAME, a.RDB$FIELD_POSITION,'
1690 + ' a.RDB$NULL_FLAG, b. RDB$FIELD_LENGTH, b.RDB$FIELD_SCALE,'
1691 + ' c.RDB$TYPE_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_SUB_TYPE,'
1692 + ' b.RDB$DESCRIPTION, b.RDB$CHARACTER_LENGTH, b.RDB$FIELD_SCALE'
1693 + ' as RDB$FIELD_PRECISION, a.RDB$DEFAULT_SOURCE, b.RDB$DEFAULT_SOURCE'
1694 + ' as RDB$DEFAULT_SOURCE_DOMAIN, b.RDB$COMPUTED_SOURCE as RDB$COMPUTED_SOURCE'
1695 + ' , b.RDB$CHARACTER_SET_ID FROM RDB$RELATION_FIELDS a'
1696 + ' JOIN RDB$FIELDS b ON (b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE)'
1697 + ' LEFT JOIN RDB$TYPES c ON b.RDB$FIELD_TYPE = c.RDB$TYPE'
1698 + ' and c.RDB$FIELD_NAME = ''RDB$FIELD_TYPE'''
1699 + ' WHERE 1=1' + LTableNamePattern + LColumnNamePattern
1700 + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$FIELD_POSITION';
1704 SQL := ' SELECT a.RDB$RELATION_NAME, a.RDB$FIELD_NAME, a.RDB$FIELD_POSITION,'
1705 + ' a.RDB$NULL_FLAG, a.RDB$DEFAULT_VALUE, b. RDB$FIELD_LENGTH,'
1706 + ' b.RDB$FIELD_SCALE, c.RDB$TYPE_NAME, b.RDB$FIELD_TYPE,'
1707 + ' b.RDB$FIELD_SUB_TYPE, b.RDB$DESCRIPTION, b.RDB$CHARACTER_LENGTH,'
1708 + ' b.RDB$FIELD_PRECISION, a.RDB$DEFAULT_SOURCE, b.RDB$DEFAULT_SOURCE'
1709 + ' as RDB$DEFAULT_SOURCE_DOMAIN,b.RDB$COMPUTED_SOURCE as RDB$COMPUTED_SOURCE'
1710 + ' , b.RDB$CHARACTER_SET_ID FROM RDB$RELATION_FIELDS a'
1711 + ' JOIN RDB$FIELDS b ON (b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE)'
1712 + ' LEFT JOIN RDB$TYPES c ON (b.RDB$FIELD_TYPE = c.RDB$TYPE'
1713 + ' and c.RDB$FIELD_NAME = ''RDB$FIELD_TYPE'')'
1714 + ' WHERE 1=1' + LTableNamePattern + LColumnNamePattern
1715 + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$FIELD_POSITION';
1718 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1720 ColumnIndexes[1] := FindColumn('RDB$FIELD_TYPE');
1721 ColumnIndexes[2] := FindColumn('RDB$FIELD_SUB_TYPE');
1722 ColumnIndexes[3] := FindColumn('RDB$FIELD_SCALE');
1723 ColumnIndexes[4] := FindColumn('RDB$FIELD_NAME');
1724 ColumnIndexes[5] := FindColumn('RDB$DEFAULT_SOURCE');
1725 ColumnIndexes[6] := FindColumn('RDB$DEFAULT_SOURCE_DOMAIN');
1726 ColumnIndexes[7] := FindColumn('RDB$RELATION_NAME');
1727 ColumnIndexes[8] := FindColumn('RDB$TYPE_NAME');
1728 ColumnIndexes[9] := FindColumn('RDB$FIELD_PRECISION');
1729 ColumnIndexes[10] := FindColumn('RDB$FIELD_LENGTH');
1730 ColumnIndexes[11] := FindColumn('RDB$NULL_FLAG');
1731 ColumnIndexes[12] := FindColumn('RDB$DESCRIPTION');
1732 ColumnIndexes[13] := FindColumn('RDB$FIELD_POSITION');
1733 ColumnIndexes[14] := FindColumn('RDB$COMPUTED_SOURCE');
1734 ColumnIndexes[15] := FindColumn('RDB$CHARACTER_SET_ID');
1737 TypeName := GetInt(ColumnIndexes[1]);
1738 if TypeName = 14 then //'TEXT'
1739 SubTypeName := GetInt(ColumnIndexes[15]) //need a way to determine CS_Binary (octets) for stBytes on the other hand the subtype is useless here
1741 SubTypeName := GetInt(ColumnIndexes[2]);
1742 FieldScale := GetInt(ColumnIndexes[3]);
1743 ColumnName := GetString(ColumnIndexes[4]);
1745 if (GetString(ColumnIndexes[14]) <> '') then //AVZ -- not isNull(14) was not working correcly here could be ' ' - subselect
1746 begin //Computed by Source & Sub Selects //AVZ
1747 if ((TypeName = 16) and (FieldScale < 0)) then SubTypeName := 1; // Fix for 0 subtype which removes decimals
1750 DefaultValue := GetString(ColumnIndexes[5]);
1751 if DefaultValue = '' then
1752 DefaultValue := GetString(ColumnIndexes[6]);
1753 if StartsWith(Trim(UpperCase(DefaultValue)), 'DEFAULT') then
1755 DefaultValue := Trim(StringReplace(DefaultValue, 'DEFAULT ', '',
1759 IF (UpperCase(DefaultValue)= '''NOW''') or (UpperCase(DefaultValue)= '"NOW"')then
1761 12: DefaultValue := 'CURRENT_DATE';
1762 13: DefaultValue := 'CURRENT_TIME';
1763 35: DefaultValue := 'CURRENT_TIMESTAMP';
1767 Result.MoveToInsertRow;
1768 Result.UpdateNull(1); //TABLE_CAT
1769 Result.UpdateNull(2); //TABLE_SCHEM
1770 Result.UpdateString(3, GetString(ColumnIndexes[7])); //TABLE_NAME
1771 Result.UpdateString(4, ColumnName); //COLUMN_NAME
1772 SQLType := ConvertInterbase6ToSqlType(TypeName, SubTypeName
1773 , ConSettings.CPType);
1774 Result.UpdateInt(5, Ord(SQLType));
1777 7 : Result.UpdateString(6, 'SMALLINT');
1778 8 : Result.UpdateString(6, 'INTEGER' );
1781 if (SubTypeName = 0) then
1782 Result.UpdateString(6, GetString(ColumnIndexes[8]));
1783 if (SubTypeName = 1) then
1784 Result.UpdateString(6, 'NUMERIC');
1785 if (SubTypeName = 2) then
1786 Result.UpdateString(6, 'DECIMAL');
1788 37 : Result.UpdateString(6, 'VARCHAR'); // Instead of VARYING
1790 Result.UpdateString(6, GetString(ColumnIndexes[8]));
1794 7, 8 : Result.UpdateInt(7, 0);
1795 16 : Result.UpdateInt(7, GetInt(ColumnIndexes[9]));
1796 37, 38: Result.UpdateNull(7); //the defaults of the resultsets will be used if null
1797 {if ( ConSettings.ClientCodePage.ID = 0 ) then //CharcterSet 'NONE'
1798 Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings,
1799 GetInt(ColumnIndexes[10]), GetConnection.GetIZPlainDriver.ValidateCharEncoding(SubTypeName).CharWidth, nil, True)) //FireBird return Char*Bytes for Varchar
1801 Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings,
1802 GetInt(ColumnIndexes[10]), ConSettings.ClientCodePage.CharWidth, nil, True)); //FireBird return Char*Bytes for Varchar}
1804 Result.UpdateInt(7, GetInt(ColumnIndexes[10]));
1807 Result.UpdateNull(8); //BUFFER_LENGTH
1809 if FieldScale < 0 then
1810 Result.UpdateInt(9, -1 * FieldScale) //DECIMAL_DIGITS
1812 Result.UpdateInt(9, 0); //DECIMAL_DIGITS
1814 Result.UpdateInt(10, 10); //NUM_PREC_RADIX
1816 if GetInt(ColumnIndexes[11]) <> 0 then
1817 Result.UpdateInt(11, Ord(ntNoNulls)) //NULLABLE
1819 Result.UpdateInt(11, Ord(ntNullable));
1821 Result.UpdateString(12, Copy(GetString(ColumnIndexes[12]),1,255)); //REMARKS
1822 Result.UpdateString(13, DefaultValue); //COLUMN_DEF
1823 Result.UpdateNull(14); //SQL_DATA_TYPE
1824 Result.UpdateNull(15); //SQL_DATETIME_SUB
1825 Result.UpdateInt(16,
1826 GetInt(7)); //CHAR_OCTET_LENGTH
1827 Result.UpdateInt(17, GetInt(ColumnIndexes[13]) + 1); //ORDINAL_POSITION
1829 if IsNull(ColumnIndexes[11]) then
1830 Result.UpdateString(18, 'YES') //IS_NULLABLE
1832 Result.UpdateString(18, 'NO'); //IS_NULLABLE
1834 Result.UpdateNull(19); //AUTO_INCREMENT
1836 if CompareStr(ColumnName, UpperCase(ColumnName)) = 0 then
1837 Result.UpdateBoolean(20, False) //CASE_SENSITIVE
1839 Result.UpdateBoolean(20, True); //CASE_SENSITIVE
1841 Result.UpdateBoolean(21, True); //SEARCHABLE
1842 if isNull(ColumnIndexes[14]) then
1844 Result.UpdateBoolean(22, True); //WRITABLE
1845 Result.UpdateBoolean(23, True); //DEFINITELYWRITABLE
1846 Result.UpdateBoolean(24, False); //READONLY
1850 Result.UpdateBoolean(22, False); //WRITABLE
1851 Result.UpdateBoolean(23, False); //DEFINITELYWRITABLE
1852 Result.UpdateBoolean(24, True); //READONLY
1861 Gets a description of the access rights for a table's columns.
1863 <P>Only privileges matching the column name criteria are
1864 returned. They are ordered by COLUMN_NAME and PRIVILEGE.
1866 <P>Each privilige description has the following columns:
1868 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1869 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1870 <LI><B>TABLE_NAME</B> String => table name
1871 <LI><B>COLUMN_NAME</B> String => column name
1872 <LI><B>GRANTOR</B> => grantor of access (may be null)
1873 <LI><B>GRANTEE</B> String => grantee of access
1874 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1875 INSERT, UPDATE, REFRENCES, ...)
1876 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1877 to grant to others; "NO" if not; null if unknown
1880 @param catalog a catalog name; "" retrieves those without a
1881 catalog; null means drop catalog name from the selection criteria
1882 @param schema a schema name; "" retrieves those without a schema
1883 @param table a table name
1884 @param columnNamePattern a column name pattern
1885 @return <code>ResultSet</code> - each row is a column privilege description
1886 @see #getSearchStringEscape
1888 function TZInterbase6DatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;
1889 const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;
1892 TableName, FieldName, Privilege: String;
1893 Grantor, Grantee, Grantable: String;
1894 LColumnNamePattern, LTable: String;
1896 Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);
1898 LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'a.RDB$RELATION_NAME');
1899 LColumnNamePattern := ConstructNameCondition(ColumnNamePattern, 'a.RDB$FIELD_NAME');
1900 if LTable <> '' then
1901 LTable := ' and ' + LTable;
1902 if LColumnNamePattern <> '' then
1903 LColumnNamePattern := ' and ' + LColumnNamePattern;
1905 SQL := 'SELECT a.RDB$USER, a.RDB$GRANTOR, a.RDB$PRIVILEGE,'
1906 + ' a.RDB$GRANT_OPTION, a.RDB$RELATION_NAME, a.RDB$FIELD_NAME '
1907 + ' FROM RDB$USER_PRIVILEGES a, RDB$TYPES b '
1908 + ' WHERE a.RDB$OBJECT_TYPE = b.RDB$TYPE '
1909 + LTable + LColumnNamePattern
1910 + ' and b.RDB$TYPE_NAME IN (''RELATION'', ''VIEW'','
1911 + ' ''COMPUTED_FIELD'', ''FIELD'' ) AND b.RDB$FIELD_NAME'
1912 + '=''RDB$OBJECT_TYPE'' ORDER BY a.RDB$FIELD_NAME, a.RDB$PRIVILEGE ' ;
1914 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1919 TableName := GetString(5); //RDB$RELATION_NAME
1920 FieldName := GetString(6); //RDB$FIELD_NAME
1921 Privilege := GetPrivilege(GetString(3)); //RDB$PRIVILEGE
1922 Grantor := GetString(2); //RDB$GRANTOR
1923 Grantee := GetString(1); //RDB$USER
1924 if Grantor = Grantee then
1928 if FieldName = '' then
1930 LTable := ConstructNameCondition(TableName, 'a.RDB$RELATION_NAME');
1931 SQL := 'SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS A'
1932 + ' WHERE ' + LTable + LColumnNamePattern;
1933 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
1937 Result.MoveToInsertRow;
1938 Result.UpdateNull(1);
1939 Result.UpdateNull(2);
1940 Result.UpdateString(3, TableName);
1941 Result.UpdateString(4, GetString(1));
1942 Result.UpdateString(5, Grantor);
1943 Result.UpdateString(6, Grantee);
1944 Result.UpdateString(7, Privilege);
1945 Result.UpdateString(8, Grantable);
1953 Result.MoveToInsertRow;
1954 Result.UpdateNull(1);
1955 Result.UpdateNull(2);
1956 Result.UpdateString(3, TableName);
1957 Result.UpdateString(4, FieldName);
1958 Result.UpdateString(5, Grantor);
1959 Result.UpdateString(6, Grantee);
1960 Result.UpdateString(7, Privilege);
1961 Result.UpdateString(8, Grantable);
1970 Gets a description of the access rights for each table available
1971 in a catalog. Note that a table privilege applies to one or
1972 more columns in the table. It would be wrong to assume that
1973 this priviledge applies to all columns (this may be true for
1974 some systems but is not true for all.)
1976 <P>Only privileges matching the schema and table name
1977 criteria are returned. They are ordered by TABLE_SCHEM,
1978 TABLE_NAME, and PRIVILEGE.
1980 <P>Each privilige description has the following columns:
1982 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1983 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1984 <LI><B>TABLE_NAME</B> String => table name
1985 <LI><B>GRANTOR</B> => grantor of access (may be null)
1986 <LI><B>GRANTEE</B> String => grantee of access
1987 <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1988 INSERT, UPDATE, REFRENCES, ...)
1989 <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1990 to grant to others; "NO" if not; null if unknown
1993 @param catalog a catalog name; "" retrieves those without a
1994 catalog; null means drop catalog name from the selection criteria
1995 @param schemaPattern a schema name pattern; "" retrieves those
1997 @param tableNamePattern a table name pattern
1998 @return <code>ResultSet</code> - each row is a table privilege description
1999 @see #getSearchStringEscape
2001 function TZInterbase6DatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;
2002 const SchemaPattern: string; const TableNamePattern: string): IZResultSet;
2005 TableName, Privilege, Grantor: String;
2006 Grantee, Grantable: String;
2007 LTableNamePattern: String;
2009 Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);
2011 LTableNamePattern := ConstructNameCondition(TableNamePattern, 'a.RDB$RELATION_NAME');
2012 if LTableNamePattern <> '' then
2013 LTableNamePattern := ' and ' + LTableNamePattern;
2015 SQL := 'SELECT a.RDB$USER, a.RDB$GRANTOR, a.RDB$PRIVILEGE,'
2016 + ' a.RDB$GRANT_OPTION, a.RDB$RELATION_NAME FROM RDB$USER_PRIVILEGES a,'
2017 + ' RDB$TYPES b WHERE a.RDB$OBJECT_TYPE = b.RDB$TYPE AND '
2018 + ' b.RDB$TYPE_NAME IN (''RELATION'', ''VIEW'', ''COMPUTED_FIELD'','
2019 + ' ''FIELD'' ) AND a.RDB$FIELD_NAME IS NULL '+ LTableNamePattern
2020 + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$PRIVILEGE';
2022 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2026 TableName := GetString(5); //RDB$RELATION_NAME
2027 Privilege := GetPrivilege(GetString(3)); //RDB$PRIVILEGE
2028 Grantor := GetString(2); //RDB$GRANTOR
2029 Grantee := GetString(1); //RDB$USER
2031 if Grantor = Grantee then
2036 Result.MoveToInsertRow;
2037 Result.UpdateNull(1);
2038 Result.UpdateNull(2);
2039 Result.UpdateString(3, TableName);
2040 Result.UpdateString(4, Grantor);
2041 Result.UpdateString(5, Grantee);
2042 Result.UpdateString(6, Privilege);
2043 Result.UpdateString(7, Grantable);
2051 Gets a description of a table's columns that are automatically
2052 updated when any value in a row is updated. They are
2055 <P>Each column description has the following columns:
2057 <LI><B>SCOPE</B> short => is not used
2058 <LI><B>COLUMN_NAME</B> String => column name
2059 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2060 <LI><B>TYPE_NAME</B> String => Data source dependent type name
2061 <LI><B>COLUMN_SIZE</B> int => precision
2062 <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
2063 <LI><B>DECIMAL_DIGITS</B> short => scale
2064 <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
2065 like an Oracle ROWID
2067 <LI> versionColumnUnknown - may or may not be pseudo column
2068 <LI> versionColumnNotPseudo - is NOT a pseudo column
2069 <LI> versionColumnPseudo - is a pseudo column
2073 @param catalog a catalog name; "" retrieves those without a
2074 catalog; null means drop catalog name from the selection criteria
2075 @param schema a schema name; "" retrieves those without a schema
2076 @param table a table name
2077 @return <code>ResultSet</code> - each row is a column description
2078 @exception SQLException if a database access error occurs
2080 function TZInterbase6DatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;
2081 const Schema: string; const Table: string): IZResultSet;
2083 Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);
2085 Result.MoveToInsertRow;
2086 Result.UpdateNull(1);
2087 Result.UpdateString(2, 'ctid');
2088 // Result.UpdateInt(3, GetSQLType('tid')); //FIX IT
2089 Result.UpdateString(4, 'tid');
2090 Result.UpdateNull(5);
2091 Result.UpdateNull(6);
2092 Result.UpdateNull(7);
2093 Result.UpdateInt(4, Ord(vcPseudo));
2098 Gets a description of a table's primary key columns. They
2099 are ordered by COLUMN_NAME.
2101 <P>Each primary key column description has the following columns:
2103 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2104 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2105 <LI><B>TABLE_NAME</B> String => table name
2106 <LI><B>COLUMN_NAME</B> String => column name
2107 <LI><B>KEY_SEQ</B> short => sequence number within primary key
2108 <LI><B>PK_NAME</B> String => primary key name (may be null)
2111 @param catalog a catalog name; "" retrieves those without a
2112 catalog; null means drop catalog name from the selection criteria
2113 @param schema a schema name; "" retrieves those
2115 @param table a table name
2116 @return <code>ResultSet</code> - each row is a primary key column description
2117 @exception SQLException if a database access error occurs
2119 function TZInterbase6DatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;
2120 const Schema: string; const Table: string): IZResultSet;
2125 LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'a.RDB$RELATION_NAME');
2126 if LTable <> '' then
2127 LTable := ' AND ' + LTable;
2129 SQL := ' SELECT null as TABLE_CAT, null as TABLE_SCHEM,'
2130 + ' a.RDB$RELATION_NAME as TABLE_NAME, b.RDB$FIELD_NAME as COLUMN_NAME,'
2131 + ' b.RDB$FIELD_POSITION+1 as KEY_SEQ, a.RDB$INDEX_NAME as PK_NAME'
2132 + ' FROM RDB$RELATION_CONSTRAINTS a JOIN RDB$INDEX_SEGMENTS b ON'
2133 + ' (a.RDB$INDEX_NAME = b.RDB$INDEX_NAME)'
2134 + ' WHERE RDB$CONSTRAINT_TYPE = ''PRIMARY KEY''' + LTable
2135 + ' ORDER BY a.RDB$RELATION_NAME, b.RDB$FIELD_NAME';
2137 Result := CopyToVirtualResultSet(
2138 GetConnection.CreateStatement.ExecuteQuery(SQL),
2139 ConstructVirtualResultSet(PrimaryKeyColumnsDynArray));
2143 Gets a description of the primary key columns that are
2144 referenced by a table's foreign key columns (the primary keys
2145 imported by a table). They are ordered by PKTABLE_CAT,
2146 PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
2148 <P>Each primary key column description has the following columns:
2150 <LI><B>PKTABLE_CAT</B> String => primary key table catalog
2151 being imported (may be null)
2152 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
2153 being imported (may be null)
2154 <LI><B>PKTABLE_NAME</B> String => primary key table name
2156 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2158 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2159 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2160 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2161 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2162 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2163 <LI><B>UPDATE_RULE</B> short => What happens to
2164 foreign key when primary is updated:
2166 <LI> importedNoAction - do not allow update of primary
2167 key if it has been imported
2168 <LI> importedKeyCascade - change imported key to agree
2169 with primary key update
2170 <LI> importedKeySetNull - change imported key to NULL if
2171 its primary key has been updated
2172 <LI> importedKeySetDefault - change imported key to default values
2173 if its primary key has been updated
2174 <LI> importedKeyRestrict - same as importedKeyNoAction
2175 (for ODBC 2.x compatibility)
2177 <LI><B>DELETE_RULE</B> short => What happens to
2178 the foreign key when primary is deleted.
2180 <LI> importedKeyNoAction - do not allow delete of primary
2181 key if it has been imported
2182 <LI> importedKeyCascade - delete rows that import a deleted key
2183 <LI> importedKeySetNull - change imported key to NULL if
2184 its primary key has been deleted
2185 <LI> importedKeyRestrict - same as importedKeyNoAction
2186 (for ODBC 2.x compatibility)
2187 <LI> importedKeySetDefault - change imported key to default if
2188 its primary key has been deleted
2190 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2191 <LI><B>PK_NAME</B> String => primary key name (may be null)
2192 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2193 constraints be deferred until commit
2195 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2196 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2197 <LI> importedKeyNotDeferrable - see SQL92 for definition
2201 @param catalog a catalog name; "" retrieves those without a
2202 catalog; null means drop catalog name from the selection criteria
2203 @param schema a schema name; "" retrieves those
2205 @param table a table name
2206 @return <code>ResultSet</code> - each row is a primary key column description
2207 @see #getExportedKeys
2209 function TZInterbase6DatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;
2210 const Schema: string; const Table: string): IZResultSet;
2215 Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);
2217 LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'RELC_FOR.RDB$RELATION_NAME'); // Modified by cipto 6/11/2007 4:53:02 PM
2218 if LTable <> '' then
2219 LTable := ' AND ' + LTable;
2221 SQL := 'SELECT RELC_PRIM.RDB$RELATION_NAME, ' // 1 prim.RDB$ key table name
2222 + ' IS_PRIM.RDB$FIELD_NAME, ' // 2 prim.RDB$ key column name
2223 + ' RELC_FOR.RDB$RELATION_NAME, ' // 3 foreign key table name
2224 + ' IS_FOR.RDB$FIELD_NAME, ' // 4 foreign key column name
2225 + ' IS_FOR.RDB$FIELD_POSITION, ' // 5 key sequence
2226 + ' REFC_PRIM.RDB$UPDATE_RULE, ' // 6
2227 + ' REFC_PRIM.RDB$DELETE_RULE, ' // 7
2228 + ' RELC_FOR.RDB$CONSTRAINT_NAME, ' // 8 foreign key constraint name
2229 + ' RELC_PRIM.RDB$CONSTRAINT_NAME ' // 9 primary key constraint name
2230 + ' FROM RDB$RELATION_CONSTRAINTS RELC_FOR, RDB$REF_CONSTRAINTS REFC_FOR, '
2231 + ' RDB$RELATION_CONSTRAINTS RELC_PRIM, RDB$REF_CONSTRAINTS REFC_PRIM, '
2232 + ' RDB$INDEX_SEGMENTS IS_PRIM, RDB$INDEX_SEGMENTS IS_FOR '
2233 + ' WHERE RELC_FOR.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' ' + LTable
2234 + ' AND RELC_FOR.RDB$CONSTRAINT_NAME=REFC_FOR.RDB$CONSTRAINT_NAME'
2235 + ' and REFC_FOR.RDB$CONST_NAME_UQ = RELC_PRIM.RDB$CONSTRAINT_NAME and '
2236 + ' RELC_PRIM.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and ' // useful check, anyay
2237 + ' RELC_PRIM.RDB$INDEX_NAME = IS_PRIM.RDB$INDEX_NAME and '
2238 + ' IS_FOR.RDB$INDEX_NAME = RELC_FOR.RDB$INDEX_NAME and '
2239 + ' IS_PRIM.RDB$FIELD_POSITION = IS_FOR.RDB$FIELD_POSITION and '
2240 + ' REFC_PRIM.RDB$CONSTRAINT_NAME = RELC_FOR.RDB$CONSTRAINT_NAME '
2241 + ' ORDER BY RELC_PRIM.RDB$RELATION_NAME, IS_FOR.RDB$FIELD_POSITION ';
2243 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2247 Result.MoveToInsertRow;
2248 Result.UpdateNull(1); //PKTABLE_CAT
2249 Result.UpdateNull(2); //PKTABLE_SCHEM
2250 Result.UpdateString(3, GetString(1)); //PKTABLE_NAME
2251 Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME
2252 Result.UpdateNull(5); //FKTABLE_CAT
2253 Result.UpdateNull(6); //FKTABLE_SCHEM
2254 Result.UpdateString(7, GetString(3)); //FKTABLE_NAME
2255 Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME
2256 Result.UpdateInt(9, GetInt(5) + 1); //KEY_SEQ
2258 if GetString(6) = 'RESTRICT' then //UPDATE_RULE
2259 Result.UpdateInt(10, Ord(ikRestrict))
2260 else if GetString(6) = 'NO ACTION' then
2261 Result.UpdateInt(10, Ord(ikNoAction))
2262 else if GetString(6) = 'SET DEFAULT' then
2263 Result.UpdateInt(10, Ord(ikSetDefault))
2264 else if GetString(6) = 'CASCADE' then
2265 Result.UpdateInt(10, Ord(ikCascade))
2266 else if GetString(6) = 'SET NULL' then
2267 Result.UpdateInt(10, Ord(ikSetNull));
2269 if GetString(7) = 'RESTRICT' then //DELETE_RULE
2270 Result.UpdateInt(11, Ord(ikRestrict))
2271 else if GetString(7) = 'NO ACTION' then
2272 Result.UpdateInt(11, Ord(ikNoAction))
2273 else if GetString(7) = 'SET DEFAULT' then
2274 Result.UpdateInt(11, Ord(ikSetDefault))
2275 else if GetString(7) = 'CASCADE' then
2276 Result.UpdateInt(11, Ord(ikCascade))
2277 else if GetString(7) = 'SET NULL' then
2278 Result.UpdateInt(11, Ord(ikSetNull));
2280 Result.UpdateString(12, GetString(8)); //FK_NAME
2281 Result.UpdateString(13, GetString(9)); //PK_NAME
2282 Result.UpdateNull(14); //DEFERABILITY
2290 Gets a description of the foreign key columns that reference a
2291 table's primary key columns (the foreign keys exported by a
2292 table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2293 FKTABLE_NAME, and KEY_SEQ.
2295 <P>Each foreign key column description has the following columns:
2297 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2298 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2299 <LI><B>PKTABLE_NAME</B> String => primary key table name
2300 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2301 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2302 being exported (may be null)
2303 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2304 being exported (may be null)
2305 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2307 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2309 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2310 <LI><B>UPDATE_RULE</B> short => What happens to
2311 foreign key when primary is updated:
2313 <LI> importedNoAction - do not allow update of primary
2314 key if it has been imported
2315 <LI> importedKeyCascade - change imported key to agree
2316 with primary key update
2317 <LI> importedKeySetNull - change imported key to NULL if
2318 its primary key has been updated
2319 <LI> importedKeySetDefault - change imported key to default values
2320 if its primary key has been updated
2321 <LI> importedKeyRestrict - same as importedKeyNoAction
2322 (for ODBC 2.x compatibility)
2324 <LI><B>DELETE_RULE</B> short => What happens to
2325 the foreign key when primary is deleted.
2327 <LI> importedKeyNoAction - do not allow delete of primary
2328 key if it has been imported
2329 <LI> importedKeyCascade - delete rows that import a deleted key
2330 <LI> importedKeySetNull - change imported key to NULL if
2331 its primary key has been deleted
2332 <LI> importedKeyRestrict - same as importedKeyNoAction
2333 (for ODBC 2.x compatibility)
2334 <LI> importedKeySetDefault - change imported key to default if
2335 its primary key has been deleted
2337 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2338 <LI><B>PK_NAME</B> String => primary key name (may be null)
2339 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2340 constraints be deferred until commit
2342 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2343 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2344 <LI> importedKeyNotDeferrable - see SQL92 for definition
2348 @param catalog a catalog name; "" retrieves those without a
2349 catalog; null means drop catalog name from the selection criteria
2350 @param schema a schema name; "" retrieves those
2352 @param table a table name
2353 @return <code>ResultSet</code> - each row is a foreign key column description
2354 @see #getImportedKeys
2356 function TZInterbase6DatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;
2357 const Schema: string; const Table: string): IZResultSet;
2362 Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);
2364 LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'RC_PRIM.RDB$RELATION_NAME'); // Modified by cipto 6/11/2007 4:54:02 PM
2365 if LTable <> '' then
2366 LTable := ' AND ' + LTable;
2368 SQL := ' SELECT RC_PRIM.RDB$RELATION_NAME, ' // prim.RDB$ key Table name
2369 + ' IS_PRIM.RDB$FIELD_NAME, ' // prim.RDB$ key column name
2370 + ' RC_FOR.RDB$RELATION_NAME, ' // foreign key Table name
2371 + ' IS_FOR.RDB$FIELD_NAME, ' // foreign key column name
2372 + ' IS_FOR.RDB$FIELD_POSITION, ' // key sequence
2373 + ' REFC_PRIM.RDB$UPDATE_RULE, ' // if update or delete rule is null, interpret as RESTRICT
2374 + ' REFC_PRIM.RDB$DELETE_RULE, '
2375 + ' RC_FOR.RDB$CONSTRAINT_NAME, ' // foreign key constraint name
2376 + ' RC_PRIM.RDB$CONSTRAINT_NAME ' // primary key constraint name
2377 + ' FROM RDB$RELATION_CONSTRAINTS RC_FOR, RDB$REF_CONSTRAINTS REFC_FOR, '
2378 + ' RDB$RELATION_CONSTRAINTS RC_PRIM, RDB$REF_CONSTRAINTS REFC_PRIM, '
2379 + ' RDB$INDEX_SEGMENTS IS_PRIM, RDB$INDEX_SEGMENTS IS_FOR '
2380 + ' WHERE RC_PRIM.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' '+ LTable
2381 + ' and REFC_FOR.RDB$CONST_NAME_UQ = RC_PRIM.RDB$CONSTRAINT_NAME'
2382 + ' and RC_FOR.RDB$CONSTRAINT_NAME = REFC_FOR.RDB$CONSTRAINT_NAME and '
2383 + ' RC_FOR.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' and '// useful check, anyay
2384 + ' RC_PRIM.RDB$INDEX_NAME = IS_PRIM.RDB$INDEX_NAME and '
2385 + ' IS_FOR.RDB$INDEX_NAME = RC_FOR.RDB$INDEX_NAME and '
2386 + ' IS_PRIM.RDB$FIELD_POSITION = IS_FOR.RDB$FIELD_POSITION and '
2387 + ' REFC_PRIM.RDB$CONSTRAINT_NAME = RC_FOR.RDB$CONSTRAINT_NAME '
2388 + ' ORDER BY RC_FOR.RDB$RELATION_NAME, IS_FOR.RDB$FIELD_POSITION ';
2390 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2394 Result.MoveToInsertRow;
2395 Result.UpdateNull(1); //PKTABLE_CAT
2396 Result.UpdateNull(2); //PKTABLE_SCHEM
2397 Result.UpdateString(3, GetString(1)); //PKTABLE_NAME
2398 Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME
2399 Result.UpdateNull(5); //FKTABLE_CAT
2400 Result.UpdateNull(6); //FKTABLE_SCHEM'
2401 Result.UpdateString(7, GetString(3)); //FKTABLE_NAME
2402 Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME
2403 Result.UpdateInt(9, GetInt(5) + 1); //KEY_SEQ
2405 if GetString(6) = 'RESTRICT' then //UPDATE_RULE
2406 Result.UpdateInt(10, Ord(ikRestrict))
2407 else if GetString(6) = 'NO ACTION' then
2408 Result.UpdateInt(10, Ord(ikNoAction))
2409 else if GetString(6) = 'SET DEFAULT' then
2410 Result.UpdateInt(10, Ord(ikSetDefault))
2411 else if GetString(6) = 'CASCADE' then
2412 Result.UpdateInt(10, Ord(ikCascade))
2413 else if GetString(6) = 'SET NULL' then
2414 Result.UpdateInt(10, Ord(ikSetNull));
2416 if GetString(7) = 'RESTRICT' then //DELETE_RULE
2417 Result.UpdateInt(11, Ord(ikRestrict))
2418 else if GetString(7) = 'NO ACTION' then
2419 Result.UpdateInt(11, Ord(ikNoAction))
2420 else if GetString(7) = 'SET DEFAULT' then
2421 Result.UpdateInt(11, Ord(ikSetDefault))
2422 else if GetString(7) = 'CASCADE' then
2423 Result.UpdateInt(11, Ord(ikCascade))
2424 else if GetString(7) = 'SET NULL' then
2425 Result.UpdateInt(11, Ord(ikSetNull));
2427 Result.UpdateString(12, GetString(8)); //FK_NAME
2428 Result.UpdateString(13, GetString(9)); //PK_NAME
2429 Result.UpdateNull(14); //DEFERABILITY
2438 Gets a description of the foreign key columns in the foreign key
2439 table that reference the primary key columns of the primary key
2440 table (describe how one table imports another's key.) This
2441 should normally return a single foreign key/primary key pair
2442 (most tables only import a foreign key from a table once.) They
2443 are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2446 <P>Each foreign key column description has the following columns:
2448 <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2449 <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2450 <LI><B>PKTABLE_NAME</B> String => primary key table name
2451 <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2452 <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2453 being exported (may be null)
2454 <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2455 being exported (may be null)
2456 <LI><B>FKTABLE_NAME</B> String => foreign key table name
2458 <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2460 <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2461 <LI><B>UPDATE_RULE</B> short => What happens to
2462 foreign key when primary is updated:
2464 <LI> importedNoAction - do not allow update of primary
2465 key if it has been imported
2466 <LI> importedKeyCascade - change imported key to agree
2467 with primary key update
2468 <LI> importedKeySetNull - change imported key to NULL if
2469 its primary key has been updated
2470 <LI> importedKeySetDefault - change imported key to default values
2471 if its primary key has been updated
2472 <LI> importedKeyRestrict - same as importedKeyNoAction
2473 (for ODBC 2.x compatibility)
2475 <LI><B>DELETE_RULE</B> short => What happens to
2476 the foreign key when primary is deleted.
2478 <LI> importedKeyNoAction - do not allow delete of primary
2479 key if it has been imported
2480 <LI> importedKeyCascade - delete rows that import a deleted key
2481 <LI> importedKeySetNull - change imported key to NULL if
2482 its primary key has been deleted
2483 <LI> importedKeyRestrict - same as importedKeyNoAction
2484 (for ODBC 2.x compatibility)
2485 <LI> importedKeySetDefault - change imported key to default if
2486 its primary key has been deleted
2488 <LI><B>FK_NAME</B> String => foreign key name (may be null)
2489 <LI><B>PK_NAME</B> String => primary key name (may be null)
2490 <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2491 constraints be deferred until commit
2493 <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2494 <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2495 <LI> importedKeyNotDeferrable - see SQL92 for definition
2499 @param primaryCatalog a catalog name; "" retrieves those without a
2500 catalog; null means drop catalog name from the selection criteria
2501 @param primarySchema a schema name; "" retrieves those
2503 @param primaryTable the table name that exports the key
2504 @param foreignCatalog a catalog name; "" retrieves those without a
2505 catalog; null means drop catalog name from the selection criteria
2506 @param foreignSchema a schema name; "" retrieves those
2508 @param foreignTable the table name that imports the key
2509 @return <code>ResultSet</code> - each row is a foreign key column description
2510 @see #getImportedKeys
2512 function TZInterbase6DatabaseMetadata.UncachedGetCrossReference(
2513 const PrimaryCatalog: string; const PrimarySchema: string;
2514 const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
2515 const ForeignTable: string): IZResultSet;
2518 LCatalog, SQLString, LPTable, LFTable: String;
2520 function GetRuleType(const Rule: String): TZImportedKey;
2522 if Rule = 'RESTRICT' then
2523 Result := ikRestrict
2524 else if Rule = 'NO ACTION' then
2525 Result := ikNoAction
2526 else if Rule = 'CASCADE' then
2528 else if Rule = 'SET DEFAULT' then
2529 Result := ikSetDefault
2530 else if Rule = 'SET NULL' then
2533 Result := ikNotDeferrable; //impossible!
2536 if PrimaryCatalog = '' then
2537 LCatalog := GetConnection.GetCatalog
2539 LCatalog := PrimaryCatalog;
2541 LPTable := ConstructNameCondition(AddEscapeCharToWildcards(PrimaryTable), 'i2.RDB$RELATION_NAME');
2542 LFTable := ConstructNameCondition(AddEscapeCharToWildcards(ForeignTable), 'rc.RDB$RELATION_NAME');
2543 if LPTable <> '' then
2544 LPTable := ' AND ' + LPTable;
2545 if LFTable <> '' then
2546 LFTable := ' AND ' + LFTable;
2548 Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,
2549 ForeignCatalog, ForeignSchema, ForeignTable);
2553 'i2.RDB$RELATION_NAME AS PKTABLE_NAME, '+
2554 's2.RDB$FIELD_NAME AS PKCOLUMN_NAME, '+
2555 'rc.RDB$RELATION_NAME as FKTABLE_NAME, '+
2556 's.RDB$FIELD_NAME AS FKCOLUMN_NAME, '+
2557 'refc.RDB$UPDATE_RULE AS UPDATE_RULE, '+
2558 'refc.RDB$DELETE_RULE AS DELETE_RULE, '+
2559 'i.RDB$INDEX_NAME AS FK_NAME, '+
2560 's2.RDB$INDEX_NAME as PK_NAME, '+
2561 'rc.RDB$DEFERRABLE AS DEFERRABILITY '+
2562 'FROM RDB$INDEX_SEGMENTS s '+
2563 'LEFT JOIN RDB$INDICES i ON i.RDB$INDEX_NAME = s.RDB$INDEX_NAME '+
2564 'LEFT JOIN RDB$RELATION_CONSTRAINTS rc ON rc.RDB$INDEX_NAME = s.RDB$INDEX_NAME '+
2565 'LEFT JOIN RDB$REF_CONSTRAINTS refc ON rc.RDB$CONSTRAINT_NAME = refc.RDB$CONSTRAINT_NAME '+
2566 'LEFT JOIN RDB$RELATION_CONSTRAINTS rc2 ON rc2.RDB$CONSTRAINT_NAME = refc.RDB$CONST_NAME_UQ '+
2567 'LEFT JOIN RDB$INDICES i2 ON i2.RDB$INDEX_NAME = rc2.RDB$INDEX_NAME '+
2568 'LEFT JOIN RDB$INDEX_SEGMENTS s2 ON i2.RDB$INDEX_NAME = s2.RDB$INDEX_NAME '+
2569 'WHERE rc.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' '+
2570 'AND rc.RDB$CONSTRAINT_TYPE IS NOT NULL '+LPTable+LFTable;
2573 with GetConnection.CreateStatement.ExecuteQuery(SQLString) do
2578 Result.MoveToInsertRow;
2579 Result.UpdateString(1, LCatalog); //PKTABLE_CAT
2580 Result.UpdateNull(2); //PKTABLE_SCHEM
2581 Result.UpdateString(3, GetString(1)); //PKTABLE_NAME
2582 Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME
2583 Result.UpdateString(5, LCatalog); //PKTABLE_CAT
2584 Result.UpdateNull(6); //FKTABLE_SCHEM
2585 Result.UpdateString(7, GetString(3)); //FKTABLE_NAME
2586 Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME
2587 Result.UpdateShort(9, KeySeq); //KEY_SEQ
2588 Result.UpdateShort(10, Ord(GetRuleType(GetString(5)))); //UPDATE_RULE
2589 Result.UpdateShort(11, Ord(GetRuleType(GetString(6)))); //DELETE_RULE
2590 Result.UpdateString(12, GetString(7)); //FK_NAME
2591 Result.UpdateString(13, GetString(8)); //PK_NAME
2592 if GetString(9) = 'NO' then
2593 Result.UpdateShort(14, Ord(ikNotDeferrable)) //DEFERRABILITY
2595 Result.UpdateShort(14, Ord(ikInitiallyDeferred)); //DEFERRABILITY
2603 Gets a description of all the standard SQL types supported by
2604 this database. They are ordered by DATA_TYPE and then by how
2605 closely the data type maps to the corresponding JDBC SQL type.
2607 <P>Each type description has the following columns:
2609 <LI><B>TYPE_NAME</B> String => Type name
2610 <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2611 <LI><B>PRECISION</B> int => maximum precision
2612 <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2614 <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2616 <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2617 the type (may be null)
2618 <LI><B>NULLABLE</B> short => can you use NULL for this type?
2620 <LI> typeNoNulls - does not allow NULL values
2621 <LI> typeNullable - allows NULL values
2622 <LI> typeNullableUnknown - nullability unknown
2624 <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2625 <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2627 <LI> typePredNone - No support
2628 <LI> typePredChar - Only supported with WHERE .. LIKE
2629 <LI> typePredBasic - Supported except for WHERE .. LIKE
2630 <LI> typeSearchable - Supported for all WHERE ..
2632 <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2633 <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2634 <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2635 auto-increment value?
2636 <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2638 <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2639 <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2640 <LI><B>SQL_DATA_TYPE</B> int => unused
2641 <LI><B>SQL_DATETIME_SUB</B> int => unused
2642 <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2645 @return <code>ResultSet</code> - each row is an SQL type description
2647 function TZInterbase6DatabaseMetadata.UncachedGetTypeInfo: IZResultSet;
2651 Result:=inherited UncachedGetTypeInfo;
2653 SQL := ' SELECT RDB$TYPE, RDB$TYPE_NAME FROM RDB$TYPES ' +
2654 ' WHERE RDB$FIELD_NAME = ''RDB$FIELD_TYPE'' ';
2655 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2659 Result.MoveToInsertRow;
2660 Result.UpdateString(1, GetString(2));
2661 Result.UpdateInt(2, Ord(ConvertInterbase6ToSqlType(GetInt(1), 0,
2662 ConSettings.CPType)));
2663 Result.UpdateInt(3, 9);
2664 Result.UpdateInt(7, Ord(ntNoNulls));
2665 Result.UpdateBoolean(8, false);
2666 Result.UpdateBoolean(9, false);
2667 Result.UpdateBoolean(11, false);
2668 Result.UpdateBoolean(12, false);
2669 Result.UpdateInt(18, 10);
2677 Gets a description of a table's indices and statistics. They are
2678 ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2680 <P>Each index column description has the following columns:
2682 <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2683 <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2684 <LI><B>TABLE_NAME</B> String => table name
2685 <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2686 false when TYPE is tableIndexStatistic
2687 <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2688 null when TYPE is tableIndexStatistic
2689 <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2691 <LI><B>TYPE</B> short => index type:
2693 <LI> tableIndexStatistic - this identifies table statistics that are
2694 returned in conjuction with a table's index descriptions
2695 <LI> tableIndexClustered - this is a clustered index
2696 <LI> tableIndexHashed - this is a hashed index
2697 <LI> tableIndexOther - this is some other style of index
2699 <LI><B>ORDINAL_POSITION</B> short => column sequence number
2700 within index; zero when TYPE is tableIndexStatistic
2701 <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2703 <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2704 "D" => descending, may be null if sort sequence is not supported;
2705 null when TYPE is tableIndexStatistic
2706 <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2707 this is the number of rows in the table; otherwise, it is the
2708 number of unique values in the index.
2709 <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
2710 this is the number of pages used for the table, otherwise it
2711 is the number of pages used for the current index.
2712 <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2716 @param catalog a catalog name; "" retrieves those without a
2717 catalog; null means drop catalog name from the selection criteria
2718 @param schema a schema name; "" retrieves those without a schema
2719 @param table a table name
2720 @param unique when true, return only indices for unique values;
2721 when false, return indices regardless of whether unique or not
2722 @param approximate when true, result is allowed to reflect approximate
2723 or out of data values; when false, results are requested to be
2725 @return <code>ResultSet</code> - each row is an index column description
2727 function TZInterbase6DatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;
2728 const Schema: string; const Table: string; Unique: Boolean;
2729 Approximate: Boolean): IZResultSet;
2734 LTable := ConstructNameCondition(Table, 'I.RDB$RELATION_NAME');
2735 if LTable <> '' then
2736 LTable := ' AND ' + LTable;
2738 Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);
2740 SQL := ' SELECT I.RDB$RELATION_NAME, I.RDB$UNIQUE_FLAG, I.RDB$INDEX_NAME,'
2741 + ' ISGMT.RDB$FIELD_POSITION, ISGMT.RDB$FIELD_NAME, I.RDB$INDEX_TYPE,'
2742 + ' I.RDB$SEGMENT_COUNT, COUNT (DISTINCT P.RDB$PAGE_NUMBER) '
2743 + ' FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS ISGMT ON'
2744 + ' I.RDB$INDEX_NAME = ISGMT.RDB$INDEX_NAME JOIN RDB$RELATIONS R ON'
2745 + ' (R.RDB$RELATION_NAME = I.RDB$RELATION_NAME) JOIN RDB$PAGES P ON'
2746 + ' (P.RDB$RELATION_ID = R.RDB$RELATION_ID AND P.RDB$PAGE_TYPE = 7'
2747 + ' OR P.RDB$PAGE_TYPE = 6) WHERE ';
2749 SQL := SQL + ' I.RDB$UNIQUE_FLAG = 1 AND ';
2751 SQL := SQL + 'I.RDB$RELATION_NAME != '''' ' + LTable
2753 + ' I.RDB$INDEX_NAME, I.RDB$RELATION_NAME, I.RDB$UNIQUE_FLAG, '
2754 + ' ISGMT.RDB$FIELD_POSITION, ISGMT.RDB$FIELD_NAME, I.RDB$INDEX_TYPE, '
2755 + ' I.RDB$SEGMENT_COUNT ORDER BY 1,2,3,4';
2758 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2762 Result.MoveToInsertRow;
2763 Result.UpdateNull(1); //TABLE_CAT
2764 Result.UpdateNull(2); //TABLE_SCHEM
2765 Result.UpdateString(3, GetString(1)); //TABLE_NAME, RDB$RELATION_NAME
2766 Result.UpdateBoolean(4, not GetBoolean(2)); //NON_UNIQUE, RDB$UNIQUE_FLAG
2767 Result.UpdateNull(5); //INDEX_QUALIFIER
2768 Result.UpdateString(6, GetString(3)); //INDEX_NAME, RDB$INDEX_NAME
2769 Result.UpdateInt(7, Ord(ntNoNulls)); //TYPE
2770 Result.UpdateInt(8, GetInt(4) + 1); //ORDINAL_POSITION, RDB$FIELD_POSITION
2771 Result.UpdateString(9, GetString(5)); //COLUMN_NAME, RDB$FIELD_NAME
2772 Result.UpdateNull(10); //ASC_OR_DESC
2773 Result.UpdateNull(11); //CARDINALITY
2774 Result.UpdateInt(12, GetInt(7)); //PAGES, RDB$SEGMENT_COUNT
2775 Result.UpdateNull(13); //FILTER_CONDITION
2782 function TZInterbase6DatabaseMetadata.UncachedGetSequences(const Catalog, SchemaPattern,
2783 SequenceNamePattern: string): IZResultSet;
2786 LSequenceNamePattern: string;
2788 Result:=inherited UncachedGetSequences(Catalog, SchemaPattern, SequenceNamePattern);
2790 LSequenceNamePattern := ConstructNameCondition(SequenceNamePattern,
2791 'RDB$GENERATOR_NAME');
2792 if LSequenceNamePattern <> '' then
2793 LSequenceNamePattern := ' and '+LSequenceNamePattern;
2795 SQL := ' SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS ' +
2796 'WHERE (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)'+ LSequenceNamePattern;
2798 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2802 Result.MoveToInsertRow;
2803 Result.UpdateNull(1);
2804 Result.UpdateNull(2);
2805 Result.UpdateString(3, GetString(1)); //RDB$GENERATOR_NAME
2813 Gets a privilege name.
2814 @param Interbase privilege name
2815 @returns a JDBC privilege name.
2817 function TZInterbase6DatabaseMetadata.GetPrivilege(Privilege: string): string;
2819 if Privilege = 'S' then
2821 else if Privilege = 'I' then
2823 else if Privilege = 'U' then
2825 else if Privilege = 'D' then
2827 else if Privilege = 'R' then
2828 Result := 'REFERENCE'
2834 Gets the used Collation and CharacterSet of spezified Object.
2836 @param catalog a catalog name; "" retrieves those without a
2837 catalog; null means drop catalog name from the selection criteria
2838 @param schema a schema name; "" and Catolog "" retrieves nothing
2839 @param table a table name; "" retrieves the Schema Colloation and CharacterSet
2840 @param ColumnNamePattern ColumnPattern;"" retrieves the
2841 Table(if @param TablePattern is set) or
2842 Schema(if @param TablePattern is NULL)
2843 Colloation and CharacterSet
2844 @return <code>ResultSet</code> - each row is a Collation, CharacterSet, ID,
2845 and ByteLength per Char of speziefied Object
2847 function TZInterbase6DatabaseMetadata.UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,
2848 TableNamePattern, ColumnNamePattern: string): IZResultSet; //EgonHugeist
2850 SQL, LCatalog: string;
2851 ColumnNameCondition, TableNameCondition: string;
2853 if Catalog = '' then
2855 if SchemaPattern <> '' then
2856 LCatalog := SchemaPattern
2858 LCatalog := FDatabase;
2861 LCatalog := Catalog;
2862 TableNameCondition := ConstructNameCondition(TableNamePattern,'R.RDB$RELATION_NAME');
2863 ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'R.RDB$FIELD_NAME');
2864 If TableNameCondition <> '' then
2865 TableNameCondition := ' and ' + TableNameCondition;
2866 If ColumnNameCondition <> '' then
2867 ColumnNameCondition := ' and ' + ColumnNameCondition;
2869 Result:=inherited UncachedGetCollationAndCharSet(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);
2871 if LCatalog <> '' then
2873 if TableNamePattern <> '' then
2875 if ColumnNamePattern <> '' then
2877 SQL := 'SELECT C.RDB$CHARACTER_SET_NAME, C.RDB$DEFAULT_COLLATE_NAME, '+
2878 'C.RDB$CHARACTER_SET_ID, C.RDB$BYTES_PER_CHARACTER '+
2879 'FROM RDB$RELATION_FIELDS R '+
2880 'right join RDB$FIELDS F on R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME '+
2881 'left join RDB$CHARACTER_SETS C on C.RDB$CHARACTER_SET_ID = F.RDB$CHARACTER_SET_ID '+
2882 'left join RDB$TYPES T on F.RDB$FIELD_TYPE = T.RDB$TYPE'+
2883 'where T.RDB$FIELD_NAME=''RDB$FIELD_TYPE'' '+
2884 ColumnNameCondition+TableNameCondition+
2885 'order by R.RDB$FIELD_POSITION;';
2886 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2890 if not ( GetString(FindColumn('RDB$CHARACTER_SET_NAME')) = 'NONE' ) then
2892 Result.MoveToInsertRow;
2893 Result.UpdateString(1, LCatalog); //COLLATION_CATALOG
2894 Result.UpdateString(2, LCatalog); //COLLATION_SCHEMA
2895 Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE
2896 Result.UpdateString(4, ColumnNamePattern);//COLLATION_COLUMN
2897 Result.UpdateString(5, GetString(FindColumn('RDB$DEFAULT_COLLATE_NAME'))); //COLLATION_NAME
2898 Result.UpdateString(6, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME
2899 Result.UpdateShort(7, GetShort(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID
2900 Result.UpdateShort(8, GetShort(FindColumn('RDB$BYTES_PER_CHARACTER'))); //CHARACTER_SET_SIZE
2911 {Brings Defaults for Table or Database up}
2912 SQL := 'SELECT D.RDB$CHARACTER_SET_NAME, CS.RDB$DEFAULT_COLLATE_NAME, '+
2913 'CS.RDB$CHARACTER_SET_ID, CS.RDB$BYTES_PER_CHARACTER '+
2914 'FROM RDB$DATABASE D '+
2915 'LEFT JOIN RDB$CHARACTER_SETS CS on '+
2916 'D.RDB$CHARACTER_SET_NAME = CS.RDB$CHARACTER_SET_NAME; ';
2917 with GetConnection.CreateStatement.ExecuteQuery(SQL) do
2921 Result.MoveToInsertRow;
2922 Result.UpdateString(1, LCatalog); //COLLATION_CATALOG
2923 Result.UpdateString(2, LCatalog); //COLLATION_SCHEMA
2924 Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE
2925 Result.UpdateNull(4);//COLLATION_COLUMN
2926 Result.UpdateString(5, GetString(FindColumn('RDB$DEFAULT_COLLATE_NAME'))); //COLLATION_NAME
2927 Result.UpdateString(6, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME
2928 Result.UpdateShort(7, GetShort(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID
2929 Result.UpdateShort(8, GetShort(FindColumn('RDB$BYTES_PER_CHARACTER'))); //CHARACTER_SET_SIZE
2937 Gets the supported CharacterSets:
2938 @return <code>ResultSet</code> - each row is a CharacterSetName and it's ID
2940 function TZInterbase6DatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist
2942 Result:=inherited UncachedGetCharacterSets;
2944 with GetConnection.CreateStatement.ExecuteQuery(
2945 'SELECT RDB$CHARACTER_SET_NAME, RDB$CHARACTER_SET_ID '+
2946 'FROM RDB$CHARACTER_SETS') do
2950 Result.MoveToInsertRow;
2951 Result.UpdateString(1, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME
2952 Result.UpdateString(2, GetString(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID