zeoslib  UNKNOWN
 All Files
ZDbcASAMetadata.pas
Go to the documentation of this file.
1 {*********************************************************}
2 { }
3 { Zeos Database Objects }
4 { Interbase Database Connectivity Classes }
5 { }
6 { Originally written by Sergey Merkuriev }
7 { }
8 {*********************************************************}
9 
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
12 { }
13 { License Agreement: }
14 { }
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. }
20 { }
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. }
39 { }
40 { }
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) }
45 { }
46 { http://www.sourceforge.net/projects/zeoslib. }
47 { }
48 { }
49 { Zeos Development Group. }
50 {********************************************************@}
51 
52 unit ZDbcASAMetadata;
53 
54 interface
55 
56 {$I ZDbc.inc}
57 
58 uses
59  Types, Classes, SysUtils, ZDbcIntfs, ZDbcMetadata, ZCompatibility,
60  ZDbcConnection, ZDbcASA, ZURL;
61 
62 type
63 
64  // technobot 2008-06-28 - methods moved as is from TZASADatabaseMetadata:
65  {** Implements ASA Database Information. }
66  TZASADatabaseInfo = class(TZAbstractDatabaseInfo)
67  public
68  constructor Create(const Metadata: TZAbstractDatabaseMetadata);
69  destructor Destroy; override;
70 
71  // database/driver/server info:
72  function GetDatabaseProductName: string; override;
73  function GetDatabaseProductVersion: string; override;
74  function GetDriverName: string; override;
75 // function GetDriverVersion: string; override; -> Same as parent
76  function GetDriverMajorVersion: Integer; override;
77  function GetDriverMinorVersion: Integer; override;
78 // function GetServerVersion: string; -> Not implemented
79 
80  // capabilities (what it can/cannot do):
81 // function AllProceduresAreCallable: Boolean; override; -> Not implemented
82 // function AllTablesAreSelectable: Boolean; override; -> Not implemented
83  function SupportsMixedCaseIdentifiers: Boolean; override;
84  function SupportsMixedCaseQuotedIdentifiers: Boolean; override;
85 // function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented
86 // function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented
87 // function SupportsColumnAliasing: Boolean; override; -> Not implemented
88 // function SupportsConvert: Boolean; override; -> Not implemented
89 // function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):
90 // Boolean; override; -> Not implemented
91 // function SupportsTableCorrelationNames: Boolean; override; -> Not implemented
92 // function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented
93  function SupportsExpressionsInOrderBy: Boolean; override;
94  function SupportsOrderByUnrelated: Boolean; override;
95  function SupportsGroupBy: Boolean; override;
96  function SupportsGroupByUnrelated: Boolean; override;
97  function SupportsGroupByBeyondSelect: Boolean; override;
98 // function SupportsLikeEscapeClause: Boolean; override; -> Not implemented
99 // function SupportsMultipleResultSets: Boolean; override; -> Not implemented
100 // function SupportsMultipleTransactions: Boolean; override; -> Not implemented
101 // function SupportsNonNullableColumns: Boolean; override; -> Not implemented
102 // function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented
103 // function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented
104 // function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented
105 // function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented
106 // function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented
107 // function SupportsANSI92FullSQL: Boolean; override; -> Not implemented
108  function SupportsIntegrityEnhancementFacility: Boolean; override;
109 // function SupportsOuterJoins: Boolean; override; -> Not implemented
110 // function SupportsFullOuterJoins: Boolean; override; -> Not implemented
111 // function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented
112  function SupportsSchemasInDataManipulation: Boolean; override;
113  function SupportsSchemasInProcedureCalls: Boolean; override;
114  function SupportsSchemasInTableDefinitions: Boolean; override;
115  function SupportsSchemasInIndexDefinitions: Boolean; override;
116  function SupportsSchemasInPrivilegeDefinitions: Boolean; override;
117  function SupportsCatalogsInDataManipulation: Boolean; override;
118  function SupportsCatalogsInProcedureCalls: Boolean; override;
119  function SupportsCatalogsInTableDefinitions: Boolean; override;
120  function SupportsCatalogsInIndexDefinitions: Boolean; override;
121  function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;
122  function SupportsPositionedDelete: Boolean; override;
123  function SupportsPositionedUpdate: Boolean; override;
124  function SupportsSelectForUpdate: Boolean; override;
125  function SupportsStoredProcedures: Boolean; override;
126  function SupportsSubqueriesInComparisons: Boolean; override;
127  function SupportsSubqueriesInExists: Boolean; override;
128  function SupportsSubqueriesInIns: Boolean; override;
129  function SupportsSubqueriesInQuantifieds: Boolean; override;
130  function SupportsCorrelatedSubqueries: Boolean; override;
131  function SupportsUnion: Boolean; override;
132  function SupportsUnionAll: Boolean; override;
133  function SupportsOpenCursorsAcrossCommit: Boolean; override;
134  function SupportsOpenCursorsAcrossRollback: Boolean; override;
135  function SupportsOpenStatementsAcrossCommit: Boolean; override;
136  function SupportsOpenStatementsAcrossRollback: Boolean; override;
137  function SupportsTransactions: Boolean; override;
138  function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):
139  Boolean; override;
140  function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;
141  function SupportsDataManipulationTransactionsOnly: Boolean; override;
142  function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;
143  function SupportsResultSetConcurrency(_Type: TZResultSetType;
144  Concurrency: TZResultSetConcurrency): Boolean; override;
145 // function SupportsBatchUpdates: Boolean; override; -> Not implemented
146 
147  // maxima:
148  function GetMaxBinaryLiteralLength: Integer; override;
149  function GetMaxCharLiteralLength: Integer; override;
150  function GetMaxColumnNameLength: Integer; override;
151  function GetMaxColumnsInGroupBy: Integer; override;
152  function GetMaxColumnsInIndex: Integer; override;
153  function GetMaxColumnsInOrderBy: Integer; override;
154  function GetMaxColumnsInSelect: Integer; override;
155  function GetMaxColumnsInTable: Integer; override;
156  function GetMaxConnections: Integer; override;
157  function GetMaxCursorNameLength: Integer; override;
158  function GetMaxIndexLength: Integer; override;
159  function GetMaxSchemaNameLength: Integer; override;
160  function GetMaxProcedureNameLength: Integer; override;
161  function GetMaxCatalogNameLength: Integer; override;
162  function GetMaxRowSize: Integer; override;
163  function GetMaxStatementLength: Integer; override;
164  function GetMaxStatements: Integer; override;
165  function GetMaxTableNameLength: Integer; override;
166  function GetMaxTablesInSelect: Integer; override;
167  function GetMaxUserNameLength: Integer; override;
168 
169  // policies (how are various data and operations handled):
170 // function IsReadOnly: Boolean; override; -> Not implemented
171 // function IsCatalogAtStart: Boolean; override; -> Not implemented
172  function DoesMaxRowSizeIncludeBlobs: Boolean; override;
173 // function NullsAreSortedHigh: Boolean; override; -> Not implemented
174 // function NullsAreSortedLow: Boolean; override; -> Not implemented
175  function NullsAreSortedAtStart: Boolean; override;
176 // function NullsAreSortedAtEnd: Boolean; override; -> Not implemented
177 // function NullPlusNonNullIsNull: Boolean; override; -> Not implemented
178  function UsesLocalFiles: Boolean; override;
179  function UsesLocalFilePerTable: Boolean; override;
180  function StoresUpperCaseIdentifiers: Boolean; override;
181  function StoresLowerCaseIdentifiers: Boolean; override;
182  function StoresMixedCaseIdentifiers: Boolean; override;
183  function StoresUpperCaseQuotedIdentifiers: Boolean; override;
184  function StoresLowerCaseQuotedIdentifiers: Boolean; override;
185  function StoresMixedCaseQuotedIdentifiers: Boolean; override;
186  function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;
187  function DataDefinitionCausesTransactionCommit: Boolean; override;
188  function DataDefinitionIgnoredInTransactions: Boolean; override;
189 
190  // interface details (terms, keywords, etc):
191 // function GetIdentifierQuoteString: string; override; -> Not implemented
192  function GetSchemaTerm: string; override;
193  function GetProcedureTerm: string; override;
194  function GetCatalogTerm: string; override;
195  function GetCatalogSeparator: string; override;
196  function GetSQLKeywords: string; override;
197  function GetNumericFunctions: string; override;
198  function GetStringFunctions: string; override;
199  function GetSystemFunctions: string; override;
200  function GetTimeDateFunctions: string; override;
201  function GetSearchStringEscape: string; override;
202  function GetExtraNameCharacters: string; override;
203  end;
204 
205  {** Implements ASA Database Metadata. }
206  TZASADatabaseMetadata = class(TZAbstractDatabaseMetadata)
207  private
208  FASAConnection: TZASAConnection;
209  function ComposeObjectString(const S: String; Const NullText: String = 'null';
210  QuoteChar: Char = #39): String;
211  protected
212  function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-28
213 
214  function UncachedGetTables(const Catalog: string; const SchemaPattern: string;
215  const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;
216  function UncachedGetSchemas: IZResultSet; override;
217 // function UncachedGetCatalogs: IZResultSet; override; -> Not implemented
218  function UncachedGetTableTypes: IZResultSet; override;
219  function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;
220  const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;
221  function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;
222  const TableNamePattern: string): IZResultSet; override;
223  function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;
224  const Table: string; const ColumnNamePattern: string): IZResultSet; override;
225  function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;
226  const Table: string): IZResultSet; override;
227  function UncachedGetImportedKeys(const Catalog: string; const Schema: string;
228  const Table: string): IZResultSet; override;
229  function UncachedGetExportedKeys(const Catalog: string; const Schema: string;
230  const Table: string): IZResultSet; override;
231  function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;
232  const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;
233  const ForeignTable: string): IZResultSet; override;
234  function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;
235  Unique: Boolean; Approximate: Boolean): IZResultSet; override;
236 // function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;
237 // const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented
238  function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;
239  const ProcedureNamePattern: string): IZResultSet; override;
240  function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;
241  const ProcedureNamePattern: string; const ColumnNamePattern: string):
242  IZResultSet; override;
243  function UncachedGetVersionColumns(const Catalog: string; const Schema: string;
244  const Table: string): IZResultSet; override;
245  function UncachedGetTypeInfo: IZResultSet; override;
246  function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;
247  const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;
248  public
249  constructor Create(Connection: TZAbstractConnection; const Url: TZURL); override;
250  end;
251 
252 implementation
253 
254 uses ZDbcASAUtils, ZDbcUtils;
255 
256 { TZASADatabaseInfo }
257 
258 {**
259  Constructs this object.
260  @param Metadata the interface of the correpsonding database metadata object
261 }
262 constructor TZASADatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);
263 begin
264  inherited;
265 end;
266 
267 {**
268  Destroys this object and cleanups the memory.
269 }
270 destructor TZASADatabaseInfo.Destroy;
271 begin
272  inherited;
273 end;
274 
275 //----------------------------------------------------------------------
276 // First, a variety of minor information about the target database.
277 
278 {**
279  Are NULL values sorted at the start regardless of sort order?
280  @return <code>true</code> if so; <code>false</code> otherwise
281 }
282 function TZASADatabaseInfo.NullsAreSortedAtStart: Boolean;
283 begin
284  Result := True;
285 end;
286 
287 {**
288  What's the name of this database product?
289  @return database product name
290 }
291 function TZASADatabaseInfo.GetDatabaseProductName: string;
292 begin
293  Result := 'Sybase ASA';
294 end;
295 
296 {**
297  What's the version of this database product?
298  @return database version
299 }
300 function TZASADatabaseInfo.GetDatabaseProductVersion: string;
301 begin
302  Result := '7.0+';
303 end;
304 
305 {**
306  What's the name of this JDBC driver?
307  @return JDBC driver name
308 }
309 function TZASADatabaseInfo.GetDriverName: string;
310 begin
311  Result := 'Zeos Database Connectivity Driver for Sybase ASA';
312 end;
313 
314 {**
315  What's this JDBC driver's major version number?
316  @return JDBC driver major version
317 }
318 function TZASADatabaseInfo.GetDriverMajorVersion: Integer;
319 begin
320  Result := 1;
321 end;
322 
323 {**
324  What's this JDBC driver's minor version number?
325  @return JDBC driver minor version number
326 }
327 function TZASADatabaseInfo.GetDriverMinorVersion: Integer;
328 begin
329  Result := 0;
330 end;
331 
332 {**
333  Does the database store tables in a local file?
334  @return <code>true</code> if so; <code>false</code> otherwise
335 }
336 function TZASADatabaseInfo.UsesLocalFiles: Boolean;
337 begin
338  Result := False;
339 end;
340 
341 {**
342  Does the database use a file for each table?
343  @return true if the database uses a local file for each table
344 }
345 function TZASADatabaseInfo.UsesLocalFilePerTable: Boolean;
346 begin
347  Result := False;
348 end;
349 
350 {**
351  Does the database treat mixed case unquoted SQL identifiers as
352  case sensitive and as a result store them in mixed case?
353  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.
354  @return <code>true</code> if so; <code>false</code> otherwise
355 }
356 function TZASADatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;
357 begin
358  Result := False;
359 end;
360 
361 {**
362  Does the database treat mixed case unquoted SQL identifiers as
363  case insensitive and store them in upper case?
364  @return <code>true</code> if so; <code>false</code> otherwise
365 }
366 function TZASADatabaseInfo.StoresUpperCaseIdentifiers: Boolean;
367 begin
368  Result := False;
369 end;
370 
371 {**
372  Does the database treat mixed case unquoted SQL identifiers as
373  case insensitive and store them in lower case?
374  @return <code>true</code> if so; <code>false</code> otherwise
375 }
376 function TZASADatabaseInfo.StoresLowerCaseIdentifiers: Boolean;
377 begin
378  Result := False;
379 end;
380 
381 {**
382  Does the database treat mixed case unquoted SQL identifiers as
383  case insensitive and store them in mixed case?
384  @return <code>true</code> if so; <code>false</code> otherwise
385 }
386 function TZASADatabaseInfo.StoresMixedCaseIdentifiers: Boolean;
387 begin
388  Result := True;
389 end;
390 
391 {**
392  Does the database treat mixed case quoted SQL identifiers as
393  case sensitive and as a result store them in mixed case?
394  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.
395  @return <code>true</code> if so; <code>false</code> otherwise
396 }
397 function TZASADatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;
398 begin
399  Result := False;
400 end;
401 
402 {**
403  Does the database treat mixed case quoted SQL identifiers as
404  case insensitive and store them in upper case?
405  @return <code>true</code> if so; <code>false</code> otherwise
406 }
407 function TZASADatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;
408 begin
409  Result := False;
410 end;
411 
412 {**
413  Does the database treat mixed case quoted SQL identifiers as
414  case insensitive and store them in lower case?
415  @return <code>true</code> if so; <code>false</code> otherwise
416 }
417 function TZASADatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;
418 begin
419  Result := False;
420 end;
421 
422 {**
423  Does the database treat mixed case quoted SQL identifiers as
424  case insensitive and store them in mixed case?
425  @return <code>true</code> if so; <code>false</code> otherwise
426 }
427 function TZASADatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;
428 begin
429  Result := True;
430 end;
431 
432 {**
433  Gets a comma-separated list of all a database's SQL keywords
434  that are NOT also SQL92 keywords.
435  @return the list
436 }
437 function TZASADatabaseInfo.GetSQLKeywords: string;
438 begin
439  Result := 'add,all,alter,and,any,as,asc,backup,begin,between,bigint,binary,'+
440  'bit,bottom,break,by,call,capability,cascade,case,cast,char,'+
441  'char_convert,character,check,checkpoint,close,comment,commit,'+
442  'connect,constraint,contains,continue,convert,create,cross,cube,'+
443  'current,cursor,date,dbspace,deallocate,dec,decimal,declare,'+
444  'default,delete,deleting,desc,distinct,do,double,drop,dynamic,'+
445  'else,elseif,encrypted,end,endif,escape,exception,exec,execute,'+
446  'existing,exists,externlogin,fetch,first,float,for,foreign,'+
447  'forward,from,full,goto,grant,group,having,holdlock,identified,'+
448  'if,in,index,inner,inout,insensitive,insert,inserting,install,'+
449  'instead,int,integer,integrated,into,iq,is,isolation,join,key,'+
450  'left,like,lock,login,long,match,membership,message,mode,modify,'+
451  'natural,new,no,noholdlock,not,notify,null,numeric,of,off,on,open,'+
452  'option,options,or,order,others,out,outer,over,passthrough,'+
453  'precision,prepare,primary,print,privileges,proc,procedure,'+
454  'publication,raiserror,readtext,real,reference,references,release,'+
455  'remote,remove,rename,reorganize,resource,restore,restrict,return'+
456  'revoke,right,rollback,rollup,save,savepoint,schedule,scroll,'+
457  'select,sensitive,session,set,setuser,share,smallint,some,sqlcode,'+
458  'sqlstate,start,stop,subtrans,subtransaction,synchronize,'+
459  'syntax_error,table,temporary,then,time,timestamp,tinyint,to,top,'+
460  'tran,trigger,truncate,tsequal,union,unique,unknown,unsigned,'+
461  'update,updating,user,using,validate,values,varbinary,varchar,'+
462  'variable,varying,view,wait,waitfor,when,where,while,with,'+
463  'with_lparen,work,writetext';
464 end;
465 
466 {**
467  Gets a comma-separated list of math functions. These are the
468  X/Open CLI math function names used in the JDBC function escape
469  clause.
470  @return the list
471 }
472 function TZASADatabaseInfo.GetNumericFunctions: string;
473 begin
474  Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,'+
475  'LOG10,MOD,PI,POWER,RADIANS,RAND,REMAINDER,ROUND,SIGN,SIN,SQRT,'+
476  'TAN,TRUNCATE,TRUNCNUM';
477 end;
478 
479 {**
480  Gets a comma-separated list of string functions. These are the
481  X/Open CLI string function names used in the JDBC function escape
482  clause.
483  @return the list
484 }
485 function TZASADatabaseInfo.GetStringFunctions: string;
486 begin
487  Result := 'ASCII,BYTE_LENGTH,BYTE_SUBSTR,CHAR,CHARINDEX,CHAR_LENGTH,COMPARE,'+
488  'CSCONVERT,DIFFERENCE,INSERTSTR,LCASE,LEFT,LENGTH,LOCATE,LOWER,'+
489  'LTRIM,PATINDEX,REPEAT,REPLACE,REPLICATE,RIGHT,RTRIM,SIMILAR,'+
490  'SORTKEY,SOUNDEX,SPACE,STR,STRING,STRTOUUID,STUFF,SUBSTRING,TRIM,'+
491  'UCASE,UPPER,UUIDTOSTR';
492 end;
493 
494 {**
495  Gets a comma-separated list of system functions. These are the
496  X/Open CLI system function names used in the JDBC function escape
497  clause.
498  @return the list
499 }
500 function TZASADatabaseInfo.GetSystemFunctions: string;
501 begin
502  Result := 'CONNECTION_PROPERTY,DATALENGTH,DB_ID,DB_NAME,DB_PROPERTY,'+
503  'EVENT_CONDITION,EVENT_CONDITION_NAME,EVENT_PARAMETER,'+
504  'NEXT_CONNECTION,NEXT_DATABASE,PROPERTY,PROPERTY_DESCRIPTION,'+
505  'PROPERTY_NAME,PROPERTY_NUMBER,Col_length,Col_name,Datalength,'+
506  'Index_col,Object_id,Object_name,Suser_id,Suser_name,Tsequal,'+
507  'User_id,User_name,ARGN,COALESCE,ESTIMATE,ESTIMATE_SOURCE,'+
508  'EXPERIENCE_ESTIMATE,EXPLANATION,GET_IDENTITY,GRAPHICAL_PLAN,'+
509  'GRAPHICAL_ULPLAN,GREATER,IDENTITY,IFNULL,INDEX_ESTIMATE,ISNULL,'+
510  'LESSER,LONG_ULPLAN,NEWID,NULLIF,NUMBER,PLAN,REWRITE,SHORT_ULPLAN,'+
511  'SQLDIALECT,TRACEBACK,TRANSACTSQL,VAREXISTS,WATCOMSQL,TEXTPTR';
512 end;
513 
514 {**
515  Gets a comma-separated list of time and date functions.
516  @return the list
517 }
518 function TZASADatabaseInfo.GetTimeDateFunctions: string;
519 begin
520  Result := 'DATE,DATEADD,DATEDIFF,DATEFORMAT,DATENAME,DATEPART,DATETIME,DAY,'+
521  'DAYNAME,DAYS,DOW,GETDATE,HOUR,HOURS,MINUTE,MINUTES,MONTH,'+
522  'MONTHNAME,MONTHS,NOW,QUARTER,SECOND,SECONDS,TODAY,WEEKS,YEARS,YMD';
523 end;
524 
525 {**
526  Gets the string that can be used to escape wildcard characters.
527  This is the string that can be used to escape '_' or '%' in
528  the string pattern style catalog search parameters.
529 
530  <P>The '_' character represents any single character.
531  <P>The '%' character represents any sequence of zero or
532  more characters.
533 
534  @return the string used to escape wildcard characters
535 }
536 function TZASADatabaseInfo.GetSearchStringEscape: string;
537 begin
538  Result := '\';
539 end;
540 
541 {**
542  Gets all the "extra" characters that can be used in unquoted
543  identifier names (those beyond a-z, A-Z, 0-9 and _).
544  @return the string containing the extra characters
545 }
546 function TZASADatabaseInfo.GetExtraNameCharacters: string;
547 begin
548  Result := '@#$';
549 end;
550 
551 //--------------------------------------------------------------------
552 // Functions describing which features are supported.
553 
554 {**
555  Are expressions in "ORDER BY" lists supported?
556  @return <code>true</code> if so; <code>false</code> otherwise
557 }
558 function TZASADatabaseInfo.SupportsExpressionsInOrderBy: Boolean;
559 begin
560  Result := True;
561 end;
562 
563 {**
564  Can an "ORDER BY" clause use columns not in the SELECT statement?
565  @return <code>true</code> if so; <code>false</code> otherwise
566 }
567 function TZASADatabaseInfo.SupportsOrderByUnrelated: Boolean;
568 begin
569  Result := True;
570 end;
571 
572 {**
573  Is some form of "GROUP BY" clause supported?
574  @return <code>true</code> if so; <code>false</code> otherwise
575 }
576 function TZASADatabaseInfo.SupportsGroupBy: Boolean;
577 begin
578  Result := True;
579 end;
580 
581 {**
582  Can a "GROUP BY" clause use columns not in the SELECT?
583  @return <code>true</code> if so; <code>false</code> otherwise
584 }
585 function TZASADatabaseInfo.SupportsGroupByUnrelated: Boolean;
586 begin
587  Result := True;
588 end;
589 
590 {**
591  Can a "GROUP BY" clause add columns not in the SELECT
592  provided it specifies all the columns in the SELECT?
593  @return <code>true</code> if so; <code>false</code> otherwise
594 }
595 function TZASADatabaseInfo.SupportsGroupByBeyondSelect: Boolean;
596 begin
597  Result := False;
598 end;
599 
600 {**
601  Is the SQL Integrity Enhancement Facility supported?
602  @return <code>true</code> if so; <code>false</code> otherwise
603 }
604 function TZASADatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;
605 begin
606  Result := True;
607 end;
608 
609 {**
610  What's the database vendor's preferred term for "schema"?
611  @return the vendor term
612 }
613 function TZASADatabaseInfo.GetSchemaTerm: string;
614 begin
615  Result := 'OWNER';
616 end;
617 
618 {**
619  What's the database vendor's preferred term for "procedure"?
620  @return the vendor term
621 }
622 function TZASADatabaseInfo.GetProcedureTerm: string;
623 begin
624  Result := 'PROCEDURE';
625 end;
626 
627 {**
628  What's the database vendor's preferred term for "catalog"?
629  @return the vendor term
630 }
631 function TZASADatabaseInfo.GetCatalogTerm: string;
632 begin
633  Result := '';
634 end;
635 
636 {**
637  What's the separator between catalog and table name?
638  @return the separator string
639 }
640 function TZASADatabaseInfo.GetCatalogSeparator: string;
641 begin
642  Result := '';
643 end;
644 
645 {**
646  Can a schema name be used in a data manipulation statement?
647  @return <code>true</code> if so; <code>false</code> otherwise
648 }
649 function TZASADatabaseInfo.SupportsSchemasInDataManipulation: Boolean;
650 begin
651  Result := True;
652 end;
653 
654 {**
655  Can a schema name be used in a procedure call statement?
656  @return <code>true</code> if so; <code>false</code> otherwise
657 }
658 function TZASADatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;
659 begin
660  Result := True;
661 end;
662 
663 {**
664  Can a schema name be used in a table definition statement?
665  @return <code>true</code> if so; <code>false</code> otherwise
666 }
667 function TZASADatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;
668 begin
669  Result := True;
670 end;
671 
672 {**
673  Can a schema name be used in an index definition statement?
674  @return <code>true</code> if so; <code>false</code> otherwise
675 }
676 function TZASADatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;
677 begin
678  Result := False;
679 end;
680 
681 {**
682  Can a schema name be used in a privilege definition statement?
683  @return <code>true</code> if so; <code>false</code> otherwise
684 }
685 function TZASADatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;
686 begin
687  Result := False;
688 end;
689 
690 {**
691  Can a catalog name be used in a data manipulation statement?
692  @return <code>true</code> if so; <code>false</code> otherwise
693 }
694 function TZASADatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;
695 begin
696  Result := False;
697 end;
698 
699 {**
700  Can a catalog name be used in a procedure call statement?
701  @return <code>true</code> if so; <code>false</code> otherwise
702 }
703 function TZASADatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;
704 begin
705  Result := False;
706 end;
707 
708 {**
709  Can a catalog name be used in a table definition statement?
710  @return <code>true</code> if so; <code>false</code> otherwise
711 }
712 function TZASADatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;
713 begin
714  Result := False;
715 end;
716 
717 {**
718  Can a catalog name be used in an index definition statement?
719  @return <code>true</code> if so; <code>false</code> otherwise
720 }
721 function TZASADatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;
722 begin
723  Result := False;
724 end;
725 
726 {**
727  Can a catalog name be used in a privilege definition statement?
728  @return <code>true</code> if so; <code>false</code> otherwise
729 }
730 function TZASADatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;
731 begin
732  Result := False;
733 end;
734 
735 {**
736  Is positioned DELETE supported?
737  @return <code>true</code> if so; <code>false</code> otherwise
738 }
739 function TZASADatabaseInfo.SupportsPositionedDelete: Boolean;
740 begin
741  Result := True;
742 end;
743 
744 {**
745  Is positioned UPDATE supported?
746  @return <code>true</code> if so; <code>false</code> otherwise
747 }
748 function TZASADatabaseInfo.SupportsPositionedUpdate: Boolean;
749 begin
750  Result := True;
751 end;
752 
753 {**
754  Is SELECT for UPDATE supported?
755  @return <code>true</code> if so; <code>false</code> otherwise
756 }
757 function TZASADatabaseInfo.SupportsSelectForUpdate: Boolean;
758 begin
759  Result := True;
760 end;
761 
762 {**
763  Are stored procedure calls using the stored procedure escape
764  syntax supported?
765  @return <code>true</code> if so; <code>false</code> otherwise
766 }
767 function TZASADatabaseInfo.SupportsStoredProcedures: Boolean;
768 begin
769  Result := True;
770 end;
771 
772 {**
773  Are subqueries in comparison 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
776 }
777 function TZASADatabaseInfo.SupportsSubqueriesInComparisons: Boolean;
778 begin
779  Result := True;
780 end;
781 
782 {**
783  Are subqueries in 'exists' expressions 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
786 }
787 function TZASADatabaseInfo.SupportsSubqueriesInExists: Boolean;
788 begin
789  Result := True;
790 end;
791 
792 {**
793  Are subqueries in 'in' statements 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
796 }
797 function TZASADatabaseInfo.SupportsSubqueriesInIns: Boolean;
798 begin
799  Result := True;
800 end;
801 
802 {**
803  Are subqueries in quantified expressions 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
806 }
807 function TZASADatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;
808 begin
809  Result := True;
810 end;
811 
812 {**
813  Are correlated subqueries supported?
814  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.
815  @return <code>true</code> if so; <code>false</code> otherwise
816 }
817 function TZASADatabaseInfo.SupportsCorrelatedSubqueries: Boolean;
818 begin
819  Result := True;
820 end;
821 
822 {**
823  Is SQL UNION supported?
824  @return <code>true</code> if so; <code>false</code> otherwise
825 }
826 function TZASADatabaseInfo.SupportsUnion: Boolean;
827 begin
828  Result := True;
829 end;
830 
831 {**
832  Is SQL UNION ALL supported?
833  @return <code>true</code> if so; <code>false</code> otherwise
834 }
835 function TZASADatabaseInfo.SupportsUnionAll: Boolean;
836 begin
837  Result := True;
838 end;
839 
840 {**
841  Can cursors remain open across commits?
842  @return <code>true</code> if cursors always remain open;
843  <code>false</code> if they might not remain open
844 }
845 function TZASADatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;
846 begin
847  Result := True;
848 end;
849 
850 {**
851  Can cursors remain open across rollbacks?
852  @return <code>true</code> if cursors always remain open;
853  <code>false</code> if they might not remain open
854 }
855 function TZASADatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;
856 begin
857  Result := True;
858 end;
859 
860 {**
861  Can statements remain open across commits?
862  @return <code>true</code> if statements always remain open;
863  <code>false</code> if they might not remain open
864 }
865 function TZASADatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;
866 begin
867  Result := True;
868 end;
869 
870 {**
871  Can statements remain open across rollbacks?
872  @return <code>true</code> if statements always remain open;
873  <code>false</code> if they might not remain open
874 }
875 function TZASADatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;
876 begin
877  Result := True;
878 end;
879 
880 //----------------------------------------------------------------------
881 // The following group of methods exposes various limitations
882 // based on the target database with the current driver.
883 // Unless otherwise specified, a result of zero means there is no
884 // limit, or the limit is not known.
885 
886 {**
887  How many hex characters can you have in an inline binary literal?
888  @return max binary literal length in hex characters;
889  a result of zero means that there is no limit or the limit is not known
890 }
891 function TZASADatabaseInfo.GetMaxBinaryLiteralLength: Integer;
892 begin
893  Result := 0;
894 end;
895 
896 {**
897  What's the max length for a character literal?
898  @return max literal length;
899  a result of zero means that there is no limit or the limit is not known
900 }
901 function TZASADatabaseInfo.GetMaxCharLiteralLength: Integer;
902 begin
903  Result := 32768;
904 end;
905 
906 {**
907  What's the limit on column name length?
908  @return max column name length;
909  a result of zero means that there is no limit or the limit is not known
910 }
911 function TZASADatabaseInfo.GetMaxColumnNameLength: Integer;
912 begin
913  Result := 128;
914 end;
915 
916 {**
917  What's the maximum number of columns in a "GROUP BY" clause?
918  @return max number of columns;
919  a result of zero means that there is no limit or the limit is not known
920 }
921 function TZASADatabaseInfo.GetMaxColumnsInGroupBy: Integer;
922 begin
923  Result := 0;
924 end;
925 
926 {**
927  What's the maximum number of columns allowed in an index?
928  @return max number of columns;
929  a result of zero means that there is no limit or the limit is not known
930 }
931 function TZASADatabaseInfo.GetMaxColumnsInIndex: Integer;
932 begin
933  Result := 1000000;
934 end;
935 
936 {**
937  What's the maximum number of columns in an "ORDER BY" clause?
938  @return max number of columns;
939  a result of zero means that there is no limit or the limit is not known
940 }
941 function TZASADatabaseInfo.GetMaxColumnsInOrderBy: Integer;
942 begin
943  Result := 1000000;
944 end;
945 
946 {**
947  What's the maximum number of columns in a "SELECT" list?
948  @return max number of columns;
949  a result of zero means that there is no limit or the limit is not known
950 }
951 function TZASADatabaseInfo.GetMaxColumnsInSelect: Integer;
952 begin
953  Result := 1000000;
954 end;
955 
956 {**
957  What's the maximum number of columns in a table?
958  @return max number of columns;
959  a result of zero means that there is no limit or the limit is not known
960 }
961 function TZASADatabaseInfo.GetMaxColumnsInTable: Integer;
962 begin
963  Result := 1000000;
964 end;
965 
966 {**
967  How many active connections can we have at a time to this database?
968  @return max number of active connections;
969  a result of zero means that there is no limit or the limit is not known
970 }
971 function TZASADatabaseInfo.GetMaxConnections: Integer;
972 begin
973  Result := 0;
974 end;
975 
976 {**
977  What's the maximum cursor name length?
978  @return max cursor name length in bytes;
979  a result of zero means that there is no limit or the limit is not known
980 }
981 function TZASADatabaseInfo.GetMaxCursorNameLength: Integer;
982 begin
983  Result := 128;
984 end;
985 
986 {**
987  Retrieves the maximum number of bytes for an index, including all
988  of the parts of the index.
989  @return max index length in bytes, which includes the composite of all
990  the constituent parts of the index;
991  a result of zero means that there is no limit or the limit is not known
992 }
993 function TZASADatabaseInfo.GetMaxIndexLength: Integer;
994 begin
995  Result := 0;
996 end;
997 
998 {**
999  What's the maximum length allowed for a schema 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
1002 }
1003 function TZASADatabaseInfo.GetMaxSchemaNameLength: Integer;
1004 begin
1005  Result := 128;
1006 end;
1007 
1008 {**
1009  What's the maximum length of a procedure 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
1012 }
1013 function TZASADatabaseInfo.GetMaxProcedureNameLength: Integer;
1014 begin
1015  Result := 128;
1016 end;
1017 
1018 {**
1019  What's the maximum length of a catalog name?
1020  @return max name length in bytes;
1021  a result of zero means that there is no limit or the limit is not known
1022 }
1023 function TZASADatabaseInfo.GetMaxCatalogNameLength: Integer;
1024 begin
1025  Result := 0;
1026 end;
1027 
1028 {**
1029  What's the maximum length of a single row?
1030  @return max row size in bytes;
1031  a result of zero means that there is no limit or the limit is not known
1032 }
1033 function TZASADatabaseInfo.GetMaxRowSize: Integer;
1034 begin
1035  Result := 0;
1036 end;
1037 
1038 {**
1039  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
1040  blobs?
1041  @return <code>true</code> if so; <code>false</code> otherwise
1042 }
1043 function TZASADatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;
1044 begin
1045  Result := False;
1046 end;
1047 
1048 {**
1049  What's the maximum length of an SQL statement?
1050  @return max length in bytes;
1051  a result of zero means that there is no limit or the limit is not known
1052 }
1053 function TZASADatabaseInfo.GetMaxStatementLength: Integer;
1054 begin
1055  Result := 0;
1056 end;
1057 
1058 {**
1059  How many active statements can we have open at one time to this
1060  database?
1061  @return the maximum number of statements that can be open at one time;
1062  a result of zero means that there is no limit or the limit is not known
1063 }
1064 function TZASADatabaseInfo.GetMaxStatements: Integer;
1065 begin
1066  Result := 0;
1067 end;
1068 
1069 {**
1070  What's the maximum length of a table name?
1071  @return max name length in bytes;
1072  a result of zero means that there is no limit or the limit is not known
1073 }
1074 function TZASADatabaseInfo.GetMaxTableNameLength: Integer;
1075 begin
1076  Result := 128;
1077 end;
1078 
1079 {**
1080  What's the maximum number of tables in a SELECT statement?
1081  @return the maximum number of tables allowed in a SELECT statement;
1082  a result of zero means that there is no limit or the limit is not known
1083 }
1084 function TZASADatabaseInfo.GetMaxTablesInSelect: Integer;
1085 begin
1086  Result := 0;
1087 end;
1088 
1089 {**
1090  What's the maximum length of a user name?
1091  @return max user name length in bytes;
1092  a result of zero means that there is no limit or the limit is not known
1093 }
1094 function TZASADatabaseInfo.GetMaxUserNameLength: Integer;
1095 begin
1096  Result := 30;
1097 end;
1098 
1099 //----------------------------------------------------------------------
1100 
1101 {**
1102  What's the database's default transaction isolation level? The
1103  values are defined in <code>java.sql.Connection</code>.
1104  @return the default isolation level
1105  @see Connection
1106 }
1107 function TZASADatabaseInfo.GetDefaultTransactionIsolation:
1108  TZTransactIsolationLevel;
1109 begin
1110  Result := tiReadUncommitted;
1111 end;
1112 
1113 {**
1114  Are transactions supported? If not, invoking the method
1115  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.
1116  @return <code>true</code> if transactions are supported; <code>false</code> otherwise
1117 }
1118 function TZASADatabaseInfo.SupportsTransactions: Boolean;
1119 begin
1120  Result := True;
1121 end;
1122 
1123 {**
1124  Does this database support the given transaction isolation level?
1125  @param level the values are defined in <code>java.sql.Connection</code>
1126  @return <code>true</code> if so; <code>false</code> otherwise
1127  @see Connection
1128 }
1129 function TZASADatabaseInfo.SupportsTransactionIsolationLevel(
1130  Level: TZTransactIsolationLevel): Boolean;
1131 begin
1132  Result := True;
1133 end;
1134 
1135 {**
1136  Are both data definition and data manipulation statements
1137  within a transaction supported?
1138  @return <code>true</code> if so; <code>false</code> otherwise
1139 }
1140 function TZASADatabaseInfo.
1141  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;
1142 begin
1143  Result := True;
1144 end;
1145 
1146 {**
1147  Are only data manipulation statements within a transaction
1148  supported?
1149  @return <code>true</code> if so; <code>false</code> otherwise
1150 }
1151 function TZASADatabaseInfo.
1152  SupportsDataManipulationTransactionsOnly: Boolean;
1153 begin
1154  Result := False;
1155 end;
1156 
1157 {**
1158  Does a data definition statement within a transaction force the
1159  transaction to commit?
1160  @return <code>true</code> if so; <code>false</code> otherwise
1161 }
1162 function TZASADatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;
1163 begin
1164  Result := True;
1165 end;
1166 
1167 {**
1168  Is a data definition statement within a transaction ignored?
1169  @return <code>true</code> if so; <code>false</code> otherwise
1170 }
1171 function TZASADatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;
1172 begin
1173  Result := False;
1174 end;
1175 
1176 {**
1177  Does the database support the given result set type?
1178  @param type defined in <code>java.sql.ResultSet</code>
1179  @return <code>true</code> if so; <code>false</code> otherwise
1180 }
1181 function TZASADatabaseInfo.SupportsResultSetType(
1182  _Type: TZResultSetType): Boolean;
1183 begin
1184  Result := True;
1185 end;
1186 
1187 {**
1188  Does the database support the concurrency type in combination
1189  with the given result set type?
1190 
1191  @param type defined in <code>java.sql.ResultSet</code>
1192  @param concurrency type defined in <code>java.sql.ResultSet</code>
1193  @return <code>true</code> if so; <code>false</code> otherwise
1194 }
1195 function TZASADatabaseInfo.SupportsResultSetConcurrency(
1196  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;
1197 begin
1198  Result := True;
1199 end;
1200 
1201 { TZASADatabaseMetadata }
1202 
1203 {**
1204  Constructs this object and assignes the main properties.
1205  @param Connection a database connection object.
1206  @param Url a database connection url string.
1207  @param Info an extra connection properties.
1208 }
1209 constructor TZASADatabaseMetadata.Create(Connection: TZAbstractConnection;
1210  const Url: TZURL);
1211 begin
1212  inherited Create(Connection, Url);
1213  FASAConnection := Connection as TZASAConnection;
1214 end;
1215 
1216 {**
1217  Composes a object name, AnsiQuotedStr or NullText
1218  @param S the object string
1219  @param NullText the "NULL"-Text default: 'null'
1220  @param QuoteChar the QuoteChar default: '
1221  @return 'null' if S is '' or S if s is already Quoted or AnsiQuotedStr(S, #39)
1222 }
1223 function TZASADatabaseMetadata.ComposeObjectString(const S: String;
1224  Const NullText: String = 'null'; QuoteChar: Char = #39): String;
1225 begin
1226  if S = '' then
1227  Result := NullText
1228  else
1229  if IC.IsQuoted(s) then
1230  Result := S
1231  else
1232  Result := AnsiQuotedStr(S, QuoteChar);
1233 end;
1234 
1235 {**
1236  Constructs a database information object and returns the interface to it. Used
1237  internally by the constructor.
1238  @return the database information object interface
1239 }
1240 function TZASADatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;
1241 begin
1242  Result := TZASADatabaseInfo.Create(Self);
1243 end;
1244 
1245 {**
1246  Gets a description of the stored procedures available in a
1247  catalog.
1248 
1249  <P>Only procedure descriptions matching the schema and
1250  procedure name criteria are returned. They are ordered by
1251  PROCEDURE_SCHEM, and PROCEDURE_NAME.
1252 
1253  <P>Each procedure description has the the following columns:
1254  <OL>
1255  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1256  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1257  <LI><B>PROCEDURE_NAME</B> String => procedure name
1258  <LI> reserved for future use
1259  <LI> reserved for future use
1260  <LI> reserved for future use
1261  <LI><B>REMARKS</B> String => explanatory comment on the procedure
1262  <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:
1263  <UL>
1264  <LI> procedureResultUnknown - May return a result
1265  <LI> procedureNoResult - Does not return a result
1266  <LI> procedureReturnsResult - Returns a result
1267  </UL>
1268  </OL>
1269 
1270  @param catalog a catalog name; "" retrieves those without a
1271  catalog; null means drop catalog name from the selection criteria
1272  @param schemaPattern a schema name pattern; "" retrieves those
1273  without a schema
1274  @param procedureNamePattern a procedure name pattern
1275  @return <code>ResultSet</code> - each row is a procedure description
1276  @see #getSearchStringEscape
1277 }
1278 function TZASADatabaseMetadata.UncachedGetProcedures(const Catalog: string;
1279  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;
1280 begin
1281  Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);
1282 
1283  with GetStatement.ExecuteQuery(
1284  Format('exec sp_jdbc_stored_procedures %s, %s, %s',
1285  [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern)])) do
1286  begin
1287  while Next do
1288  begin
1289  Result.MoveToInsertRow;
1290  Result.UpdateStringByName('PROCEDURE_CAT',
1291  '');
1292  Result.UpdateStringByName('PROCEDURE_SCHEM',
1293  GetStringByName('PROCEDURE_SCHEM'));
1294  Result.UpdateStringByName('PROCEDURE_NAME',
1295  GetStringByName('PROCEDURE_NAME'));
1296  Result.UpdateStringByName('REMARKS',
1297  GetStringByName('REMARKS'));
1298  Result.UpdateShortByName('PROCEDURE_TYPE',
1299  GetShortByName('PROCEDURE_TYPE'));
1300  Result.InsertRow;
1301  end;
1302  Close;
1303  end;
1304 end;
1305 
1306 {**
1307  Gets a description of a catalog's stored procedure parameters
1308  and result columns.
1309 
1310  <P>Only descriptions matching the schema, procedure and
1311  parameter name criteria are returned. They are ordered by
1312  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,
1313  if any, is first. Next are the parameter descriptions in call
1314  order. The column descriptions follow in column number order.
1315 
1316  <P>Each row in the <code>ResultSet</code> is a parameter description or
1317  column description with the following fields:
1318  <OL>
1319  <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)
1320  <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)
1321  <LI><B>PROCEDURE_NAME</B> String => procedure name
1322  <LI><B>COLUMN_NAME</B> String => column/parameter name
1323  <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:
1324  <UL>
1325  <LI> procedureColumnUnknown - nobody knows
1326  <LI> procedureColumnIn - IN parameter
1327  <LI> procedureColumnInOut - INOUT parameter
1328  <LI> procedureColumnOut - OUT parameter
1329  <LI> procedureColumnReturn - procedure return value
1330  <LI> procedureColumnResult - result column in <code>ResultSet</code>
1331  </UL>
1332  <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1333  <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the
1334  type name is fully qualified
1335  <LI><B>PRECISION</B> int => precision
1336  <LI><B>LENGTH</B> int => length in bytes of data
1337  <LI><B>SCALE</B> short => scale
1338  <LI><B>RADIX</B> short => radix
1339  <LI><B>NULLABLE</B> short => can it contain NULL?
1340  <UL>
1341  <LI> procedureNoNulls - does not allow NULL values
1342  <LI> procedureNullable - allows NULL values
1343  <LI> procedureNullableUnknown - nullability unknown
1344  </UL>
1345  <LI><B>REMARKS</B> String => comment describing parameter/column
1346  </OL>
1347 
1348  <P><B>Note:</B> Some databases may not return the column
1349  descriptions for a procedure. Additional columns beyond
1350  REMARKS can be defined by the database.
1351 
1352  @param catalog a catalog name; "" retrieves those without a
1353  catalog; null means drop catalog name from the selection criteria
1354  @param schemaPattern a schema name pattern; "" retrieves those
1355  without a schema
1356  @param procedureNamePattern a procedure name pattern
1357  @param columnNamePattern a column name pattern
1358  @return <code>ResultSet</code> - each row describes a stored procedure parameter or
1359  column
1360  @see #getSearchStringEscape
1361 }
1362 function TZASADatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;
1363  const SchemaPattern: string; const ProcedureNamePattern: string;
1364  const ColumnNamePattern: string): IZResultSet;
1365 begin
1366  Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);
1367 
1368  with GetStatement.ExecuteQuery(
1369  Format('exec sp_jdbc_getprocedurecolumns %s, %s, %s, %s',
1370  [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern),
1371  ComposeObjectString(ColumnNamePattern)])) do
1372  begin
1373  while Next do
1374  begin
1375  Result.MoveToInsertRow;
1376  Result.UpdateStringByName('PROCEDURE_CAT',
1377  '');
1378  Result.UpdateStringByName('PROCEDURE_SCHEM',
1379  GetStringByName('PROCEDURE_SCHEM'));
1380  Result.UpdateStringByName('PROCEDURE_NAME',
1381  GetStringByName('PROCEDURE_NAME'));
1382  Result.UpdateStringByName('COLUMN_NAME',
1383  GetStringByName('COLUMN_NAME'));
1384  case GetShortByName('COLUMN_TYPE') of
1385  1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));
1386  2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));
1387  3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctOut));
1388  5: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));
1389  else
1390  Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));
1391  end;
1392  Result.UpdateShortByName('DATA_TYPE',
1393  Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),
1394  ConSettings.CPType)));
1395  Result.UpdateStringByName('TYPE_NAME',
1396  GetStringByName('TYPE_NAME'));
1397  Result.UpdateIntByName('PRECISION',
1398  GetIntByName('PRECISION'));
1399  Result.UpdateIntByName('LENGTH',
1400  GetIntByName('LENGTH'));
1401  Result.UpdateShortByName('SCALE',
1402  GetShortByName('SCALE'));
1403  Result.UpdateShortByName('RADIX',
1404  GetShortByName('RADIX'));
1405  Result.UpdateShortByName('NULLABLE',
1406  GetShortByName('NULLABLE'));
1407  Result.UpdateStringByName('REMARKS',
1408  GetStringByName('REMARKS'));
1409  Result.InsertRow;
1410  end;
1411  Close;
1412  end;
1413 end;
1414 
1415 {**
1416  Gets a description of tables available in a catalog.
1417 
1418  <P>Only table descriptions matching the catalog, schema, table
1419  name and type criteria are returned. They are ordered by
1420  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
1421 
1422  <P>Each table description has the following columns:
1423  <OL>
1424  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1425  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1426  <LI><B>TABLE_NAME</B> String => table name
1427  <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1428  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1429  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1430  <LI><B>REMARKS</B> String => explanatory comment on the table
1431  </OL>
1432 
1433  <P><B>Note:</B> Some databases may not return information for
1434  all tables.
1435 
1436  @param catalog a catalog name; "" retrieves those without a
1437  catalog; null means drop catalog name from the selection criteria
1438  @param schemaPattern a schema name pattern; "" retrieves those
1439  without a schema
1440  @param tableNamePattern a table name pattern
1441  @param types a list of table types to include; null returns all types
1442  @return <code>ResultSet</code> - each row is a table description
1443  @see #getSearchStringEscape
1444 }
1445 function TZASADatabaseMetadata.UncachedGetTables(const Catalog: string;
1446  const SchemaPattern: string; const TableNamePattern: string;
1447  const Types: TStringDynArray): IZResultSet;
1448 var
1449  I: Integer;
1450  TableTypes: string;
1451 begin
1452  Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);
1453 
1454  TableTypes := '';
1455  for I := 0 to Length(Types) - 1 do
1456  begin
1457  if TableTypes <> '' then
1458  TableTypes := TableTypes + ',';
1459  TableTypes := TableTypes + AnsiQuotedStr(Types[I], '''');
1460  end;
1461 
1462  with GetStatement.ExecuteQuery(
1463  Format('exec sp_jdbc_tables %s, %s, %s, %s',
1464  [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog),
1465  ComposeObjectString(TableTypes, 'null', '"')])) do
1466  begin
1467  while Next do
1468  begin
1469  Result.MoveToInsertRow;
1470  Result.UpdateStringByName('TABLE_CAT',
1471  '');
1472  Result.UpdateStringByName('TABLE_SCHEM',
1473  GetStringByName('TABLE_SCHEM'));
1474  Result.UpdateStringByName('TABLE_NAME',
1475  GetStringByName('TABLE_NAME'));
1476  Result.UpdateStringByName('TABLE_TYPE',
1477  GetStringByName('TABLE_TYPE'));
1478  Result.UpdateStringByName('REMARKS',
1479  GetStringByName('REMARKS'));
1480  Result.InsertRow;
1481  end;
1482  Close;
1483  end;
1484 end;
1485 
1486 {**
1487  Gets the schema names available in this database. The results
1488  are ordered by schema name.
1489 
1490  <P>The schema column is:
1491  <OL>
1492  <LI><B>TABLE_SCHEM</B> String => schema name
1493  </OL>
1494 
1495  @return <code>ResultSet</code> - each row has a single String column that is a
1496  schema name
1497 }
1498 function TZASADatabaseMetadata.UncachedGetSchemas: IZResultSet;
1499 begin
1500  Result:=inherited UncachedGetSchemas;
1501 
1502  with GetStatement.ExecuteQuery('select TABLE_SCHEM=name from sysusers where suid >= -2 order by name'
1503  {'exec sp_jdbc_getschemas'}) do
1504  begin
1505  while Next do
1506  begin
1507  Result.MoveToInsertRow;
1508  Result.UpdateStringByName('TABLE_SCHEM',
1509  GetStringByName('TABLE_SCHEM'));
1510  Result.InsertRow;
1511  end;
1512  Close;
1513  end;
1514 end;
1515 
1516 {**
1517  Gets the table types available in this database. The results
1518  are ordered by table type.
1519 
1520  <P>The table type is:
1521  <OL>
1522  <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
1523  "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
1524  "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
1525  </OL>
1526 
1527  @return <code>ResultSet</code> - each row has a single String column that is a
1528  table type
1529 }
1530 function TZASADatabaseMetadata.UncachedGetTableTypes: IZResultSet;
1531 const
1532  TablesTypes: array [0..4] of String = ( 'TABLE', 'BASE', 'SYSTEM', 'VIEW',
1533  'GLOBAL TEMPORARY');
1534 var
1535  I: Integer;
1536 begin
1537  Result:=inherited UncachedGetTableTypes;
1538 
1539  for I := 0 to 4 do
1540  begin
1541  Result.MoveToInsertRow;
1542  Result.UpdateString(1, TablesTypes[I]);
1543  Result.InsertRow;
1544  end;
1545 end;
1546 
1547 {**
1548  Gets a description of table columns available in
1549  the specified catalog.
1550 
1551  <P>Only column descriptions matching the catalog, schema, table
1552  and column name criteria are returned. They are ordered by
1553  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
1554 
1555  <P>Each column description has the following columns:
1556  <OL>
1557  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1558  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1559  <LI><B>TABLE_NAME</B> String => table name
1560  <LI><B>COLUMN_NAME</B> String => column name
1561  <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
1562  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
1563  for a UDT the type name is fully qualified
1564  <LI><B>COLUMN_SIZE</B> int => column size. For char or date
1565  types this is the maximum number of characters, for numeric or
1566  decimal types this is precision.
1567  <LI><B>BUFFER_LENGTH</B> is not used.
1568  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
1569  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
1570  <LI><B>NULLABLE</B> int => is NULL allowed?
1571  <UL>
1572  <LI> columnNoNulls - might not allow NULL values
1573  <LI> columnNullable - definitely allows NULL values
1574  <LI> columnNullableUnknown - nullability unknown
1575  </UL>
1576  <LI><B>REMARKS</B> String => comment describing column (may be null)
1577  <LI><B>COLUMN_DEF</B> String => default value (may be null)
1578  <LI><B>SQL_DATA_TYPE</B> int => unused
1579  <LI><B>SQL_DATETIME_SUB</B> int => unused
1580  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
1581  maximum number of bytes in the column
1582  <LI><B>ORDINAL_POSITION</B> int => index of column in table
1583  (starting at 1)
1584  <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
1585  does not allow NULL values; "YES" means the column might
1586  allow NULL values. An empty string means nobody knows.
1587  </OL>
1588 
1589  @param catalog a catalog name; "" retrieves those without a
1590  catalog; null means drop catalog name from the selection criteria
1591  @param schemaPattern a schema name pattern; "" retrieves those
1592  without a schema
1593  @param tableNamePattern a table name pattern
1594  @param columnNamePattern a column name pattern
1595  @return <code>ResultSet</code> - each row is a column description
1596  @see #getSearchStringEscape
1597 }
1598 function TZASADatabaseMetadata.UncachedGetColumns(const Catalog: string;
1599  const SchemaPattern: string; const TableNamePattern: string;
1600  const ColumnNamePattern: string): IZResultSet;
1601 begin
1602  Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);
1603 
1604  with GetStatement.ExecuteQuery(
1605  Format('exec sp_jdbc_columns %s, %s, %s, %s',
1606  [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog),
1607  ComposeObjectString(ColumnNamePattern)])) do
1608  begin
1609  while Next do
1610  begin
1611  Result.MoveToInsertRow;
1612  Result.UpdateStringByName('TABLE_CAT',
1613  '');
1614  Result.UpdateStringByName('TABLE_SCHEM',
1615  GetStringByName('TABLE_SCHEM'));
1616  Result.UpdateStringByName('TABLE_NAME',
1617  GetStringByName('TABLE_NAME'));
1618  Result.UpdateStringByName('COLUMN_NAME',
1619  GetStringByName('COLUMN_NAME'));
1620  //The value in the resultset will be used
1621  // Result.UpdateShortByName('DATA_TYPE',
1622  // Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'))));
1623  Result.UpdateStringByName('TYPE_NAME',
1624  GetStringByName('TYPE_NAME'));
1625  //Result.UpdateIntByName('COLUMN_SIZE',
1626  //GetIntByName('COLUMN_SIZE'));
1627  Result.UpdateIntByName('BUFFER_LENGTH',
1628  GetIntByName('BUFFER_LENGTH'));
1629  Result.UpdateIntByName('DECIMAL_DIGITS',
1630  GetIntByName('DECIMAL_DIGITS'));
1631  Result.UpdateIntByName('NUM_PREC_RADIX',
1632  GetShortByName('NUM_PREC_RADIX'));
1633  Result.UpdateStringByName('REMARKS',
1634  GetStringByName('REMARKS'));
1635  Result.UpdateStringByName('COLUMN_DEF',
1636  GetStringByName('COLUMN_DEF'));
1637  Result.UpdateShortByName('SQL_DATA_TYPE',
1638  GetShortByName('SQL_DATA_TYPE'));
1639  Result.UpdateShortByName('SQL_DATETIME_SUB',
1640  GetShortByName('SQL_DATETIME_SUB'));
1641  Result.UpdateIntByName('CHAR_OCTET_LENGTH',
1642  GetIntByName('CHAR_OCTET_LENGTH'));
1643  Result.UpdateIntByName('ORDINAL_POSITION',
1644  GetIntByName('ORDINAL_POSITION'));
1645 
1646  Result.UpdateBooleanByName('AUTO_INCREMENT',
1647  CompareText( Trim( String(GetStringByName('COLUMN_DEF'))), 'autoincrement') = 0 );
1648  Result.UpdateNullByName('CASE_SENSITIVE');
1649  Result.UpdateBooleanByName('SEARCHABLE', False);
1650  Result.UpdateStringByName('IS_NULLABLE', GetStringByName( 'IS_NULLABLE'));
1651  Result.UpdateShortByName('NULLABLE', GetShortByName( 'NULLABLE'));
1652  Result.UpdateBooleanByName('WRITABLE', True);
1653  Result.UpdateBooleanByName('DEFINITELYWRITABLE', True);
1654  Result.UpdateBooleanByName('READONLY', False);
1655  Result.InsertRow;
1656  end;
1657  Close;
1658  end;
1659  Result.First;
1660  with GetStatement.ExecuteQuery(
1661  Format('select c.column_id,c.nulls '+
1662  'from SYS.SYSCOLUMN as c join SYS.SYSTABLE as t on c.table_id=t.table_id '+
1663  'where t.table_name like %s escape ''\'' and '+
1664  'USER_NAME(t.creator) like %s escape ''\'' and '+
1665  'c.column_name like %s escape ''\'' and c.column_type=''C'' '+
1666  'order by USER_NAME(t.creator) asc,t.table_name asc,c.column_id asc',
1667  [ComposeObjectString(TableNamePattern, '''%'''),
1668  ComposeObjectString(SchemaPattern, '''%'''),
1669  ComposeObjectString(ColumnNamePattern, '''%''')])) do
1670  begin
1671  while Next do
1672  begin
1673  while Result.GetIntByName( 'ORDINAL_POSITION') <>
1674  GetIntByName( 'column_id') do
1675  Result.Next;
1676  Result.UpdateBooleanByName( 'WRITABLE', False);
1677  Result.UpdateBooleanByName( 'DEFINITELYWRITABLE', False);
1678  Result.UpdateBooleanByName( 'READONLY', True);
1679  if GetStringByName( 'nulls') = 'N' then
1680  begin
1681  Result.UpdateShortByName( 'NULLABLE', 0);
1682  Result.UpdateStringByName( 'IS_NULLABLE', 'NO');
1683  end;
1684  Result.UpdateRow;
1685  end;
1686  Close;
1687  end;
1688 end;
1689 
1690 {**
1691  Gets a description of the access rights for a table's columns.
1692 
1693  <P>Only privileges matching the column name criteria are
1694  returned. They are ordered by COLUMN_NAME and PRIVILEGE.
1695 
1696  <P>Each privilige description has the following columns:
1697  <OL>
1698  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1699  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1700  <LI><B>TABLE_NAME</B> String => table name
1701  <LI><B>COLUMN_NAME</B> String => column name
1702  <LI><B>GRANTOR</B> => grantor of access (may be null)
1703  <LI><B>GRANTEE</B> String => grantee of access
1704  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1705  INSERT, UPDATE, REFRENCES, ...)
1706  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1707  to grant to others; "NO" if not; null if unknown
1708  </OL>
1709 
1710  @param catalog a catalog name; "" retrieves those without a
1711  catalog; null means drop catalog name from the selection criteria
1712  @param schema a schema name; "" retrieves those without a schema
1713  @param table a table name
1714  @param columnNamePattern a column name pattern
1715  @return <code>ResultSet</code> - each row is a column privilege description
1716  @see #getSearchStringEscape
1717 }
1718 function TZASADatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;
1719  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;
1720 begin
1721  Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);
1722 
1723  with GetStatement.ExecuteQuery(
1724  Format('exec sp_jdbc_getcolumnprivileges %s, %s, %s, %s',
1725  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table), ComposeObjectString(ColumnNamePattern)])) do
1726  begin
1727  while Next do
1728  begin
1729  Result.MoveToInsertRow;
1730  Result.UpdateStringByName('TABLE_CAT',
1731  '');
1732  Result.UpdateStringByName('TABLE_SCHEM',
1733  GetStringByName('TABLE_SCHEM'));
1734  Result.UpdateStringByName('TABLE_NAME',
1735  GetStringByName('TABLE_NAME'));
1736  Result.UpdateStringByName('COLUMN_NAME',
1737  GetStringByName('COLUMN_NAME'));
1738  Result.UpdateStringByName('GRANTOR',
1739  GetStringByName('GRANTOR'));
1740  Result.UpdateStringByName('GRANTEE',
1741  GetStringByName('GRANTEE'));
1742  Result.UpdateStringByName('PRIVILEGE',
1743  GetStringByName('PRIVILEGE'));
1744  Result.UpdateStringByName('IS_GRANTABLE',
1745  GetStringByName('IS_GRANTABLE'));
1746  Result.InsertRow;
1747  end;
1748  Close;
1749  end;
1750 end;
1751 
1752 {**
1753  Gets a description of the access rights for each table available
1754  in a catalog. Note that a table privilege applies to one or
1755  more columns in the table. It would be wrong to assume that
1756  this priviledge applies to all columns (this may be true for
1757  some systems but is not true for all.)
1758 
1759  <P>Only privileges matching the schema and table name
1760  criteria are returned. They are ordered by TABLE_SCHEM,
1761  TABLE_NAME, and PRIVILEGE.
1762 
1763  <P>Each privilige description has the following columns:
1764  <OL>
1765  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1766  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1767  <LI><B>TABLE_NAME</B> String => table name
1768  <LI><B>GRANTOR</B> => grantor of access (may be null)
1769  <LI><B>GRANTEE</B> String => grantee of access
1770  <LI><B>PRIVILEGE</B> String => name of access (SELECT,
1771  INSERT, UPDATE, REFRENCES, ...)
1772  <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
1773  to grant to others; "NO" if not; null if unknown
1774  </OL>
1775 
1776  @param catalog a catalog name; "" retrieves those without a
1777  catalog; null means drop catalog name from the selection criteria
1778  @param schemaPattern a schema name pattern; "" retrieves those
1779  without a schema
1780  @param tableNamePattern a table name pattern
1781  @return <code>ResultSet</code> - each row is a table privilege description
1782  @see #getSearchStringEscape
1783 }
1784 function TZASADatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;
1785  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;
1786 begin
1787  Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);
1788 
1789  with GetStatement.ExecuteQuery(
1790  Format('exec sp_jdbc_gettableprivileges %s, %s, %s',
1791  [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(TableNamePattern)])) do
1792  begin
1793  while Next do
1794  begin
1795  Result.MoveToInsertRow;
1796  Result.UpdateStringByName('TABLE_CAT',
1797  '');
1798  Result.UpdateStringByName('TABLE_SCHEM',
1799  GetStringByName('TABLE_SCHEM'));
1800  Result.UpdateStringByName('TABLE_NAME',
1801  GetStringByName('TABLE_NAME'));
1802  Result.UpdateStringByName('GRANTOR',
1803  GetStringByName('GRANTOR'));
1804  Result.UpdateStringByName('GRANTEE',
1805  GetStringByName('GRANTEE'));
1806  Result.UpdateStringByName('PRIVILEGE',
1807  GetStringByName('PRIVILEGE'));
1808  Result.UpdateStringByName('IS_GRANTABLE',
1809  GetStringByName('IS_GRANTABLE'));
1810  Result.InsertRow;
1811  end;
1812  Close;
1813  end;
1814 end;
1815 
1816 {**
1817  Gets a description of a table's columns that are automatically
1818  updated when any value in a row is updated. They are
1819  unordered.
1820 
1821  <P>Each column description has the following columns:
1822  <OL>
1823  <LI><B>SCOPE</B> short => is not used
1824  <LI><B>COLUMN_NAME</B> String => column name
1825  <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
1826  <LI><B>TYPE_NAME</B> String => Data source dependent type name
1827  <LI><B>COLUMN_SIZE</B> int => precision
1828  <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
1829  <LI><B>DECIMAL_DIGITS</B> short => scale
1830  <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
1831  like an Oracle ROWID
1832  <UL>
1833  <LI> versionColumnUnknown - may or may not be pseudo column
1834  <LI> versionColumnNotPseudo - is NOT a pseudo column
1835  <LI> versionColumnPseudo - is a pseudo column
1836  </UL>
1837  </OL>
1838 
1839  @param catalog a catalog name; "" retrieves those without a
1840  catalog; null means drop catalog name from the selection criteria
1841  @param schema a schema name; "" retrieves those without a schema
1842  @param table a table name
1843  @return <code>ResultSet</code> - each row is a column description
1844  @exception SQLException if a database access error occurs
1845 }
1846 function TZASADatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;
1847  const Schema: string; const Table: string): IZResultSet;
1848 begin
1849  Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);
1850 
1851  with GetStatement.ExecuteQuery(
1852  Format('exec sp_jdbc_getversioncolumns %s, %s, %s',
1853  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do
1854  begin
1855  while Next do
1856  begin
1857  Result.MoveToInsertRow;
1858  Result.UpdateShortByName('SCOPE',
1859  GetShortByName('SCOPE'));
1860  Result.UpdateStringByName('COLUMN_NAME',
1861  GetStringByName('COLUMN_NAME'));
1862  Result.UpdateShortByName('DATA_TYPE',
1863  Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),
1864  ConSettings.CPType)));
1865  Result.UpdateStringByName('TYPE_NAME',
1866  GetStringByName('TYPE_NAME'));
1867  Result.UpdateIntByName('COLUMN_SIZE',
1868  GetIntByName('COLUMN_SIZE'));
1869  Result.UpdateIntByName('BUFFER_LENGTH',
1870  GetIntByName('BUFFER_LENGTH'));
1871  Result.UpdateIntByName('DECIMAL_DIGITS',
1872  GetIntByName('DECIMAL_DIGITS'));
1873  Result.UpdateShortByName('PSEUDO_COLUMN',
1874  GetShortByName('PSEUDO_COLUMN'));
1875  Result.InsertRow;
1876  end;
1877  Close;
1878  end;
1879 end;
1880 
1881 {**
1882  Gets a description of a table's primary key columns. They
1883  are ordered by COLUMN_NAME.
1884 
1885  <P>Each primary key column description has the following columns:
1886  <OL>
1887  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
1888  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
1889  <LI><B>TABLE_NAME</B> String => table name
1890  <LI><B>COLUMN_NAME</B> String => column name
1891  <LI><B>KEY_SEQ</B> short => sequence number within primary key
1892  <LI><B>PK_NAME</B> String => primary key name (may be null)
1893  </OL>
1894 
1895  @param catalog a catalog name; "" retrieves those without a
1896  catalog; null means drop catalog name from the selection criteria
1897  @param schema a schema name; "" retrieves those
1898  without a schema
1899  @param table a table name
1900  @return <code>ResultSet</code> - each row is a primary key column description
1901  @exception SQLException if a database access error occurs
1902 }
1903 function TZASADatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;
1904  const Schema: string; const Table: string): IZResultSet;
1905 begin
1906  Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);
1907 
1908  with GetStatement.ExecuteQuery(
1909  Format('exec sp_jdbc_primarykey %s, %s, %s',
1910  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do
1911  begin
1912  while Next do
1913  begin
1914  Result.MoveToInsertRow;
1915  Result.UpdateStringByName('TABLE_CAT',
1916  '');
1917  Result.UpdateStringByName('TABLE_SCHEM',
1918  GetStringByName('TABLE_SCHEM'));
1919  Result.UpdateStringByName('TABLE_NAME',
1920  GetStringByName('TABLE_NAME'));
1921  Result.UpdateStringByName('COLUMN_NAME',
1922  GetStringByName('COLUMN_NAME'));
1923  Result.UpdateShortByName('KEY_SEQ',
1924  GetShortByName('KEY_SEQ'));
1925  Result.UpdateStringByName('PK_NAME',
1926  GetStringByName('PK_NAME'));
1927  Result.InsertRow;
1928  end;
1929  Close;
1930  end;
1931 end;
1932 
1933 {**
1934  Gets a description of the primary key columns that are
1935  referenced by a table's foreign key columns (the primary keys
1936  imported by a table). They are ordered by PKTABLE_CAT,
1937  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
1938 
1939  <P>Each primary key column description has the following columns:
1940  <OL>
1941  <LI><B>PKTABLE_CAT</B> String => primary key table catalog
1942  being imported (may be null)
1943  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
1944  being imported (may be null)
1945  <LI><B>PKTABLE_NAME</B> String => primary key table name
1946  being imported
1947  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
1948  being imported
1949  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
1950  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
1951  <LI><B>FKTABLE_NAME</B> String => foreign key table name
1952  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
1953  <LI><B>KEY_SEQ</B> short => sequence number within foreign key
1954  <LI><B>UPDATE_RULE</B> short => What happens to
1955  foreign key when primary is updated:
1956  <UL>
1957  <LI> importedNoAction - do not allow update of primary
1958  key if it has been imported
1959  <LI> importedKeyCascade - change imported key to agree
1960  with primary key update
1961  <LI> importedKeySetNull - change imported key to NULL if
1962  its primary key has been updated
1963  <LI> importedKeySetDefault - change imported key to default values
1964  if its primary key has been updated
1965  <LI> importedKeyRestrict - same as importedKeyNoAction
1966  (for ODBC 2.x compatibility)
1967  </UL>
1968  <LI><B>DELETE_RULE</B> short => What happens to
1969  the foreign key when primary is deleted.
1970  <UL>
1971  <LI> importedKeyNoAction - do not allow delete of primary
1972  key if it has been imported
1973  <LI> importedKeyCascade - delete rows that import a deleted key
1974  <LI> importedKeySetNull - change imported key to NULL if
1975  its primary key has been deleted
1976  <LI> importedKeyRestrict - same as importedKeyNoAction
1977  (for ODBC 2.x compatibility)
1978  <LI> importedKeySetDefault - change imported key to default if
1979  its primary key has been deleted
1980  </UL>
1981  <LI><B>FK_NAME</B> String => foreign key name (may be null)
1982  <LI><B>PK_NAME</B> String => primary key name (may be null)
1983  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
1984  constraints be deferred until commit
1985  <UL>
1986  <LI> importedKeyInitiallyDeferred - see SQL92 for definition
1987  <LI> importedKeyInitiallyImmediate - see SQL92 for definition
1988  <LI> importedKeyNotDeferrable - see SQL92 for definition
1989  </UL>
1990  </OL>
1991 
1992  @param catalog a catalog name; "" retrieves those without a
1993  catalog; null means drop catalog name from the selection criteria
1994  @param schema a schema name; "" retrieves those
1995  without a schema
1996  @param table a table name
1997  @return <code>ResultSet</code> - each row is a primary key column description
1998  @see #getExportedKeys
1999 }
2000 function TZASADatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;
2001  const Schema: string; const Table: string): IZResultSet;
2002 begin
2003  Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);
2004 
2005  with GetStatement.ExecuteQuery(
2006  Format('exec sp_jdbc_importkey %s, %s, %s',
2007  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do
2008  begin
2009  while Next do
2010  begin
2011  Result.MoveToInsertRow;
2012  Result.UpdateStringByName('PKTABLE_CAT',
2013  '');
2014  Result.UpdateStringByName('PKTABLE_SCHEM',
2015  GetStringByName('PKTABLE_SCHEM'));
2016  Result.UpdateStringByName('PKTABLE_NAME',
2017  GetStringByName('PKTABLE_NAME'));
2018  Result.UpdateStringByName('PKCOLUMN_NAME',
2019  GetStringByName('PKCOLUMN_NAME'));
2020  Result.UpdateStringByName('FKTABLE_CAT',
2021  '');
2022  Result.UpdateStringByName('FKTABLE_SCHEM',
2023  GetStringByName('FKTABLE_SCHEM'));
2024  Result.UpdateStringByName('FKTABLE_NAME',
2025  GetStringByName('FKTABLE_NAME'));
2026  Result.UpdateStringByName('FKCOLUMN_NAME',
2027  GetStringByName('FKCOLUMN_NAME'));
2028  Result.UpdateShortByName('KEY_SEQ',
2029  GetShortByName('KEY_SEQ'));
2030  Result.UpdateShortByName('UPDATE_RULE',
2031  GetShortByName('UPDATE_RULE'));
2032  Result.UpdateShortByName('DELETE_RULE',
2033  GetShortByName('DELETE_RULE'));
2034  Result.UpdateStringByName('FK_NAME',
2035  GetStringByName('FK_NAME'));
2036  Result.UpdateStringByName('PK_NAME',
2037  GetStringByName('PK_NAME'));
2038  Result.UpdateIntByName('DEFERRABILITY',
2039  GetIntByName('DEFERRABILITY'));
2040  Result.InsertRow;
2041  end;
2042  Close;
2043  end;
2044 end;
2045 
2046 {**
2047  Gets a description of the foreign key columns that reference a
2048  table's primary key columns (the foreign keys exported by a
2049  table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
2050  FKTABLE_NAME, and KEY_SEQ.
2051 
2052  <P>Each foreign key column description has the following columns:
2053  <OL>
2054  <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2055  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2056  <LI><B>PKTABLE_NAME</B> String => primary key table name
2057  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2058  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2059  being exported (may be null)
2060  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2061  being exported (may be null)
2062  <LI><B>FKTABLE_NAME</B> String => foreign key table name
2063  being exported
2064  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2065  being exported
2066  <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2067  <LI><B>UPDATE_RULE</B> short => What happens to
2068  foreign key when primary is updated:
2069  <UL>
2070  <LI> importedNoAction - do not allow update of primary
2071  key if it has been imported
2072  <LI> importedKeyCascade - change imported key to agree
2073  with primary key update
2074  <LI> importedKeySetNull - change imported key to NULL if
2075  its primary key has been updated
2076  <LI> importedKeySetDefault - change imported key to default values
2077  if its primary key has been updated
2078  <LI> importedKeyRestrict - same as importedKeyNoAction
2079  (for ODBC 2.x compatibility)
2080  </UL>
2081  <LI><B>DELETE_RULE</B> short => What happens to
2082  the foreign key when primary is deleted.
2083  <UL>
2084  <LI> importedKeyNoAction - do not allow delete of primary
2085  key if it has been imported
2086  <LI> importedKeyCascade - delete rows that import a deleted key
2087  <LI> importedKeySetNull - change imported key to NULL if
2088  its primary key has been deleted
2089  <LI> importedKeyRestrict - same as importedKeyNoAction
2090  (for ODBC 2.x compatibility)
2091  <LI> importedKeySetDefault - change imported key to default if
2092  its primary key has been deleted
2093  </UL>
2094  <LI><B>FK_NAME</B> String => foreign key name (may be null)
2095  <LI><B>PK_NAME</B> String => primary key name (may be null)
2096  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2097  constraints be deferred until commit
2098  <UL>
2099  <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2100  <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2101  <LI> importedKeyNotDeferrable - see SQL92 for definition
2102  </UL>
2103  </OL>
2104 
2105  @param catalog a catalog name; "" retrieves those without a
2106  catalog; null means drop catalog name from the selection criteria
2107  @param schema a schema name; "" retrieves those
2108  without a schema
2109  @param table a table name
2110  @return <code>ResultSet</code> - each row is a foreign key column description
2111  @see #getImportedKeys
2112 }
2113 function TZASADatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;
2114  const Schema: string; const Table: string): IZResultSet;
2115 var KeySeq: Integer;
2116 begin
2117  Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);
2118 
2119  KeySeq := 0;
2120  with GetStatement.ExecuteQuery(
2121  Format('exec sp_jdbc_exportkey %s, %s, %s',
2122  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do
2123  begin
2124  while Next do
2125  begin
2126  Inc(KeySeq);
2127  Result.MoveToInsertRow;
2128  Result.UpdateStringByName('PKTABLE_CAT',
2129  '');
2130  Result.UpdateStringByName('PKTABLE_SCHEM',
2131  GetStringByName('PKTABLE_SCHEM'));
2132  Result.UpdateStringByName('PKTABLE_NAME',
2133  GetStringByName('PKTABLE_NAME'));
2134  Result.UpdateStringByName('PKCOLUMN_NAME',
2135  GetStringByName('PKCOLUMN_NAME'));
2136  Result.UpdateStringByName('FKTABLE_CAT',
2137  '');
2138  Result.UpdateStringByName('FKTABLE_SCHEM',
2139  GetStringByName('FKTABLE_SCHEM'));
2140  Result.UpdateStringByName('FKTABLE_NAME',
2141  GetStringByName('FKTABLE_NAME'));
2142  Result.UpdateStringByName('FKCOLUMN_NAME',
2143  GetStringByName('FKCOLUMN_NAME'));
2144  Result.UpdateShortByName('KEY_SEQ', KeySeq);
2145  Result.UpdateShortByName('UPDATE_RULE',
2146  GetShortByName('UPDATE_RULE'));
2147  Result.UpdateShortByName('DELETE_RULE',
2148  GetShortByName('DELETE_RULE'));
2149  Result.UpdateStringByName('FK_NAME',
2150  GetStringByName('FK_NAME'));
2151  Result.UpdateStringByName('PK_NAME',
2152  GetStringByName('PK_NAME'));
2153  Result.UpdateIntByName('DEFERRABILITY',
2154  GetIntByName('DEFERRABILITY'));
2155  Result.InsertRow;
2156  end;
2157  Close;
2158  end;
2159 end;
2160 
2161 {**
2162  Gets a description of the foreign key columns in the foreign key
2163  table that reference the primary key columns of the primary key
2164  table (describe how one table imports another's key.) This
2165  should normally return a single foreign key/primary key pair
2166  (most tables only import a foreign key from a table once.) They
2167  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
2168  KEY_SEQ.
2169 
2170  <P>Each foreign key column description has the following columns:
2171  <OL>
2172  <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
2173  <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
2174  <LI><B>PKTABLE_NAME</B> String => primary key table name
2175  <LI><B>PKCOLUMN_NAME</B> String => primary key column name
2176  <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
2177  being exported (may be null)
2178  <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
2179  being exported (may be null)
2180  <LI><B>FKTABLE_NAME</B> String => foreign key table name
2181  being exported
2182  <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
2183  being exported
2184  <LI><B>KEY_SEQ</B> short => sequence number within foreign key
2185  <LI><B>UPDATE_RULE</B> short => What happens to
2186  foreign key when primary is updated:
2187  <UL>
2188  <LI> importedNoAction - do not allow update of primary
2189  key if it has been imported
2190  <LI> importedKeyCascade - change imported key to agree
2191  with primary key update
2192  <LI> importedKeySetNull - change imported key to NULL if
2193  its primary key has been updated
2194  <LI> importedKeySetDefault - change imported key to default values
2195  if its primary key has been updated
2196  <LI> importedKeyRestrict - same as importedKeyNoAction
2197  (for ODBC 2.x compatibility)
2198  </UL>
2199  <LI><B>DELETE_RULE</B> short => What happens to
2200  the foreign key when primary is deleted.
2201  <UL>
2202  <LI> importedKeyNoAction - do not allow delete of primary
2203  key if it has been imported
2204  <LI> importedKeyCascade - delete rows that import a deleted key
2205  <LI> importedKeySetNull - change imported key to NULL if
2206  its primary key has been deleted
2207  <LI> importedKeyRestrict - same as importedKeyNoAction
2208  (for ODBC 2.x compatibility)
2209  <LI> importedKeySetDefault - change imported key to default if
2210  its primary key has been deleted
2211  </UL>
2212  <LI><B>FK_NAME</B> String => foreign key name (may be null)
2213  <LI><B>PK_NAME</B> String => primary key name (may be null)
2214  <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key
2215  constraints be deferred until commit
2216  <UL>
2217  <LI> importedKeyInitiallyDeferred - see SQL92 for definition
2218  <LI> importedKeyInitiallyImmediate - see SQL92 for definition
2219  <LI> importedKeyNotDeferrable - see SQL92 for definition
2220  </UL>
2221  </OL>
2222 
2223  @param primaryCatalog a catalog name; "" retrieves those without a
2224  catalog; null means drop catalog name from the selection criteria
2225  @param primarySchema a schema name; "" retrieves those
2226  without a schema
2227  @param primaryTable the table name that exports the key
2228  @param foreignCatalog a catalog name; "" retrieves those without a
2229  catalog; null means drop catalog name from the selection criteria
2230  @param foreignSchema a schema name; "" retrieves those
2231  without a schema
2232  @param foreignTable the table name that imports the key
2233  @return <code>ResultSet</code> - each row is a foreign key column description
2234  @see #getImportedKeys
2235 }
2236 function TZASADatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;
2237  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;
2238  const ForeignSchema: string; const ForeignTable: string): IZResultSet;
2239 begin
2240  Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,
2241  ForeignCatalog, ForeignSchema, ForeignTable);
2242 
2243  with GetStatement.ExecuteQuery(
2244  Format('exec sp_jdbc_getcrossreferences %s, %s, %s, %s, %s, %s',
2245  [ComposeObjectString(PrimaryCatalog), ComposeObjectString(PrimarySchema), ComposeObjectString(PrimaryTable),
2246  ComposeObjectString(ForeignCatalog), ComposeObjectString(ForeignSchema), ComposeObjectString(ForeignTable)])) do
2247  begin
2248  while Next do
2249  begin
2250  Result.MoveToInsertRow;
2251  Result.UpdateStringByName('PKTABLE_CAT',
2252  '');
2253  Result.UpdateStringByName('PKTABLE_SCHEM',
2254  GetStringByName('PKTABLE_SCHEM'));
2255  Result.UpdateStringByName('PKTABLE_NAME',
2256  GetStringByName('PKTABLE_NAME'));
2257  Result.UpdateStringByName('PKCOLUMN_NAME',
2258  GetStringByName('PKCOLUMN_NAME'));
2259  Result.UpdateStringByName('FKTABLE_CAT',
2260  '');
2261  Result.UpdateStringByName('FKTABLE_SCHEM',
2262  GetStringByName('FKTABLE_SCHEM'));
2263  Result.UpdateStringByName('FKTABLE_NAME',
2264  GetStringByName('FKTABLE_NAME'));
2265  Result.UpdateStringByName('FKCOLUMN_NAME',
2266  GetStringByName('FKCOLUMN_NAME'));
2267  Result.UpdateShortByName('KEY_SEQ',
2268  GetShortByName('KEY_SEQ'));
2269  Result.UpdateShortByName('UPDATE_RULE',
2270  GetShortByName('UPDATE_RULE'));
2271  Result.UpdateShortByName('DELETE_RULE',
2272  GetShortByName('DELETE_RULE'));
2273  Result.UpdateStringByName('FK_NAME',
2274  GetStringByName('FK_NAME'));
2275  Result.UpdateStringByName('PK_NAME',
2276  GetStringByName('PK_NAME'));
2277  Result.UpdateIntByName('DEFERRABILITY',
2278  GetIntByName('DEFERRABILITY'));
2279  Result.InsertRow;
2280  end;
2281  Close;
2282  end;
2283 end;
2284 
2285 {**
2286  Gets a description of all the standard SQL types supported by
2287  this database. They are ordered by DATA_TYPE and then by how
2288  closely the data type maps to the corresponding JDBC SQL type.
2289 
2290  <P>Each type description has the following columns:
2291  <OL>
2292  <LI><B>TYPE_NAME</B> String => Type name
2293  <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
2294  <LI><B>PRECISION</B> int => maximum precision
2295  <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
2296  (may be null)
2297  <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
2298  (may be null)
2299  <LI><B>CREATE_PARAMS</B> String => parameters used in creating
2300  the type (may be null)
2301  <LI><B>NULLABLE</B> short => can you use NULL for this type?
2302  <UL>
2303  <LI> typeNoNulls - does not allow NULL values
2304  <LI> typeNullable - allows NULL values
2305  <LI> typeNullableUnknown - nullability unknown
2306  </UL>
2307  <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
2308  <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
2309  <UL>
2310  <LI> typePredNone - No support
2311  <LI> typePredChar - Only supported with WHERE .. LIKE
2312  <LI> typePredBasic - Supported except for WHERE .. LIKE
2313  <LI> typeSearchable - Supported for all WHERE ..
2314  </UL>
2315  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
2316  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
2317  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
2318  auto-increment value?
2319  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
2320  (may be null)
2321  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
2322  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
2323  <LI><B>SQL_DATA_TYPE</B> int => unused
2324  <LI><B>SQL_DATETIME_SUB</B> int => unused
2325  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
2326  </OL>
2327 
2328  @return <code>ResultSet</code> - each row is an SQL type description
2329 }
2330 function TZASADatabaseMetadata.UncachedGetTypeInfo: IZResultSet;
2331 begin
2332  Result:=inherited UncachedGetTypeInfo;
2333 
2334  with GetStatement.ExecuteQuery('exec sp_jdbc_datatype_info') do
2335  begin
2336  while Next do
2337  begin
2338  Result.MoveToInsertRow;
2339  Result.UpdateStringByName('TYPE_NAME',
2340  GetStringByName('TYPE_NAME'));
2341  Result.UpdateShortByName('DATA_TYPE',
2342  Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),
2343  ConSettings.CPType)));
2344  Result.UpdateIntByName('PRECISION',
2345  GetIntByName('PRECISION'));
2346  Result.UpdateStringByName('LITERAL_PREFIX',
2347  GetStringByName('LITERAL_PREFIX'));
2348  Result.UpdateStringByName('LITERAL_SUFFIX',
2349  GetStringByName('LITERAL_SUFFIX'));
2350  Result.UpdateStringByName('CREATE_PARAMS',
2351  GetStringByName('CREATE_PARAMS'));
2352  Result.UpdateShortByName('NULLABLE',
2353  GetShortByName('NULLABLE'));
2354  Result.UpdateBooleanByName('CASE_SENSITIVE',
2355  GetShortByName('CASE_SENSITIVE') = 1);
2356  Result.UpdateShortByName('SEARCHABLE',
2357  GetShortByName('SEARCHABLE'));
2358  Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',
2359  GetShortByName('UNSIGNED_ATTRIBUTE') = 1);
2360  Result.UpdateBooleanByName('FIXED_PREC_SCALE',
2361  GetShortByName('FIXED_PREC_SCALE') = 1);
2362  Result.UpdateBooleanByName('AUTO_INCREMENT',
2363  GetShortByName('AUTO_INCREMENT') = 1);
2364  Result.UpdateStringByName('LOCAL_TYPE_NAME',
2365  GetStringByName('LOCAL_TYPE_NAME'));
2366  Result.UpdateShortByName('MINIMUM_SCALE',
2367  GetShortByName('MINIMUM_SCALE'));
2368  Result.UpdateShortByName('MAXIMUM_SCALE',
2369  GetShortByName('MAXIMUM_SCALE'));
2370  Result.UpdateShortByName('SQL_DATA_TYPE',
2371  GetShortByName('SQL_DATA_TYPE'));
2372  Result.UpdateShortByName('SQL_DATETIME_SUB',
2373  GetShortByName('SQL_DATETIME_SUB'));
2374  Result.UpdateShortByName('NUM_PREC_RADIX',
2375  GetShortByName('NUM_PREC_RADIX'));
2376  Result.InsertRow;
2377  end;
2378  Close;
2379  end;
2380 end;
2381 
2382 {**
2383  Gets a description of a table's indices and statistics. They are
2384  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
2385 
2386  <P>Each index column description has the following columns:
2387  <OL>
2388  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
2389  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
2390  <LI><B>TABLE_NAME</B> String => table name
2391  <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
2392  false when TYPE is tableIndexStatistic
2393  <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
2394  null when TYPE is tableIndexStatistic
2395  <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
2396  tableIndexStatistic
2397  <LI><B>TYPE</B> short => index type:
2398  <UL>
2399  <LI> tableIndexStatistic - this identifies table statistics that are
2400  returned in conjuction with a table's index descriptions
2401  <LI> tableIndexClustered - this is a clustered index
2402  <LI> tableIndexHashed - this is a hashed index
2403  <LI> tableIndexOther - this is some other style of index
2404  </UL>
2405  <LI><B>ORDINAL_POSITION</B> short => column sequence number
2406  within index; zero when TYPE is tableIndexStatistic
2407  <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
2408  tableIndexStatistic
2409  <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending,
2410  "D" => descending, may be null if sort sequence is not supported;
2411  null when TYPE is tableIndexStatistic
2412  <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then
2413  this is the number of rows in the table; otherwise, it is the
2414  number of unique values in the index.
2415  <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
2416  this is the number of pages used for the table, otherwise it
2417  is the number of pages used for the current index.
2418  <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
2419  (may be null)
2420  </OL>
2421 
2422  @param catalog a catalog name; "" retrieves those without a
2423  catalog; null means drop catalog name from the selection criteria
2424  @param schema a schema name; "" retrieves those without a schema
2425  @param table a table name
2426  @param unique when true, return only indices for unique values;
2427  when false, return indices regardless of whether unique or not
2428  @param approximate when true, result is allowed to reflect approximate
2429  or out of data values; when false, results are requested to be
2430  accurate
2431  @return <code>ResultSet</code> - each row is an index column description
2432 }
2433 function TZASADatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;
2434  const Schema: string; const Table: string; Unique: Boolean;
2435  Approximate: Boolean): IZResultSet;
2436 var
2437  Is_Unique, Accuracy: string;
2438 begin
2439  Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);
2440 
2441  if Unique then
2442  Is_Unique := '''1'''
2443  else
2444  Is_Unique := '''0''';
2445 
2446  if Approximate then
2447  Accuracy := '''1'''
2448  else
2449  Accuracy := '''0''';
2450 
2451  with GetStatement.ExecuteQuery(
2452  Format('exec sp_jdbc_getindexinfo %s, %s, %s, %s, %s',
2453  [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table), Is_Unique, Accuracy])) do
2454  begin
2455  while Next do
2456  begin
2457  Result.MoveToInsertRow;
2458  Result.UpdateStringByName('TABLE_CAT',
2459  '');
2460  Result.UpdateStringByName('TABLE_SCHEM',
2461  GetStringByName('TABLE_SCHEM'));
2462  Result.UpdateStringByName('TABLE_NAME',
2463  GetStringByName('TABLE_NAME'));
2464  Result.UpdateBooleanByName('NON_UNIQUE',
2465  GetShortByName('NON_UNIQUE') = 1);
2466  Result.UpdateStringByName('INDEX_QUALIFIER',
2467  GetStringByName('INDEX_QUALIFIER'));
2468  Result.UpdateStringByName('INDEX_NAME',
2469  GetStringByName('INDEX_NAME'));
2470  Result.UpdateShortByName('TYPE',
2471  GetShortByName('TYPE'));
2472  Result.UpdateShortByName('ORDINAL_POSITION',
2473  GetShortByName('ORDINAL_POSITION'));
2474  Result.UpdateStringByName('COLUMN_NAME',
2475  GetStringByName('COLUMN_NAME'));
2476  Result.UpdateStringByName('ASC_OR_DESC',
2477  GetStringByName('ASC_OR_DESC'));
2478  Result.UpdateIntByName('CARDINALITY',
2479  GetIntByName('CARDINALITY'));
2480  Result.UpdateIntByName('PAGES',
2481  GetIntByName('PAGES'));
2482  Result.UpdateStringByName('FILTER_CONDITION',
2483  GetStringByName('FILTER_CONDITION'));
2484  Result.InsertRow;
2485  end;
2486  Close;
2487  end;
2488 end;
2489 
2490 {**
2491  Gets a description of the user-defined types defined in a particular
2492  schema. Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,
2493  or DISTINCT.
2494 
2495  <P>Only types matching the catalog, schema, type name and type
2496  criteria are returned. They are ordered by DATA_TYPE, TYPE_SCHEM
2497  and TYPE_NAME. The type name parameter may be a fully-qualified
2498  name. In this case, the catalog and schemaPattern parameters are
2499  ignored.
2500 
2501  <P>Each type description has the following columns:
2502  <OL>
2503  <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)
2504  <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)
2505  <LI><B>TYPE_NAME</B> String => type name
2506  <LI><B>CLASS_NAME</B> String => Java class name
2507  <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.
2508  One of JAVA_OBJECT, STRUCT, or DISTINCT
2509  <LI><B>REMARKS</B> String => explanatory comment on the type
2510  </OL>
2511 
2512  <P><B>Note:</B> If the driver does not support UDTs, an empty
2513  result set is returned.
2514 
2515  @param catalog a catalog name; "" retrieves those without a
2516  catalog; null means drop catalog name from the selection criteria
2517  @param schemaPattern a schema name pattern; "" retrieves those
2518  without a schema
2519  @param typeNamePattern a type name pattern; may be a fully-qualified name
2520  @param types a list of user-named types to include (JAVA_OBJECT,
2521  STRUCT, or DISTINCT); null returns all types
2522  @return <code>ResultSet</code> - each row is a type description
2523 }
2524 function TZASADatabaseMetadata.UncachedGetUDTs(const Catalog: string;
2525  const SchemaPattern: string; const TypeNamePattern: string;
2526  const Types: TIntegerDynArray): IZResultSet;
2527 var
2528  I: Integer;
2529  UDTypes: string;
2530 begin
2531  Result:=inherited UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);
2532 
2533  UDTypes := '';
2534  for I := 0 to Length(Types) - 1 do
2535  begin
2536  if Length(UDTypes) > 0 then
2537  UDTypes := UDTypes + ',';
2538  UDTypes := UDTypes + AnsiQuotedStr(IntToStr(Types[I]), '''');
2539  end;
2540 
2541  with GetStatement.ExecuteQuery(
2542  Format('exec sp_jdbc_getudts %s, %s, %s, %s',
2543  [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern, '''%'''),
2544  ComposeObjectString(TypeNamePattern, '''%'''),
2545  ComposeObjectString(UDTypes, 'null', '"')])) do
2546  begin
2547  while Next do
2548  begin
2549  Result.MoveToInsertRow;
2550  Result.UpdateStringByName('TYPE_CAT',
2551  GetStringByName('TYPE_CAT'));
2552  Result.UpdateStringByName('TYPE_SCHEM',
2553  GetStringByName('TYPE_SCHEM'));
2554  Result.UpdateStringByName('TYPE_NAME',
2555  GetStringByName('TYPE_NAME'));
2556  Result.UpdateStringByName('JAVA_CLASS',
2557  GetStringByName('JAVA_CLASS'));
2558  Result.UpdateShortByName('DATA_TYPE',
2559  Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),
2560  ConSettings.CPType)));
2561  Result.UpdateStringByName('REMARKS',
2562  GetStringByName('REMARKS'));
2563  Result.InsertRow;
2564  end;
2565  Close;
2566  end;
2567 end;
2568 
2569 end.
2570 
2571