00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __DATABASE_H__
00012 #define __DATABASE_H__
00013
00014 #include "class.h"
00015 #include "reference.h"
00016 #include "file.h"
00017 #include "pagepool.h"
00018
00019 BEGIN_GIGABASE_NAMESPACE
00020
00021 #ifdef _WINCE
00022
00025 const size_t dbDefaultInitIndexSize = 10*1024;
00026
00030 const size_t dbDefaultExtensionQuantum = 1*512*1024;
00031 #else
00032
00035 const size_t dbDefaultInitIndexSize = 512*1024;
00036
00040 const size_t dbDefaultExtensionQuantum = 4*1024*1024;
00041 #endif
00042
00046 const unsigned dbMaxParallelSearchThreads = 64;
00047
00051 enum dbHandleFlags {
00052 dbPageObjectFlag = 0x1,
00053 dbModifiedFlag = 0x2,
00054 dbFreeHandleFlag = 0x4,
00055 dbFlagsMask = 0x7,
00056 dbFlagsBits = 3
00057 };
00058
00059 const size_t dbAllocationQuantumBits = 6;
00060 const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
00061 const size_t dbPageBits = 13;
00062 const size_t dbPageSize = 1 << dbPageBits;
00063 const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
00064 const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
00065 const size_t dbHandleBits = 1 + sizeof(offs_t)/4;
00066 const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
00067 const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
00068 const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
00069 const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);
00070 const size_t dbDefaultSelectionLimit = 2000000000;
00075 const int dbBMsearchThreshold = 512;
00079 const size_t dbIndexedMergeThreshold = 100;
00080
00081
00082 const char_t dbMatchAnyOneChar = '_';
00083 const char_t dbMatchAnySubstring = '%';
00084
00085 const int dbMaxFileSegments = 64;
00086
00090 enum dbPredefinedIds {
00091 dbInvalidId,
00092 dbMetaTableId,
00093 dbBitmapId,
00094 dbFirstUserId = dbBitmapId + dbBitmapPages
00095 };
00096
00100 enum dbLockType {
00101 dbNoLock,
00102 dbSharedLock,
00103 dbUpdateLock,
00104 dbExclusiveLock
00105 };
00106
00110 class dbHeader {
00111 public:
00112 int4 curr;
00113 int4 dirty;
00114 int4 initialized;
00115 #if dbDatabaseOffsetBits > 32 && defined(ALIGN_HEADER)
00116 int4 pad1;
00117 #endif
00118 struct {
00119 offs_t size;
00120 offs_t index;
00121 offs_t shadowIndex;
00122 oid_t indexSize;
00123 oid_t shadowIndexSize;
00124 oid_t indexUsed;
00125 oid_t freeList;
00126 oid_t bitmapEnd;
00127 #if dbDatabaseOffsetBits > 32 && dbDatabaseOidBits <= 32 && defined(ALIGN_HEADER)
00128 oid_t pad2;
00129 #endif
00130 } root[2];
00131
00132 int4 versionMajor;
00133 int4 versionMinor;
00134 int4 transactionId;
00135 int4 mode;
00136
00137 enum {
00138 MODE_ALIGN_HEADER = 0x01,
00139 MODE_OID_64 = 0x02,
00140 MODE_OFFS_64 = 0x04,
00141 MODE_UNICODE = 0x08,
00142 MODE_AUTOINCREMENT = 0x10,
00143 MODE_RECTANGLE_DIM = 0x20
00144 };
00145
00146 int getVersion() {
00147 return versionMajor*100 + versionMinor;
00148 }
00149
00150 bool isCompatible();
00151 static int getCurrentMode();
00152
00153 bool isInitialized() {
00154 return initialized == 1
00155 && (dirty == 1 || dirty == 0)
00156 && (curr == 1 || curr == 0)
00157 && root[curr].size > root[curr].index
00158 && root[curr].size > root[curr].shadowIndex
00159 && root[curr].size > root[curr].indexSize*sizeof(offs_t)
00160 + root[curr].shadowIndexSize*sizeof(offs_t)
00161 && root[curr].indexSize >= root[curr].indexUsed
00162 && root[curr].indexUsed >= dbFirstUserId
00163 && root[curr].bitmapEnd > dbBitmapId;
00164 }
00165 };
00166
00167 class dbSynthesizedAttribute;
00168 class dbInheritedAttribute;
00169 class dbDatabaseThreadContext;
00170
00171 struct dbMemoryStatistic {
00172 offs_t used;
00173 offs_t free;
00174 offs_t nHoles;
00175 offs_t minHoleSize;
00176 offs_t maxHoleSize;
00177 size_t nHolesOfSize[dbDatabaseOffsetBits];
00178 };
00179
00180 class dbMonitor {
00181 public:
00182 dbLockType accLock;
00183
00184 dbDatabaseThreadContext* firstPending;
00185 dbDatabaseThreadContext* lastPending;
00186
00187 int nLockUpgrades;
00188
00189 int nReaders;
00190 int nWriters;
00191 int backupInProgress;
00192
00193 void wait(dbLockType type, dbMutex& mutex, dbDatabaseThreadContext* ctx);
00194
00195 dbMonitor() {
00196 firstPending = lastPending = NULL;
00197 accLock = dbNoLock;
00198 backupInProgress = 0;
00199 nReaders = nWriters = 0;
00200 nLockUpgrades = 0;
00201 }
00202 };
00203
00204
00205
00206 class dbAnyCursor;
00207 class dbQuery;
00208 class dbExprNode;
00209 class dbSearchContext;
00210
00211
00212 class dbVisitedObject {
00213 public:
00214 dbVisitedObject* next;
00215 oid_t oid;
00216
00217 dbVisitedObject(oid_t oid, dbVisitedObject* chain) {
00218 this->oid = oid;
00219 next = chain;
00220 }
00221 };
00222
00226 class GIGABASE_DLL_ENTRY dbDatabase {
00227 friend class dbSelection;
00228 friend class dbAnyCursor;
00229 friend class dbHashTable;
00230 friend class dbQuery;
00231 friend class dbRtree;
00232 friend class dbRtreePage;
00233 friend class dbBtree;
00234 friend class dbBtreePage;
00235 friend class dbThickBtreePage;
00236 friend class dbInheritedAttribute;
00237 friend class dbParallelQueryContext;
00238 friend class dbServer;
00239 friend class dbPagePool;
00240
00241 friend class dbBlob;
00242 friend class dbBlobIterator;
00243 friend class dbBlobReadIterator;
00244 friend class dbBlobWriteIterator;
00245 friend class dbAnyContainer;
00246
00247 friend class dbGetTie;
00248 friend class dbPutTie;
00249
00250 friend class dbUserFunctionArgument;
00251
00252 friend class dbCLI;
00253 friend class GiSTdb;
00254
00255 friend class dbBtreeIterator;
00256 friend class dbRtreeIterator;
00257 friend class dbTableIterator;
00258 public:
00266 bool open(char_t const* databaseName, time_t transactionCommitDelay = 0, int openAttr = 0);
00267
00275 bool open(dbFile* file, time_t transactionCommitDelay = 0, bool deleteFileOnClose = false);
00276
00277 enum dbAccessType {
00278 dbReadOnly,
00279 dbAllAccess,
00280 dbMulticlientReadOnly,
00281 dbMulticlientReadWrite
00282 };
00283
00287 struct OpenParameters {
00291 char_t const* databaseName;
00292
00296 int openAttr;
00297
00301 dbFile* file;
00302
00306 time_t transactionCommitDelay;
00307
00311 bool deleteFileOnClose;
00312
00316 dbAccessType accessType;
00317
00324 size_t poolSize;
00325
00329 size_t extensionQuantum;
00330
00334 size_t initIndexSize;
00335
00339 int nThreads;
00340
00341 OpenParameters() {
00342 databaseName = NULL;
00343 openAttr = 0;
00344 file = NULL;
00345 transactionCommitDelay = 0;
00346 deleteFileOnClose = false;
00347 accessType = dbAllAccess;
00348 poolSize = 0;
00349 extensionQuantum = dbDefaultExtensionQuantum;
00350 initIndexSize = dbDefaultInitIndexSize;
00351 nThreads = 1;
00352 }
00353 };
00354
00355
00361 bool open(OpenParameters& params);
00362
00363
00367 virtual void close();
00368
00372 void commit();
00373
00377 void executeBatch();
00378
00383 void precommit();
00384
00388 void rollback();
00389
00394 void attach();
00395
00401 void attach(dbDatabaseThreadContext* ctx);
00402
00403 enum DetachFlags {
00404 COMMIT = 1,
00405 DESTROY_CONTEXT = 2
00406 };
00411 void detach(int flags = COMMIT|DESTROY_CONTEXT);
00412
00417 void lock(dbLockType type = dbExclusiveLock) { beginTransaction(type); }
00418
00427 bool backup(char_t const* backupFileName, bool compactify);
00428
00438 bool backup(dbOSFile* file, bool compactify);
00439
00446 bool restore(char_t const* backupFileName, char_t const* databaseFileName);
00447
00451 int getVersion();
00452
00457 void assign(dbTableDescriptor& desc) {
00458 assert(((void)"Table is not yet assigned to the database",
00459 desc.tableId == 0));
00460 desc.db = this;
00461 desc.fixedDatabase = true;
00462 }
00463
00470 dbTableDescriptor* lookupTable(dbTableDescriptor* desc);
00471
00476 void getMemoryStatistic(dbMemoryStatistic& stat);
00477
00485 void setConcurrency(unsigned nThreads);
00486
00491 offs_t getAllocatedSize() { return allocatedSize; }
00492
00500 void allowColumnsDeletion(bool enabled = true) {
00501 confirmDeleteColumns = enabled;
00502 }
00503
00511 bool prepareQuery(dbAnyCursor* cursor, dbQuery& query);
00512
00516 enum dbErrorClass {
00517 NoError,
00518 QueryError,
00519 ArithmeticError,
00520 IndexOutOfRangeError,
00521 DatabaseOpenError,
00522 FileError,
00523 OutOfMemoryError,
00524 Deadlock,
00525 NullReferenceError,
00526 FileLimitExeeded,
00527 DatabaseReadOnly
00528 };
00529 typedef void (*dbErrorHandler)(int error, char const* msg, int msgarg, void* context);
00530
00537 dbErrorHandler setErrorHandler(dbErrorHandler newHandler, void* errorHandlerContext = NULL);
00538
00539
00546 virtual void scheduleBackup(char_t const* fileName, time_t periodSec);
00547
00548
00556 virtual void handleError(dbErrorClass error, char const* msg = NULL,
00557 int arg = 0);
00558
00559 dbAccessType accessType;
00560 size_t extensionQuantum;
00561 size_t initIndexSize;
00562
00563 static unsigned dbParallelScanThreshold;
00564
00573 void insertRecord(dbTableDescriptor* table, dbAnyReference* ref,
00574 void const* record, bool batch);
00579 offs_t used();
00580
00584 bool isOpen() const { return opened; }
00585
00592 offs_t getDatabaseSize() {
00593 return header->root[1-curr].size;
00594 }
00595
00602 void setFileExtensionQuantum(offs_t quantum) {
00603 dbFileExtensionQuantum = quantum;
00604 }
00605
00610 void setFileSizeLimit(offs_t limit) {
00611 dbFileSizeLimit = limit;
00612 }
00613
00625 void createCluster(offs_t size);
00626
00627
00628 #ifndef NO_MEMBER_TEMPLATES
00629
00634 template<class T>
00635 dbReference<T> insert(T const& record) {
00636 dbReference<T> ref;
00637 insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, false);
00638 return ref;
00639 }
00646 template<class T>
00647 dbReference<T> batchInsert(T const& record) {
00648 dbReference<T> ref;
00649 insertRecord(lookupTable(&T::dbDescriptor), &ref, &record, true);
00650 return ref;
00651 }
00652 #endif
00653
00666 dbDatabase(dbAccessType type = dbAllAccess,
00667 size_t poolSize = 0,
00668 size_t dbExtensionQuantum = dbDefaultExtensionQuantum,
00669 size_t dbInitIndexSize = dbDefaultInitIndexSize,
00670 int nThreads = 1
00671
00672
00673
00674
00675 #ifdef NO_PTHREADS
00676 , bool usePthreads = false
00677 #endif
00678 );
00679
00683 virtual ~dbDatabase();
00684
00685 protected:
00686 dbThreadContext<dbDatabaseThreadContext> threadContext;
00687
00688 dbThreadPool threadPool;
00689
00690 dbHeader* header;
00691 int4* dirtyPagesMap;
00692 unsigned parThreads;
00693 bool modified;
00694
00695 int curr;
00696
00697
00698 int transactionId;
00699
00700 bool uncommittedChanges;
00701
00702 offs_t dbFileExtensionQuantum;
00703 offs_t dbFileSizeLimit;
00704
00705
00706 volatile int commitInProgress;
00707 volatile int concurrentTransId;
00708
00709 oid_t currRBitmapPage;
00710 size_t currRBitmapOffs;
00711
00712 oid_t currPBitmapPage;
00713 size_t currPBitmapOffs;
00714
00715
00716 struct dbLocation {
00717 offs_t pos;
00718 offs_t size;
00719 dbLocation* next;
00720 };
00721 dbLocation* reservedChain;
00722
00723 oid_t committedIndexSize;
00724 oid_t currIndexSize;
00725
00726 oid_t updatedRecordId;
00727
00728 dbFile* file;
00729 dbMutex mutex;
00730 dbSemaphore writeSem;
00731 dbSemaphore readSem;
00732 dbSemaphore upgradeSem;
00733 dbEvent backupCompletedEvent;
00734 dbMonitor monitor;
00735 dbPagePool pool;
00736 dbTableDescriptor* tables;
00737
00738 int* bitmapPageAvailableSpace;
00739 bool opened;
00740
00741 offs_t allocatedSize;
00742
00743 int forceCommitCount;
00744 time_t commitDelay;
00745 time_t commitTimeout;
00746 time_t commitTimerStarted;
00747
00748 dbMutex commitThreadSyncMutex;
00749 dbMutex delayedCommitStartTimerMutex;
00750 dbMutex delayedCommitStopTimerMutex;
00751 dbEvent commitThreadSyncEvent;
00752
00753 dbEvent delayedCommitStartTimerEvent;
00754
00755 dbEvent delayedCommitStopTimerEvent;
00756 dbDatabaseThreadContext* delayedCommitContext;
00757
00758 dbMutex backupMutex;
00759 dbEvent backupInitEvent;
00760 char_t* backupFileName;
00761 time_t backupPeriod;
00762
00763 dbThread backupThread;
00764 dbThread commitThread;
00765
00766 dbTableDescriptor* batchList;
00767
00768 int accessCount;
00769
00770 dbL2List threadContextList;
00771 dbMutex threadContextListMutex;
00772
00773 dbErrorHandler errorHandler;
00774 void* errorHandlerContext;
00775
00776 bool confirmDeleteColumns;
00777 int schemeVersion;
00778 dbVisitedObject* visitedChain;
00779
00780 bool deleteFile;
00781
00787 dbTableDescriptor* loadMetaTable();
00788
00789 void releaseFile();
00790
00794 virtual void replicatePage(offs_t pageOffs, void* pageData);
00795
00799 void delayedCommit();
00800
00804 void backupScheduler();
00805
00806 static void thread_proc delayedCommitProc(void* arg) {
00807 ((dbDatabase*)arg)->delayedCommit();
00808 }
00809
00810 static void thread_proc backupSchedulerProc(void* arg) {
00811 ((dbDatabase*)arg)->backupScheduler();
00812 }
00813
00818 void commit(dbDatabaseThreadContext* ctx);
00819
00825 offs_t getPos(oid_t oid) {
00826 byte* p = pool.get(header->root[1-curr].index
00827 + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
00828 offs_t pos = *((offs_t*)p + oid % dbHandlesPerPage);
00829 pool.unfix(p);
00830 return pos;
00831 }
00832
00838 void setPos(oid_t oid, offs_t pos) {
00839 byte* p = pool.put(header->root[1-curr].index
00840 + (offs_t)(oid / dbHandlesPerPage) * dbPageSize);
00841 *((offs_t*)p + oid % dbHandlesPerPage) = pos;
00842 pool.unfix(p);
00843 }
00844
00851 dbRecord* getRow(dbGetTie& tie, oid_t oid) {
00852 offs_t pos = getPos(oid);
00853 assert(!(pos & (dbFreeHandleFlag|dbPageObjectFlag)));
00854 tie.set(pool, pos & ~dbFlagsMask);
00855 return (dbRecord*)tie.get();
00856 }
00857
00863 void getHeader(dbRecord& rec, oid_t oid) {
00864 offs_t pos = getPos(oid);
00865 int offs = (int)pos & (dbPageSize-1);
00866 byte* p = pool.get(pos - offs);
00867 rec = *(dbRecord*)(p + (offs & ~dbFlagsMask));
00868 pool.unfix(p);
00869 }
00870
00876 byte* put(oid_t oid) {
00877 offs_t pos = getPos(oid);
00878 int offs = (int)pos & (dbPageSize-1);
00879 return pool.put(pos-offs) + (offs & ~dbFlagsMask);
00880 }
00881
00887 byte* get(oid_t oid) {
00888 offs_t pos = getPos(oid);
00889 int offs = (int)pos & (dbPageSize-1);
00890 return pool.get(pos-offs) + (offs & ~dbFlagsMask);
00891 }
00892
00900 dbRecord* putRow(dbPutTie& tie, oid_t oid, size_t newSize);
00901
00908 dbRecord* putRow(dbPutTie& tie, oid_t oid);
00909
00916 byte* put(dbPutTie& tie, oid_t oid);
00917
00922 void restoreTablesConsistency();
00923
00929 void applyIndex(dbFieldDescriptor* field, dbSearchContext& sc);
00930
00947 bool isIndexApplicable(dbAnyCursor* cursor, dbExprNode* expr, dbQuery& query,
00948 dbFieldDescriptor* &indexedField, bool& truncate, bool ascent, bool forAll);
00949
00957 bool isIndexApplicableToExpr(dbSearchContext& sc, dbExprNode* expr);
00958
00962 bool followInverseReference(dbExprNode* expr, dbExprNode* andExpr,
00963 dbAnyCursor* cursor, oid_t iref);
00964
00972 bool existsInverseReference(dbExprNode* expr, int nExistsClauses);
00973
00980 static void _fastcall execute(dbExprNode* expr,
00981 dbInheritedAttribute& iattr,
00982 dbSynthesizedAttribute& sattr);
00991 bool evaluateBoolean(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbAnyCursor* cursor);
00992
01002 size_t evaluateString(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, char_t* buf, size_t bufSize);
01003
01011 void evaluate(dbExprNode* expr, oid_t oid, dbTableDescriptor* table, dbSynthesizedAttribute& result);
01012
01017 void select(dbAnyCursor* cursor);
01018
01024 void select(dbAnyCursor* cursor, dbQuery& query);
01025
01031 void traverse(dbAnyCursor* cursor, dbQuery& query);
01032
01039 void update(oid_t oid, dbTableDescriptor* table, void const* record);
01040
01046 void remove(dbTableDescriptor* table, oid_t oid);
01047
01055 offs_t allocate(offs_t size, oid_t oid = 0);
01056
01062 void free(offs_t pos, offs_t size);
01063
01068 void extend(offs_t size);
01069
01076 void cloneBitmap(offs_t pos, offs_t size);
01077
01082 oid_t allocateId();
01083
01088 void freeId(oid_t oid);
01089
01096 void updateCursors(oid_t oid, bool removed = false);
01097
01102 oid_t allocatePage() {
01103 oid_t oid = allocateId();
01104 setPos(oid, allocate(dbPageSize) | dbPageObjectFlag | dbModifiedFlag);
01105 return oid;
01106 }
01107
01112 void freePage(oid_t oid);
01113
01121 oid_t allocateRow(oid_t tableId, size_t size,
01122 dbTableDescriptor* desc = NULL)
01123 {
01124 oid_t oid = allocateId();
01125 allocateRow(tableId, oid, size, desc);
01126 return oid;
01127 }
01128
01137 void allocateRow(oid_t tableId, oid_t oid, size_t size, dbTableDescriptor* desc);
01138
01145 void freeRow(oid_t tableId, oid_t oid, dbTableDescriptor* desc = NULL);
01146
01151 static void deleteCompiledQuery(dbExprNode* tree);
01152
01157 void beginTransaction(dbLockType type);
01162 void endTransaction(dbDatabaseThreadContext* ctx);
01163
01167 void initializeMetaTable();
01168
01175 bool loadScheme();
01176
01182 bool completeDescriptorsInitialization();
01183
01189 void reformatTable(oid_t tableId, dbTableDescriptor* desc);
01190
01196 void addIndices(dbTableDescriptor* desc);
01197
01203 oid_t addNewTable(dbTableDescriptor* desc);
01204
01211 void updateTableDescriptor(dbTableDescriptor* desc,
01212 oid_t tableId, dbTable* table);
01213
01214
01220 void removeInverseReferences(dbTableDescriptor* desc, oid_t oid);
01221
01222
01231 void insertInverseReference(dbFieldDescriptor* desc, oid_t reverseId,
01232 oid_t targetId);
01233
01242 void removeInverseReference(dbFieldDescriptor* desc,
01243 oid_t reverseId, oid_t targetId);
01244
01245
01250 void deleteTable(dbTableDescriptor* desc);
01251
01256 void dropTable(dbTableDescriptor* desc);
01257
01262 void createIndex(dbFieldDescriptor* fd);
01263
01268 void createHashTable(dbFieldDescriptor* fd);
01269
01274 void dropIndex(dbFieldDescriptor* fd);
01275
01280 void dropHashTable(dbFieldDescriptor* fd);
01281
01287 void linkTable(dbTableDescriptor* table, oid_t tableId);
01288
01293 void unlinkTable(dbTableDescriptor* table);
01294
01295
01302 bool wasReserved(offs_t pos, offs_t size);
01303
01312 void reserveLocation(dbLocation& location, offs_t pos, offs_t size);
01313
01318 void commitLocation();
01319
01325 dbTableDescriptor* findTable(char_t const* name);
01326
01333 dbTableDescriptor* findTableByName(char_t const* name);
01334
01335
01340 dbTableDescriptor* getTables() {
01341 return tables;
01342 }
01343
01344
01349 void cleanupOnOpenError();
01350
01354 void setDirty();
01355
01359 void refreshTable(dbTableDescriptor* desc);
01360 };
01361
01362 template<class T>
01363 dbReference<T> insert(T const& record) {
01364 dbReference<T> ref;
01365 T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, false);
01366 return ref;
01367 }
01368
01369 template<class T>
01370 dbReference<T> batchInsert(T const& record) {
01371 dbReference<T> ref;
01372 T::dbDescriptor.getDatabase()->insertRecord(&T::dbDescriptor, &ref, &record, true);
01373 return ref;
01374 }
01375
01376 #ifdef NO_MEMBER_TEMPLATES
01377 template<class T>
01378 dbReference<T> insert(dbDatabase& db, T const& record) {
01379 dbReference<T> ref;
01380 db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, false);
01381 return ref;
01382 }
01383 template<class T>
01384 dbReference<T> batchInsert(dbDatabase& db, T const& record) {
01385 dbReference<T> ref;
01386 db.insertRecord(db.lookupTable(&T::dbDescriptor), &ref, &record, true);
01387 return ref;
01388 }
01389 #endif
01390
01391 class dbSearchContext {
01392 public:
01393 dbDatabase* db;
01394 dbExprNode* condition;
01395 dbAnyCursor* cursor;
01396 char_t* firstKey;
01397 int firstKeyInclusion;
01398 char_t* lastKey;
01399 int lastKeyInclusion;
01400 int prefixLength;
01401 int offs;
01402 int probes;
01403 bool ascent;
01404 bool tmpKeys;
01405 bool spatialSearch;
01406 bool arraySearch;
01407
01408 void operator = (dbSearchContext const& sc);
01409
01410 union {
01411 bool b;
01412 int1 i1;
01413 int2 i2;
01414 int4 i4;
01415 db_int8 i8;
01416 real4 f4;
01417 real8 f8;
01418 oid_t oid;
01419 void* raw;
01420 rectangle* rect;
01421 char_t* s;
01422 dbAnyArray* a;
01423 } literal[2];
01424 };
01425
01426 END_GIGABASE_NAMESPACE
01427
01428 #endif
01429