00001 /* File: orastuff.h 00002 ** Author(s): Ernie Johnson 00003 ** Contact: xsb-contact@cs.sunysb.edu 00004 ** 00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998 00006 ** 00007 ** XSB is free software; you can redistribute it and/or modify it under the 00008 ** terms of the GNU Library General Public License as published by the Free 00009 ** Software Foundation; either version 2 of the License, or (at your option) 00010 ** any later version. 00011 ** 00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY 00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 ** FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for 00015 ** more details. 00016 ** 00017 ** You should have received a copy of the GNU Library General Public License 00018 ** along with XSB; if not, write to the Free Software Foundation, 00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00020 ** 00021 ** $Id: orastuff.h,v 1.6 2005/01/14 18:31:25 ruim Exp $ 00022 ** 00023 */ 00024 00025 00026 00027 /* 00028 * M I S C E L L A N E O U S 00029 * ========================= 00030 */ 00031 00032 /* SQL Communications Area 00033 ----------------------- */ 00034 00035 #define SQLCA_INIT 00036 EXEC SQL INCLUDE sqlca; 00037 00038 /* ------------------------------------------------------------------------ */ 00039 00040 /* 00041 * Number of cursors we can handle at once. 00042 */ 00043 #define NUM_CURSORS 21 00044 00045 00046 /* 00047 * Statuses returned to Prolog from the Oracle Interace Primitives. 00048 */ 00049 #define ORACLE_EXCEPTION 2 00050 #define INTERFACE_EXCEPTION 1 00051 #define SUCCESS 0 00052 #define INTERFACE_ERROR -1 00053 #define ORACLE_ERROR -2 00054 00055 #define IsExceptionStatus(Status) (Status > SUCCESS) 00056 #define IsSuccessStatus(Status) (Status == SUCCESS) 00057 #define IsFailureStatus(Status) (Status < SUCCESS) 00058 00059 00060 /* ======================================================================== */ 00061 00062 /* 00063 * T A L K I N G T O O R A C L E 00064 * ================================= 00065 */ 00066 00067 /* 00068 * Oracle Descriptors 00069 * ================== 00070 * The use of DB cursors center around the use of so-called descriptors. 00071 * These are data structures defined by Oracle which allow certain 00072 * information to be conveyed, between the program and the DB, about the 00073 * query. A descriptor can be dedicated to either input or output. Input 00074 * descriptors are only necessary when using SQL query templates: an SQL 00075 * statement with placeholders where values must be inserted. The use of 00076 * templates allows for re-use of DB parsing info, but it requires the 00077 * overhead of descriptor manipulation. SQL statements which are passed 00078 * with values intact as a string to Oracle can be executed immediately. 00079 * All SQL SELECT statements require a descriptor to handle DB output. 00080 */ 00081 00082 00083 /* SQL Descriptor Area (SQLDA) 00084 --------------------------- */ 00085 00086 EXEC SQL INCLUDE sqlda; 00087 00088 00089 /* SQLDA Access Macros 00090 ------------------- */ 00091 00092 #define SQLDA_NumEntriesAlloced(SQLDA) ((SQLDA)->N) 00093 #define SQLDA_ItemValueArrayBase(SQLDA,Index) ((SQLDA)->V[Index]) 00094 #define SQLDA_ItemValueArrayWidth(SQLDA,Index) ((SQLDA)->L[Index]) 00095 #define SQLDA_ItemValueArrayType(SQLDA,Index) ((SQLDA)->T[Index]) 00096 #define SQLDA_IndValueArrayBase(SQLDA,Index) ((SQLDA)->I[Index]) 00097 #define SQLDA_NumEntriesFound(SQLDA) ((SQLDA)->F) 00098 #define SQLDA_ItemNameBuffer(SQLDA,Index) ((SQLDA)->S[Index]) 00099 #define SQLDA_ItemNameBufLen(SQLDA,Index) ((SQLDA)->M[Index]) 00100 #define SQLDA_ItemNameLength(SQLDA,Index) ((SQLDA)->C[Index]) 00101 #define SQLDA_IndNameBuffer(SQLDA,Index) ((SQLDA)->X[Index]) 00102 #define SQLDA_IndNameBufLen(SQLDA,Index) ((SQLDA)->Y[Index]) 00103 #define SQLDA_IndNameLength(SQLDA,Index) ((SQLDA)->Z[Index]) 00104 00105 00106 /* SQLDA Methods (taken from sqlcpr.h) 00107 ------------- */ 00108 00109 /* Allocates SQL Descriptor Area */ 00110 extern SQLDA *sqlald( int, unsigned int, unsigned int ); 00111 00112 /* Deallcates SQL Descriptor Area */ 00113 extern void sqlclu( SQLDA * ); 00114 00115 /* Checks and resets the high order bit of an SQLDA type field after a 00116 DESCRIBE of the SLIs This bit indicates whether a column has been 00117 specified as NON NULL: 1 = allows NULLs, 0 = disallows NULLs. */ 00118 extern void sqlnul( short*, short*, int* ); 00119 00120 /* Extracts precision (number of significant digits) and scale (where 00121 rounding occurs) from the length field of an SQLDA associated with a 00122 NUMBER datatype. */ 00123 extern void sqlprc( long*, int*, int* ); 00124 00125 00126 /* Descriptor Constants 00127 -------------------- */ 00128 00129 /* 00130 * Maximum number of input placeholders or output columns allowed. 00131 * (There's a real limit set by Oracle; find this constant.) 00132 */ 00133 00134 #define MAX_NUM_IOVALUES 100 00135 00136 00137 /* 00138 * Limits on the maximum length of the *names* of the select-list 00139 * items and bind variables. 00140 * Bind variables are called "bindX" where X is a counter. 00141 * SLI names depend on the table's column names, or the computation 00142 * to be performed. 00143 */ 00144 00145 #define BINDVAR_NAME_BUFFER_SIZE 8 00146 #define SLI_NAME_BUFFER_SIZE 30 00147 00148 00149 /* 00150 * ORACLE recognizes two classes of datatypes: internal and external. 00151 * Internal datatypes specify how ORACLE (a) stores data in database 00152 * columns, and (b) represents database pseudocolumns. External datatypes 00153 * specify how data is stored in host variables. External datatypes 00154 * include the internal datatypes plus other language-specific types. 00155 * Below, a description of all the Internal and the relevant External 00156 * datatypes are given. 00157 * 00158 * A description containing the term "binary" means that the data would be 00159 * received in some non-native-language format, either because it is a 00160 * representation used internally by Oracle (as in the case of NUMBER and 00161 * DATE) or because the data has a structure imposed by some external 00162 * influence. ORACLE, therefore, does not know the format of this data 00163 * and hence does not attempt to interpret it, as in the case of the RAW 00164 * and LONG RAW datatypes. 00165 * 00166 * A description containing the term "fixed-length" means that every byte 00167 * of the input value or column field is significant. In particular, a 00168 * column value of this type contains blank padding when extracted, even 00169 * if the host variable is declared to be of a "variable length" type. 00170 */ 00171 00172 enum OracleDataTypes { 00173 00174 /* Internal (and External) DataTypes */ 00175 00176 VARCHAR2_ODT = 1, /* Variable-length character string */ 00177 NUMBER_ODT = 2, /* Binary Number */ 00178 LONG_ODT = 8, /* Fixed-length character string */ 00179 ROWID_ODT = 11, /* Binary value */ 00180 DATE_ODT = 12, /* Fixed-length date/time value */ 00181 RAW_ODT = 23, /* Fixed-length binary data */ 00182 LONGRAW_ODT = 24, /* Fixed-length binary data */ 00183 CHAR_ODT = 96, /* Fixed-length character string */ 00184 00185 /* External DataTypes (cont'd) */ 00186 00187 INTEGER_ODT = 3, /* Signed Integer */ 00188 FLOAT_ODT = 4, /* Floating point number */ 00189 STRING_ODT = 5, /* NULL-terminated character string */ 00190 VARNUM_ODT = 6, /* Variable-length binary number */ 00191 VARCHAR_ODT = 9, /* Variable-length character string */ 00192 VARRAW_ODT = 15, /* Variable-length binary data */ 00193 UNSIGNED_ODT = 68, /* Unsigned integer */ 00194 LONGVARCHAR_ODT = 94, /* Variable-length character string */ 00195 LONGVARRAW_ODT = 95, /* Variable-length binary data */ 00196 CHARZ_ODT = 97 /* C fixed-length, NULL-terminated char string */ 00197 }; 00198 00199 /* Some data types have a fixed or limited representation as strings... */ 00200 #define ROWID_TO_STRING_BUFSIZE 20 00201 #define DATE_TO_STRING_BUFSIZE 10 00202 00203 /* Others give no hint as to its size, so we set our own limit */ 00204 #define LONG_TO_STRING_BUFSIZE 100 00205 00206 /* ------------------------------------------------------------------------ */ 00207 00208 /* 00209 * Local Extensions for Host Variable Arrays 00210 * ========================================= 00211 * Constants, Types, and Data Structures for managing Oracle descriptors 00212 * which allow for the use of multi-tuple input and output. The size of 00213 * these arrays are obtained from XSB's global flags. 00214 * (In the literature, input placeholders are referred to as "bind 00215 * variables" and elements of an output tuple are referred to as 00216 * "select list items".) 00217 */ 00218 00219 typedef unsigned int uint; 00220 00221 00222 typedef struct Bind_Variable_Specification { 00223 SQLDA *descriptor; /* Oracle Bind Descriptor */ 00224 uint array_length; /* number of elements in the input arrays */ 00225 uint cur_entry_index; /* which element of the BV arrays are to be filled; 00226 valid range: [0..(array_length-1)] */ 00227 } BindVarSpec; 00228 00229 00230 /* 00231 * Original details about a table's columns, as reported by 00232 * DESCRIBE SELECT LIST. 00233 */ 00234 typedef struct Table_Column_Attributes { 00235 short datatype; /* after the null-bit has been cleared */ 00236 short not_null; /* TRUE = NULLs not allowed; FALSE = NULLs allowed */ 00237 long size; /* width of column, may be 0 if none given at creation */ 00238 } ColumnSpec; 00239 00240 typedef struct Select_List_Item_Specification { 00241 SQLDA *descriptor; /* Oracle Select Descriptor */ 00242 uint array_length; /* number of elements in the output arrays */ 00243 ColumnSpec *column_specs; /* array of details about the selected columns */ 00244 uint cur_row_index; /* indicates the element across all arrays to be 00245 read; valid range: [0..(array_length-1)] */ 00246 uint cur_col_index; /* denotes which SLI should next be read by Prolog; 00247 valid range: [0..(numSLIs-1)] */ 00248 int cur_row_number; /* RowID of next tuple to return to Prolog */ 00249 uint total_rows_recvd; /* total num rows received from Oracle so far */ 00250 xsbBool end_of_active_set; /* flag indicating whether the last of the active 00251 set has been returned from Oracle. */ 00252 } SLI_Spec; 00253 00254 00255 /* 00256 * Default array widths in bytes for select list items (output) and bind 00257 * variables (input). Actual values can be set by the user and are 00258 * stored in flags ORA_INPUTARRAY_LENGTH and ORA_OUTPUTARRAY_LENGTH. 00259 * Whenever the values of these flags are <= 0, the defaults are used. 00260 */ 00261 #define DEFAULT_INPUTARRAY_LENGTH 200 00262 #define DEFAULT_INPUTARRAY_WIDTH 30 00263 #define DEFAULT_OUTPUTARRAY_LENGTH 200 00264 00265 00266 /* ======================================================================== */ 00267 00268 /* 00269 * S T A T E M E N T P R O P E R T I E S 00270 * ======================================= 00271 * 00272 * 00273 * Reusing a DB cursor can greatly reduce the time needed to process a 00274 * statement. An SQL statement can be considered to have a particular 00275 * "template": syntactically valid SQL constructs together with 00276 * placeholders for input and ouput values. XSB determines and maintains 00277 * templates for SQL statements established through many Oracle-interface 00278 * predicates, and in doing so, assigns to each distinct template a unique 00279 * number. This number allows us to reuse internal and database 00280 * structures created while processing a query with the same template. 00281 * 00282 * Together with this number, the text string representing the statement 00283 * itself and a tag indicating the type of statement are all maintained 00284 * for an issued Oracle query. 00285 */ 00286 00287 00288 typedef unsigned int TemplateNumber; 00289 00290 00291 /* SQL Statement Type 00292 * ------------------ 00293 * We enumerate only classes of statments, where each one requires unique 00294 * handling. (Explicit numbering for coordination with Prolog.) 00295 */ 00296 typedef enum SQL_Stmt_Type_Classes { 00297 SELECT_SQL_STMT = 0, /* Uses output arrays */ 00298 INSERT_SQL_STMT = 1, /* Uses input arrays */ 00299 CURSOR_DAMAGING_SQL_STMT = 2, /* Transaction Control and Data Def'n SQL 00300 stmts (which trigger COMMITs) invalidate cursors */ 00301 OTHER_SQL_STMT = 3 /* Other Data Manipulation, and Session and System 00302 Control SQL stmts which are benign... we think */ 00303 } SqlStmtType; 00304 00305 00306 typedef struct SQL_Statement_Specification { 00307 TemplateNumber template; 00308 SqlStmtType type; 00309 char *string; 00310 } SqlStmtSpec; 00311 00312 00313 /* ======================================================================== */ 00314 00315 /* 00316 * C U R S O R C O M P O N E N T S 00317 * ================================= 00318 * 00319 * 00320 * The following data structure tracks the allocation of Oracle cursors, as 00321 * well as local structures, to submitted SQL statements. Handles for 00322 * these resources, represented as indices into this array, are maintained 00323 * for the last NUM_CURSORS active statements. 00324 * 00325 * In Oracle, cursors are destroyed when a scheme-altering operation is 00326 * executed. Therefore, locally we must break ties between the templates 00327 * and the now defunct cursors (subsequent statement calls will have to 00328 * rebuild these structures). We do so by invalidating all active cursor 00329 * handles and resetting all inactive cursor ones to the unused state. We 00330 * must also establish tests to ensure that operations are performed only 00331 * on valid cursors. 00332 */ 00333 00334 00335 typedef int CursorHandle; 00336 00337 typedef enum Cursor_Status { 00338 UNUSED_CURSOR_STATUS, /* Has no allocated internal structures */ 00339 ACTIVE_CURSOR_STATUS, /* Currently in use */ 00340 INACTIVE_CURSOR_STATUS, /* Not in use; maintains internal structures */ 00341 INVALID_CURSOR_STATUS /* ACTIVE cursor destroyed by execution of a 00342 Transaction Control SQL statement */ 00343 } CursorStatus; 00344 00345 #define INVALID_CURSOR_HANDLE -1 00346 00347 00348 typedef struct Cursor_Components { 00349 CursorStatus status; 00350 SqlStmtSpec stmt; 00351 BindVarSpec bv; 00352 SLI_Spec sli; 00353 } Cursor;