1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // CegoTableManager.cc
4 // -------------------
5 // Cego table manager class implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2019 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: CegoTableManager
14 //
15 // Description: The table manager provides are required methods for local tableset operations
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20 
21 // base includes
22 #include <lfcbase/Sleeper.h>
23 #include <lfcbase/Exception.h>
24 #include <lfcbase/Timer.h>
25 #include <lfcbase/SetT.h>
26 #include <lfcbase/Datetime.h>
27 
28 // cego includes
29 #include "CegoDefs.h"
30 #include "CegoTableManager.h"
31 #include "CegoTransactionManager.h"
32 #include "CegoBufferPage.h"
33 #include "CegoObject.h"
34 #include "CegoAVLIndexManager.h"
35 #include "CegoAVLIndexEntry.h"
36 #include "CegoAVLIndexCursor.h"
37 #include "CegoBTreeCursor.h"
38 #include "CegoBTreeManager.h"
39 #include "CegoTableCursor.h"
40 #include "CegoAttrCond.h"
41 #include "CegoXMLdef.h"
42 #include "CegoTypeConverter.h"
43 #include "CegoCheckObject.h"
44 #include "CegoSelect.h"
45 #include "CegoDbThreadPool.h"
46 
47 #include <string.h>
48 #include <stdlib.h>
49 
CegoTableManager(CegoDatabaseManager * pDBMng)50 CegoTableManager::CegoTableManager(CegoDatabaseManager *pDBMng) : CegoSystemObject(pDBMng)
51 {
52     _pTM = new CegoTransactionManager(this);
53     for ( int i=0;i<TABMNG_MAXTABSET; i++)
54     {
55 	_tid[i]=0;
56 	_tastep[i]=0;
57     }
58 
59     _encBufLen=0;
60     _pEncBuf=0;
61 
62     _isAborted = false;
63     _autoCommit = true;
64     _doAppend = true;
65     _isolationLevel = CegoTableManager::READ_COMMITTED;
66     _modId = pDBMng->getModId("CegoTableManager");
67     _pPool = 0;
68 }
69 
~CegoTableManager()70 CegoTableManager::~CegoTableManager()
71 {
72     if ( _pEncBuf )
73     {
74 	free ( _pEncBuf);
75     }
76     delete _pTM;
77 }
78 
setThreadId(unsigned long long tid)79 void CegoTableManager::setThreadId(unsigned long long tid)
80 {
81     _threadId = tid;
82 }
83 
getThreadId() const84 unsigned long long CegoTableManager::getThreadId() const
85 {
86     return _threadId;
87 }
88 
setPoolSyncInfo(CegoDbThreadPool * pPool,int thrIdx)89 void CegoTableManager::setPoolSyncInfo(CegoDbThreadPool *pPool, int thrIdx)
90 {
91     _pPool = pPool;
92     _thrIdx = thrIdx;
93 }
94 
setAppend(bool doAppend)95 void CegoTableManager::setAppend(bool doAppend)
96 {
97     _doAppend = doAppend;
98 }
99 
createBasicTableSet(const Chain & tableSet)100 void CegoTableManager::createBasicTableSet(const Chain& tableSet)
101 {
102     _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating basic tableset files ..."));
103 
104     int tabSetId =_pDBMng->getTabSetId(tableSet);
105     int sysSize = _pDBMng->getSysSize(tableSet);
106     int tmpFileId = _pDBMng->getTmpFid(tableSet);
107     int tmpSize = _pDBMng->getTmpSize(tableSet);
108     Chain dbSysFileName = _pDBMng->getSysFileName(tableSet);
109 
110     if ( sysSize < TABMNG_HASHSIZE )
111     {
112 	Chain msg = Chain("System space must be at least ") + Chain(TABMNG_HASHSIZE) + Chain(" pages ");
113 	throw Exception(EXLOC, msg);
114     }
115 
116     if ( tmpSize < TABMNG_HASHSIZE )
117     {
118 	Chain msg = Chain("Tmp space must be at least ") + Chain(TABMNG_HASHSIZE) + Chain(" pages ");
119 	throw Exception(EXLOC, msg);
120     }
121 
122     _pDBMng->log(_modId, Logger::NOTICE, Chain("Initializing sysfile ") + dbSysFileName + Chain(" ..."));
123 
124     PageIdType pageOffset;
125 
126     pageOffset = _pDBMng->getNextPageOffset(sysSize);
127     _pDBMng->initDataFile(tabSetId, dbSysFileName, tabSetId,  sysSize, pageOffset, CegoFileHandler::SYSTEMFILE);
128 
129     _pDBMng->setSysPageOffset(tabSetId, pageOffset);
130 
131     _pDBMng->log(_modId, Logger::NOTICE, Chain("Registrating sysfile ") + dbSysFileName + Chain(" ..."));
132     _pDBMng->regDataFile(tabSetId, dbSysFileName, tabSetId, _pLockHandle);
133 
134     for ( PageIdType i = 0 ; i < TABMNG_HASHSIZE ; i++ )
135     {
136 	_pDBMng->claimPage(pageOffset + i, _pLockHandle);
137     }
138 
139     Chain dbTempFileName = _pDBMng->getTmpFileName(tableSet);
140 
141     _pDBMng->log(_modId, Logger::NOTICE, Chain("Initializing tempfile ") + dbTempFileName + Chain(" ..."));
142     pageOffset = _pDBMng->getNextPageOffset(tmpSize);
143     _pDBMng->initDataFile(tabSetId, dbTempFileName, tmpFileId, tmpSize, pageOffset, CegoFileHandler::TEMP);
144 
145     _pDBMng->setTempPageOffset(tabSetId, pageOffset);
146 
147     _pDBMng->log(_modId, Logger::NOTICE, Chain("Registrating tempfile ") + dbTempFileName + Chain(" ..."));
148     _pDBMng->regDataFile(tabSetId, dbTempFileName, tmpFileId, _pLockHandle);
149 
150     for ( PageIdType i = 0 ; i < TABMNG_HASHSIZE ; i++ )
151     {
152 	_pDBMng->claimPage(pageOffset + i, _pLockHandle);
153     }
154 
155     _pDBMng->initLogFiles(tableSet, false);
156     _pDBMng->setCommittedLSN(tableSet, 0);
157 
158     ListT<Chain> dfList;
159     ListT<int> fidList;
160     ListT<int> sizeList;
161 
162     _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, sizeList);
163 
164     Chain *pFileName = dfList.First();
165     int *pFid = fidList.First();
166     int *pSize = sizeList.First();
167 
168     while ( pFileName && pFid && pSize )
169     {
170 	_pDBMng->log(_modId, Logger::NOTICE, Chain("Init datafile ") + *pFileName + Chain(" ..."));
171 
172 	pageOffset = _pDBMng->getNextPageOffset(*pSize);
173 	_pDBMng->initDataFile(tabSetId, *pFileName, *pFid, *pSize, pageOffset, CegoFileHandler::DATAFILE);
174 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
175 
176 	pFileName = dfList.Next();
177 	pFid = fidList.Next();
178 	pSize = sizeList.Next();
179     }
180 
181     dfList.Empty();
182     fidList.Empty();
183     sizeList.Empty();
184 
185     _pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, sizeList);
186 
187     pFileName = dfList.First();
188     pFid = fidList.First();
189     pSize = sizeList.First();
190 
191     while ( pFileName && pFid && pSize )
192     {
193 
194 	_pDBMng->log(_modId, Logger::NOTICE, Chain("Init sysfile ") + *pFileName + Chain(" ..."));
195 
196 	pageOffset = _pDBMng->getNextPageOffset(*pSize);
197 	_pDBMng->initDataFile(tabSetId, *pFileName, *pFid, *pSize, pageOffset, CegoFileHandler::SYSTEMFILE);
198 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
199 
200 	pFileName = dfList.Next();
201 	pFid = fidList.Next();
202 	pSize = sizeList.Next();
203 
204     }
205 
206     dfList.Empty();
207     fidList.Empty();
208     sizeList.Empty();
209 
210     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
211 
212     pFileName = dfList.First();
213     pFid = fidList.First();
214     pSize = sizeList.First();
215 
216     while ( pFileName && pFid && pSize )
217     {
218 	_pDBMng->log(_modId, Logger::NOTICE, Chain("Init tempfile ") + *pFileName + Chain(" ..."));
219 
220 	pageOffset = _pDBMng->getNextPageOffset(*pSize);
221 	_pDBMng->initDataFile(tabSetId, *pFileName, *pFid, *pSize, pageOffset, CegoFileHandler::TEMP);
222 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
223 
224 	pFileName = dfList.Next();
225 	pFid = fidList.Next();
226 	pSize = sizeList.Next();
227     }
228 
229     _pDBMng->setTableSetRunState(tableSet, XML_OFFLINE_VALUE);
230 
231     _pDBMng->doc2Xml();
232 
233     _pDBMng->log(_modId, Logger::NOTICE, Chain("Tableset ") + tableSet + Chain(" created succesful"));
234 }
235 
dropTableSet(const Chain & tableSet)236 void CegoTableManager::dropTableSet(const Chain& tableSet)
237 {
238     Chain status = _pDBMng->getTableSetRunState(tableSet);
239 
240     if ( status == Chain(XML_OFFLINE_VALUE) || status == Chain(XML_CHECKPOINT_VALUE)  )
241     {
242 	Chain dbSysFileName = _pDBMng->getSysFileName(tableSet);
243 	Chain dbTempFileName = _pDBMng->getTmpFileName(tableSet);
244 
245 	int tabSetId = _pDBMng->getTabSetId(tableSet);
246 	_pDBMng->writeAndRemoveTabSet(tabSetId, _pLockHandle);
247 
248 	File dbSysFile(dbSysFileName);
249 
250 	try
251 	{
252 	    dbSysFile.remove();
253 	}
254 	catch ( Exception e )
255 	{
256 	    _pDBMng->log(_modId, Logger::NOTICE, Chain("System file ") + dbSysFileName + Chain(" does not exist ( Ignored )"));
257 	}
258 
259 	File dbTempFile(dbTempFileName);
260 
261 	try
262 	{
263 	    dbTempFile.remove();
264 	}
265 	catch ( Exception e )
266 	{
267 	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Temp file ") + dbTempFileName + Chain(" does not exist ( Ignored )"));
268 	}
269 
270 	ListT<Chain> lfList;
271 	ListT<int> lfsizeList;
272 	ListT<Chain> statusList;
273 
274 	_pDBMng->getLogFileInfo(tableSet, lfList, lfsizeList, statusList);
275 
276 	Chain *pLog = lfList.First();
277 
278 	while ( pLog )
279 	{
280 	    File logFile(*pLog);
281 	    try
282 	    {
283 		logFile.remove();
284 	    }
285 	    catch ( Exception e )
286 	    {
287 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Log file ") + *pLog + Chain(" does not exist ( Ignored )"));
288 	    }
289 
290 	    pLog = lfList.Next();
291 	}
292 
293 	ListT<Chain> dfList;
294 	ListT<int> fidList;
295 	ListT<int> dfsizeList;
296 
297 	_pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, dfsizeList);
298 
299 	Chain *pFileName = dfList.First();
300 
301 	while ( pFileName )
302 	{
303 	    File dataFile(*pFileName);
304 
305 	    try
306 	    {
307 		dataFile.remove();
308 	    }
309 	    catch ( Exception e )
310 	    {
311 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Data file ") + *pFileName + Chain(" does not exist ( Ignored )"));
312 	    }
313 
314 	    pFileName = dfList.Next();
315 	}
316 
317 	dfList.Empty();
318 	fidList.Empty();
319 	dfsizeList.Empty();
320 
321 	_pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, dfsizeList);
322 
323 	pFileName = dfList.First();
324 
325 	while ( pFileName )
326 	{
327 	    File dataFile(*pFileName);
328 
329 	    try
330 	    {
331 		dataFile.remove();
332 	    }
333 	    catch ( Exception e )
334 	    {
335 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Temp file ") + *pFileName + Chain(" does not exist ( Ignored )"));
336 	    }
337 
338 	    pFileName = dfList.Next();
339 	}
340 
341 	dfList.Empty();
342 	fidList.Empty();
343 	dfsizeList.Empty();
344 
345 	_pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, dfsizeList);
346 
347 	pFileName = dfList.First();
348 
349 	while ( pFileName )
350 	{
351 	    File dataFile(*pFileName);
352 
353 	    try
354 	    {
355 		dataFile.remove();
356 	    }
357 	    catch ( Exception e )
358 	    {
359 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Sys file ") + *pFileName + Chain(" does not exist ( Ignored )"));
360 	    }
361 
362 	    pFileName = dfList.Next();
363 	}
364 
365 	// dropping counters
366 	ListT<Chain> counterList;
367 	_pDBMng->getCounterList(tabSetId, counterList);
368 	Chain* pCounter = counterList.First();
369 	while ( pCounter )
370 	{
371 	    _pDBMng->removeCounter(tabSetId, *pCounter);
372 	    pCounter = counterList.Next();
373 	}
374 
375 	_pDBMng->setCurrentLSN(tabSetId, 0);
376 	_pDBMng->setTableSetRunState(tableSet,XML_DEFINED_VALUE);
377 	_pDBMng->doc2Xml();
378 
379 	_pDBMng->log(_modId, Logger::NOTICE, Chain("Tableset ") + tableSet + Chain(" dropped"));
380     }
381     else
382     {
383 	throw Exception(EXLOC, Chain("Tableset must be in status offline to drop"));
384     }
385 }
386 
reorgTableSet(const Chain & tableSet)387 void CegoTableManager::reorgTableSet(const Chain& tableSet)
388 {
389     int tabSetId = _pDBMng->getTabSetId(tableSet);
390     _pTM->reorgSystemSpace(tabSetId);
391 }
392 
stopTableSet(const Chain & tableSet,bool archComplete)393 void CegoTableManager::stopTableSet(const Chain& tableSet, bool archComplete)
394 {
395     _pDBMng->log(_modId, Logger::NOTICE, Chain("Stopping tableset ") + tableSet + Chain(" ..."));
396 
397     int tabSetId = _pDBMng->getTabSetId(tableSet);
398 
399     if ( _pDBMng->hasLogConnection(tabSetId) )
400     {
401 	_pDBMng->releaseLogConnection(tabSetId);
402     }
403     else
404     {
405 	unsigned long long lsn = _pDBMng->getCurrentLSN(tabSetId);
406 	_pDBMng->setCommittedLSN(tabSetId, lsn);
407 	_pDBMng->writeCheckPoint(tableSet, true, archComplete, _pLockHandle);
408     }
409 
410     _pTM->release(tabSetId);
411 
412     _pDBMng->writeAndRemoveTabSet(tabSetId, _pLockHandle);
413 
414     _pDBMng->stopLog(tabSetId);
415 
416     _pDBMng->setTableSetRunState(tableSet, XML_OFFLINE_VALUE);
417 
418     _pDBMng->doc2Xml();
419 
420     _pDBMng->log(_modId, Logger::NOTICE, Chain("Tableset ") + tableSet + Chain(" stopped"));
421 }
422 
resetTableSet(const Chain & tableSet)423 void CegoTableManager::resetTableSet(const Chain& tableSet)
424 {
425     _pDBMng->log(_modId, Logger::NOTICE, Chain("Resetting tableset ") + tableSet + Chain(" ..."));
426 
427     int tabSetId = _pDBMng->getTabSetId(tableSet);
428 
429     if ( _pDBMng->hasLogConnection(tabSetId) )
430     {
431 	_pDBMng->releaseLogConnection(tabSetId);
432     }
433     else
434     {
435 	unsigned long long lsn = _pDBMng->getCurrentLSN(tabSetId);
436 	_pDBMng->setCommittedLSN(tabSetId, lsn);
437 	_pDBMng->writeCheckPoint(tableSet, false, false, _pLockHandle);
438     }
439 
440     _pTM->release(tabSetId);
441 
442     if ( _pDBMng->getTableSetRunState(tableSet) == Chain(XML_BACKUP_VALUE) )
443     {
444 	endBackup(tableSet, Chain("Tableset reset"), false);
445     }
446 
447     if ( _pDBMng->getTableSetRunState(tableSet) == Chain(XML_ONLINE_VALUE) )
448     {
449 	_pDBMng->writeAndRemoveTabSet(tabSetId, _pLockHandle);
450     }
451 
452     Chain primary = _pDBMng->getPrimary(tableSet);
453     _pDBMng->setSecondary(tableSet, primary);
454 
455     _pDBMng->setTableSetRunState(tableSet, XML_OFFLINE_VALUE);
456     _pDBMng->setTableSetSyncState(tableSet, XML_SYNCHED_VALUE);
457 
458     _pDBMng->log(_modId, Logger::NOTICE, Chain("Tableset ") + tableSet + Chain(" reset"));
459 }
460 
beginBackup(const Chain & tableSet,const Chain & msg)461 void CegoTableManager::beginBackup(const Chain& tableSet, const Chain& msg)
462 {
463     if ( _pDBMng->getTableSetRunState(tableSet) != Chain(XML_ONLINE_VALUE) )
464     {
465 	Chain msg = Chain("Tableset ") + tableSet + Chain(" must be in runstate ONLINE to begin backup mode");
466 	throw Exception(EXLOC, msg);
467     }
468 
469     if ( _pDBMng->isArchiveMode(tableSet) == false )
470     {
471 	Chain msg = Chain("Archive not enabled for tableset ") + tableSet;
472 	throw Exception(EXLOC, msg);
473     }
474 
475     _pDBMng->log(_modId, Logger::NOTICE, Chain("Begin backup for tableset ") + tableSet);
476 
477     _pDBMng->writeCheckPoint(tableSet, true, false, _pLockHandle);
478 
479     Chain tsTicketName = _pDBMng->getTSTicket(tableSet);
480 
481     File tsTicket(tsTicketName);
482     if ( tsTicket.exists())
483 	throw Exception(EXLOC, Chain("Backup tableset ticket exists"));
484 
485     XMLSuite xml;
486     Chain tsTicketData;
487 
488     Document *pDoc = new Document;
489 
490     try
491     {
492 	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
493 	pDoc->setDocType(XML_TSTICKET_DOC);
494 
495 	xml.setDocument(pDoc);
496 
497 	Element *pRoot = _pDBMng->getTableSetInfo(tableSet);
498 	pDoc->setRootElement(pRoot);
499 
500 	xml.getXMLChain( tsTicketData );
501 
502 	delete pDoc;
503     }
504     catch ( Exception e )
505     {
506 	delete pDoc;
507 	Chain msg;
508 	e.pop(msg);
509 	throw Exception(EXLOC, Chain("Cannot write ticket data") + msg);
510     }
511 
512     tsTicket.open(File::WRITE);
513     tsTicket.writeChain(tsTicketData);
514     tsTicket.close();
515 
516     _pDBMng->setTableSetRunState(tableSet, XML_BACKUP_VALUE);
517 
518     int tabSetId =_pDBMng->getTabSetId(tableSet);
519     _pDBMng->setBackup(tabSetId, true);
520     int tmpFileId = _pDBMng->getTmpFid(tableSet);
521     _pDBMng->setBackup(tmpFileId, true);
522 
523     ListT<Chain> dfList;
524     ListT<int> fidList;
525     ListT<int> sizeList;
526 
527     _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, sizeList);
528 
529     int *pFid = fidList.First();
530 
531     while ( pFid )
532     {
533 	_pDBMng->setBackup(*pFid, true);
534 	pFid = fidList.Next();
535     }
536 
537     dfList.Empty();
538     fidList.Empty();
539     sizeList.Empty();
540 
541     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
542 
543     pFid = fidList.First();
544 
545     while ( pFid )
546     {
547 	_pDBMng->setBackup(*pFid, true);
548 	pFid = fidList.Next();
549     }
550 
551     addBUStat(tabSetId, Chain("BEGIN BACKUP"), msg);
552 }
553 
endBackup(const Chain & tableSet,const Chain & msg,bool keepTicket)554 void CegoTableManager::endBackup(const Chain& tableSet, const Chain& msg, bool keepTicket)
555 {
556     if ( _pDBMng->getTableSetRunState(tableSet) != Chain(XML_BACKUP_VALUE) )
557     {
558 	Chain msg = Chain("Tableset ") + tableSet + Chain(" must be in runstate BACKUP to end backup mode");
559 	throw Exception(EXLOC, msg);
560     }
561 
562     if ( _pDBMng->isArchiveMode(tableSet) == false )
563     {
564 	Chain msg = Chain("Archive not enabled for tableset ") + tableSet;
565 	throw Exception(EXLOC, msg);
566     }
567 
568     _pDBMng->log(_modId, Logger::NOTICE, Chain("End backup for tableset ") + tableSet);
569 
570     int tabSetId =_pDBMng->getTabSetId(tableSet);
571     _pDBMng->setBackup(tabSetId, false);
572     int tmpFileId = _pDBMng->getTmpFid(tableSet);
573     _pDBMng->setBackup(tmpFileId, false);
574 
575     ListT<Chain> dfList;
576     ListT<int> fidList;
577     ListT<int> sizeList;
578 
579     _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, sizeList);
580 
581     int *pFid = fidList.First();
582 
583     while ( pFid )
584     {
585 	_pDBMng->setBackup(*pFid, false);
586 	pFid = fidList.Next();
587     }
588 
589     dfList.Empty();
590     fidList.Empty();
591     sizeList.Empty();
592 
593     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
594 
595     pFid = fidList.First();
596 
597     while ( pFid )
598     {
599 	_pDBMng->setBackup(*pFid, false);
600 	pFid = fidList.Next();
601     }
602 
603     CegoLogRecord logRec;
604     CegoLogRecord lr;
605     lr.setAction(CegoLogRecord::LOGREC_BUFIN);
606     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
607 
608     _pDBMng->writeCheckPoint(tableSet, true, false, _pLockHandle);
609 
610     if ( keepTicket == false)
611     {
612 	Chain tsTicketName = _pDBMng->getTSTicket(tableSet);
613 	File tsTicket(tsTicketName);
614 	tsTicket.remove();
615     }
616     _pDBMng->setTableSetRunState(tableSet, XML_ONLINE_VALUE);
617 
618     addBUStat(tabSetId, Chain("END BACKUP"), msg);
619 }
620 
resetBUStat(const Chain & tableSet)621 void CegoTableManager::resetBUStat(const Chain& tableSet)
622 {
623     int tabSetId =_pDBMng->getTabSetId(tableSet);
624     truncateObject(tabSetId, Chain(SYSTAB_BUSTAT_ID), CegoObject::SYSTEM);
625 }
626 
syncTableSet(const Chain & tableSet,const Chain & msg,const Chain & escCmd,int timeout)627 void CegoTableManager::syncTableSet(const Chain& tableSet, const Chain& msg, const Chain& escCmd, int timeout)
628 {
629     if ( _pDBMng->getTableSetRunState(tableSet) != Chain(XML_ONLINE_VALUE) )
630     {
631 	Chain msg = Chain("Tableset ") + tableSet + Chain(" must be in runstate ONLINE to perform sync");
632 	throw Exception(EXLOC, msg);
633     }
634 
635     _pDBMng->writeCheckPoint(tableSet, true, true, _pLockHandle, escCmd, timeout);
636     int tabSetId =_pDBMng->getTabSetId(tableSet);
637     addBUStat(tabSetId, Chain("EXTERNAL SYNC"), msg);
638 }
639 
logTo(const Chain & tableSet,const Chain & secondary)640 void CegoTableManager::logTo(const Chain& tableSet, const Chain& secondary)
641 {
642     Chain dbHost;
643     _pDBMng->getDBHost(dbHost);
644 
645     int tabSetId = _pDBMng->getTabSetId(tableSet);
646 
647     _pDBMng->releaseLogConnection(tabSetId);
648 
649     if ( secondary != dbHost )
650     {
651 	int logPort;
652 	_pDBMng->getLogPort(logPort);
653 
654 	Chain logUser = _pDBMng->getTSLogUser(tableSet);
655 	Chain logPwd = _pDBMng->getUserPwd(logUser);
656 
657 	_pDBMng->allocateLogConnection(tabSetId, tableSet, secondary, logPort, logUser, logPwd);
658     }
659     else
660     {
661 	_pDBMng->setActiveLogFile(tableSet);
662     }
663 
664     unsigned long long cplsn = _pDBMng->getCommittedLSN(tableSet);
665 
666     _pDBMng->setCurrentLSN(tabSetId, cplsn);
667     _pDBMng->startLog(tabSetId);
668 }
669 
addDataFile(const Chain & tableSet,const Chain & type,int fileId,const Chain & dataFile,int fileSize)670 void CegoTableManager::addDataFile(const Chain& tableSet, const Chain& type, int fileId, const Chain& dataFile, int fileSize)
671 {
672     int tabSetId = _pDBMng->getTabSetId(tableSet);
673 
674     _pDBMng->log(_modId, Logger::NOTICE, Chain("Initializing datafile ") + dataFile + Chain(" ..."));
675 
676     PageIdType pageOffset;
677     pageOffset = _pDBMng->getNextPageOffset(fileSize);
678 
679     if ( type == Chain(XML_APPFILE_VALUE) )
680     {
681 	_pDBMng->initDataFile(tabSetId, dataFile, fileId, fileSize, pageOffset, CegoFileHandler::DATAFILE);
682     }
683     else if ( type == Chain(XML_TEMPFILE_VALUE) )
684     {
685 	_pDBMng->initDataFile(tabSetId, dataFile, fileId, fileSize, pageOffset, CegoFileHandler::TEMP);
686     }
687     else if ( type == Chain(XML_SYSFILE_VALUE) )
688     {
689 	_pDBMng->initDataFile(tabSetId, dataFile, fileId, fileSize, pageOffset, CegoFileHandler::SYSTEMFILE);
690     }
691 
692     _pDBMng->regDataFile(tabSetId, dataFile, fileId, _pLockHandle);
693 }
694 
setIsolationLevel(IsolationLevel level)695 void CegoTableManager::setIsolationLevel(IsolationLevel level)
696 {
697     _isolationLevel = level;
698 }
699 
getIsolationLevel() const700 CegoTableManager::IsolationLevel CegoTableManager::getIsolationLevel() const
701 {
702     return _isolationLevel;
703 }
704 
setAutoCommit(bool autoCommit)705 void CegoTableManager::setAutoCommit(bool autoCommit)
706 {
707     _autoCommit = autoCommit;
708 }
709 
getAutoCommit() const710 bool CegoTableManager::getAutoCommit() const
711 {
712     return _autoCommit;
713 }
714 
lockTable(int tabSetId,const Chain & tableName)715 void CegoTableManager::lockTable(int tabSetId, const Chain& tableName)
716 {
717     _pDBMng->useObject(tabSetId, tableName, CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
718 }
719 
unlockTable(int tabSetId,const Chain & tableName)720 void CegoTableManager::unlockTable(int tabSetId, const Chain& tableName)
721 {
722     _pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE, _threadId);
723 }
724 
beginTransaction(int tabSetId,bool doLog)725 void CegoTableManager::beginTransaction(int tabSetId, bool doLog)
726 {
727     if (_tid[tabSetId] == 0)
728     {
729 	_tid[tabSetId]=_pDBMng->nextTID(tabSetId);
730 	_tastep[tabSetId]=0;
731 
732 	if ( doLog )
733 	{
734 	    // create log entry
735 	    CegoLogRecord lr;
736 	    lr.setAction(CegoLogRecord::LOGREC_BEGIN);
737 	    lr.setTID(_tid[tabSetId]);
738 	    _pDBMng->logIt(tabSetId, lr, _pLockHandle);
739 	}
740     }
741     else
742     {
743 	Chain msg = Chain("Already active transaction on tableset ") + Chain(tabSetId);
744 	throw Exception(EXLOC, msg);
745     }
746 }
747 
getTransactionAffectedTables(int tabSetId,SetT<Chain> & tableList)748 void CegoTableManager::getTransactionAffectedTables(int tabSetId, SetT<Chain>& tableList)
749 {
750     unsigned long long ctid = _tid[tabSetId];
751     if ( ctid > 0 )
752 	_pTM->getTransactionAffectedTables(tabSetId, ctid, tableList);
753 }
754 
commitTransactionSynced(int tabSetId)755 unsigned long long CegoTableManager::commitTransactionSynced(int tabSetId)
756 {
757     unsigned long long numCommitOp=0;
758 
759     SetT<Chain> tableList;
760 
761     getTransactionAffectedTables(tabSetId, tableList);
762 
763     Chain *pTable;
764 
765     pTable = tableList.First();
766     while ( pTable )
767     {
768 	_pDBMng->useObject(tabSetId, *pTable, CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
769 	pTable = tableList.Next();
770     }
771 
772     try
773     {
774 	numCommitOp = commitTransaction(tabSetId, true);
775     }
776     catch ( Exception e )
777     {
778 	pTable = tableList.First();
779 	while ( pTable )
780 	{
781 	    _pDBMng->unuseObject(tabSetId, *pTable, CegoObject::TABLE);
782 	    pTable = tableList.Next();
783 	}
784     }
785     pTable = tableList.First();
786     while ( pTable )
787     {
788 	_pDBMng->unuseObject(tabSetId, *pTable, CegoObject::TABLE);
789 	pTable = tableList.Next();
790     }
791 
792     return numCommitOp;
793 }
794 
commitTransaction(int tabSetId,bool doLog)795 unsigned long long CegoTableManager::commitTransaction(int tabSetId, bool doLog)
796 {
797     if (_tid[tabSetId] != 0)
798     {
799 	unsigned long long ctid = _tid[tabSetId];
800 	_tid[tabSetId] = 0;
801 	_tastep[tabSetId] = 0;
802 
803 	unsigned long long n = _pTM->commitTransaction(tabSetId, ctid);
804 
805 	if ( doLog )
806 	{
807 	    // create log entry
808 	    CegoLogRecord lr;
809 	    lr.setAction(CegoLogRecord::LOGREC_COMMIT);
810 	    lr.setTID(ctid);
811 	    _pDBMng->logIt(tabSetId, lr, _pLockHandle);
812 	}
813 
814 	return n;
815     }
816     else
817     {
818 	// nothing to do
819 	return 0;
820     }
821 }
822 
rollbackTransactionSynced(int tabSetId)823 unsigned long long CegoTableManager::rollbackTransactionSynced(int tabSetId)
824 {
825     unsigned long long numRollbackOp=0;
826 
827     SetT<Chain> tableList;
828     getTransactionAffectedTables(tabSetId, tableList);
829 
830     Chain *pTable;
831 
832     pTable = tableList.First();
833     while ( pTable )
834     {
835 	_pDBMng->useObject(tabSetId, *pTable, CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
836 	pTable = tableList.Next();
837     }
838 
839     try
840     {
841 	numRollbackOp = rollbackTransaction(tabSetId, true);
842     }
843     catch ( Exception e )
844     {
845 	pTable = tableList.First();
846 	while ( pTable )
847 	{
848 	    _pDBMng->unuseObject(tabSetId, *pTable, CegoObject::TABLE);
849 	    pTable = tableList.Next();
850 	}
851     }
852     pTable = tableList.First();
853     while ( pTable )
854     {
855 	_pDBMng->unuseObject(tabSetId, *pTable, CegoObject::TABLE);
856 	pTable = tableList.Next();
857     }
858 
859     return numRollbackOp;
860 }
861 
rollbackTransaction(int tabSetId,bool doLog)862 unsigned long long CegoTableManager::rollbackTransaction(int tabSetId, bool doLog)
863 {
864     if (_tid[tabSetId] != 0)
865     {
866 	unsigned long long ctid = _tid[tabSetId];
867 	_tid[tabSetId] = 0;
868 
869 	unsigned long long n = _pTM->rollbackTransaction(tabSetId, ctid);
870 
871 	if ( doLog )
872 	{
873 	    // create log entry
874 	    CegoLogRecord lr;
875 	    lr.setAction(CegoLogRecord::LOGREC_ABORT);
876 	    lr.setTID(_tid[tabSetId]);
877 	    _pDBMng->logIt(tabSetId, lr, _pLockHandle);
878 	}
879 
880 	return n;
881     }
882     else
883     {
884 	// nothing to do
885 	return 0;
886     }
887 }
888 
getTID(int tabSetId)889 unsigned long long CegoTableManager::getTID(int tabSetId)
890 {
891     return(_tid[tabSetId]);
892 }
893 
setTAStep(int tabSetId,unsigned long long tastep)894 void CegoTableManager::setTAStep(int tabSetId, unsigned long long tastep)
895 {
896     _tastep[tabSetId]=tastep;
897 }
898 
getTAStep(int tabSetId)899 unsigned long long CegoTableManager::getTAStep(int tabSetId)
900 {
901     return(_tastep[tabSetId]);
902 }
903 
setTID(int tabSetId,unsigned long long tid)904 void CegoTableManager::setTID(int tabSetId, unsigned long long tid)
905 {
906     _tid[tabSetId] = tid;
907 }
908 
setTupleInfo(int tabSetId,const CegoDataPointer dp,unsigned long long tid,unsigned long long tastep,CegoTupleState ts)909 void CegoTableManager::setTupleInfo(int tabSetId, const CegoDataPointer dp, unsigned long long tid, unsigned long long tastep, CegoTupleState ts)
910 {
911     char *pc;
912     int len;
913 
914     CegoBufferPage bp;
915     claimDataPtrUnlocked(tabSetId, CegoBufferPool::SYNC, dp, pc, len, bp);
916 
917     CegoQueryHelper::encodeTupleHeader(tid, tastep, ts, pc);
918 
919     releaseDataPtrUnlocked(bp, true);
920 }
921 
getTupleInfo(int tabSetId,const CegoDataPointer dp,unsigned long long & tid,unsigned long long & tastep,CegoTupleState & ts)922 void CegoTableManager::getTupleInfo(int tabSetId, const CegoDataPointer dp, unsigned long long& tid, unsigned long long& tastep, CegoTupleState& ts)
923 {
924     char *pc;
925     int len;
926 
927     CegoBufferPage bp;
928     claimDataPtrUnlocked(tabSetId, CegoBufferPool::SYNC, dp, pc, len, bp);
929 
930     CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);
931 
932     releaseDataPtrUnlocked(bp, true);
933 }
934 
createDataTable(int tabSetId,const Chain & tableName,CegoObject::ObjectType type,const ListT<CegoField> & fl,bool useColumnId)935 CegoTableObject CegoTableManager::createDataTable(int tabSetId, const Chain& tableName, CegoObject::ObjectType type, const ListT<CegoField>& fl, bool useColumnId)
936 {
937     if ( type != CegoObject::RBSEG && getTID(tabSetId > 0 ) )
938     {
939 	Chain msg = Chain("create data table in a transaction not allowed");
940 	throw Exception(EXLOC, msg);
941     }
942 
943     // check duplicate column names
944 
945     ListT<CegoField> cfl = fl;
946     CegoField* pF = fl.First();
947     while (pF)
948     {
949 	int count=0;
950 	CegoField* pCF = cfl.First();
951 	while ( pCF )
952 	{
953 	    if ( pCF->getAttrName() == pF->getAttrName() )
954 		count++;
955 	    pCF = cfl.Next();
956 	}
957 
958 	if ( count > 1 )
959 	{
960 	    Chain msg = Chain("Column ") + pF->getAttrName() + Chain(" multiple defined");
961 	    throw Exception(EXLOC, msg);
962 	}
963 
964 	pF = fl.Next();
965     }
966 
967     // define field id's
968     int id=1;
969 
970     if ( useColumnId == false )
971     {
972 	CegoField* pF = fl.First();
973 	while (pF)
974 	{
975 	    pF->setId(id);
976 	    pF = fl.Next();
977 	    if ( pF )
978 		id++;
979 	}
980     }
981     else
982     {
983 	// for plain export and import, we read complete record chunks with id information
984 	// so for tableimport, we have to restore the previous exported id configuration
985 	CegoField* pF = fl.First();
986 	while (pF)
987 	{
988 	    if ( id < pF->getId() )
989 		id = pF->getId();
990 	    pF = fl.Next();
991 	}
992     }
993 
994 
995     CegoLogRecord lr;
996     if ( type != CegoObject::RBSEG )
997     {
998 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
999     }
1000 
1001     CegoTableObject oe(tabSetId, type, tableName, fl, tableName);
1002     oe.setMaxFid(id);
1003     createTableObject(oe);
1004 
1005     if ( type != CegoObject::RBSEG )
1006     {
1007 	// create log entry
1008 	lr.setObjectInfo(oe.getName(), oe.getType());
1009 	lr.setAction(CegoLogRecord::LOGREC_CREATE);
1010 
1011 	char *buf;
1012 	buf = (char*)malloc(oe.getEntrySize());
1013 	if (buf == NULL)
1014 	{
1015 	    throw Exception(EXLOC, Chain("malloc system error"));
1016 	}
1017 	oe.encode(buf);
1018 	lr.setData(buf);
1019 	lr.setDataLen(oe.getEntrySize());
1020 
1021 	_pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
1022 	free(buf);
1023     }
1024 
1025     return oe;
1026 }
1027 
alterDataTableSynced(CegoTableObject & oe,const ListT<CegoAlterDesc> & alterList)1028 void CegoTableManager::alterDataTableSynced(CegoTableObject& oe, const ListT<CegoAlterDesc>& alterList)
1029 {
1030     _pDBMng->useObject(oe.getTabSetId(), oe.getName(), CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
1031 
1032     try
1033     {
1034 	alterDataTable(oe.getTabSetId(), oe.getName(), CegoObject::TABLE, alterList);
1035     }
1036     catch ( Exception e )
1037     {
1038 	_pDBMng->unuseObject(oe.getTabSetId(), oe.getName(), CegoObject::TABLE);
1039 	throw e;
1040     }
1041 
1042     _pDBMng->unuseObject(oe.getTabSetId(), oe.getName(), CegoObject::TABLE);
1043 }
1044 
alterDataTable(int tabSetId,const Chain & tableName,CegoObject::ObjectType type,const ListT<CegoAlterDesc> & alterList)1045 void CegoTableManager::alterDataTable(int tabSetId, const Chain& tableName, CegoObject::ObjectType type, const ListT<CegoAlterDesc>& alterList)
1046 {
1047     if ( getTID(tabSetId) > 0 )
1048     {
1049 	Chain msg = Chain("alter data table in a transaction not allowed");
1050 	throw Exception(EXLOC, msg);
1051     }
1052 
1053 
1054 
1055     ListT<CegoTableObject> idxList;
1056     ListT<CegoBTreeObject> btreeList;
1057     ListT<CegoKeyObject> keyList;
1058     ListT<CegoCheckObject> checkList;
1059     ListT<CegoTriggerObject> triggerList;
1060     ListT<CegoAliasObject> aliasList;
1061     int numInvalid;
1062 
1063     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
1064 
1065     if ( numInvalid > 0 )
1066     {
1067 	throw Exception(EXLOC, Chain("Invalid index detected, must be valid for table alter"));
1068     }
1069 
1070     // TODO : handle trigger, check and alias objects for table alter operations
1071     //        for now, we deny altering
1072 
1073     if ( checkList.Size() > 0 )
1074     {
1075 	throw Exception(EXLOC, Chain("Check object detected, must be dropped before table alter"));
1076     }
1077     if ( triggerList.Size() > 0 )
1078     {
1079 	throw Exception(EXLOC, Chain("Trigger object detected, must be dropped before table alter"));
1080     }
1081     if ( aliasList.Size() > 0 )
1082     {
1083 	throw Exception(EXLOC, Chain("Alias object detected, must be dropped before table alter"));
1084     }
1085 
1086     CegoTableObject oe;
1087     getObject(tabSetId, tableName, type, oe);
1088 
1089     ListT<CegoKeyObject> keyAlterList;
1090     ListT<CegoTableObject> idxAlterList;
1091     ListT<CegoBTreeObject> btreeAlterList;
1092 
1093     ListT<CegoKeyObject> keyDropList;
1094     ListT<CegoTableObject> idxDropList;
1095     ListT<CegoBTreeObject> btreeDropList;
1096 
1097 
1098 
1099     ListT<CegoField> alterSchema = oe.getSchema();
1100 
1101     // getting max id
1102     int maxFid = oe.getMaxFid();
1103 
1104     CegoAlterDesc* pAD = alterList.First();
1105     while (pAD)
1106     {
1107 	switch ( pAD->getType() )
1108 	{
1109 	case CegoAlterDesc::ADD:
1110 	{
1111 	    CegoField* pSF = alterSchema.Find(CegoField(tableName, pAD->getAttrName()));
1112 	    if (pSF)
1113 	    {
1114 		Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" already exists");
1115 		throw Exception(EXLOC, msg);
1116 	    }
1117 	    else
1118 	    {
1119 		if ( pAD->getField().isNullable() == false )
1120 		{
1121 		    CegoObjectCursor *pOC = getObjectCursor(tabSetId, tableName, tableName, type);
1122 		    int len;
1123 		    CegoDataPointer dp;
1124 		    if ( pOC->getFirst(len, dp) )
1125 		    {
1126 			delete pOC;
1127 			throw Exception(EXLOC, Chain("Column ") + pAD->getAttrName() + Chain(" cannot be added as not nullable to non-empty table"));
1128 		    }
1129 		    delete pOC;
1130 		}
1131 
1132 		maxFid++;
1133 		pAD->getField().setId(maxFid);
1134 		alterSchema.Insert(pAD->getField());
1135 	    }
1136 	    break;
1137 	}
1138 	case CegoAlterDesc::DROP:
1139 	{
1140 	    getKeyAndIdxRef(tabSetId, tableName, pAD->getAttrName(), keyDropList, idxDropList, btreeDropList);
1141 
1142 	    CegoField* pSF = alterSchema.Find(CegoField(tableName, pAD->getAttrName()));
1143 	    if (pSF)
1144 	    {
1145 		alterSchema.Remove(*pSF);
1146 	    }
1147 	    else
1148 	    {
1149 		Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" does not exist");
1150 		throw Exception(EXLOC, msg);
1151 	    }
1152 	    break;
1153 	}
1154 	case CegoAlterDesc::MODIFY_COLUMN:
1155 	{
1156 	    ListT<CegoKeyObject> keyList;
1157 	    ListT<CegoTableObject> idxList;
1158 	    ListT<CegoBTreeObject> btreeList;
1159 
1160 	    if ( pAD->getField().isNullable() == false )
1161 	    {
1162 		CegoField* pF = alterSchema.Find(pAD->getField());
1163 		if ( pF )
1164 		{
1165 		    pAD->getField().setId(pF->getId());
1166 		    if ( checkNullValue(tabSetId, tableName, pAD->getField()) )
1167 		    {
1168 			Chain msg = Chain("Null values exist for column ") + pAD->getAttrName();
1169 			throw Exception(EXLOC, msg);
1170 		    }
1171 		}
1172 	    }
1173 
1174 	    getKeyAndIdxRef(tabSetId, tableName, pAD->getAttrName(), keyList, idxList, btreeList);
1175 
1176 	    // check if any constraints or index object are defined
1177 
1178 	    // check key objects
1179 	    CegoKeyObject* pKey = keyList.First();
1180 	    while ( pKey )
1181 	    {
1182 		if ( (Chain)pKey->getTabName() == (Chain)tableName )
1183 		{
1184 		    CegoField *pF = pKey->getKeySchema().First();
1185 		    while ( pF )
1186 		    {
1187 			if ( pF->getAttrName() == pAD->getAttrName() )
1188 			{
1189 			    Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" with foreign key cannot be altered");
1190 			    throw Exception(EXLOC, msg);
1191 			}
1192 			pF = pKey->getKeySchema().Next();
1193 		    }
1194 		}
1195 		else if ( (Chain)pKey->getRefTable() == (Chain)tableName )
1196 		{
1197 		    CegoField *pF = pKey->getRefSchema().First();
1198 		    while ( pF )
1199 		    {
1200 			if ( pF->getAttrName() == pAD->getAttrName() )
1201 			{
1202 			    Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" with foreign key cannot be altered");
1203 			    throw Exception(EXLOC, msg);
1204 			}
1205 			pF = pKey->getRefSchema().Next();
1206 		    }
1207 		}
1208 		pKey = keyList.Next();
1209 	    }
1210 
1211 	    // columns with avl trees can be modified, so we don't have to check for it
1212 
1213 	    // check btree objects
1214 	    CegoBTreeObject* pBTree = btreeList.First();
1215 	    while ( pBTree )
1216 	    {
1217 		CegoField *pF = pBTree->getSchema().First();
1218 		while ( pF )
1219 		{
1220 		    if ( pF->getAttrName() == pAD->getAttrName() )
1221 		    {
1222 			Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" with btree cannot be altered");
1223 			throw Exception(EXLOC, msg);
1224 		    }
1225 		    pF = pBTree->getSchema().Next();
1226 		}
1227 		pBTree = btreeList.Next();
1228 	    }
1229 
1230 	    CegoField* pSF = alterSchema.Find(CegoField(tableName, pAD->getAttrName()));
1231 	    if (pSF)
1232 	    {
1233 		int id = pSF->getId();
1234 
1235 		// check if field data type could be converted
1236 		if ( pSF->getType() == pAD->getField().getType() )
1237 		{
1238 		    *pSF = pAD->getField();
1239 		    pSF->setId(id);
1240 		}
1241 		else
1242 		{
1243 		    Chain msg = Chain("Cannot change column ") + pSF->getAttrName() + Chain(" from type ") + CEGO_TYPE_MAP[pSF->getType()] + Chain(" to ") + CEGO_TYPE_MAP[pAD->getField().getType()];
1244 		    throw Exception(EXLOC, msg);
1245 		}
1246 		if ( pSF->getLength() > pAD->getField().getLength() )
1247                 {
1248                     Chain msg = Chain("Cannot shrink column size for ") + pSF->getAttrName() + Chain(" from size  ") + Chain(pSF->getLength()) + Chain(" to ") + Chain(pAD->getField().getLength());
1249                     throw Exception(EXLOC, msg);
1250                 }
1251 	    }
1252 	    else
1253 	    {
1254 		Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" does not exist");
1255 		throw Exception(EXLOC, msg);
1256 	    }
1257 	    break;
1258 	}
1259 	case CegoAlterDesc::MODIFY_DEFAULT:
1260 	{
1261 	    CegoField* pSF = alterSchema.Find(CegoField(tableName, pAD->getAttrName()));
1262 	    if (pSF)
1263 	    {
1264 		CegoFieldValue fv = pAD->getField().getValue();
1265 
1266 		if ( fv.castTo(pSF->getType(), pSF->getDim()) == false )
1267 		    throw Exception(EXLOC, Chain("Cannot cast from <")
1268 				    + CEGO_TYPE_MAP[fv.getType()]
1269 				    + Chain("> to <")
1270 				    + CEGO_TYPE_MAP[pSF->getType()]
1271 				    + Chain(">"));
1272 
1273 		pSF->setValue( fv );
1274 	    }
1275 	    else
1276 	    {
1277 		Chain msg = Chain("Column ") + pAD->getAttrName() + Chain(" does not exist");
1278 		throw Exception(EXLOC, msg);
1279 	    }
1280 	    break;
1281 	}
1282 	case CegoAlterDesc::RENAME:
1283 	{
1284 	    CegoField* pCF = alterSchema.Find(CegoField(tableName, pAD->getAttrName()));
1285 	    if ( pCF )
1286 	    {
1287 		throw Exception(EXLOC, Chain("Attribute ") + pCF->getAttrName() + Chain(" already defined"));
1288 	    }
1289 
1290 	    ListT<CegoKeyObject> keyList;
1291 	    ListT<CegoTableObject> idxList;
1292 	    ListT<CegoBTreeObject> btreeList;
1293 
1294 	    getKeyAndIdxRef(tabSetId, tableName, pAD->getOldAttrName(), keyList, idxList, btreeList);
1295 
1296 	    CegoKeyObject* pKey = keyList.First();
1297 	    while ( pKey )
1298 	    {
1299 		if ( (Chain)pKey->getTabName() == (Chain)tableName )
1300 		{
1301 		    CegoField *pF = pKey->getKeySchema().First();
1302 		    while ( pF )
1303 		    {
1304 			if ( pF->getAttrName() == pAD->getOldAttrName() )
1305 			{
1306 			    pF->setAttrName(pAD->getAttrName());
1307 			}
1308 			pF = pKey->getKeySchema().Next();
1309 		    }
1310 		}
1311 		else if ( (Chain)pKey->getRefTable() == (Chain)tableName )
1312 		{
1313 		    CegoField *pF = pKey->getRefSchema().First();
1314 		    while ( pF )
1315 		    {
1316 			if ( pF->getAttrName() == pAD->getOldAttrName() )
1317 			{
1318 			    pF->setAttrName(pAD->getAttrName());
1319 			}
1320 			pF = pKey->getRefSchema().Next();
1321 		    }
1322 		}
1323 		pKey = keyList.Next();
1324 	    }
1325 
1326 	    CegoTableObject* pIdx = idxList.First();
1327 	    while ( pIdx )
1328 	    {
1329 		CegoField *pF = pIdx->getSchema().First();
1330 		while ( pF )
1331 		{
1332 		    if ( pF->getAttrName() == pAD->getOldAttrName() )
1333 		    {
1334 			pF->setAttrName(pAD->getAttrName());
1335 		    }
1336 		    pF = pIdx->getSchema().Next();
1337 		}
1338 		pIdx = idxList.Next();
1339 	    }
1340 
1341 	    CegoBTreeObject* pBTree = btreeList.First();
1342 	    while ( pBTree )
1343 	    {
1344 		CegoField *pF = pBTree->getSchema().First();
1345 		while ( pF )
1346 		{
1347 		    if ( pF->getAttrName() == pAD->getOldAttrName() )
1348 		    {
1349 			pF->setAttrName(pAD->getAttrName());
1350 		    }
1351 		    pF = pBTree->getSchema().Next();
1352 		}
1353 		pBTree = btreeList.Next();
1354 	    }
1355 
1356 	    keyAlterList += keyList;
1357 	    idxAlterList += idxList;
1358 	    btreeAlterList += btreeList;
1359 
1360 	    CegoField* pSF = alterSchema.Find(CegoField(tableName, pAD->getOldAttrName()));
1361 	    if (pSF)
1362 	    {
1363 		pSF->setAttrName(pAD->getField().getAttrName());
1364 	    }
1365 	    else
1366 	    {
1367 		Chain msg = Chain("Column ") + pAD->getAttrName() + Chain("does not exist");
1368 		throw Exception(EXLOC, msg);
1369 	    }
1370 	    break;
1371 	}
1372 	}
1373 	pAD = alterList.Next();
1374     }
1375 
1376     CegoKeyObject* pDropKey = keyDropList.First();
1377     while ( pDropKey )
1378     {
1379 
1380 	CegoLogRecord lr;
1381 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1382 
1383 	removeObject(tabSetId, pDropKey->getName(), pDropKey->getType());
1384 
1385 	// create log entry
1386 	lr.setObjectInfo(pDropKey->getName(), pDropKey->getType());
1387 	lr.setAction(CegoLogRecord::LOGREC_DROP);
1388 	lr.setData(0);
1389 	lr.setDataLen(0);
1390 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1391 
1392 
1393 	pDropKey = keyDropList.Next();
1394     }
1395 
1396     CegoTableObject* pDropIdx = idxDropList.First();
1397     while ( pDropIdx )
1398     {
1399 	CegoLogRecord lr;
1400 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1401 
1402 	removeObject(tabSetId, pDropIdx->getName(), pDropIdx->getType());
1403 
1404 	// create log entry
1405 	lr.setObjectInfo(pDropIdx->getName(), pDropIdx->getType());
1406 	lr.setAction(CegoLogRecord::LOGREC_DROP);
1407 	lr.setData(0);
1408 	lr.setDataLen(0);
1409 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1410 
1411 	pDropIdx = idxDropList.Next();
1412     }
1413 
1414     CegoBTreeObject* pDropBTree = btreeDropList.First();
1415     while ( pDropBTree )
1416     {
1417 	CegoLogRecord lr;
1418 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1419 
1420 	removeObject(tabSetId, pDropBTree->getName(), pDropBTree->getType());
1421 
1422 	// create log entry
1423 	lr.setObjectInfo(pDropBTree->getName(), pDropBTree->getType());
1424 	lr.setAction(CegoLogRecord::LOGREC_DROP);
1425 	lr.setData(0);
1426 	lr.setDataLen(0);
1427 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1428 
1429 	pDropBTree = btreeDropList.Next();
1430     }
1431 
1432     CegoKeyObject* pKey = keyAlterList.First();
1433     while ( pKey )
1434     {
1435 	CegoLogRecord lr;
1436 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1437 
1438 	alterKeyObject(tabSetId, tableName, *pKey);
1439 
1440 	// create log entry
1441 	lr.setObjectInfo(pKey->getName(), pKey->getType());
1442 	lr.setAction(CegoLogRecord::LOGREC_ALTER);
1443 
1444 	char *buf;
1445 	buf = (char*)malloc(pKey->getEntrySize());
1446 	if (buf == NULL)
1447 	{
1448 	    throw Exception(EXLOC, Chain("malloc system error"));
1449 	}
1450 
1451 	pKey->encode(buf);
1452 	lr.setData(buf);
1453 	lr.setDataLen(pKey->getEntrySize());
1454 
1455 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1456 
1457 	free(buf);
1458 
1459 	pKey = keyAlterList.Next();
1460     }
1461 
1462     CegoTableObject* pIdx = idxAlterList.First();
1463     while ( pIdx )
1464     {
1465 	CegoLogRecord lr;
1466 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1467 
1468 	alterTableObject(tabSetId, pIdx->getName(), pIdx->getType(), *pIdx);
1469 
1470 	// create log entry
1471 	lr.setObjectInfo(pIdx->getName(), pIdx->getType());
1472 	lr.setAction(CegoLogRecord::LOGREC_ALTER);
1473 
1474 	char *buf;
1475 	buf = (char*)malloc(pIdx->getEntrySize());
1476 	if (buf == NULL)
1477 	{
1478 	    throw Exception(EXLOC, Chain("malloc system error"));
1479 	}
1480 
1481 	pIdx->encode(buf);
1482 	lr.setData(buf);
1483 	lr.setDataLen(pIdx->getEntrySize());
1484 
1485 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1486 
1487 	free(buf);
1488 
1489 	pIdx = idxAlterList.Next();
1490     }
1491 
1492     CegoBTreeObject* pBTree = btreeAlterList.First();
1493     while ( pBTree )
1494     {
1495 	CegoLogRecord lr;
1496 	lr.setLSN(_pDBMng->nextLSN(tabSetId));
1497 
1498 	alterBTreeObject(tabSetId, pBTree->getName(), pBTree->getType(), *pBTree);
1499 
1500 	// create log entry
1501 	lr.setObjectInfo(pBTree->getName(), pBTree->getType());
1502 	lr.setAction(CegoLogRecord::LOGREC_ALTER);
1503 
1504 	char *buf;
1505 	buf = (char*)malloc(pBTree->getEntrySize());
1506 	if (buf == NULL)
1507 	{
1508 	    throw Exception(EXLOC, Chain("malloc system error"));
1509 	}
1510 
1511 	pBTree->encode(buf);
1512 	lr.setData(buf);
1513 	lr.setDataLen(pBTree->getEntrySize());
1514 
1515 	_pDBMng->logIt(tabSetId, lr, _pLockHandle);
1516 
1517 	free(buf);
1518 
1519 	pBTree = btreeAlterList.Next();
1520     }
1521 
1522     CegoTableObject aoe(tabSetId, type, tableName, alterSchema, tableName);
1523     aoe.setMaxFid(maxFid);
1524 
1525     CegoLogRecord lr;
1526     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1527 
1528     alterTableObject(tabSetId, tableName, type, aoe);
1529 
1530     // create log entry
1531     lr.setObjectInfo(aoe.getName(), aoe.getType());
1532     lr.setAction(CegoLogRecord::LOGREC_ALTER);
1533 
1534     char *buf;
1535     buf = (char*)malloc(aoe.getEntrySize());
1536     if (buf == NULL)
1537     {
1538 	throw Exception(EXLOC, Chain("malloc system error"));
1539     }
1540 
1541     aoe.encode(buf);
1542     lr.setData(buf);
1543     lr.setDataLen(aoe.getEntrySize());
1544 
1545     _pDBMng->logIt(aoe.getTabSetId(), lr, _pLockHandle);
1546 
1547     free(buf);
1548 }
1549 
renameObject(int tabSetId,const Chain & objName,CegoObject::ObjectType type,const Chain & newObjName)1550 void CegoTableManager::renameObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, const Chain& newObjName)
1551 {
1552     switch ( type )
1553     {
1554     case CegoObject::TABLE:
1555     {
1556 	renameTable(tabSetId, objName, newObjName);
1557 	break;
1558     }
1559     case CegoObject::AVLTREE:
1560     case CegoObject::UAVLTREE:
1561     case CegoObject::PAVLTREE:
1562     {
1563 	renameIndex(tabSetId, objName, type, newObjName);
1564 	break;
1565     }
1566     case CegoObject::BTREE:
1567     case CegoObject::UBTREE:
1568     case CegoObject::PBTREE:
1569     {
1570 	renameBTree(tabSetId, objName, type, newObjName);
1571 	break;
1572     }
1573     case CegoObject::FKEY:
1574     {
1575 	renameKey(tabSetId, objName, newObjName);
1576 	break;
1577     }
1578     case CegoObject::PROCEDURE:
1579     {
1580 	renameProcedure(tabSetId, objName, newObjName);
1581 	break;
1582     }
1583     case CegoObject::VIEW:
1584     {
1585 	renameView(tabSetId, objName, newObjName);
1586 	break;
1587     }
1588     case CegoObject::CHECK:
1589     {
1590 	renameCheck(tabSetId, objName, newObjName);
1591 	break;
1592     }
1593     case CegoObject::RBSEG:
1594     {
1595 	renameRBO(tabSetId, objName, newObjName);
1596 	break;
1597     }
1598     case CegoObject::TRIGGER:
1599     {
1600 	renameTrigger(tabSetId, objName, newObjName);
1601 	break;
1602     }
1603     case CegoObject::SYSTEM:
1604     case CegoObject::JOIN:
1605     case CegoObject::ALIAS:
1606     case CegoObject::UNDEFINED:
1607 	throw Exception(EXLOC, Chain("Cannot rename object"));
1608     }
1609 }
1610 
renameTable(int tabSetId,const Chain & tableName,const Chain & newTableName)1611 void CegoTableManager::renameTable(int tabSetId, const Chain& tableName, const Chain& newTableName)
1612 {
1613     CegoTableObject oe;
1614     getObject(tabSetId, tableName, CegoObject::TABLE, oe);
1615 
1616     CegoObject::ObjectType type = oe.getType();
1617     oe.setName(newTableName);
1618     oe.setTabName(newTableName);
1619 
1620     ListT<CegoTableObject> idxList;
1621     ListT<CegoBTreeObject> btreeList;
1622     ListT<CegoKeyObject> keyList;
1623     ListT<CegoCheckObject> checkList;
1624     ListT<CegoTriggerObject> triggerList;
1625     ListT<CegoAliasObject> aliasList;
1626     int numInvalid;
1627 
1628     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
1629 
1630     if ( numInvalid > 0 )
1631     {
1632 	throw Exception(EXLOC, Chain("Invalid index detected, must be valid for table renaming"));
1633     }
1634 
1635     CegoTableObject *pIO = idxList.First();
1636     while ( pIO )
1637     {
1638 	if ( pIO->getType() == CegoObject::AVLTREE
1639 	     || pIO->getType() == CegoObject::UAVLTREE
1640 	     || pIO->getType() == CegoObject::PAVLTREE )
1641 	{
1642 
1643 	    CegoTableObject idx;
1644 	    getObject(tabSetId, pIO->getName(), pIO->getType(), idx);
1645 	    idx.setTabName( newTableName );
1646 
1647 	    alterTableObject(tabSetId, pIO->getName(), pIO->getType(), idx);
1648 
1649 	}
1650 	pIO = idxList.Next();
1651     }
1652 
1653     CegoBTreeObject *pBTO = btreeList.First();
1654     while ( pBTO )
1655     {
1656 	if ( pBTO->getType() == CegoObject::BTREE
1657 	     || pBTO->getType() == CegoObject::UBTREE
1658 	     || pBTO->getType() == CegoObject::PBTREE )
1659 	{
1660 
1661 	    CegoBTreeObject btree;
1662 	    getObject(tabSetId, pBTO->getName(), pBTO->getType(), btree);
1663 	    btree.setTabName( newTableName );
1664 
1665 	    alterBTreeObject(tabSetId, pBTO->getName(), pBTO->getType(), btree);
1666 
1667 	}
1668 	pBTO = btreeList.Next();
1669     }
1670 
1671     CegoKeyObject *pKO = keyList.First();
1672     while ( pKO )
1673     {
1674 	CegoKeyObject keyObj;
1675 	getObject(tabSetId, pKO->getName(), pKO->getType(), keyObj);
1676 	keyObj.setTabName( newTableName );
1677 
1678 	alterKeyObject(tabSetId, pKO->getName(), keyObj);
1679 
1680 	pKO = keyList.Next();
1681     }
1682 
1683     CegoCheckObject *pCO = checkList.First();
1684     while ( pCO )
1685     {
1686 	CegoCheckObject checkObj;
1687 	getObject(tabSetId, pCO->getName(), pCO->getType(), checkObj);
1688 	checkObj.setTabName( newTableName );
1689 
1690 	alterCheckObject(tabSetId, pCO->getName(), checkObj);
1691 
1692 	pCO = checkList.Next();
1693     }
1694 
1695     CegoTriggerObject *pTO = triggerList.First();
1696     while ( pTO )
1697     {
1698 	CegoTriggerObject triggerObj;
1699 	getObject(tabSetId, pTO->getName(), pTO->getType(), triggerObj);
1700 	triggerObj.setTabName( newTableName );
1701 
1702 	alterTriggerObject(tabSetId, pTO->getName(), triggerObj);
1703 
1704 	pTO = triggerList.Next();
1705     }
1706 
1707 
1708     CegoLogRecord lr;
1709     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1710 
1711     alterTableObject(tabSetId, tableName, type, oe);
1712 
1713     // create log entry
1714     lr.setObjectInfo(tableName, type);
1715     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1716 
1717     lr.setData((char*)newTableName);
1718     lr.setDataLen(newTableName.length());
1719 
1720     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
1721 }
1722 
renameIndex(int tabSetId,const Chain & idxName,CegoObject::ObjectType type,const Chain & newIdxName)1723 void CegoTableManager::renameIndex(int tabSetId, const Chain& idxName, CegoObject::ObjectType type, const Chain& newIdxName)
1724 {
1725     if ( type != CegoObject::PAVLTREE && type !=  CegoObject::UAVLTREE && type != CegoObject::AVLTREE )
1726 	throw Exception(EXLOC, Chain("Invalid index type"));
1727 
1728     CegoTableObject oe;
1729     getObject(tabSetId, idxName, type, oe);
1730 
1731     oe.setName(newIdxName);
1732 
1733     CegoLogRecord lr;
1734     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1735 
1736     alterTableObject(tabSetId, idxName, type, oe);
1737 
1738     // create log entry
1739     lr.setObjectInfo(idxName, type);
1740     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1741     lr.setData((char*)newIdxName);
1742     lr.setDataLen(newIdxName.length());
1743 
1744     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
1745 }
1746 
renameBTree(int tabSetId,const Chain & btreeName,CegoObject::ObjectType type,const Chain & newBTreeName)1747 void CegoTableManager::renameBTree(int tabSetId, const Chain& btreeName, CegoObject::ObjectType type, const Chain& newBTreeName)
1748 {
1749     if ( type != CegoObject::PBTREE && type !=  CegoObject::UBTREE && type != CegoObject::BTREE )
1750 	throw Exception(EXLOC, Chain("Invalid btree type"));
1751 
1752     CegoBTreeObject btoe;
1753     getObject(tabSetId, btreeName, type, btoe);
1754 
1755     btoe.setName(newBTreeName);
1756 
1757     CegoLogRecord lr;
1758     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1759 
1760     alterBTreeObject(tabSetId, btreeName, type, btoe);
1761 
1762     // create log entry
1763     lr.setObjectInfo(btreeName, type);
1764     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1765     lr.setData((char*)newBTreeName);
1766     lr.setDataLen(newBTreeName.length());
1767 
1768     _pDBMng->logIt(btoe.getTabSetId(), lr, _pLockHandle);
1769 }
1770 
renameKey(int tabSetId,const Chain & keyName,const Chain & newKeyName)1771 void CegoTableManager::renameKey(int tabSetId, const Chain& keyName, const Chain& newKeyName)
1772 {
1773     CegoKeyObject oe;
1774     getObject(tabSetId, keyName, CegoObject::FKEY, oe);
1775 
1776     oe.setName(newKeyName);
1777 
1778     CegoLogRecord lr;
1779     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1780 
1781     alterKeyObject(tabSetId, keyName, oe);
1782 
1783     // create log entry
1784     lr.setObjectInfo(keyName, CegoObject::FKEY);
1785     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1786 
1787     lr.setData((char*)newKeyName);
1788     lr.setDataLen(newKeyName.length());
1789 
1790     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
1791 }
1792 
renameRBO(int tabSetId,const Chain & rboName,const Chain & newRboName)1793 void CegoTableManager::renameRBO(int tabSetId, const Chain& rboName, const Chain& newRboName)
1794 {
1795     CegoTableObject rbo;
1796     getObject(tabSetId, rboName, CegoObject::RBSEG, rbo);
1797 
1798     rbo.setName(newRboName);
1799 
1800     alterTableObject(tabSetId, rboName, CegoObject::RBSEG, rbo);
1801 
1802     // no need to create log entry
1803 }
1804 
renameProcedure(int tabSetId,const Chain & procName,const Chain & newProcName)1805 void CegoTableManager::renameProcedure(int tabSetId, const Chain& procName, const Chain& newProcName)
1806 {
1807     CegoProcObject oe;
1808     getObject(tabSetId, procName, CegoObject::FKEY, oe);
1809 
1810     oe.setName(newProcName);
1811 
1812     CegoLogRecord lr;
1813     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1814 
1815     alterProcObject(tabSetId, procName, oe);
1816 
1817     // create log entry
1818     lr.setObjectInfo(procName, CegoObject::FKEY);
1819     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1820     lr.setData((char*)newProcName);
1821     lr.setDataLen(newProcName.length());
1822 
1823     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
1824 }
1825 
renameView(int tabSetId,const Chain & viewName,const Chain & newViewName)1826 void CegoTableManager::renameView(int tabSetId, const Chain& viewName, const Chain& newViewName)
1827 {
1828     CegoViewObject oe;
1829     getObject(tabSetId, viewName, CegoObject::VIEW, oe);
1830 
1831     oe.setName(newViewName);
1832 
1833     CegoLogRecord lr;
1834     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1835 
1836     alterViewObject(tabSetId, viewName, oe);
1837 
1838     // create log entry
1839     lr.setObjectInfo(viewName, CegoObject::VIEW);
1840     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1841     lr.setData((char*)newViewName);
1842     lr.setDataLen(newViewName.length());
1843 
1844     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
1845 }
1846 
renameCheck(int tabSetId,const Chain & checkName,const Chain & newCheckName)1847 void CegoTableManager::renameCheck(int tabSetId, const Chain& checkName, const Chain& newCheckName)
1848 {
1849     CegoCheckObject oe;
1850     getObject(tabSetId, checkName, CegoObject::CHECK, oe);
1851 
1852     oe.setName(newCheckName);
1853 
1854     CegoLogRecord lr;
1855     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1856 
1857     alterCheckObject(tabSetId, checkName, oe);
1858 
1859     // create log entry
1860     lr.setObjectInfo(checkName, CegoObject::CHECK);
1861     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1862     lr.setData((char*)newCheckName);
1863     lr.setDataLen(newCheckName.length());
1864 
1865     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
1866 }
1867 
renameTrigger(int tabSetId,const Chain & triggerName,const Chain & newTriggerName)1868 void CegoTableManager::renameTrigger(int tabSetId, const Chain& triggerName, const Chain& newTriggerName)
1869 {
1870     CegoTriggerObject to;
1871     getObject(tabSetId, triggerName, CegoObject::TRIGGER, to);
1872 
1873     to.setName(newTriggerName);
1874 
1875     CegoLogRecord lr;
1876     lr.setLSN(_pDBMng->nextLSN(tabSetId));
1877 
1878     alterTriggerObject(tabSetId, triggerName, to);
1879 
1880     // create log entry
1881     lr.setObjectInfo(triggerName, CegoObject::TRIGGER);
1882     lr.setAction(CegoLogRecord::LOGREC_RENAME);
1883     lr.setData((char*)newTriggerName);
1884     lr.setDataLen(newTriggerName.length());
1885 
1886     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
1887 }
1888 
1889 
reorgObjectSynced(int tabSetId,const Chain & objName,CegoObject::ObjectType type)1890 void CegoTableManager::reorgObjectSynced(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
1891 {
1892     _pDBMng->useObject(tabSetId, objName, type, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
1893 
1894     try
1895     {
1896 	reorgObject(tabSetId, objName, type);
1897     }
1898     catch ( Exception e )
1899     {
1900 	_pDBMng->unuseObject(tabSetId, objName, type);
1901     }
1902     _pDBMng->unuseObject(tabSetId, objName, type);
1903 }
1904 
reorgTable(int tabSetId,const Chain & tableName)1905 void CegoTableManager::reorgTable(int tabSetId, const Chain& tableName)
1906 {
1907     reorgObject(tabSetId, tableName, CegoObject::TABLE);
1908 }
1909 
invalidateIndexForTable(int tabSetId,const Chain & tableName)1910 void CegoTableManager::invalidateIndexForTable(int tabSetId, const Chain& tableName)
1911 {
1912     ListT<CegoTableObject> idxList;
1913     ListT<CegoBTreeObject> btreeList;
1914     ListT<CegoKeyObject> keyList;
1915     ListT<CegoCheckObject> checkList;
1916     ListT<CegoTriggerObject> triggerList;
1917     ListT<CegoAliasObject> aliasList;
1918     int numInvalid;
1919 
1920     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
1921 
1922     CegoTableObject *pIdx = idxList.First();
1923     while ( pIdx )
1924     {
1925 	invalidateObject(tabSetId, pIdx->getName(), pIdx->getType());
1926 	pIdx = idxList.Next();
1927     }
1928 
1929     CegoBTreeObject *pBTree = btreeList.First();
1930     while ( pBTree )
1931     {
1932 	invalidateObject(tabSetId, pBTree->getName(), pBTree->getType());
1933 	pBTree = btreeList.Next();
1934     }
1935 }
1936 
insertDataTable(CegoTableObject & oe,ListT<CegoField> & fvl,CegoDataPointer & dp,bool doLogging,bool flushLog)1937 void CegoTableManager::insertDataTable(CegoTableObject& oe, ListT<CegoField>& fvl, CegoDataPointer& dp, bool doLogging, bool flushLog)
1938 {
1939     // nextTAStep
1940     // if ( getTID(oe.getTabSetId()) != 0 )
1941     // 	_tastep[oe.getTabSetId()]++;
1942 
1943     ListT<CegoTableObject> idxList;
1944     ListT<CegoBTreeObject> btreeList;
1945     ListT<CegoKeyObject> keyList;
1946     ListT<CegoCheckObject> checkList;
1947     ListT<CegoTriggerObject> triggerList;
1948     ListT<CegoAliasObject> aliasList;
1949     int numInvalid;
1950 
1951     bool doAppend;
1952 
1953     if ( oe.getType() == CegoObject::TABLE )
1954     {
1955 	getObjectListByTable(oe.getTabSetId(), oe.getName(), idxList, btreeList, keyList,
1956 			     checkList, triggerList, aliasList, numInvalid);
1957 	if ( numInvalid > 0 )
1958 	{
1959 	    // for ongoing transactions, we don't support online index build up
1960 	    if ( getTID(oe.getTabSetId() != 0 ))
1961 	    {
1962 		throw Exception(EXLOC, Chain("Invalid index detected, must be valid for transactions"));
1963 	    }
1964 	    doAppend = true;
1965 	}
1966 	else
1967 	{
1968 	    doAppend = _doAppend;
1969 	}
1970     }
1971 
1972     CegoDataPointer sysEntry;
1973     Chain virginIndex;
1974     insertDataTable(oe, fvl, idxList, btreeList, keyList, checkList, sysEntry, virginIndex, dp, doLogging, doAppend, true, flushLog);
1975 }
1976 
insertDataTable(CegoTableObject & oe,ListT<CegoField> & nfvl,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,const ListT<CegoCheckObject> & checkList,const CegoDataPointer & sysEntry,const Chain & virginIndex,CegoDataPointer & dp,bool doLogging,bool doAppend,bool increaseStep,bool flushLog)1977 void CegoTableManager::insertDataTable(CegoTableObject& oe, ListT<CegoField>& nfvl,
1978 				       const ListT<CegoTableObject>& idxList,
1979 				       const ListT<CegoBTreeObject>& btreeList,
1980 				       const ListT<CegoKeyObject>& keyList,
1981 				       const ListT<CegoCheckObject>& checkList,
1982 				       const CegoDataPointer& sysEntry,
1983 				       const Chain& virginIndex,
1984 				       CegoDataPointer& dp, bool doLogging, bool doAppend, bool increaseStep, bool flushLog)
1985 {
1986 
1987     CegoLogRecord lr;
1988 
1989     // we have to create log seq number at the beginning BEFORE performing the opertion.
1990     // The reason is, a sync point might happen during the operation and the operation then is
1991     // written after the sync point. For this we have to ensure a log seqnr < lsn(syncpoint) to catch this operation
1992     // during recovery
1993 
1994     if ( oe.getType() == CegoObject::TABLE && doLogging == true )
1995     {
1996 	lr.setLSN(_pDBMng->nextLSN(oe.getTabSetId()));
1997     }
1998 
1999     // nextTAStep, just done for explicit insert ( disabled for use by updateTuple method, since TA step is already increased by embedding update method )
2000     if ( increaseStep )
2001     {
2002 	if ( getTID(oe.getTabSetId()) != 0 )
2003 	    _tastep[oe.getTabSetId()]++;
2004     }
2005 
2006     CegoDataPointer nil;
2007 
2008     dp = nil;
2009 
2010     unsigned long long tid = 0;
2011     unsigned long long tastep = 0;
2012     CegoTupleState ts = COMMITTED;
2013 
2014     int idxInsertCount=0;
2015     int btreeInsertCount=0;
2016 
2017     /////////////////////////////////////////////
2018     // Step 1 : Setting ids and check null values
2019     /////////////////////////////////////////////
2020     // after setting ids, the fvl must be sorted in terms of the id
2021 
2022     CegoField* pF = nfvl.First();
2023     while (pF)
2024     {
2025 
2026 	CegoField* pSF = oe.getSchema().Find(CegoField(oe.getName(), pF->getAttrName()));
2027 
2028 	// check for allowed null values
2029 	if ( pF->getValue().getType() == NULL_TYPE && pSF->isNullable() == false )
2030 	{
2031 	    throw Exception(EXLOC, Chain("Invalid null value"));
2032 	}
2033 
2034 	if ( pSF )
2035 	{
2036 	    pF->setId(pSF->getId());
2037 	}
2038 
2039 	pF = nfvl.Next();
2040     }
2041 
2042     ListT<CegoField> fvl;
2043 
2044     pF = nfvl.First();
2045     int maxId=0;
2046     while ( pF )
2047     {
2048 	if ( pF->getId() > maxId )
2049 	    maxId = pF->getId();
2050 	pF = nfvl.Next();
2051     }
2052 
2053     for ( int id=0; id<=maxId; id++ )
2054     {
2055 	CegoField *pF = nfvl.First();
2056 	while ( pF )
2057 	{
2058 	    if ( pF->getId() == id )
2059 	    {
2060 		fvl.Insert(*pF);
2061 		pF = 0;
2062 	    }
2063 	    else
2064 	    {
2065 		pF = nfvl.Next();
2066 	    }
2067 	}
2068     }
2069 
2070     unsigned long long cpCount = _pDBMng->getCPCount();
2071 
2072     int encLen;
2073 
2074     try
2075     {
2076 	/////////////////////////////////////////////
2077 	// Step 2 : Insert table data
2078 	/////////////////////////////////////////////
2079 
2080 	if ( oe.getType() == CegoObject::TABLE )
2081 	{
2082 	    tid = getTID(oe.getTabSetId());
2083 	    tastep = getTAStep(oe.getTabSetId());
2084 	    if ( tid > 0 )
2085 		ts = INSERTED;
2086 	}
2087 
2088 
2089 	// cout << "Encode FVL with tid = " << tid << " tastep=" << tastep << "ts = " << ts << endl;
2090 
2091 	encLen = CegoQueryHelper::encodeFVL(tid, tastep, ts, fvl, _pEncBuf, _encBufLen);
2092 
2093 	int numTries=0;
2094 	while ( dp == nil )
2095 	{
2096 	    try
2097 	    {
2098 		if ( sysEntry == nil )
2099 		{
2100 		    dp = insertData(oe, _pEncBuf, encLen, doAppend);
2101 		}
2102 		else
2103 		{
2104 		    dp = insertData(sysEntry, oe, _pEncBuf, encLen, doAppend);
2105 		}
2106 	    }
2107 	    catch ( Exception e)
2108 	    {
2109 		Chain msg;
2110 		e.pop(msg);
2111 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Retry insert after :  ") +  msg);
2112 
2113 		if ( numTries == LCKMNG_NUMLOCKTRIES )
2114 		{
2115 		    throw Exception(EXLOC, msg);
2116 		}
2117 		numTries++;
2118 	    }
2119 	}
2120 
2121 	///////////////////////////////////
2122 	// Step 3 : check key contraints //
2123 	///////////////////////////////////
2124 
2125 	// Note: since fkeys can refer to a primary key inside the same table and the same row,
2126 	// this must be done as the second step
2127 
2128 	if ( ! keyList.isEmpty() )
2129 	{
2130 	    CegoKeyObject* pKey = keyList.First();
2131 	    while ( pKey )
2132 	    {
2133 		if ( (Chain)pKey->getTabName() == (Chain)oe.getName() )
2134 		{
2135 		    Chain idxName = pKey->getRefTable() + Chain(TABMNG_PBTREE_SUFFIX);
2136 		    bool hasBTree = true;
2137 		    ListT<CegoField> rfl;
2138 		    ListT<CegoField> ifl;
2139 
2140 		    try
2141 		    {
2142 			if ( objectExists(oe.getTabSetId(), idxName, CegoObject::PBTREE ))
2143 			{
2144 			    CegoBTreeObject pbt;
2145 			    getObject(oe.getTabSetId(), idxName, CegoObject::PBTREE, pbt);
2146 			    rfl = pbt.getSchema();
2147 			    ifl = pbt.getSchema();
2148 			}
2149 			else
2150 			{
2151 			    idxName = pKey->getRefTable() + Chain(TABMNG_PIDX_SUFFIX);
2152 			    hasBTree = false;
2153 
2154 			    CegoTableObject poe;
2155 			    getObject(oe.getTabSetId(), idxName, CegoObject::PAVLTREE, poe);
2156 			    rfl = poe.getSchema();
2157 			    ifl = poe.getSchema();
2158 			}
2159 		    }
2160 		    catch ( Exception e )
2161 		    {
2162 			Chain msg = Chain("Primary index or btree required for insert operation");
2163 			throw Exception(EXLOC, msg);
2164 		    }
2165 
2166 		    ListT<CegoField> kfl = pKey->getKeySchema();
2167 		    CegoField *pKF = kfl.First();
2168 		    while ( pKF )
2169 		    {
2170 			CegoField *pDF = fvl.Find(*pKF);
2171 			if ( pDF )
2172 			{
2173 			    pKF->setValue(pDF->getValue());
2174 			}
2175 			else
2176 			{
2177 			    Chain msg = Chain("Cannot access key attribute <") + pKF->getAttrName() + Chain(">");
2178 			    throw Exception(EXLOC, msg);
2179 			}
2180 			pKF = kfl.Next();
2181 		    }
2182 
2183 		    CegoField *pRF = rfl.First();
2184 		    pKF = kfl.First();
2185 
2186 		    CegoAttrCond ac;
2187 
2188 		    while ( pKF && pRF )
2189 		    {
2190 			// cout << "Adding search cond " << pRF->getTableAlias() << " ." << pRF->getAttrName() << " = " << pKF->getValue() << endl;
2191 			ac.add(CegoAttrComp(pRF->getTableAlias(), pRF->getAttrName(), EQUAL, pKF->getValue()));
2192 			pRF = rfl.Next();
2193 			pKF = kfl.Next();
2194 		    }
2195 
2196 		    bool hasTuple;
2197 
2198 		    if ( hasBTree )
2199 		    {
2200 			CegoBTreeCursor btc(this, oe.getTabSetId(), idxName, CegoObject::PBTREE, &ac, false, false);
2201 			CegoDataPointer dp;
2202 			hasTuple = btc.getFirst(ifl, dp);
2203 		    }
2204 		    else
2205 		    {
2206 			CegoAVLIndexCursor ic(this, oe.getTabSetId(), idxName, CegoObject::PAVLTREE, &ac, false, false);
2207 			CegoDataPointer dp;
2208 			hasTuple = ic.getFirst(ifl, dp);
2209 		    }
2210 
2211 		    if ( hasTuple == false )
2212 		    {
2213 			// check for self refering tables, if the new inserted tuple can satisfy the constraint
2214 
2215 			if ( (Chain)pKey->getTabName() == (Chain)pKey->getRefTable() )
2216 			{
2217 			    bool keyMatch = true;
2218 			    pKF = kfl.First();
2219 			    pRF = rfl.First();
2220 			    while ( pKF && keyMatch )
2221 			    {
2222 				CegoField *pF = nfvl.Find(CegoField(Chain(), pRF->getAttrName()));
2223 				if ( pF )
2224 				{
2225 				    // cout << "Comparing " << pKF->getValue() << " and " << pF->getValue() << endl;
2226 				    if ( ! ( (CegoFieldValue)pKF->getValue() == (CegoFieldValue)pF->getValue()) )
2227 				    {
2228 					keyMatch=false;
2229 				    }
2230 				}
2231 				else
2232 				{
2233 				    Chain msg = Chain("Cannot access key attribute <") + pRF->getAttrName() + Chain(">");
2234 				    throw Exception(EXLOC, msg);
2235 				}
2236 				pKF = kfl.Next();
2237 				pRF = rfl.Next();
2238 			    }
2239 
2240 			    if ( keyMatch == false )
2241 			    {
2242 				Chain msg = Chain("Missing foreign key value in reference btree <") + idxName + Chain(">");
2243 				throw Exception(EXLOC, msg);
2244 			    }
2245 			}
2246 			else
2247 			{
2248 			    Chain msg = Chain("Missing foreign key value in reference btree <") + idxName + Chain(">");
2249 			    throw Exception(EXLOC, msg);
2250 			}
2251 		    }
2252 		}
2253 		pKey = keyList.Next();
2254 	    }
2255 	}
2256 
2257 	///////////////////////////////////
2258 	// Step 4 : Check check constraints
2259 	///////////////////////////////////
2260 
2261 	if ( ! checkList.isEmpty() )
2262 	{
2263 	    CegoCheckObject* pCheck = checkList.First();
2264 	    while ( pCheck )
2265 	    {
2266 		// cout << "======= Check Constraint .." << endl;
2267 		pCheck->getPredDesc()->clearAttrCache();
2268 		// cout << "after clear attr cache" << endl;
2269 
2270 		// we need to create an additional reference to call evalPredicate
2271 		ListT<CegoField>* xfl[2];
2272 		xfl[0] = &fvl;
2273 		xfl[1] = 0;
2274 
2275 		if ( CegoQueryHelper::evalPredicate(0, 0, xfl, 0, pCheck->getPredDesc(), 0) == false )
2276 		{
2277 		    Chain msg = Chain("Check constraint ") + pCheck->getName() + Chain(" violated");
2278 		    throw Exception(EXLOC, msg);
2279 		}
2280 
2281 		pCheck = checkList.Next();
2282 	    }
2283 	}
2284 
2285 	///////////////////////////////////
2286 	// Step 5: Add index ref         //
2287 	///////////////////////////////////
2288 
2289 	CegoTableObject* pOE = idxList.First();
2290 
2291 	idxInsertCount=0;
2292 	while (pOE)
2293 	{
2294 	    if (pOE->getName() != virginIndex &&
2295 		pOE->isValid() &&
2296 		( pOE->getType() == CegoObject::AVLTREE
2297 		  || pOE->getType() == CegoObject::UAVLTREE
2298 		  || pOE->getType() == CegoObject::PAVLTREE ) )
2299 	    {
2300 		char p[TABMNG_MAXINDEXVALUE];
2301 		int len = TABMNG_MAXINDEXVALUE;
2302 		int idxLen;
2303 		CegoDataPointer ritp;
2304 
2305 		extractIndexValue(fvl, pOE->getSchema(), p, len, idxLen);
2306 
2307 		CegoDataPointer nil;
2308 
2309 		CegoAVLIndexManager idxMng(this);
2310 		idxMng.insertNativeIndexTable(*pOE,
2311 					      nil,
2312 					      dp,
2313 					      p,
2314 					      idxLen,
2315 					      getTID(oe.getTabSetId()),
2316 					      doAppend,
2317 					      ritp);
2318 		idxInsertCount++;
2319 	    }
2320 	    pOE = idxList.Next();
2321 	}
2322 
2323 	///////////////////////////////////
2324 	// Step 6: Add btree ref         //
2325 	///////////////////////////////////
2326 
2327 	CegoBTreeObject* pBTO = btreeList.First();
2328 
2329 	btreeInsertCount=0;
2330 	while (pBTO)
2331 	{
2332 	    if (pBTO->getName() != virginIndex &&
2333 		pBTO->isValid() &&
2334 		( pBTO->getType() == CegoObject::BTREE
2335 		  || pBTO->getType() == CegoObject::UBTREE
2336 		  || pBTO->getType() == CegoObject::PBTREE ) )
2337 	    {
2338 		CegoBTreeValue iv;
2339 
2340 		iv.valueFromSchema(fvl, pBTO->getSchema());
2341 
2342 		CegoBTreeManager btreeMng(this, pBTO);
2343 
2344 		// cout << "############ BEFORE INSERT ##################" << endl;
2345 		// btreeMng.dumpBTree();
2346 
2347 
2348 		btreeMng.insertBTreeWithCommit(dp,
2349 				     iv,
2350 				     getTID(oe.getTabSetId()));
2351 		btreeInsertCount++;
2352 
2353 		// cout << "############ AFTER INSERT ##################" << endl;
2354 		// btreeMng.dumpBTree();
2355 	    }
2356 
2357 	    pBTO = btreeList.Next();
2358 	}
2359 
2360 	/////////////////////////////////
2361 	// Step 7: Make rollback entry  //
2362 	/////////////////////////////////
2363 	// any exceptions also have to be catched ( e.g. temp space expired )
2364 	// to rollback the complete insert operation
2365 
2366 	if (oe.getType() == CegoObject::TABLE && getTID(oe.getTabSetId()) != 0)
2367 	{
2368 	    _pTM->newRBEntry(oe.getTabSetId(), getTID(oe.getTabSetId()), dp.getPageId(), dp.getOffset(), oe.getName());
2369 	}
2370     }
2371     catch ( Exception e)
2372     {
2373 	if ( dp != nil )
2374 	{
2375 	    deleteData(oe.getType(), oe.getTabSetId(), dp);
2376 
2377 	    /* if a checkpoint has occured during teh insert procedure, we have to sync again
2378 	       to have consistent data on disk */
2379 
2380 	    if ( _pDBMng->getCPCount() > cpCount )
2381 	    {
2382 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Forced checkpoint by insertDataTable"));
2383 		_pDBMng->writeCheckPoint(oe.getTabSetId(), true, Chain(""), 0,  _pLockHandle);
2384 	    }
2385 
2386 	    int i=0;
2387 	    CegoTableObject* pOE = idxList.First();
2388 	    while (pOE && i < idxInsertCount)
2389 	    {
2390 		if (pOE->getName() != virginIndex &&
2391 		    pOE->isValid() &&
2392 		    ( pOE->getType() == CegoObject::AVLTREE
2393 		      || pOE->getType() == CegoObject::UAVLTREE
2394 		      || pOE->getType() == CegoObject::PAVLTREE ) )
2395 		{
2396 		    char p[TABMNG_MAXINDEXVALUE];
2397 		    int len = TABMNG_MAXINDEXVALUE;
2398 		    int idxLen;
2399 
2400 		    extractIndexValue(fvl, pOE->getSchema(), p, len, idxLen);
2401 
2402 		    try
2403 		    {
2404 			// cout << "Deleting index for " << pOE->getName() << " of len " << idxLen << endl;
2405 			CegoAVLIndexManager idxMng(this);
2406 			idxMng.deleteIndexTable(oe.getTabSetId(), oe.getName(), oe.getType(),
2407 						pOE->getName(), pOE->getType(), pOE->getSchema(), dp, p, idxLen);
2408 		    }
2409 		    catch ( Exception e )
2410 		    {
2411 			Chain msg;
2412 			e.pop(msg);
2413 			throw Exception(EXLOC, Chain("Cannot delete index row : ") + msg);
2414 		    }
2415 		    i++;
2416 		}
2417 		pOE = idxList.Next();
2418 	    }
2419 
2420 	    CegoBTreeObject* pBTO = btreeList.First();
2421 
2422 	    i=0;
2423 	    while (pBTO && i < btreeInsertCount )
2424 	    {
2425 		if (pBTO->getName() != virginIndex &&
2426 		    pBTO->isValid() &&
2427 		    ( pBTO->getType() == CegoObject::BTREE
2428 		      || pBTO->getType() == CegoObject::UBTREE
2429 		      || pBTO->getType() == CegoObject::PBTREE ) )
2430 		{
2431 		    CegoBTreeValue btv;
2432 		    btv.valueFromSchema(fvl, pBTO->getSchema());
2433 
2434 		    try
2435 		    {
2436 			CegoBTreeManager btreeMng(this, pBTO);
2437 			btreeMng.deleteBTree(btv, dp, getTID(oe.getTabSetId()));
2438 		    }
2439 		    catch ( Exception e )
2440 		    {
2441 			Chain msg;
2442 			e.pop(msg);
2443 			throw Exception(EXLOC, Chain("Cannot delete btree row : ") + msg);
2444 		    }
2445 		    i++;
2446 		}
2447 
2448 		pBTO = btreeList.Next();
2449 	    }
2450 	}
2451 
2452 	throw e;
2453     }
2454 
2455     // increase lob refs here
2456 
2457     pF = fvl.First();
2458     while (pF)
2459     {
2460 	if ( pF->getValue().getType() == BLOB_TYPE  )
2461 	{
2462 	    PageIdType pageId;
2463 	    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
2464 
2465 	    increaseBlobRef(oe.getTabSetId(), pageId);
2466 	}
2467 	else if ( pF->getValue().getType() == CLOB_TYPE  )
2468 	{
2469 	    PageIdType pageId;
2470 	    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
2471 
2472 	    increaseClobRef(oe.getTabSetId(), pageId);
2473 	}
2474 
2475 	pF = fvl.Next();
2476     }
2477 
2478     if (oe.getType() == CegoObject::TABLE && doLogging == true)
2479     {
2480 
2481 	ListT<CegoBlob> blobList;
2482 	getBlobs(oe.getTabSetId(), fvl, blobList);
2483 
2484 	ListT<CegoClob> clobList;
2485 	getClobs(oe.getTabSetId(), fvl, clobList);
2486 
2487 	if ( blobList.Size() > 0 || clobList.Size() > 0 )
2488 	{
2489 
2490 	    encLen = CegoQueryHelper::encodeFVL(tid, tastep, ts, fvl, blobList, clobList, _pEncBuf, _encBufLen);
2491 
2492 	    CegoBlob *pBlob = blobList.First();
2493 	    while ( pBlob )
2494 	    {
2495 		pBlob->release();
2496 		pBlob = blobList.Next();
2497 	    }
2498 	    CegoClob *pClob = clobList.First();
2499 	    while ( pClob )
2500 	    {
2501 		pClob->release();
2502 		pClob = clobList.Next();
2503 	    }
2504 	}
2505 
2506 	lr.setObjectInfo(oe.getName(), CegoObject::TABLE);
2507 
2508 	lr.setAction(CegoLogRecord::LOGREC_INSERT);
2509 	lr.setData(_pEncBuf);
2510 	lr.setDataLen(encLen);
2511 
2512 	lr.setTID(getTID(oe.getTabSetId()));
2513 	if ( getTID(oe.getTabSetId()) > 0 )
2514 	    lr.setTAStep(_tastep[oe.getTabSetId()]);
2515 	else
2516 	    lr.setTAStep(0);
2517 
2518 	_pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle, flushLog);
2519     }
2520 }
2521 
updateDataTable(int tabSetId,const Chain & tableName,const Chain & tableAlias,CegoPredDesc * pPred,const ListT<CegoField> & updList,ListT<CegoExpr * > & exprList,bool returnOnFirst,ListT<CegoField> & returnList,CegoProcBlock * pBlock)2522 unsigned long long CegoTableManager::updateDataTable(int tabSetId, const Chain& tableName, const Chain& tableAlias,
2523 						     CegoPredDesc* pPred, const ListT<CegoField>& updList,
2524 						     ListT<CegoExpr*>& exprList, bool returnOnFirst, ListT<CegoField>& returnList,
2525 						     CegoProcBlock* pBlock)
2526 {
2527     ListT<CegoTableObject> idxList;
2528     ListT<CegoBTreeObject> btreeList;
2529     ListT<CegoKeyObject> keyList;
2530     ListT<CegoCheckObject> checkList;
2531     ListT<CegoTriggerObject> triggerList;
2532     ListT<CegoAliasObject> aliasList;
2533     int numInvalid;
2534 
2535     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
2536 
2537     if ( numInvalid > 0 )
2538     {
2539 	throw Exception(EXLOC, Chain("Invalid index detected, must be valid for update operations"));
2540     }
2541 
2542     unsigned long long updCount = updateDataTable(tabSetId, tableName, tableAlias,
2543 						  idxList, btreeList, keyList, checkList,
2544 						  pPred, updList, exprList, returnOnFirst, returnList, pBlock);
2545 
2546     return updCount;
2547 }
2548 
updateDataTable(int tabSetId,const Chain & tableName,const Chain & tableAlias,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,const ListT<CegoCheckObject> & checkList,CegoPredDesc * pPred,const ListT<CegoField> & updList,ListT<CegoExpr * > & exprList,bool returnOnFirst,ListT<CegoField> & returnList,CegoProcBlock * pBlock)2549 unsigned long long CegoTableManager::updateDataTable(int tabSetId, const Chain& tableName, const Chain& tableAlias,
2550 						     const ListT<CegoTableObject>& idxList,
2551 						     const ListT<CegoBTreeObject>& btreeList,
2552 						     const ListT<CegoKeyObject>& keyList,
2553 						     const ListT<CegoCheckObject>& checkList,
2554 						     CegoPredDesc* pPred,
2555 						     const ListT<CegoField>& updList,
2556 						     ListT<CegoExpr*>& exprList,
2557 						     bool returnOnFirst,
2558 						     ListT<CegoField>& returnList,
2559 						     CegoProcBlock* pBlock)
2560 {
2561 
2562     unsigned long long updCount = 0;
2563 
2564     unsigned long long tid = getTID(tabSetId);
2565 
2566     CegoLogRecord lr;
2567     lr.setObjectInfo(tableName, CegoObject::TABLE);
2568     lr.setAction(CegoLogRecord::LOGREC_UPDATE);
2569 
2570     // increase tastep to filter out modifications for this step for any cursor
2571     if ( tid != 0 )
2572 	_tastep[tabSetId]++;
2573 
2574     lr.setTID(tid);
2575     if ( tid > 0 )
2576 	lr.setTAStep(_tastep[tabSetId]);
2577     else
2578 	lr.setTAStep(0);
2579 
2580     CegoTableObject oe;
2581     CegoBufferPage bp;
2582     getObjectWithFix(tabSetId, tableName, CegoObject::TABLE, oe, bp);
2583 
2584     // make log entry first
2585 
2586     ListT<CegoBlob> blobList;
2587     getBlobs(oe.getTabSetId(), exprList, pBlock, blobList);
2588 
2589     ListT<CegoClob> clobList;
2590     getClobs(oe.getTabSetId(), exprList, pBlock, clobList);
2591 
2592 
2593     char *pLogBuf = 0;
2594     int logBuflen = 0;
2595 
2596     CegoQueryHelper::encodeUpdRec(tableAlias, pPred, updList, exprList, blobList, clobList, returnOnFirst, pBlock, pLogBuf, logBuflen);
2597 
2598     lr.setData(pLogBuf);
2599     lr.setDataLen(logBuflen);
2600 
2601     try
2602     {
2603 	CegoDataPointer sysEntry(bp.getPageId(), bp.getEntryPos());
2604 
2605 	ListT<CegoField> fl = oe.getSchema();
2606 
2607 	// init returnlist with empty schema
2608 	returnList = fl;
2609 
2610 	if ( tableName != tableAlias )
2611 	{
2612 	    // set up the defined alias for attribute evaluation
2613 	    CegoField *pF =  fl.First();
2614 	    while (pF)
2615 	    {
2616 		pF->setTableAlias(tableAlias);
2617 		pF = fl.Next();
2618 	    }
2619 	}
2620 
2621 	if (pPred == 0)
2622 	{
2623 #ifdef CGDEBUG
2624 	    _pDBMng->log(_modId, Logger::DEBUG, Chain("Updating ") + oe.getTabName() + Chain(" with fulltablescan"));
2625 #endif
2626 
2627 	    CegoTableCursor* pTC = new CegoTableCursor(this, tabSetId, oe.getTabName(), true);
2628 
2629 	    try
2630 	    {
2631 		bool moreTuple;
2632 
2633 		CegoDataPointer dp;
2634 
2635 		checkTypes(fl, updList);
2636 
2637 		moreTuple = pTC->getFirst(fl, dp);
2638 
2639 		while ( moreTuple && _isAborted == false && ( returnOnFirst == false || ( returnOnFirst == true && updCount == 0)) )
2640 		{
2641 
2642 		    /*
2643 		      Since we are inside a transaction and use ObjectCursor,
2644 		      we don't have to reset the Tablecursor to the beginning after modifying the
2645 		    */
2646 
2647 		    Chain virginIndex;
2648 		    if ( updateTuple(oe, sysEntry, dp, fl, updList, exprList, returnList, idxList, btreeList, keyList, checkList, virginIndex, _doAppend, pBlock) )
2649 			updCount++;
2650 
2651 		    moreTuple = pTC->getNext(fl, dp);
2652 		}
2653 	    }
2654 	    catch ( Exception e )
2655 	    {
2656 		delete pTC;
2657 		throw e;
2658 	    }
2659 
2660 	    delete pTC;
2661 
2662 	    if ( _isAborted )
2663 	    {
2664 		throw Exception(EXLOC, Chain("Update aborted by user"));
2665 	    }
2666 	}
2667 	else
2668 	{
2669 	    ListT<CegoField>* xfl[3];
2670 	    xfl[0] = &fl;
2671 	    if ( pBlock )
2672 		xfl[1] = pBlock->getTriggerValueList();
2673 	    else
2674 		xfl[1] = 0;
2675 	    xfl[2] = 0; // terminate in any case
2676 
2677 	    ListT<CegoSelect*> queryList;
2678 	    pPred->getSelectQueryList(queryList);
2679 	    CegoSelect **pSelect = queryList.First();
2680 	    while ( pSelect )
2681 	    {
2682 		(*pSelect)->setParentJoinBuf(xfl);
2683 		pSelect = queryList.Next();
2684 	    }
2685 	    pPred->analyzeSelect();
2686 
2687 	    CegoAttrCond ac;
2688 	    CegoQueryHelper::AttrCondMatch m = CegoQueryHelper::checkAttrCond(ac, pPred, fl, &fl,1, pBlock);
2689 
2690 	    if  ( m == CegoQueryHelper::COMPLETE )
2691 	    {
2692 		bool isAffected = false;
2693 
2694 		CegoAttrComp *pAC = 0;
2695 		pAC = ac.getAttrCompSet().First();
2696 
2697 		while ( pAC )
2698 		{
2699 		    CegoField *pF = updList.First();
2700 		    while ( pF && isAffected == false )
2701 		    {
2702 			if ( pF->getAttrName() == pAC->getAttrName() )
2703 			{
2704 			    isAffected = true;
2705 			}
2706 			else
2707 			{
2708 			    pF = updList.Next();
2709 			}
2710 		    }
2711 
2712 		    pAC = ac.getAttrCompSet().Next();
2713 
2714 		}
2715 		if ( isAffected == true )
2716 		    m = CegoQueryHelper::INAPP;
2717 	    }
2718 
2719 
2720 	    if ( m == CegoQueryHelper::INAPP )
2721 	    {
2722 #ifdef CGDEBUG
2723 		_pDBMng->log(_modId, Logger::DEBUG, Chain("Updating ") + oe.getTabName() + Chain(" with fulltablescan"));
2724 #endif
2725 
2726 		CegoTableCursor* pTC = new CegoTableCursor(this, tabSetId, oe.getTabName(), true);
2727 
2728 		try
2729 		{
2730 		    bool moreTuple;
2731 
2732 		    CegoDataPointer dp;
2733 
2734 		    checkTypes(fl, updList);
2735 
2736 		    moreTuple = pTC->getFirst(fl, dp);
2737 
2738 		    while ( moreTuple && _isAborted == false && ( returnOnFirst == false || ( returnOnFirst == true && updCount == 0 ) ) )
2739 		    {
2740 			pPred->clearAttrCache();
2741 
2742 			if ( CegoQueryHelper::evalPredicate(0, 0, xfl, 0, pPred, pBlock))
2743 			{
2744 			    Chain virginIndex;
2745 
2746 			    if ( updateTuple(oe, sysEntry, dp, fl, updList, exprList, returnList, idxList, btreeList, keyList, checkList, virginIndex, _doAppend, pBlock) )
2747 				updCount++;
2748 
2749 			    moreTuple = pTC->getNext(fl, dp);
2750 			}
2751 			else
2752 			{
2753 			    moreTuple = pTC->getNext(fl, dp);
2754 			}
2755 		    }
2756 		}
2757 		catch ( Exception e )
2758 		{
2759 		    // now we can release the index root page
2760 		    delete pTC;
2761 		    throw e;
2762 		}
2763 
2764 		delete pTC;
2765 
2766 		if ( _isAborted )
2767 		{
2768 		    throw Exception(EXLOC, Chain("Update aborted by user"));
2769 		}
2770 	    }
2771 	    else
2772 	    {
2773 #ifdef CGDEBUG
2774 		_pDBMng->log(_modId, Logger::DEBUG, Chain("Updating ") + oe.getTabName() + Chain(" using AttrCond ") + ac.toChain());
2775 #endif
2776 
2777 		CegoTableCursor *pTC = new CegoTableCursor(this, tabSetId, oe.getTabName(), true);
2778 		Chain virginIndex;
2779 
2780 		try
2781 		{
2782 		    checkTypes(fl, updList);
2783 
2784 		    CegoAttrCond::IndexMatch indexMatch = pTC->setup(ac);
2785 
2786 
2787 		    CegoObject::ObjectType virginType;
2788 
2789 		    if ( indexMatch == CegoAttrCond::FULL || indexMatch == CegoAttrCond::PART )
2790 		    {
2791 			virginIndex = pTC->getIndexName();
2792 			virginType = pTC->getIndexType();
2793 		    }
2794 
2795 #ifdef CGDEBUG
2796 		    _pDBMng->log(_modId, Logger::DEBUG, Chain("Virgin index is ") + virginIndex);
2797 #endif
2798 
2799 		    bool moreTuple;
2800 		    CegoDataPointer dp;
2801 
2802 		    moreTuple = pTC->getFirst(fl, dp);
2803 
2804 		    while ( moreTuple && _isAborted == false && ( returnOnFirst == false || ( returnOnFirst == true && updCount == 0 ) ) )
2805 		    {
2806 #ifdef CGDEBUG
2807 			_pDBMng->log(_modId, Logger::DEBUG, Chain("Checking pred for update ..."));
2808 #endif
2809 			pPred->clearAttrCache();
2810 			if ( CegoQueryHelper::evalPredicate(0, 0, xfl, 0, pPred, pBlock))
2811 			{
2812 #ifdef CGDEBUG
2813 			    _pDBMng->log(_modId, Logger::DEBUG, Chain("Updating tuple..."));
2814 #endif
2815 
2816 			    if ( updateTuple(oe, sysEntry, dp, fl, updList, exprList, returnList, idxList, btreeList, keyList, checkList, virginIndex, _doAppend, pBlock) )
2817 				updCount++;
2818 
2819 			    moreTuple = pTC->getNext(fl, dp);
2820 			}
2821 			else
2822 			{
2823 			    moreTuple = pTC->getNext(fl, dp);
2824 			}
2825 		    }
2826 #ifdef CGDEBUG
2827 		    _pDBMng->log(_modId, Logger::DEBUG, Chain("Commiting update "));
2828 #endif
2829 
2830 		    if ( virginIndex != Chain() )
2831 			_pTM->commitUpdate(tabSetId, virginIndex, virginType, getTID(tabSetId), _doAppend);
2832 		}
2833 		catch ( Exception e )
2834 		{
2835 		    if ( virginIndex != Chain() )
2836 		    {
2837 			_pTM->abortUpdate(tabSetId, getTID(tabSetId));
2838 		    }
2839 
2840 		    delete pTC;
2841 		    throw e;
2842 		}
2843 
2844 		delete pTC;
2845 
2846 		if ( _isAborted )
2847 		{
2848 		    throw Exception(EXLOC, Chain("Update aborted by user"));
2849 		}
2850 	    }
2851 	}
2852     }
2853     catch ( Exception e )
2854     {
2855 	if ( logBuflen > 0 )
2856 	    free ( pLogBuf );
2857 
2858 	// now we can release the index root page
2859 	_pDBMng->bufferUnfix(bp, true, _pLockHandle);
2860 	throw e;
2861     }
2862 
2863     _pDBMng->bufferUnfix(bp, true, _pLockHandle);
2864 
2865 #ifdef CGDEBUG
2866     _pDBMng->log(_modId, Logger::DEBUG, Chain("Update finished, updCount = ") + Chain(updCount));
2867 #endif
2868 
2869 
2870     /*
2871       for the update operation, we have to get the LSN AFTER successful operation
2872       otherwise, it may occur, that a checkpoint happens during the update with a higher LSN
2873       and so the operation is lost
2874     */
2875 
2876     // log update record
2877     lr.setLSN(_pDBMng->nextLSN(tabSetId));
2878     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
2879     if ( logBuflen > 0 )
2880 	free ( pLogBuf );
2881 
2882     return updCount;
2883 }
2884 
updateTuple(CegoTableObject & oe,const CegoDataPointer & sysEntry,const CegoDataPointer & dp,ListT<CegoField> & fl,const ListT<CegoField> & nfvl,ListT<CegoExpr * > & exprList,ListT<CegoField> & updSchema,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,const ListT<CegoCheckObject> & checkList,const Chain & virginIndex,bool doAppend,CegoProcBlock * pBlock)2885 bool CegoTableManager::updateTuple(CegoTableObject& oe, const CegoDataPointer& sysEntry, const CegoDataPointer& dp,
2886 				   ListT<CegoField>& fl,
2887 				   const ListT<CegoField>& nfvl,
2888 				   ListT<CegoExpr*>& exprList,
2889 				   ListT<CegoField>& updSchema,
2890 				   const ListT<CegoTableObject>& idxList,
2891 				   const ListT<CegoBTreeObject>& btreeList,
2892 				   const ListT<CegoKeyObject>& keyList,
2893 				   const ListT<CegoCheckObject>& checkList,
2894 				   const Chain& virginIndex,
2895 				   bool doAppend,
2896 				   CegoProcBlock* pBlock)
2897 {
2898 #ifdef CGDEBUG
2899     _pDBMng->log(_modId, Logger::DEBUG, Chain("Updating tuple for ") + oe.getTabName());
2900 #endif
2901 
2902     CegoField* pFV = nfvl.First();
2903     CegoExpr** pExpr = exprList.First();
2904 
2905     while ( pFV && pExpr)
2906     {
2907 	ListT<CegoField>* fla[3];
2908 	fla[0] = &fl;
2909 	if ( pBlock )
2910 	    fla[1] = pBlock->getTriggerValueList();
2911 	else
2912 	    fla[1] = 0;
2913 	fla[2] = 0;// terminate in any case
2914 
2915 	(*pExpr)->setFieldListArray(fla);
2916 	// set block must be set after setFieldListArray, since in CegoFactor, sub queries are prepared
2917 	// for preparation, field list array is needed
2918 	(*pExpr)->setBlock(pBlock);
2919 
2920 	(*pExpr)->clearAttrCache();
2921 
2922 	CegoFieldValue fv = (*pExpr)->evalFieldValue();
2923 
2924 	CegoQueryHelper::prepareFieldValue(pFV, fv, this, oe.getTabSetId());
2925 
2926 	pFV->setValue(fv);
2927 	pFV = nfvl.Next();
2928 	pExpr = exprList.Next();
2929     }
2930 
2931     if ( pFV || pExpr )
2932     {
2933 	throw Exception(EXLOC, Chain("Mismatched argument count for value list"));
2934     }
2935 
2936     // ListT<CegoField> updSchema = nfvl;
2937     updSchema = nfvl;
2938 
2939     // complete updSchema
2940     CegoField* pUF = fl.First();
2941     while ( pUF )
2942     {
2943 	if ( ! updSchema.Find( *pUF ) )
2944 	{
2945 	    updSchema.Insert( *pUF );
2946 	}
2947 	pUF = fl.Next();
2948     }
2949 
2950     bool updateDone=false;
2951     unsigned long long recLock = 0;
2952 
2953     try
2954     {
2955 	recLock = _pLockHandle->lockRecord(dp, CegoLockHandler::WRITE);
2956 
2957 	checkIntegrity( oe.getTabSetId(), oe.getTabName(), idxList, btreeList, keyList, checkList, dp, fl, updSchema);
2958 
2959 	/* the update operation is devided into a delete and an insert operation */
2960 	/* We dont have to write dedicated redo log entries, since a log entry for update is already done => logging = false */
2961 
2962 	// cout << "Deleting .." << endl;
2963 	if ( deleteDataTableEntry(oe.getTabSetId(), oe.getTabName(), oe.getType(), dp, fl, idxList, btreeList, keyList, false) )
2964 	{
2965 	    CegoDataPointer ndp;
2966 
2967 	    bool increaseStep = false;
2968 	    bool flushLog = true;
2969 	    insertDataTable(oe, updSchema, idxList, btreeList, keyList, checkList, sysEntry, virginIndex, ndp, false, doAppend, increaseStep, flushLog);
2970 
2971 	    if ( virginIndex != Chain() )
2972 	    {
2973 		_pTM->recordUpdate(oe.getTabSetId(), getTID(oe.getTabSetId()), ndp);
2974 	    }
2975 
2976 	    updateDone =  true;
2977 	}
2978 	else
2979 	{
2980 	    // if delete failed, we have to cleanup lob data
2981 	    CegoField* pF = updSchema.First();
2982 	    while ( pF)
2983 	    {
2984 		if ( pF->getValue().getType() == BLOB_TYPE && pF->getValue().getValue() != 0 )
2985 		{
2986 		    PageIdType pageId;
2987 		    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
2988 
2989 		    decreaseBlobRef(oe.getTabSetId(), pageId);
2990 		}
2991 
2992 		if ( pF->getValue().getType() == CLOB_TYPE && pF->getValue().getValue() != 0 )
2993 		{
2994 		    PageIdType pageId;
2995 		    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
2996 
2997 		    decreaseClobRef(oe.getTabSetId(), pageId);
2998 		}
2999 
3000 		pF = updSchema.Next();
3001 	    }
3002 	}
3003 
3004 	_pLockHandle->unlockRecord(recLock);
3005 	return updateDone;
3006     }
3007     catch ( Exception e )
3008     {
3009 	if ( recLock )
3010 	    _pLockHandle->unlockRecord(recLock);
3011 	throw e;
3012     }
3013 }
3014 
getKeyAndIdxRef(int tabSetId,const Chain & tableName,const Chain & attrName,ListT<CegoKeyObject> & refKeyList,ListT<CegoTableObject> & refIdxList,ListT<CegoBTreeObject> & refBTreeList)3015 void CegoTableManager::getKeyAndIdxRef(int tabSetId, const Chain& tableName, const Chain& attrName,
3016 				       ListT<CegoKeyObject>& refKeyList,
3017 				       ListT<CegoTableObject>& refIdxList,
3018 				       ListT<CegoBTreeObject>& refBTreeList)
3019 {
3020     ListT<CegoTableObject> idxList;
3021     ListT<CegoBTreeObject> btreeList;
3022     ListT<CegoKeyObject> keyList;
3023     ListT<CegoCheckObject> checkList;
3024     ListT<CegoTriggerObject> triggerList;
3025     ListT<CegoAliasObject> aliasList;
3026     int numInvalid;
3027 
3028     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
3029 
3030     if ( ! keyList.isEmpty() )
3031     {
3032 	CegoKeyObject* pKey = keyList.First();
3033 	while ( pKey )
3034 	{
3035 	    if ( (Chain)pKey->getTabName() == (Chain)tableName )
3036 	    {
3037 		CegoField *pF = pKey->getKeySchema().First();
3038 		while ( pF )
3039 		{
3040 		    if ( pF->getAttrName() == attrName )
3041 		    {
3042 			refKeyList.Insert(*pKey);
3043 		    }
3044 		    pF = pKey->getKeySchema().Next();
3045 		}
3046 	    }
3047 	    else if ( (Chain)pKey->getRefTable() == (Chain)tableName )
3048 	    {
3049 		CegoField *pF = pKey->getRefSchema().First();
3050 		while ( pF )
3051 		{
3052 		    if ( pF->getAttrName() == attrName )
3053 		    {
3054 			refKeyList.Insert(*pKey);
3055 		    }
3056 		    pF = pKey->getRefSchema().Next();
3057 		}
3058 	    }
3059 	    pKey = keyList.Next();
3060 	}
3061     }
3062     if ( ! idxList.isEmpty() )
3063     {
3064 	CegoTableObject* pIdx = idxList.First();
3065 	while ( pIdx )
3066 	{
3067 	    CegoField *pF = pIdx->getSchema().First();
3068 	    while ( pF )
3069 	    {
3070 		if ( pF->getAttrName() == attrName )
3071 		{
3072 		    refIdxList.Insert(*pIdx);
3073 		    // return true;
3074 		}
3075 		pF = pIdx->getSchema().Next();
3076 	    }
3077 	    pIdx = idxList.Next();
3078 	}
3079     }
3080 
3081     if ( ! btreeList.isEmpty() )
3082     {
3083 	CegoBTreeObject* pBTree = btreeList.First();
3084 	while ( pBTree )
3085 	{
3086 	    CegoField *pF = pBTree->getSchema().First();
3087 	    while ( pF )
3088 	    {
3089 		if ( pF->getAttrName() == attrName )
3090 		{
3091 		    refBTreeList.Insert(*pBTree);
3092 		    // return true;
3093 		}
3094 		pF = pBTree->getSchema().Next();
3095 	    }
3096 	    pBTree = btreeList.Next();
3097 	}
3098     }
3099 
3100     return;
3101 }
3102 
keyReferenceExists(int tabSetId,const Chain & tableName,const ListT<CegoField> & fl,const ListT<CegoKeyObject> & keyList)3103 bool CegoTableManager::keyReferenceExists(int tabSetId, const Chain& tableName, const ListT<CegoField>& fl, const ListT<CegoKeyObject>& keyList)
3104 {
3105     if ( ! keyList.isEmpty() )
3106     {
3107         CegoKeyObject* pKey = keyList.First();
3108         while ( pKey )
3109         {
3110             if ( (Chain)pKey->getRefTable() == (Chain)tableName )
3111             {
3112                 CegoTableCursor tc(this, tabSetId, pKey->getTabName());
3113 
3114                 CegoField *pKF = pKey->getKeySchema().First();
3115                 CegoField *pRF = pKey->getRefSchema().First();
3116 
3117                 CegoAttrCond ac;
3118 
3119                 while ( pKF && pRF )
3120                 {
3121                     CegoField *pF = fl.Find(*pRF);
3122                     // cout << "Setting up " << pKF->getAttrName() << " = " <<  pF->getValue() << endl;
3123                     ac.add(CegoAttrComp(pKF->getTableAlias(), pKF->getAttrName(), EQUAL, pF->getValue()));
3124 
3125                     pKF = pKey->getKeySchema().Next();
3126                     pRF = pKey->getRefSchema().Next();
3127                 }
3128 
3129 		CegoTableObject oe;
3130 		getObject(tabSetId, pKey->getTabName(), CegoObject::TABLE, oe);
3131 
3132 		ListT<CegoField> kfl = oe.getSchema();
3133 
3134                 pKF = kfl.First();
3135                 while ( pKF )
3136                 {
3137                     pKF->setTableName(pKey->getTabName());
3138                     pKF->setTableAlias(pKey->getTabName());
3139 
3140                     CegoField *pF = fl.Find(CegoField(pKF->getTableAlias(), pKF->getAttrName()));
3141                     if ( pF )
3142                     {
3143 			pKF->setId(pF->getId());
3144                     }
3145                     pKF = kfl.Next();
3146                 }
3147                 CegoDataPointer dp;
3148 
3149 		CegoAttrCond::IndexMatch indexMatch = tc.setup(ac);
3150                 bool moreTuple = tc.getFirst(kfl, dp);
3151 
3152                 if ( indexMatch == CegoAttrCond::FULL )
3153                 {
3154 		    if ( moreTuple )
3155 		    {
3156 			// treat self refering tables
3157 			if ( pKey->getRefTable() == pKey->getTabName() )
3158 			{
3159 			    pRF = pKey->getRefSchema().First();
3160 			    while ( pRF )
3161 			    {
3162 				// we just search for attrname, since must be unique and tablename could be setup with alias
3163 				CegoField *pF = fl.Find(CegoField(Chain(), pRF->getAttrName()));
3164 				if ( pF )
3165 				{
3166 				    CegoField *pKFV = kfl.Find(*pRF);
3167 				    if ( pKFV )
3168 				    {
3169 					if ( ! ( (CegoFieldValue)pF->getValue() == (CegoFieldValue)pKFV->getValue()) )
3170 					{
3171 					    // cursor tuple is not the to-deleted tuple, so we really found a key reference
3172 					    return true;
3173 					}
3174 				    }
3175 				    else
3176 				    {
3177 					Chain msg = Chain("Unknown key attribute <" ) + pRF->getAttrName() + Chain(">");
3178 					throw Exception(EXLOC, msg);
3179 				    }
3180 				}
3181 				pRF = pKey->getRefSchema().Next();
3182 			    }
3183 			}
3184 			else
3185 			{
3186 			    return true;
3187 			}
3188 		    }
3189                 }
3190                 else
3191                 {
3192 		    while ( moreTuple )
3193 		    {
3194 			bool isMatch = true;
3195 			pKF = pKey->getKeySchema().First();
3196 			pRF = pKey->getRefSchema().First();
3197 			while ( pKF && pRF && isMatch)
3198 			{
3199 			    // we just search for attrname, since must be unique and tablename could be setup with alias
3200 			    CegoField *pF = fl.Find(CegoField(Chain(), pRF->getAttrName()));
3201 			    if ( pF )
3202 			    {
3203 				CegoField *pKFV = kfl.Find(*pKF);
3204 				if ( ! ( (CegoFieldValue)pF->getValue() == (CegoFieldValue)pKFV->getValue()) )
3205 				{
3206 				    isMatch=false;
3207 				}
3208 			    }
3209 			    else
3210 			    {
3211 				Chain msg = Chain("Unknown key attribute <" ) + pKF->getAttrName() + Chain(">");
3212 				throw Exception(EXLOC, msg);
3213 			    }
3214 			    pRF = pKey->getRefSchema().Next();
3215 			    pKF = pKey->getKeySchema().Next();
3216 			}
3217 			if ( isMatch )
3218 			{
3219 			    // for self refering keys, we still have to check primary key, if cursor tuple != delete tuple
3220 
3221 			    if ( pKey->getRefTable() == pKey->getTabName() )
3222 			    {
3223 				pRF = pKey->getRefSchema().First();
3224 				while ( pRF )
3225 				{
3226 				    // we just search for attrname, since must be unique and tablename could be setup with alias
3227 				    CegoField *pF = fl.Find(CegoField(Chain(), pRF->getAttrName()));
3228 				    if ( pF )
3229 				    {
3230 					CegoField *pKFV = kfl.Find(*pRF);
3231 					if ( pKFV )
3232 					{
3233 					    if ( ! ( (CegoFieldValue)pF->getValue() == (CegoFieldValue)pKFV->getValue()) )
3234 					    {
3235 						// cursor tuple is not the to-deleted tuple, so we really found a key reference
3236 						return true;
3237 					    }
3238 					}
3239 					else
3240 					{
3241 					    Chain msg = Chain("Unknown key attribute <" ) + pRF->getAttrName() + Chain(">");
3242 					    throw Exception(EXLOC, msg);
3243 					}
3244 				    }
3245 				    pRF = pKey->getRefSchema().Next();
3246 				}
3247 			    }
3248 			    else
3249 			    {
3250 				return true;
3251 			    }
3252 			}
3253 			moreTuple = tc.getNext(kfl, dp);
3254                     }
3255                 }
3256             }
3257             pKey = keyList.Next();
3258         }
3259     }
3260     return false;
3261 }
3262 
checkIntegrity(int tabSetId,const Chain & tableName,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,const ListT<CegoCheckObject> & checkList,const CegoDataPointer & dp,const ListT<CegoField> & fvl,const ListT<CegoField> & nfvl)3263 void CegoTableManager::checkIntegrity(int tabSetId,
3264 				      const Chain& tableName,
3265 				      const ListT<CegoTableObject>& idxList,
3266 				      const ListT<CegoBTreeObject>& btreeList,
3267 				      const ListT<CegoKeyObject>& keyList,
3268 				      const ListT<CegoCheckObject>& checkList,
3269 				      const CegoDataPointer& dp, const ListT<CegoField>& fvl, const ListT<CegoField>& nfvl)
3270 {
3271     /*
3272     if ( ! idxList.isEmpty() )
3273     {
3274 	if ( checkIndexIntegrity(idxList, tabSetId, dp, fvl, nfvl) == false )
3275 	    throw Exception(EXLOC, Chain("Constraint violation on unique index"));
3276     }
3277     */
3278 
3279     /*
3280     if ( ! btreeList.isEmpty() )
3281     {
3282 	if ( checkBTreeIntegrity(btreeList, tabSetId, dp, fvl, nfvl) == false )
3283 	    throw Exception(EXLOC, Chain("Constraint violation on unique btree"));
3284     }
3285     */
3286 
3287     /*
3288     if ( ! keyList.isEmpty() )
3289     {
3290 	if ( checkKeyIntegrity(keyList, tabSetId, tableName, fvl, nfvl) == false )
3291 	    throw Exception(EXLOC, Chain("Constraint violation on foreign key"));
3292     }
3293     */
3294 
3295     checkIndexIntegrity(idxList, tabSetId, dp, fvl, nfvl);
3296     checkBTreeIntegrity(btreeList, tabSetId, dp, fvl, nfvl);
3297     checkKeyIntegrity(keyList, tabSetId, tableName, fvl, nfvl);
3298     checkCheckIntegrity(checkList, nfvl);
3299 
3300 }
3301 
checkKeyIntegrity(const ListT<CegoKeyObject> & keyList,int tabSetId,const Chain & tableName,const ListT<CegoField> & fvl,const ListT<CegoField> & nfvl)3302 void CegoTableManager::checkKeyIntegrity(const ListT<CegoKeyObject>& keyList, int tabSetId, const Chain& tableName, const ListT<CegoField>& fvl, const ListT<CegoField>& nfvl)
3303 {
3304     CegoKeyObject* pKey = keyList.First();
3305     while ( pKey )
3306     {
3307         if ( (Chain)pKey->getRefTable() == (Chain)tableName )
3308         {
3309             CegoTableCursor tc(this, tabSetId, pKey->getTabName());
3310             CegoField *pRF, *pKF;
3311 
3312             // get reference key value from old tuple value
3313             ListT<CegoField> rfl = pKey->getRefSchema();
3314             pRF = rfl.First();
3315             while ( pRF )
3316             {
3317                 CegoField *pF = fvl.Find(*pRF);
3318                 if ( pF )
3319                 {
3320                     pRF->setValue(pF->getValue());
3321                 }
3322 		else
3323 		{
3324 		    Chain msg = Chain("Unknown reference attribute <" ) + pRF->getAttrName() + Chain(">");
3325 		    throw Exception(EXLOC, msg);
3326 		}
3327 
3328                 pRF = rfl.Next();
3329             }
3330 
3331             CegoAttrCond ac;
3332             pKF = pKey->getKeySchema().First();
3333             pRF = rfl.First();
3334             while ( pKF && pRF )
3335             {
3336                 ac.add(CegoAttrComp(pKey->getTabName(), pKF->getAttrName(), EQUAL, pRF->getValue()));
3337 
3338                 pKF = pKey->getKeySchema().Next();
3339                 pRF = rfl.Next();
3340             }
3341 
3342             CegoAttrCond::IndexMatch indexMatch = tc.setup(ac);
3343 
3344             CegoTableObject oe;
3345             getObject(tabSetId, pKey->getTabName(), CegoObject::TABLE, oe);
3346 
3347             ListT<CegoField> kfl = pKey->getKeySchema();
3348             pKF = kfl.First();
3349             while ( pKF )
3350             {
3351                 pKF->setTableName(pKey->getTabName());
3352                 pKF->setTableAlias(pKey->getTabName());
3353 
3354                 CegoField *pF = oe.getSchema().Find(CegoField(pKey->getTabName(), pKF->getAttrName()));
3355                 if ( pF )
3356                 {
3357                     pKF->setId(pF->getId());
3358                     pKF = kfl.Next();
3359                 }
3360             }
3361 
3362             CegoDataPointer dp;
3363             bool moreTuple = tc.getFirst(kfl, dp);
3364 
3365             if ( indexMatch == CegoAttrCond::FULL )
3366             {
3367                 if ( moreTuple )
3368                 {
3369                     bool keyMatch=true;
3370                     pKF = kfl.First();
3371                     pRF = rfl.First();
3372                     while ( pKF && pRF && keyMatch)
3373                     {
3374 			// we must search for undefined tablename, since for update opertions, also an alias could be setup
3375                         CegoField *pNF = nfvl.Find(CegoField(Chain(), pRF->getAttrName()));
3376                         if ( pNF )
3377                         {
3378                             if ( ! ( (CegoFieldValue)pNF->getValue() == (CegoFieldValue)pKF->getValue()) )
3379                             {
3380                                 keyMatch=false;
3381                             }
3382                         }
3383                         pKF = kfl.Next();
3384                     }
3385                     if ( keyMatch == false )
3386 		    {
3387 			Chain msg = Chain("Foreign key " ) + pKey->getName() + Chain(" violated");
3388 			throw Exception(EXLOC, msg);
3389 
3390                         // return false;
3391 		    }
3392                     return; //  true;
3393                 }
3394                 return; //  true;
3395             }
3396             else
3397             {
3398                 while ( moreTuple )
3399                 {
3400                     bool isMatch = true;
3401                     pKF = kfl.First();
3402                     pRF = rfl.First();
3403                     while ( pKF && pRF && isMatch)
3404                     {
3405 			// we must search for undefined tablename, since for update opertions, also an alias could be setup
3406                         CegoField *pF = fvl.Find(CegoField(Chain(), pRF->getAttrName()));
3407                         if ( pF )
3408                         {
3409                             if ( ! ( (CegoFieldValue)pF->getValue() == (CegoFieldValue)pKF->getValue()) )
3410                             {
3411                                 isMatch=false;
3412                             }
3413                         }
3414                         else
3415                         {
3416 			    Chain msg = Chain("Unknown key attribute <" ) + pKF->getAttrName() + Chain(">");
3417 			    throw Exception(EXLOC, msg);
3418                         }
3419                         pRF = rfl.Next();
3420                         pKF = kfl.Next();
3421                     }
3422                     if ( isMatch )
3423                     {
3424                         bool keyMatch=true;
3425                         pKF = kfl.First();
3426                         pRF = rfl.First();
3427                         while ( pKF && pRF && keyMatch)
3428                         {
3429 			    // we must search for undefined tablename, since for update opertions, also an alias could be setup
3430                             CegoField *pNF = nfvl.Find(CegoField(Chain(), pRF->getAttrName()));
3431                             if ( pNF )
3432                             {
3433                                 if ( ! ( (CegoFieldValue)pNF->getValue() == (CegoFieldValue)pKF->getValue()) )
3434                                 {
3435                                     keyMatch=false;
3436                                 }
3437                             }
3438 			    else
3439 			    {
3440 				Chain msg = Chain("Unknown reference attribute <" ) + pRF->getAttrName() + Chain(">");
3441 				throw Exception(EXLOC, msg);
3442 			    }
3443                             pRF = rfl.Next();
3444                             pKF = kfl.Next();
3445                         }
3446                         if ( keyMatch == false )
3447 			{
3448 			    Chain msg = Chain("Foreign key " ) + pKey->getName() + Chain(" violated");
3449 			    throw Exception(EXLOC, msg);
3450 			    //    return false;
3451 			}
3452 
3453                     }
3454                     moreTuple = tc.getNext(kfl, dp);
3455                 }
3456 
3457                 return; // true;
3458             }
3459         }
3460        pKey = keyList.Next();
3461     }
3462     return; // true;
3463 }
3464 
checkIndexIntegrity(const ListT<CegoTableObject> & idxList,int tabSetId,const CegoDataPointer & dp,const ListT<CegoField> & fvl,const ListT<CegoField> & nfvl)3465 void CegoTableManager::checkIndexIntegrity(const ListT<CegoTableObject>& idxList, int tabSetId, const CegoDataPointer& dp, const ListT<CegoField>& fvl, const ListT<CegoField>& nfvl)
3466 {
3467     CegoTableObject* pOE = idxList.First();
3468 
3469     while (pOE)
3470     {
3471 	if ( pOE->getType() == CegoObject::UAVLTREE
3472 	     || pOE->getType() == CegoObject::PAVLTREE )
3473 	{
3474 	    CegoFieldValue fv = getIndexSearchValue(pOE->getSchema(), nfvl);
3475 
3476 	    CegoField *pF = pOE->getSchema().First();
3477 
3478 	    CegoAttrCond ac;
3479 	    ac.add(CegoAttrComp( pF->getTableAlias(), pF->getAttrName(), EQUAL, fv));
3480 
3481 	    CegoAVLIndexCursor ic(this, tabSetId, pOE->getName(), pOE->getType(), &ac, false, true);
3482 
3483 	    CegoDataPointer ndp;
3484 	    bool attrMatch = ic.getFirst(pOE->getSchema(), ndp);
3485 
3486 	    while ( attrMatch )
3487 	    {
3488 		CegoField *pIF = pOE->getSchema().First();
3489 		while ( pIF && attrMatch )
3490 		{
3491 		    CegoField *pNF = nfvl.Find(*pIF);
3492 
3493 		    if ( pNF )
3494 		    {
3495 			if ( pNF->getValue() != pIF->getValue() )
3496 			    attrMatch = false;
3497 			else
3498 			    pIF = pOE->getSchema().Next();
3499 		    }
3500 		    else
3501 		    {
3502 			pIF = pOE->getSchema().Next();
3503 		    }
3504 		}
3505 
3506 		if ( ndp != dp && attrMatch )
3507 		{
3508 		    ic.abort();
3509 
3510 		    Chain msg = Chain("Duplicate entry for index " ) + pOE->getName();
3511 		    throw Exception(EXLOC, msg);
3512 
3513 		    // return false;
3514 		}
3515 
3516 		attrMatch = ic.getNext(pOE->getSchema(), ndp);
3517 	    }
3518 	}
3519 	pOE = idxList.Next();
3520     }
3521     return; // true;
3522 }
3523 
checkBTreeIntegrity(const ListT<CegoBTreeObject> & btreeList,int tabSetId,const CegoDataPointer & dp,const ListT<CegoField> & fvl,const ListT<CegoField> & nfvl)3524 void CegoTableManager::checkBTreeIntegrity(const ListT<CegoBTreeObject>& btreeList, int tabSetId, const CegoDataPointer& dp, const ListT<CegoField>& fvl, const ListT<CegoField>& nfvl)
3525 {
3526     CegoBTreeObject* pOE = btreeList.First();
3527 
3528     while (pOE)
3529     {
3530 	if ( pOE->getType() == CegoObject::UBTREE
3531 	     || pOE->getType() == CegoObject::PBTREE )
3532 	{
3533 	    CegoFieldValue fv = getIndexSearchValue(pOE->getSchema(), nfvl);
3534 
3535 	    CegoField *pF = pOE->getSchema().First();
3536 
3537 	    CegoAttrCond ac;
3538 	    ac.add(CegoAttrComp( pF->getTableAlias(), pF->getAttrName(), EQUAL, fv));
3539 
3540 	    CegoBTreeCursor btc(this, tabSetId, pOE->getName(), pOE->getType(), &ac, false, true);
3541 
3542 	    CegoDataPointer ndp;
3543 	    bool attrMatch = btc.getFirst(pOE->getSchema(), ndp);
3544 
3545 	    while ( attrMatch )
3546 	    {
3547 		CegoField *pIF = pOE->getSchema().First();
3548 		while ( pIF && attrMatch )
3549 		{
3550 		    CegoField *pNF = nfvl.Find(*pIF);
3551 
3552 		    if ( pNF )
3553 		    {
3554 			if ( pNF->getValue() != pIF->getValue() )
3555 			    attrMatch = false;
3556 			else
3557 			    pIF = pOE->getSchema().Next();
3558 		    }
3559 		    else
3560 		    {
3561 			pIF = pOE->getSchema().Next();
3562 		    }
3563 		}
3564 
3565 		if ( ndp != dp && attrMatch )
3566 		{
3567 		    // we still have to check the tuple state, it might be that the found entry
3568 		    // was made by another transaction and is still not commited
3569 
3570 		    unsigned long long tid;
3571 		    unsigned long long tastep;
3572 		    CegoTupleState ts;
3573 
3574 		    getTupleInfo(tabSetId, ndp, tid, tastep, ts);
3575 
3576 		    if ( ts == COMMITTED )
3577 		    {
3578 			//  just if the tuple state is commited,
3579 			//  we have detected a duplicate
3580 
3581 			btc.abort();
3582 
3583 			Chain msg = Chain("Dupliate entry for btree " ) + pOE->getName();
3584 			throw Exception(EXLOC, msg);
3585 
3586 
3587 			// return false;
3588 		    }
3589 		}
3590 
3591 		attrMatch = btc.getNext(pOE->getSchema(), ndp);
3592 	    }
3593 
3594 	}
3595 	pOE = btreeList.Next();
3596     }
3597     return; //  true;
3598 }
3599 
checkCheckIntegrity(const ListT<CegoCheckObject> & checkList,const ListT<CegoField> & nfvl)3600 void CegoTableManager::checkCheckIntegrity(const ListT<CegoCheckObject>& checkList, const ListT<CegoField>& nfvl)
3601 {
3602     if ( ! checkList.isEmpty() )
3603     {
3604 	// we need to make a copy, since nvfl ist const
3605 	ListT<CegoField> fvl = nfvl;
3606 
3607 	CegoCheckObject* pCheck = checkList.First();
3608 	while ( pCheck )
3609 	{
3610 	    pCheck->getPredDesc()->clearAttrCache();
3611 
3612 	    ListT<CegoField>* xfl[2];
3613 	    xfl[0] = &fvl;
3614 	    xfl[1] = 0;
3615 
3616 	    if ( CegoQueryHelper::evalPredicate(0, 0, xfl, 0, pCheck->getPredDesc(), 0) == false )
3617 	    {
3618 		Chain msg = Chain("Check constraint ") + pCheck->getName() + Chain(" violated");
3619 		throw Exception(EXLOC, msg);
3620 	    }
3621 
3622 	    pCheck = checkList.Next();
3623 	}
3624     }
3625     return; // true;
3626 }
3627 
checkNullValue(int tabSetId,const Chain & tableName,const CegoField & f)3628 bool CegoTableManager::checkNullValue(int tabSetId, const Chain& tableName, const CegoField& f)
3629 {
3630     CegoTableCursor *pTC = new CegoTableCursor(this, tabSetId, tableName);
3631     CegoAttrCond attrCond;
3632     CegoFieldValue nullValue;
3633 
3634     bool hasNullValue = false;
3635 
3636     attrCond.add(CegoAttrComp(f.getTableAlias(), f.getAttrName(), EQUAL, nullValue));
3637     CegoAttrCond::IndexMatch m = pTC->setup(attrCond);
3638     CegoDataPointer dp;
3639     ListT<CegoField> fl;
3640     CegoField *pF;
3641 
3642     if ( m == CegoAttrCond::INAPP )
3643     {
3644 	fl.Insert(f);
3645 	if ( pTC->getFirst(fl, dp) )
3646 	{
3647 	    pF = fl.First();
3648 	    if ( pF )
3649 	    {
3650 		if ( pF->getValue() == nullValue )
3651 		{
3652 		    hasNullValue = true;
3653 		}
3654 		else
3655 		{
3656 		    while ( pTC->getNext(fl, dp) && hasNullValue == false)
3657 		    {
3658 			pF = fl.First();
3659 			if ( pF )
3660 			{
3661 			    if ( pF->getValue() == nullValue )
3662 			    {
3663 				hasNullValue = true;
3664 			    }
3665 			}
3666 		    }
3667 		}
3668 	    }
3669 	}
3670     }
3671     else
3672     {
3673 	fl.Insert(f);
3674 	if ( pTC->getFirst(fl, dp) )
3675 	{
3676 	    hasNullValue = true;
3677 	}
3678     }
3679     pTC->abort();
3680     delete pTC;
3681 
3682     return hasNullValue;
3683 }
3684 
checkTypes(const ListT<CegoField> & fl,const ListT<CegoField> & nfl)3685 void CegoTableManager::checkTypes(const ListT<CegoField>& fl, const ListT<CegoField>& nfl)
3686 {
3687     CegoField *pF = fl.First();
3688     while ( pF )
3689     {
3690 	CegoField *pD = nfl.Find(*pF);
3691 	if ( pD )
3692 	{
3693 	    if ( pD->getType() != pF->getType() )
3694 	    {
3695 		throw Exception(EXLOC, Chain("Mismatched data type <")
3696 				+ CEGO_TYPE_MAP[(int)(pD->getType())]
3697 				+ Chain("> for attribute ") + pF->getAttrName()
3698 				+ Chain(", expected type <")
3699 				+ CEGO_TYPE_MAP[(int)(pF->getType())]
3700 				+ Chain(">"));
3701 
3702 	    }
3703 	}
3704 	pF = fl.Next();
3705     }
3706 }
3707 
getIndexSearchValue(const ListT<CegoField> & idxSchema,const ListT<CegoField> & nfvl)3708 const CegoFieldValue& CegoTableManager::getIndexSearchValue(const ListT<CegoField>& idxSchema, const ListT<CegoField>& nfvl)
3709 {
3710     CegoField *pSF = idxSchema.First();
3711 
3712     CegoField *pVF = nfvl.First();
3713     while ( pVF )
3714     {
3715 	if ( (Chain)pSF->getAttrName() == (Chain)pVF->getAttrName() )
3716 	    return pVF->getValue();
3717 	pVF = nfvl.Next();
3718     }
3719 
3720     throw Exception(EXLOC, Chain("No index value found"));
3721 }
3722 
deleteDataTable(CegoTableObject & oe,CegoPredDesc * pPred,CegoProcBlock * pBlock,bool isSynced)3723 unsigned long long CegoTableManager::deleteDataTable(CegoTableObject& oe, CegoPredDesc* pPred, CegoProcBlock* pBlock, bool isSynced)
3724 {
3725     ListT<CegoTableObject> idxList;
3726     ListT<CegoBTreeObject> btreeList;
3727     ListT<CegoKeyObject> keyList;
3728     ListT<CegoCheckObject> checkList;
3729     ListT<CegoTriggerObject> triggerList;
3730     ListT<CegoAliasObject> aliasList;
3731     int numInvalid;
3732 
3733     getObjectListByTable(oe.getTabSetId(), oe.getTabName(), idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
3734 
3735     if ( numInvalid > 0 )
3736     {
3737 	throw Exception(EXLOC, Chain("Invalid index detected, must be valid for delete opertions"));
3738     }
3739 
3740     return deleteDataTable(oe, idxList, btreeList, keyList, pPred, pBlock, isSynced);
3741 }
3742 
deleteDataTable(CegoTableObject & oe,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,CegoPredDesc * pPred,CegoProcBlock * pBlock,bool isSynced)3743 unsigned long long CegoTableManager::deleteDataTable(CegoTableObject& oe,
3744 						     const ListT<CegoTableObject>& idxList,
3745 						     const ListT<CegoBTreeObject>& btreeList,
3746 						     const ListT<CegoKeyObject>& keyList,
3747 						     CegoPredDesc* pPred, CegoProcBlock* pBlock, bool isSynced)
3748 {
3749     unsigned long tid = getTID(oe.getTabSetId());
3750 
3751     // prepare log entry first
3752     CegoLogRecord lr;
3753     lr.setObjectInfo(oe.getName(), oe.getType());
3754     lr.setAction(CegoLogRecord::LOGREC_DELETE);
3755     lr.setTID(tid);
3756 
3757     if ( tid != 0 )
3758 	_tastep[oe.getTabSetId()]++;
3759 
3760     if ( tid > 0 )
3761 	lr.setTAStep(_tastep[oe.getTabSetId()]);
3762     else
3763 	lr.setTAStep(0);
3764 
3765     unsigned long long delCount = 0;
3766 
3767     if (pPred == 0)
3768     {
3769 	CegoTableCursor* pTC = new CegoTableCursor(this, oe.getTabSetId(), oe.getTabName(), true);
3770 
3771 	try
3772 	{
3773 	    bool moreTuple;
3774 
3775 	    CegoDataPointer dp;
3776 	    ListT<CegoField> fl = oe.getSchema();
3777 
3778 	    moreTuple = pTC->getFirst(fl, dp);
3779 
3780 	    while (moreTuple && _isAborted == false )
3781 	    {
3782 		ListT<CegoField> nfl = oe.getSchema();
3783 		CegoDataPointer ndp;
3784 		moreTuple = pTC->getNext(nfl, ndp);
3785 
3786 		deleteDataTableEntrySynced(oe.getTabSetId(), oe.getTabName(), CegoObject::TABLE, dp, fl, idxList, btreeList, keyList, true, false, isSynced);
3787 
3788 		delCount++;
3789 
3790 		if ( moreTuple )
3791 		{
3792 		    dp = ndp;
3793 		    fl = nfl;
3794 		}
3795 	    }
3796 
3797 	    delete pTC;
3798 	}
3799 	catch ( Exception e)
3800 	{
3801 	    delete pTC;
3802 	    throw e;
3803 	}
3804     }
3805     else
3806     {
3807 	if ( oe.getTabName() != oe.getTabAlias() )
3808 	{
3809 	    // set up the defined alias for attribute evaluation
3810 	    CegoField *pF = oe.getSchema().First();
3811 	    while (pF)
3812 	    {
3813 		pF->setTableAlias(oe.getTabAlias());
3814 		pF = oe.getSchema().Next();
3815 	    }
3816 	}
3817 
3818 	ListT<CegoField> fl = oe.getSchema();
3819 
3820 	// we need to create an additional reference to use the setFieldListArray method
3821 	ListT<CegoField>* xfl[3];
3822 	xfl[0] = &fl;
3823 	if ( pBlock )
3824 	    xfl[1] = pBlock->getTriggerValueList();
3825 	else
3826 	    xfl[1] = 0;
3827 	xfl[2] = 0; // terminate in any case
3828 
3829 	ListT<CegoSelect*> queryList;
3830 	pPred->getSelectQueryList(queryList);
3831 	CegoSelect **pSelect = queryList.First();
3832 	while ( pSelect )
3833 	{
3834 	    (*pSelect)->setParentJoinBuf(xfl);
3835 	    pSelect = queryList.Next();
3836 	}
3837 
3838 	pPred->analyzeSelect();
3839 
3840 	// we have to resolve external references in a second step, since they are handled with lower priority
3841 	pSelect = queryList.First();
3842 	while ( pSelect )
3843 	{
3844 	    // before evaluating external table references, we have to prepare to resolve native query attributes first
3845 	    (*pSelect)->prepare();
3846 
3847 	    (*pSelect)->evalExtTableReferences(&oe, fl);
3848 	    pSelect = queryList.Next();
3849 	}
3850 
3851 	CegoAttrCond ac;
3852 	CegoQueryHelper::AttrCondMatch m = CegoQueryHelper::checkAttrCond(ac, pPred, fl, &fl, 1, pBlock);
3853 
3854 	CegoTableCursor *pTC = new CegoTableCursor(this, oe.getTabSetId(), oe.getTabName(), true);
3855 
3856 	try
3857 	{
3858 	    CegoAttrCond::IndexMatch idxMatch = CegoAttrCond::INAPP;
3859 
3860 	    if ( m != CegoQueryHelper::INAPP )
3861 		idxMatch = pTC->setup(ac);
3862 
3863 	    if ( idxMatch == CegoAttrCond::INAPP )
3864 	    {
3865 		ListT<CegoField> ufl = (ListT<CegoField>)oe.getSchema();
3866 
3867 		// we need to create an additional reference for evalPredicate method
3868 		ListT<CegoField>* xufl[3];
3869 		xufl[0] = &ufl;
3870 		if ( pBlock )
3871 		    xufl[1] = pBlock->getTriggerValueList();
3872 		else
3873 		    xufl[1] = 0;
3874 		xufl[2] = 0; // terminate in any case
3875 
3876 		CegoDataPointer dp;
3877 		bool moreTuple;
3878 		moreTuple = pTC->getFirst(ufl, dp);
3879 		while (moreTuple && _isAborted == false)
3880 		{
3881 		    pPred->clearAttrCache();
3882 		    if ( CegoQueryHelper::evalPredicate(0, 0, xufl, 0, pPred, pBlock))
3883 		    {
3884 			if ( tid == 0 )
3885 			{
3886 			    // before deleting, we first have to skip to next valid tuple
3887 			    ListT<CegoField> nfl = oe.getSchema();
3888 			    CegoDataPointer ndp;
3889 			    moreTuple = pTC->getNext(nfl, ndp);
3890 
3891 			    deleteDataTableEntrySynced(oe.getTabSetId(), oe.getTabName(), CegoObject::TABLE, dp, ufl, idxList, btreeList, keyList, true, false, isSynced);
3892 			    delCount++;
3893 
3894 			    if ( moreTuple )
3895 			    {
3896 				dp = ndp;
3897 				ufl = nfl;
3898 			    }
3899 			}
3900 			else
3901 			{
3902 			    deleteDataTableEntrySynced(oe.getTabSetId(), oe.getTabName(), CegoObject::TABLE, dp, ufl, idxList, btreeList, keyList, true, false, isSynced);
3903 			    delCount++;
3904 			    moreTuple = pTC->getNext(ufl, dp);
3905 			}
3906 		    }
3907 		    else
3908 		    {
3909 			moreTuple = pTC->getNext(ufl, dp);
3910 		    }
3911 		}
3912 	    }
3913 	    else
3914 	    {
3915 		ListT<CegoField> ufl = (ListT<CegoField>)oe.getSchema();
3916 
3917 		// we need to create an additional reference for evalPredicate method
3918 		ListT<CegoField>* xufl[2];
3919 		xufl[0] = &ufl;
3920 		xufl[1] = 0;
3921 
3922 		bool moreTuple;
3923 
3924 		CegoDataPointer dp;
3925 
3926 		moreTuple = pTC->getFirst(ufl, dp);
3927 
3928 		while (moreTuple && _isAborted == false)
3929 		{
3930 		    pPred->clearAttrCache();
3931 
3932 		    if ( CegoQueryHelper::evalPredicate(0, 0, xufl, 0, pPred, pBlock))
3933 		    {
3934 			if ( tid == 0 )
3935 			{
3936 			    /* if we are not inside a transaction, the index or btree object for the delete condition
3937 			       was modified and we have to reset the cursor */
3938 
3939 			    pTC->abort();
3940 
3941 			    // cout << "Deleting data table with index cursor ..." << dp << endl;
3942 			    deleteDataTableEntrySynced(oe.getTabSetId(), oe.getTabName(), CegoObject::TABLE, dp, ufl, idxList, btreeList, keyList, true, false, isSynced);
3943 			    delCount++;
3944 
3945 			    moreTuple = pTC->getFirst(ufl, dp);
3946 			}
3947 			else
3948 			{
3949 			    deleteDataTableEntrySynced(oe.getTabSetId(), oe.getTabName(), CegoObject::TABLE, dp, ufl, idxList, btreeList, keyList, true, false, isSynced);
3950 			    delCount++;
3951 			    moreTuple = pTC->getNext(ufl, dp);
3952 			}
3953 		    }
3954 		    else
3955 		    {
3956 			moreTuple = pTC->getNext(ufl, dp);
3957 		    }
3958 		}
3959 	    }
3960 	}
3961 	catch ( Exception e )
3962 	{
3963 	    delete pTC;
3964 	    throw e;
3965 	}
3966 
3967 	delete pTC;
3968 
3969 	if ( _isAborted )
3970 	{
3971 	    throw Exception(EXLOC, Chain("Delete aborted by user"));
3972 	}
3973 
3974 
3975     }
3976 
3977 #ifdef CGDEBUG
3978     _pDBMng->log(_modId, Logger::DEBUG, Chain("Delete finished, delCount = ") + Chain(delCount));
3979 #endif
3980 
3981     // commit delete record
3982 
3983     char *pLogBuf = 0;
3984     int logBuflen = 0;
3985 
3986     CegoQueryHelper::encodeDelRec(oe.getTabAlias(), pPred, pBlock, pLogBuf, logBuflen);
3987 
3988     /*
3989       for the delete operation, we have to get the LSN AFTER successful operation
3990       otherwise, it may occur, that a checkpoint happens during the delete with a higher LSN
3991       and so the operation is lost
3992     */
3993 
3994     lr.setLSN(_pDBMng->nextLSN(oe.getTabSetId()));
3995     lr.setData(pLogBuf);
3996     lr.setDataLen(logBuflen);
3997 
3998     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
3999 
4000     if ( logBuflen > 0 )
4001 	free ( pLogBuf );
4002 
4003     return delCount;
4004 }
4005 
deleteDataTableEntrySynced(int tabSetId,const Chain & tableName,CegoObject::ObjectType type,const CegoDataPointer & dp,const ListT<CegoField> & fvl,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,bool doCheckKey,bool doIgnoreIndexError,bool isSynced)4006 void CegoTableManager::deleteDataTableEntrySynced(int tabSetId, const Chain& tableName, CegoObject::ObjectType type,
4007 						  const CegoDataPointer& dp, const ListT<CegoField>& fvl,
4008 						  const ListT<CegoTableObject>& idxList,
4009 						  const ListT<CegoBTreeObject>& btreeList,
4010 						  const ListT<CegoKeyObject>& keyList,
4011 						  bool doCheckKey, bool doIgnoreIndexError, bool isSynced)
4012 {
4013 
4014     unsigned long long recLock = 0;
4015 
4016     try
4017     {
4018 	recLock = _pLockHandle->lockRecord(dp, CegoLockHandler::WRITE);
4019 
4020 	deleteDataTableEntry(tabSetId, tableName, type, dp, fvl, idxList, btreeList, keyList, doCheckKey, doIgnoreIndexError);
4021 
4022 	_pLockHandle->unlockRecord(recLock);
4023 
4024     }
4025     catch ( Exception e )
4026     {
4027 	if ( recLock )
4028 	    _pLockHandle->unlockRecord(recLock);
4029 	throw e;
4030     }
4031 }
4032 
deleteDataTableEntry(int tabSetId,const Chain & tableName,CegoObject::ObjectType type,const CegoDataPointer & dp,const ListT<CegoField> & fvl,const ListT<CegoTableObject> & idxList,const ListT<CegoBTreeObject> & btreeList,const ListT<CegoKeyObject> & keyList,bool doCheckKey,bool doIgnoreIndexError)4033 bool CegoTableManager::deleteDataTableEntry(int tabSetId, const Chain& tableName,
4034 					    CegoObject::ObjectType type,
4035 					    const CegoDataPointer& dp,
4036 					    const ListT<CegoField>& fvl,
4037 					    const ListT<CegoTableObject>& idxList,
4038 					    const ListT<CegoBTreeObject>& btreeList,
4039 					    const ListT<CegoKeyObject>& keyList,
4040 					    bool doCheckKey, bool doIgnoreIndexError)
4041 {
4042     if ( doCheckKey )
4043 	if ( keyReferenceExists(tabSetId, tableName, fvl, keyList) )
4044 	    throw Exception(EXLOC, Chain("Constraint violation on foreign key"));
4045 
4046     // we just delete entries on committed tuples
4047     if ( getTID(tabSetId) == 0 )
4048     {
4049 	// delete index entries
4050 
4051 	CegoTableObject* pOE = idxList.First();
4052 	while (pOE)
4053 	{
4054 	    if ( pOE->isValid()
4055 		 && ( pOE->getType() == CegoObject::AVLTREE
4056 		      || pOE->getType() == CegoObject::UAVLTREE
4057 		      || pOE->getType() == CegoObject::PAVLTREE ) )
4058 	    {
4059 		char p[TABMNG_MAXINDEXVALUE];
4060 		int len = TABMNG_MAXINDEXVALUE;
4061 		int idxLen;
4062 
4063 		extractIndexValue(fvl, pOE->getSchema(), p, len, idxLen);
4064 
4065 		try
4066 		{
4067 		    CegoAVLIndexManager idxMng(this);
4068 		    idxMng.deleteIndexTable(tabSetId, tableName, type, pOE->getName(), pOE->getType(), pOE->getSchema(), dp, p, idxLen, true);
4069 		}
4070 		catch ( Exception e )
4071 		{
4072 		    if ( doIgnoreIndexError == false )
4073 			throw e;
4074 		}
4075 	    }
4076 	    pOE = idxList.Next();
4077 	}
4078 
4079 	// delete btree entries
4080 
4081 	CegoBTreeObject* pBTO = btreeList.First();
4082 	while (pBTO)
4083 	{
4084 	    if (pBTO->getType() == CegoObject::BTREE
4085 		|| pBTO->getType() == CegoObject::UBTREE
4086 		|| pBTO->getType() == CegoObject::PBTREE )
4087 
4088 	    {
4089 		CegoBTreeValue btv;
4090 		btv.valueFromSchema(fvl, pBTO->getSchema());
4091 
4092 		try
4093 		{
4094 		    CegoBTreeManager btreeMng(this, pBTO);
4095 		    btreeMng.deleteBTree(btv, dp, getTID(tabSetId));
4096 		}
4097 		catch ( Exception e )
4098 		{
4099 		    if ( doIgnoreIndexError == false )
4100 			throw e;
4101 		}
4102 	    }
4103 	    pBTO = btreeList.Next();
4104 	}
4105 
4106         // delete blob and clob entries
4107 	CegoField *pF = fvl.First();
4108 
4109 	while ( pF)
4110 	{
4111 	    if ( pF->getValue().getType() == BLOB_TYPE && pF->getValue().getValue() != 0 )
4112 	    {
4113 		PageIdType pageId;
4114 		memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4115 
4116 		decreaseBlobRef(tabSetId, pageId);
4117 	    }
4118 
4119 	    if ( pF->getValue().getType() == CLOB_TYPE && pF->getValue().getValue() != 0 )
4120 	    {
4121 		PageIdType pageId;
4122 		memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4123 
4124 		decreaseClobRef(tabSetId, pageId);
4125 	    }
4126 
4127 	    pF = fvl.Next();
4128 	}
4129 
4130 	int numTries=0;
4131 	bool isDeleted=false;
4132 	while ( isDeleted == false )
4133 	{
4134 	    try
4135 	    {
4136 #ifdef CGDEBUG
4137 		_pDBMng->log(_modId, Logger::DEBUG, Chain("Deleting tuple"));
4138 #endif
4139 		deleteData(type, tabSetId, dp);
4140 		isDeleted=true;
4141 	    }
4142 	    catch ( Exception e )
4143 	    {
4144 		Chain msg;
4145 		e.pop(msg);
4146 		_pDBMng->log(_modId, Logger::NOTICE, Chain("Retry delete after :  ") + msg);
4147 
4148 		if ( numTries == LCKMNG_NUMLOCKTRIES )
4149 		{
4150 		    throw Exception(EXLOC, msg);
4151 		}
4152 		numTries++;
4153 	    }
4154 	}
4155 
4156 	return true;
4157     }
4158     else //  getTID(tabSetId) != 0
4159     {
4160 	unsigned long long tid;
4161 	unsigned long long tastep;
4162 	CegoTupleState ts;
4163 
4164 	bool tupleTouched = false;
4165 
4166 	getTupleInfo(tabSetId, dp, tid, tastep, ts);
4167 
4168 	// is tuple untouched or already modified by the same transaction
4169 	if ( getTID(tabSetId) == tid || tid == 0 )
4170 	{
4171 	    _pTM->newRBEntry(tabSetId, getTID(tabSetId), dp.getPageId(), dp.getOffset(), tableName);
4172 
4173 	    if ( ts == INSERTED )
4174 		setTupleInfo(tabSetId, dp, getTID(tabSetId), getTAStep(tabSetId), OBSOLETE);
4175 	    else
4176 		setTupleInfo(tabSetId, dp, getTID(tabSetId), getTAStep(tabSetId), DELETED);
4177 
4178 	    tupleTouched = true;
4179 	}
4180 
4181 	return tupleTouched;
4182     }
4183 }
4184 
truncateTable(int tabSetId,const Chain & tableName)4185 void CegoTableManager::truncateTable(int tabSetId, const Chain& tableName)
4186 {
4187 
4188 #ifdef CGDEBUG
4189     _pDBMng->log(_modId, Logger::DEBUG, Chain("Start of call truncateTable(") + Chain(tabSetId)
4190 		 + Chain(",") + tableName + Chain(")"));
4191 
4192 #endif
4193 
4194     if ( getTID(tabSetId) > 0 )
4195     {
4196 	Chain msg = Chain("Truncate in a transaction not allowed");
4197 	throw Exception(EXLOC, msg);
4198     }
4199 
4200     if  ( _pTM->hasOpenTransaction(tabSetId, tableName) )
4201     {
4202 	Chain msg = Chain("Table ") + tableName + Chain(" still has open transactions");
4203 	throw Exception(EXLOC, msg);
4204     }
4205 
4206     ListT<CegoTableObject> idxList;
4207     ListT<CegoBTreeObject> btreeList;
4208     ListT<CegoKeyObject> keyList;
4209     ListT<CegoCheckObject> checkList;
4210     ListT<CegoTriggerObject> triggerList;
4211     ListT<CegoAliasObject> aliasList;
4212 
4213     int numInvalid;
4214 
4215     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
4216 
4217     CegoKeyObject *pKey = keyList.First();
4218     while ( pKey )
4219     {
4220 	if ( pKey->getRefTable() == tableName )
4221 	{
4222 
4223 	    CegoTableCursor* pTC = new CegoTableCursor(this, tabSetId, pKey->getTabName(), true);
4224 
4225 	    try
4226 	    {
4227 		bool moreTuple;
4228 		CegoDataPointer dp;
4229 		ListT<CegoField> fl;
4230 		moreTuple = pTC->getFirst(fl, dp);
4231 
4232 		if  (moreTuple)
4233 		{
4234 		    throw Exception(EXLOC, Chain("Cannnot truncate key reference table with existing references"));
4235 		}
4236 
4237 		delete pTC;
4238 	    }
4239 	    catch ( Exception e )
4240 	    {
4241 		delete pTC;
4242 		throw e;
4243 	    }
4244 	}
4245 	pKey = keyList.Next();
4246     }
4247 
4248     CegoTableObject *pIO = idxList.First();
4249     while ( pIO )
4250     {
4251 #ifdef CGDEBUG
4252 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Truncating index ") + pIO->getName() + Chain(" ..."));
4253 #endif
4254 
4255 	truncateObject(tabSetId, pIO->getName(), pIO->getType());
4256 	pIO = idxList.Next();
4257     }
4258 
4259     CegoBTreeObject *pBTO = btreeList.First();
4260     while ( pBTO )
4261     {
4262 #ifdef CGDEBUG
4263 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Truncating btree ") + pBTO->getName() + Chain(" ..."));
4264 #endif
4265 
4266 	truncateObject(tabSetId, pBTO->getName(), pBTO->getType());
4267 
4268 	pBTO = btreeList.Next();
4269     }
4270 
4271     // check for blobs and remove
4272 
4273     CegoTableObject oe;
4274     getObject(tabSetId, tableName, CegoObject::TABLE, oe);
4275     ListT<CegoField> fl = oe.getSchema();
4276 
4277     bool hasXlobField = false;
4278     CegoField *pF = fl.First();
4279     while ( pF )
4280     {
4281 	if ( pF->getType() == BLOB_TYPE || pF->getType() == CLOB_TYPE )
4282 	    hasXlobField = true;
4283 	pF = fl.Next();
4284     }
4285 
4286     if ( hasXlobField )
4287     {
4288 	CegoTableCursor* pTC = new CegoTableCursor(this, tabSetId, tableName, true);
4289 
4290 	try
4291 	{
4292 	    bool moreTuple;
4293 	    CegoDataPointer dp;
4294 	    moreTuple = pTC->getFirst(fl, dp);
4295 
4296 	    while (moreTuple)
4297 	    {
4298 		CegoField *pF = fl.First();
4299 		while ( pF )
4300 		{
4301 		    if ( pF->getType() == BLOB_TYPE && pF->getValue().getValue() != 0 )
4302 		    {
4303 			PageIdType pageId;
4304 			memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4305 
4306 #ifdef CGDEBUG
4307 			_pDBMng->log(_modId, Logger::DEBUG, Chain("Releasing blob [") + Chain(pageId) + Chain("]"));
4308 #endif
4309 
4310 			decreaseBlobRef(tabSetId, pageId);
4311 		    }
4312 
4313 		    if ( pF->getType() == CLOB_TYPE && pF->getValue().getValue() != 0 )
4314 		    {
4315 			PageIdType pageId;
4316 			memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4317 
4318 #ifdef CGDEBUG
4319 			_pDBMng->log(_modId, Logger::DEBUG, Chain("Releasing clob [") + Chain(pageId) + Chain("]"));
4320 #endif
4321 
4322 			decreaseClobRef(tabSetId, pageId);
4323 		    }
4324 
4325 		    pF = fl.Next();
4326 		}
4327 		moreTuple = pTC->getNext(fl, dp);
4328 	    }
4329 	    delete pTC;
4330 	}
4331 	catch ( Exception e )
4332 	{
4333 	    delete pTC;
4334 	    throw e;
4335 	}
4336     }
4337 
4338 #ifdef CGDEBUG
4339     _pDBMng->log(_modId, Logger::DEBUG, Chain("Truncating table ") + tableName + Chain(" ..."));
4340 #endif
4341 
4342     CegoLogRecord lr;
4343     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4344 
4345     truncateObject(tabSetId, tableName, CegoObject::TABLE);
4346 
4347     // create log entry
4348     lr.setObjectInfo(tableName, CegoObject::TABLE);
4349     lr.setAction(CegoLogRecord::LOGREC_TRUNCATE);
4350     lr.setData(0);
4351     lr.setDataLen(0);
4352 
4353     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4354 
4355 }
4356 
dropObjectSynced(int tabSetId,const Chain & objName,CegoObject::ObjectType type)4357 void CegoTableManager::dropObjectSynced(int tabSetId, const Chain& objName, CegoObject::ObjectType type)
4358 {
4359     Chain useName;
4360     CegoObject::ObjectType useType;
4361 
4362     if ( type == CegoObject::AVLTREE
4363 	 || type == CegoObject::UAVLTREE
4364 	 || type == CegoObject::PAVLTREE )
4365     {
4366 	CegoTableObject io;
4367 	getObject(tabSetId, objName, type, io);
4368 	useName = io.getTabName();
4369 	useType=CegoObject::TABLE;
4370 
4371 
4372 	// We still have to check, if any foreign key reference exists
4373 	// If so, we do not allow to remove
4374 	if ( io.getType() == CegoObject::PAVLTREE )
4375 	{
4376 	    ListT<CegoTableObject> checkIdxList;
4377 	    ListT<CegoBTreeObject> checkBTreeList;
4378 	    ListT<CegoKeyObject> checkKeyList;
4379 	    ListT<CegoCheckObject> checkList;
4380 	    ListT<CegoTriggerObject> triggerList;
4381 	    ListT<CegoAliasObject> aliasList;
4382 	    int numInvalid;
4383 
4384 	    getObjectListByTable(tabSetId, useName, checkIdxList, checkBTreeList, checkKeyList, checkList, triggerList, aliasList, numInvalid);
4385 	    CegoKeyObject *pKey = checkKeyList.First();
4386 	    while ( pKey )
4387 	    {
4388 		if ( pKey->getRefTable() == useName )
4389 		{
4390 		    throw Exception(EXLOC, Chain("Cannnot drop primary avltree with existing key reference"));
4391 		}
4392 		pKey = checkKeyList.Next();
4393 	    }
4394 	}
4395     }
4396     else if ( type == CegoObject::BTREE
4397 	 || type == CegoObject::UBTREE
4398 	 || type == CegoObject::PBTREE )
4399     {
4400 	CegoBTreeObject bto;
4401 	getObject(tabSetId, objName, type, bto);
4402 	useName = bto.getTabName();
4403 	useType=CegoObject::TABLE;
4404 
4405 	// We still have to check, if any foreign key reference exists
4406 	// If so, we do not allow to remove
4407 	if ( bto.getType() == CegoObject::PBTREE )
4408 	{
4409 	    ListT<CegoTableObject> checkIdxList;
4410 	    ListT<CegoBTreeObject> checkBTreeList;
4411 	    ListT<CegoKeyObject> checkKeyList;
4412 	    ListT<CegoCheckObject> checkList;
4413 	    ListT<CegoTriggerObject> triggerList;
4414 	    ListT<CegoAliasObject> aliasList;
4415 	    int numInvalid;
4416 
4417 	    getObjectListByTable(tabSetId, useName, checkIdxList, checkBTreeList, checkKeyList, checkList, triggerList, aliasList, numInvalid);
4418 	    CegoKeyObject *pKey = checkKeyList.First();
4419 	    while ( pKey )
4420 	    {
4421 		if ( pKey->getRefTable() == useName )
4422 		{
4423 		    throw Exception(EXLOC, Chain("Cannnot drop primary btree with existing key reference"));
4424 		}
4425 		pKey = checkKeyList.Next();
4426 	    }
4427 	}
4428     }
4429     else if ( type == CegoObject::TABLE )
4430     {
4431 	useName = objName;
4432 	useType=type;
4433     }
4434     else if ( type == CegoObject::PROCEDURE
4435 	      || type == CegoObject::VIEW )
4436     {
4437 	useName = objName;
4438 	useType=type;
4439     }
4440     else if ( type == CegoObject::FKEY )
4441     {
4442 	CegoKeyObject ko;
4443 	getObject(tabSetId, objName, type, ko);
4444 	useName = ko.getTabName();
4445 	useType=CegoObject::TABLE;
4446     }
4447     else if ( type == CegoObject::CHECK )
4448     {
4449 	CegoCheckObject co;
4450 	getObject(tabSetId, objName, type, co);
4451 	useName = co.getTabName();
4452 	useType=CegoObject::TABLE;
4453     }
4454     else if ( type == CegoObject::TRIGGER )
4455     {
4456 	CegoTriggerObject to;
4457 	getObject(tabSetId, objName, type, to);
4458 	useName = to.getTabName();
4459 	useType=CegoObject::TABLE;
4460     }
4461     else if ( type == CegoObject::ALIAS )
4462     {
4463 	// CegoAliasObject ao;
4464 	// getObject(tabSetId, objName, type, ao);
4465 	// useName = ao.getTabName();
4466 	// useType=CegoObject::TABLE;
4467 
4468 	// for alias objects, we allow drop without synching with corresponding table
4469 	useName = objName;
4470 	useType=type;
4471     }
4472 
4473     else
4474     {
4475 	throw Exception(EXLOC, Chain("Invalid object type"));
4476     }
4477 
4478     _pDBMng->useObject(tabSetId, useName, useType, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
4479 
4480     try
4481     {
4482 	switch ( type )
4483 	{
4484 	case CegoObject::TABLE:
4485 	    dropTable(tabSetId, objName);
4486 	    break;
4487 	case CegoObject::AVLTREE:
4488 	case CegoObject::UAVLTREE:
4489 	case CegoObject::PAVLTREE:
4490 	    dropIndex(tabSetId, objName);
4491 	    break;
4492 	case CegoObject::BTREE:
4493 	case CegoObject::UBTREE:
4494 	case CegoObject::PBTREE:
4495 	    dropBTree(tabSetId, objName);
4496 	    break;
4497 	case CegoObject::VIEW:
4498 	    dropView(tabSetId, objName);
4499 	    break;
4500 	case CegoObject::PROCEDURE:
4501 	    dropProcedure(tabSetId, objName);
4502 	    break;
4503 	case CegoObject::FKEY:
4504 	    dropFKey(tabSetId, objName);
4505 	    break;
4506 	case CegoObject::CHECK:
4507 	    dropCheck(tabSetId, objName);
4508 	    break;
4509 	case CegoObject::TRIGGER:
4510 	    dropTrigger(tabSetId, objName);
4511 	    break;
4512 	case CegoObject::ALIAS:
4513 	    dropAlias(tabSetId, objName);
4514 	    break;
4515 	case CegoObject::SYSTEM:
4516 	case CegoObject::RBSEG:
4517 	case CegoObject::JOIN:
4518 	case CegoObject::UNDEFINED:
4519 	    throw Exception(EXLOC, "Invalid object type for drop");
4520 	}
4521     }
4522     catch ( Exception e )
4523     {
4524 
4525 	_pDBMng->unuseObject(tabSetId, useName, useType);
4526 	throw e;
4527     }
4528 
4529 
4530     // _pDBMng->printObjectList();
4531 
4532     // cout << "Removing object " << objName << " of type " << type << endl;
4533 
4534     _pDBMng->removeObject(tabSetId, objName, type);
4535 
4536     // _pDBMng->printObjectList();
4537 
4538     if ( useName != objName )
4539      	_pDBMng->unuseObject(tabSetId, useName, useType);
4540 }
4541 
dropTable(int tabSetId,const Chain & tableName)4542 void CegoTableManager::dropTable(int tabSetId,
4543 				 const Chain& tableName)
4544 {
4545 #ifdef CGDEBUG
4546     _pDBMng->log(_modId, Logger::DEBUG, Chain("Start of call dropTable(") + Chain(tabSetId)
4547 		 + Chain(",") + tableName + Chain(")"));
4548 
4549 #endif
4550 
4551     if ( getTID(tabSetId) > 0 )
4552     {
4553 	Chain msg = Chain("Drop in a transaction not allowed");
4554 	throw Exception(EXLOC, msg);
4555     }
4556 
4557     if  ( _pTM->hasOpenTransaction(tabSetId, tableName) )
4558     {
4559 	Chain msg = Chain("Table ") + tableName + Chain(" still has open transactions");
4560 	throw Exception(EXLOC, msg);
4561     }
4562 
4563     ListT<CegoTableObject> idxList;
4564     ListT<CegoBTreeObject> btreeList;
4565     ListT<CegoKeyObject> keyList;
4566     ListT<CegoCheckObject> checkList;
4567     ListT<CegoTriggerObject> triggerList;
4568     ListT<CegoAliasObject> aliasList;
4569     int numInvalid;
4570 
4571     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
4572 
4573     CegoKeyObject *pKey = keyList.First();
4574     while ( pKey )
4575     {
4576 	if ( pKey->getRefTable() == tableName && pKey->getTabName() != tableName )
4577 	{
4578 	    throw Exception(EXLOC, Chain("Cannnot drop table with existing foreign key reference"));
4579 	}
4580 	pKey = keyList.Next();
4581     }
4582 
4583     CegoTableObject *pIO = idxList.First();
4584     while ( pIO )
4585     {
4586 	if ( pIO->getType() == CegoObject::AVLTREE
4587 	     || pIO->getType() == CegoObject::UAVLTREE
4588 	     || pIO->getType() == CegoObject::PAVLTREE )
4589 	{
4590 #ifdef CGDEBUG
4591 	    _pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping index ") + pIO->getName() + Chain(" ..."));
4592 #endif
4593 
4594 	    removeObject(tabSetId, pIO->getName(), pIO->getType());
4595 	    _pDBMng->removeObject(tabSetId, pIO->getName(), pIO->getType());
4596 
4597 
4598 	}
4599 	pIO = idxList.Next();
4600     }
4601 
4602     CegoBTreeObject *pBTO = btreeList.First();
4603     while ( pBTO )
4604     {
4605 	if ( pBTO->getType() == CegoObject::BTREE
4606 	     || pBTO->getType() == CegoObject::UBTREE
4607 	     || pBTO->getType() == CegoObject::PBTREE )
4608 	{
4609 #ifdef CGDEBUG
4610 	    _pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping btree ") + pBTO->getName() + Chain(" ..."));
4611 #endif
4612 
4613 	    removeObject(tabSetId, pBTO->getName(), pBTO->getType());
4614 	    _pDBMng->removeObject(tabSetId, pBTO->getName(), pBTO->getType());
4615 
4616 	}
4617 	pBTO = btreeList.Next();
4618     }
4619 
4620     CegoKeyObject *pKO = keyList.First();
4621     while ( pKO )
4622     {
4623 #ifdef CGDEBUG
4624 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping key ") + pKO->getName() + Chain(" ..."));
4625 #endif
4626 	removeObject(tabSetId, pKO->getName(), pKO->getType());
4627 	_pDBMng->removeObject(tabSetId, pKO->getName(), pKO->getType());
4628 
4629 
4630 	pKO = keyList.Next();
4631     }
4632 
4633     CegoCheckObject *pCO = checkList.First();
4634     while ( pCO )
4635     {
4636 #ifdef CGDEBUG
4637 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping check ") + pCO->getName() + Chain(" ..."));
4638 #endif
4639 
4640 	removeObject(tabSetId, pCO->getName(), pCO->getType());
4641 	_pDBMng->removeObject(tabSetId, pCO->getName(), pCO->getType());
4642 
4643 	pCO = checkList.Next();
4644     }
4645 
4646     CegoTriggerObject *pTO = triggerList.First();
4647     while ( pTO )
4648     {
4649 #ifdef CGDEBUG
4650 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping trigger ") + pTO->getName() + Chain(" ..."));
4651 #endif
4652 
4653 	removeObject(tabSetId, pTO->getName(), pTO->getType());
4654 	_pDBMng->removeObject(tabSetId, pTO->getName(), pTO->getType());
4655 
4656 	pTO = triggerList.Next();
4657     }
4658 
4659     CegoAliasObject *pAO = aliasList.First();
4660     while ( pAO )
4661     {
4662 #ifdef CGDEBUG
4663 	_pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping alias ") + pAO->getName() + Chain(" ..."));
4664 #endif
4665 
4666 	removeObject(tabSetId, pAO->getName(), pAO->getType());
4667 	_pDBMng->removeObject(tabSetId, pAO->getName(), pAO->getType());
4668 
4669 	pAO = aliasList.Next();
4670     }
4671 
4672     // check for blobs and remove
4673 
4674     CegoTableObject oe;
4675     getObject(tabSetId, tableName, CegoObject::TABLE, oe);
4676     ListT<CegoField> fl = oe.getSchema();
4677 
4678     bool hasXlobField = false;
4679     CegoField *pF = fl.First();
4680     while ( pF )
4681     {
4682 	if ( pF->getType() == BLOB_TYPE || pF->getType() == CLOB_TYPE )
4683 	    hasXlobField = true;
4684 	pF = fl.Next();
4685     }
4686 
4687     if ( hasXlobField )
4688     {
4689 	CegoTableCursor* pTC = new CegoTableCursor(this, tabSetId, tableName, true);
4690 
4691 	try
4692 	{
4693 	    bool moreTuple;
4694 	    CegoDataPointer dp;
4695 	    moreTuple = pTC->getFirst(fl, dp);
4696 
4697 	    while (moreTuple)
4698 	    {
4699 		CegoField *pF = fl.First();
4700 		while ( pF )
4701 		{
4702 		    if ( pF->getType() == BLOB_TYPE && pF->getValue().getValue() != 0 )
4703 		    {
4704 			PageIdType pageId;
4705 			memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4706 
4707 #ifdef CGDEBUG
4708 			_pDBMng->log(_modId, Logger::DEBUG, Chain("Releasing blob [") + Chain(pageId) + Chain("]"));
4709 #endif
4710 
4711 			decreaseBlobRef(tabSetId, pageId);
4712 		    }
4713 
4714 		    if ( pF->getType() == CLOB_TYPE && pF->getValue().getValue() != 0 )
4715 		    {
4716 			PageIdType pageId;
4717 			memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
4718 
4719 #ifdef CGDEBUG
4720 			_pDBMng->log(_modId, Logger::DEBUG, Chain("Releasing clob [") + Chain(pageId) + Chain("]"));
4721 #endif
4722 
4723 			decreaseClobRef(tabSetId, pageId);
4724 		    }
4725 
4726 		    pF = fl.Next();
4727 		}
4728 		moreTuple = pTC->getNext(fl, dp);
4729 	    }
4730 	    delete pTC;
4731 	}
4732 	catch ( Exception e )
4733 	{
4734 	    delete pTC;
4735 	    throw e;
4736 	}
4737     }
4738 
4739 #ifdef CGDEBUG
4740     _pDBMng->log(_modId, Logger::DEBUG, Chain("Dropping table ") + tableName + Chain(" ..."));
4741 #endif
4742 
4743     CegoLogRecord lr;
4744     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4745 
4746     removeObject(tabSetId, tableName, CegoObject::TABLE);
4747 
4748     // create log entry
4749     lr.setObjectInfo(tableName, CegoObject::TABLE);
4750     lr.setAction(CegoLogRecord::LOGREC_DROP);
4751     lr.setData(0);
4752     lr.setDataLen(0);
4753     // lr.setTID(0);
4754 
4755     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4756 
4757 }
4758 
dropIndex(int tabSetId,const Chain & idxName)4759 void CegoTableManager::dropIndex(int tabSetId, const Chain& idxName)
4760 {
4761     if ( getTID(tabSetId) > 0 )
4762     {
4763 	Chain msg = Chain("Drop in a transaction not allowed");
4764 	throw Exception(EXLOC, msg);
4765     }
4766 
4767     CegoObject::ObjectType idxType = CegoObject::AVLTREE;
4768 
4769     if ( ! objectExists(tabSetId, idxName, idxType ) )
4770     {
4771 	Chain msg = "Unknown index " + idxName;
4772 	throw Exception(EXLOC, msg);
4773     }
4774 
4775     CegoLogRecord lr;
4776     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4777 
4778     removeObject(tabSetId, idxName, idxType);
4779 
4780     // create log entry
4781     lr.setObjectInfo(idxName, idxType);
4782     lr.setAction(CegoLogRecord::LOGREC_DROP);
4783     lr.setData(0);
4784     lr.setDataLen(0);
4785     // lr.setTID(0);
4786 
4787     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4788 }
4789 
dropBTree(int tabSetId,const Chain & btreeName)4790 void CegoTableManager::dropBTree(int tabSetId, const Chain& btreeName)
4791 {
4792     if ( getTID(tabSetId) > 0 )
4793     {
4794 	Chain msg = Chain("Drop in a transaction not allowed");
4795 	throw Exception(EXLOC, msg);
4796     }
4797 
4798     CegoObject::ObjectType btType = CegoObject::BTREE;
4799 
4800     if ( ! objectExists(tabSetId, btreeName, btType ) )
4801     {
4802 	Chain msg = "Unknown btree " + btreeName;
4803 	throw Exception(EXLOC, msg);
4804     }
4805 
4806     CegoLogRecord lr;
4807     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4808 
4809     removeObject(tabSetId, btreeName, btType);
4810 
4811     // create log entry
4812     lr.setObjectInfo(btreeName, btType);
4813     lr.setAction(CegoLogRecord::LOGREC_DROP);
4814     lr.setData(0);
4815     lr.setDataLen(0);
4816     // lr.setTID(0);
4817 
4818     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4819 
4820 }
4821 
dropView(int tabSetId,const Chain & viewName)4822 void CegoTableManager::dropView(int tabSetId, const Chain& viewName)
4823 {
4824     if ( getTID(tabSetId) > 0 )
4825     {
4826 	Chain msg = Chain("drop in a transaction not allowed");
4827 	throw Exception(EXLOC, msg);
4828     }
4829 
4830     CegoLogRecord lr;
4831     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4832 
4833     removeObject(tabSetId, viewName, CegoObject::VIEW);
4834 
4835     // create log entry
4836     lr.setObjectInfo(viewName, CegoObject::VIEW);
4837     lr.setAction(CegoLogRecord::LOGREC_DROP);
4838     lr.setData(0);
4839     lr.setDataLen(0);
4840     // lr.setTID(0);
4841 
4842     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4843 }
4844 
dropProcedure(int tabSetId,const Chain & procName)4845 void CegoTableManager::dropProcedure(int tabSetId, const Chain& procName)
4846 {
4847     if ( getTID(tabSetId) > 0 )
4848     {
4849 	Chain msg = Chain("drop in a transaction not allowed");
4850 	throw Exception(EXLOC, msg);
4851     }
4852 
4853     CegoLogRecord lr;
4854     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4855 
4856     removeObject(tabSetId, procName, CegoObject::PROCEDURE);
4857 
4858     // create log entry
4859     lr.setObjectInfo(procName, CegoObject::PROCEDURE);
4860     lr.setAction(CegoLogRecord::LOGREC_DROP);
4861     lr.setData(0);
4862     lr.setDataLen(0);
4863     // lr.setTID(0);
4864     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4865 }
4866 
dropFKey(int tabSetId,const Chain & fkey)4867 void CegoTableManager::dropFKey(int tabSetId, const Chain& fkey)
4868 {
4869     if ( getTID(tabSetId) > 0 )
4870     {
4871 	Chain msg = Chain("drop in a transaction not allowed");
4872 	throw Exception(EXLOC, msg);
4873     }
4874 
4875     CegoLogRecord lr;
4876     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4877 
4878     removeObject(tabSetId, fkey, CegoObject::FKEY);
4879 
4880     // create log entry
4881     lr.setObjectInfo(fkey, CegoObject::FKEY);
4882     lr.setAction(CegoLogRecord::LOGREC_DROP);
4883     lr.setData(0);
4884     lr.setDataLen(0);
4885     // lr.setTID(0);
4886     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4887 }
4888 
dropCheck(int tabSetId,const Chain & check)4889 void CegoTableManager::dropCheck(int tabSetId, const Chain& check)
4890 {
4891     if ( getTID(tabSetId) > 0 )
4892     {
4893 	Chain msg = Chain("drop in a transaction not allowed");
4894 	throw Exception(EXLOC, msg);
4895     }
4896 
4897     CegoLogRecord lr;
4898     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4899 
4900     removeObject(tabSetId, check, CegoObject::CHECK);
4901 
4902     // create log entry
4903     lr.setObjectInfo(check, CegoObject::CHECK);
4904     lr.setAction(CegoLogRecord::LOGREC_DROP);
4905     lr.setData(0);
4906     lr.setDataLen(0);
4907     // lr.setTID(0);
4908     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4909 }
4910 
dropTrigger(int tabSetId,const Chain & trigger)4911 void CegoTableManager::dropTrigger(int tabSetId, const Chain& trigger)
4912 {
4913     if ( getTID(tabSetId) > 0 )
4914     {
4915 	Chain msg = Chain("drop in a transaction not allowed");
4916 	throw Exception(EXLOC, msg);
4917     }
4918 
4919     CegoLogRecord lr;
4920     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4921 
4922     removeObject(tabSetId, trigger, CegoObject::TRIGGER);
4923 
4924     // create log entry
4925     lr.setObjectInfo(trigger, CegoObject::TRIGGER);
4926     lr.setAction(CegoLogRecord::LOGREC_DROP);
4927     lr.setData(0);
4928     lr.setDataLen(0);
4929     // lr.setTID(0);
4930     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4931 }
4932 
dropAlias(int tabSetId,const Chain & aliasName)4933 void CegoTableManager::dropAlias(int tabSetId, const Chain& aliasName)
4934 {
4935     if ( getTID(tabSetId) > 0 )
4936     {
4937 	Chain msg = Chain("drop in a transaction not allowed");
4938 	throw Exception(EXLOC, msg);
4939     }
4940 
4941     CegoLogRecord lr;
4942     lr.setLSN(_pDBMng->nextLSN(tabSetId));
4943 
4944     removeObject(tabSetId, aliasName, CegoObject::ALIAS);
4945 
4946     // create log entry
4947     lr.setObjectInfo(aliasName, CegoObject::ALIAS);
4948     lr.setAction(CegoLogRecord::LOGREC_DROP);
4949     lr.setData(0);
4950     lr.setDataLen(0);
4951     // lr.setTID(0);
4952     _pDBMng->logIt(tabSetId, lr, _pLockHandle);
4953 }
4954 
4955 
correctTableSet(int tabSetId,bool doSync)4956 void CegoTableManager::correctTableSet(int tabSetId, bool doSync)
4957 {
4958     ListT<Chain> tabList;
4959     getObjectList(tabSetId, CegoObject::TABLE, tabList);
4960 
4961     Chain *pTableName = tabList.First();
4962     while ( pTableName )
4963     {
4964 	correctIndexForTable(tabSetId, *pTableName, doSync, false);
4965 
4966 	pTableName = tabList.Next();
4967     }
4968 }
4969 
correctIndexForTable(int tabSetId,const Chain & tableName,bool doSync,bool doForce)4970 void CegoTableManager::correctIndexForTable(int tabSetId, const Chain& tableName, bool doSync, bool doForce)
4971 {
4972     ListT<CegoTableObject> idxList;
4973     ListT<CegoBTreeObject> btreeList;
4974     ListT<CegoKeyObject> keyList;
4975     ListT<CegoCheckObject> checkList;
4976     ListT<CegoTriggerObject> triggerList;
4977     ListT<CegoAliasObject> aliasList;
4978     int numInvalid;
4979 
4980     setIgnoreInvalid(false);
4981     getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);
4982 
4983     // correct indexes
4984     CegoTableObject *pIdx = idxList.First();
4985     while ( pIdx )
4986     {
4987 	if ( pIdx->isValid() == false || doForce )
4988 	{
4989 	    dropIndex(tabSetId, pIdx->getName());
4990 	    bool isCached=false;
4991 	    createIndexTable(tabSetId, pIdx->getName(), pIdx->getTabName(), pIdx->getSchema(), pIdx->getType(), isCached);
4992 	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Index ") + pIdx->getName() + Chain(" was corrected"));
4993 	}
4994 
4995 	pIdx = idxList.Next();
4996     }
4997 
4998     // correct btrees
4999     CegoBTreeObject *pBTree = btreeList.First();
5000     while ( pBTree )
5001     {
5002 	if ( pBTree->isValid() == false || doForce )
5003 	{
5004 	    dropBTree(tabSetId, pBTree->getName());
5005 	    // to be defensive, we don't use btree cache for correction
5006 	    bool isCached = false;
5007 	    createBTree(tabSetId, pBTree->getName(), pBTree->getTabName(), pBTree->getSchema(), pBTree->getType(), doSync, isCached);
5008 	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Btree ") + pBTree->getName() + Chain(" was corrected"));
5009 	}
5010 	pBTree = btreeList.Next();
5011     }
5012 }
5013 
cleanTableSet(int tabSetId)5014 int CegoTableManager::cleanTableSet(int tabSetId)
5015 {
5016     ListT<Chain> tabList;
5017     getObjectList(tabSetId, CegoObject::TABLE, tabList);
5018 
5019     int traceCount = 0;
5020     Chain *pTableName = tabList.First();
5021     while ( pTableName )
5022     {
5023 	traceCount += traceObject(tabSetId, *pTableName, CegoObject::TABLE);
5024 
5025 	CegoTableObject oe;
5026 	getObject(tabSetId, *pTableName, CegoObject::TABLE, oe);
5027 
5028 	bool traceLob = false;
5029 	CegoField *pF = oe.getSchema().First();
5030 	while ( pF && traceLob == false)
5031 	{
5032 	    if ( pF->getType() == CLOB_TYPE || pF->getType() == BLOB_TYPE )
5033 	    {
5034 		traceLob=true;
5035 	    }
5036 	    pF = oe.getSchema().Next();
5037 	}
5038 
5039 	if ( traceLob )
5040 	{
5041 	    CegoTableCursor tc(this, tabSetId, *pTableName);
5042 	    ListT<CegoField> fl = oe.getSchema();
5043 	    CegoDataPointer dp;
5044 
5045 	    if ( tc.getFirst(fl, dp) )
5046 	    {
5047 		do
5048 		{
5049 		    CegoField *pF = fl.First();
5050 		    while ( pF )
5051 		    {
5052 			if ( pF->getValue().getType() == BLOB_TYPE
5053 			     || pF->getValue().getType() == CLOB_TYPE  )
5054 			{
5055 			    PageIdType pageId;
5056 			    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
5057 			    traceCount += traceObjectPages(tabSetId, pageId);
5058 			}
5059 			pF = fl.Next();
5060 		    }
5061 		}
5062 		while ( tc.getNext(fl, dp) );
5063 	    }
5064 	}
5065 
5066 	pTableName = tabList.Next();
5067     }
5068 
5069     ListT<Chain> avlList;
5070     getObjectList(tabSetId, CegoObject::AVLTREE, avlList);
5071 
5072     Chain *pAVL = avlList.First();
5073     while ( pAVL )
5074     {
5075 	traceCount += traceObject(tabSetId, *pAVL, CegoObject::AVLTREE);
5076 	pAVL = avlList.Next();
5077     }
5078 
5079     ListT<Chain> btreeList;
5080     getObjectList(tabSetId, CegoObject::BTREE, btreeList);
5081 
5082     Chain *pBTree = btreeList.First();
5083     while ( pBTree )
5084     {
5085 	traceCount += traceObject(tabSetId, *pBTree, CegoObject::BTREE);
5086 	pBTree = btreeList.Next();
5087     }
5088 
5089     return _pDBMng->cleanPages(_pLockHandle);
5090 }
5091 
getFirstTuple(CegoObjectCursor * pC,ListT<CegoField> & fl,CegoDataPointer & dp)5092 bool CegoTableManager::getFirstTuple(CegoObjectCursor* pC, ListT<CegoField>& fl, CegoDataPointer& dp)
5093 {
5094     int len;
5095 
5096     char* pc = (char*)pC->getFirst(len, dp);
5097 
5098     if ( pc && len > 0 )
5099     {
5100 	unsigned long long tid;
5101 	unsigned long long tastep;
5102 	CegoTupleState ts;
5103 
5104 	int toff = CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);
5105 
5106 	char* tp = pc + toff;
5107 	int tlen = len - toff;
5108 
5109 	if ( tid != 0 )
5110 	{
5111 	    if  ( ( ts == INSERTED && tid == getTID(pC->getTabSetId()) )
5112 		  || ( ts == DELETED && tid != getTID(pC->getTabSetId()) ) )
5113 	    {
5114 		CegoQueryHelper::decodeFVL(fl, tp, tlen);
5115 	    }
5116 	    else
5117 	    {
5118 		return getNextTuple(pC, fl, dp);
5119 	    }
5120 	}
5121 	else
5122 	{
5123 	    CegoQueryHelper::decodeFVL(fl, tp, tlen);
5124 	}
5125 
5126 	return true;
5127     }
5128     return false;
5129 }
5130 
getNextTuple(CegoObjectCursor * pC,ListT<CegoField> & fl,CegoDataPointer & dp)5131 bool CegoTableManager::getNextTuple(CegoObjectCursor* pC, ListT<CegoField>& fl, CegoDataPointer& dp)
5132 {
5133 
5134     do
5135     {
5136 	int len;
5137 	char* pc = (char*)pC->getNext(len, dp);
5138 
5139 	if ( pc && len > 0 )
5140 	{
5141 	    unsigned long long tid;
5142 	    unsigned long long tastep;
5143 	    CegoTupleState ts;
5144 
5145 	    int toff = CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);
5146 
5147 	    char* tp = pc + toff;
5148 	    int tlen = len - toff;
5149 
5150 	    if ( tid != 0 )
5151 	    {
5152 		if ( ( ts == INSERTED && tid == getTID(pC->getTabSetId()) )
5153 		     || ( ts == DELETED && tid == getTID(pC->getTabSetId()) ) )
5154 		{
5155 		    CegoQueryHelper::decodeFVL(fl, tp, tlen);
5156 		    return true;
5157 		}
5158 	    }
5159 	    else
5160 	    {
5161 		CegoQueryHelper::decodeFVL(fl, tp, tlen);
5162 		return true;
5163 	    }
5164 	}
5165 	else
5166 	{
5167 	    return false;
5168 	}
5169 
5170     }  while ( 1 ) ;
5171 }
5172 
createIndexTableSynced(int tabSetId,const Chain & indexName,const Chain & tableName,CegoObject::ObjectType type,ListT<CegoField> & idxList,bool isCached)5173 void CegoTableManager::createIndexTableSynced(int tabSetId, const Chain& indexName, const Chain& tableName, CegoObject::ObjectType type, ListT<CegoField>& idxList, bool isCached)
5174 {
5175     if ( type == CegoObject::PAVLTREE
5176 	 || type == CegoObject::UAVLTREE
5177 	 || type == CegoObject::AVLTREE )
5178     {
5179 	if ( isCached )
5180 	{
5181 	    Chain msg = "Cache option not supported for AVL tree";
5182 	    throw Exception(EXLOC, msg);
5183 	}
5184 
5185 	_pDBMng->useObject(tabSetId, tableName, CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
5186 
5187 	try
5188 	{
5189 	    createAVLIndexTable(tabSetId, indexName, tableName, idxList, type);
5190 	}
5191 	catch ( Exception  e )
5192 	{
5193 	    _pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5194 	    throw Exception(e);
5195 	}
5196 	_pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5197     }
5198     else if ( type == CegoObject::PBTREE
5199 	 || type == CegoObject::UBTREE
5200 	 || type == CegoObject::BTREE )
5201     {
5202 	createBTree(tabSetId, indexName, tableName, idxList, type, true, isCached);
5203     }
5204 
5205     _pDBMng->addObject(tabSetId, indexName, type);
5206 }
5207 
createPrimaryIndexTable(int tabSetId,const Chain & indexName,const Chain & tableName,ListT<CegoField> & schema)5208 void CegoTableManager::createPrimaryIndexTable(int tabSetId, const Chain& indexName, const Chain& tableName, ListT<CegoField>& schema)
5209 {
5210     CegoObject::ObjectType type = CegoObject::PBTREE;
5211     bool isCached=false;
5212     createIndexTable(tabSetId, indexName, tableName, schema, type, isCached);
5213 }
5214 
createIndexTable(int tabSetId,const Chain & indexName,const Chain & tableName,ListT<CegoField> & schema,CegoObject::ObjectType type,bool isCached)5215 void CegoTableManager::createIndexTable(int tabSetId, const Chain& indexName, const Chain& tableName, ListT<CegoField>& schema, CegoObject::ObjectType type, bool isCached)
5216 {
5217     if ( type == CegoObject::PAVLTREE
5218 	 || type == CegoObject::UAVLTREE
5219 	 || type == CegoObject::AVLTREE )
5220     {
5221 	if ( isCached )
5222 	{
5223 	    Chain msg = "Cache option not supported for AVL tree";
5224 	    throw Exception(EXLOC, msg);
5225 	}
5226 
5227 	createAVLIndexTable(tabSetId, indexName, tableName, schema, type);
5228     }
5229     else if ( type == CegoObject::PBTREE
5230 	 || type == CegoObject::UBTREE
5231 	 || type == CegoObject::BTREE )
5232     {
5233 	createBTree(tabSetId, indexName, tableName, schema, type, false, isCached);
5234     }
5235     else
5236     {
5237 	throw Exception(EXLOC, Chain("Unknown index type"));
5238     }
5239 }
5240 
createBTree(int tabSetId,const Chain & btreeName,const Chain & tableName,ListT<CegoField> & schema,CegoObject::ObjectType type,bool doSync,bool isCached)5241 void CegoTableManager::createBTree(int tabSetId, const Chain& btreeName, const Chain& tableName, ListT<CegoField>& schema, CegoObject::ObjectType type, bool doSync, bool isCached)
5242 {
5243     if ( getTID(tabSetId) > 0 )
5244     {
5245 	Chain msg = Chain("create btree in a transaction not allowed");
5246 	throw Exception(EXLOC, msg);
5247     }
5248 
5249     CegoLogRecord lr;
5250     lr.setLSN(_pDBMng->nextLSN(tabSetId));
5251 
5252     CegoTableObject toe;
5253 
5254     getObject(tabSetId, tableName, CegoObject::TABLE, toe);
5255 
5256 
5257     CegoField* pF;
5258 
5259     // first we create a tableschema with the required attribute in the appropriate order
5260     ListT<CegoField> tableSchema;
5261     pF = toe.getSchema().First();
5262     while ( pF )
5263     {
5264 	if ( schema.Find(CegoField(tableName, pF->getAttrName())))
5265 	    tableSchema.Insert(*pF);
5266 	pF = toe.getSchema().Next();
5267     }
5268 
5269 
5270     pF = schema.First();
5271     while (pF)
5272     {
5273 	CegoField* pSF = toe.getSchema().Find(CegoField(tableName, pF->getAttrName()));
5274 
5275 	if ( pSF )
5276 	{
5277 	    pF->setType(pSF->getType());
5278 	    pF->setLength(pSF->getLength());
5279 	    pF->setId(pSF->getId());
5280 	}
5281 	else
5282 	{
5283 	    Chain msg = "Unknown field <" + pF->getAttrName()  + ">";
5284 	    throw Exception(EXLOC, msg);
5285 	}
5286 
5287 	if ( type == CegoObject::PBTREE && pSF->isNullable() )
5288 	{
5289 	    Chain msg = "Primary btree attribute must be not nullable";
5290 	    throw Exception(EXLOC, msg);
5291 	}
5292 
5293 	pF = schema.Next();
5294     }
5295 
5296     if ( doSync )
5297 	_pDBMng->useObject(tabSetId, tableName, CegoObject::TABLE, CegoDatabaseManager::SHARED, _threadId);
5298 
5299     CegoBTreeObject btoe(tabSetId, type, btreeName, schema, tableName);
5300     CegoDataPointer sysEntry;
5301 
5302     try
5303     {
5304 	createBTreeObject(btoe);
5305     }
5306     catch ( Exception e )
5307     {
5308 	if ( doSync )
5309 	    _pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5310 
5311 	Chain msg;
5312 	e.pop(msg);
5313 	throw Exception(EXLOC, Chain("Create of btree failed (") + msg + + Chain(")"));
5314     }
5315 
5316     // building up index
5317 
5318     CegoObjectCursor* pC = 0;
5319     CegoBufferPage bp;
5320     CegoBTreeManager* pBTreeMng = 0;
5321 
5322     try
5323     {
5324 	// we have to keep the index object in buffer pool
5325 	getObjectWithFix(tabSetId, btreeName, type, btoe, bp);
5326 	sysEntry = CegoDataPointer(bp.getPageId(), bp.getEntryPos());
5327 
5328 	// create root node
5329 
5330 	CegoBufferPage rootPage;
5331 	getNewFilePage(rootPage, btoe.getTabSetId(), btoe.getType());
5332 
5333 	rootPage.setType(CegoBufferPage::BTREE_LEAF);
5334 	CegoBTreeNode rootNode;
5335 	rootNode.setPtr(rootPage.getChunkEntry(), rootPage.getChunkLen());
5336 	rootNode.initNode();
5337 
5338 	PageIdType dataPageId = rootPage.getPageId();
5339 
5340 	btoe.setDataPageId(dataPageId);
5341 
5342 	_pDBMng->bufferUnfix(rootPage, true, _pLockHandle);
5343 
5344 	CegoDataPointer dp;
5345 	pC = getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
5346 	bool moreTuple = getFirstTuple(pC, tableSchema, dp);
5347 
5348 	pBTreeMng = new CegoBTreeManager(this, &btoe);
5349 
5350 	if ( isCached )
5351 	{
5352 	    pBTreeMng->createCache();
5353 	}
5354 
5355 	while (moreTuple && _isAborted == false)
5356 	{
5357 	    CegoBTreeValue iv;
5358 
5359 	    iv.valueFromSchema(tableSchema, schema);
5360 
5361 	    unsigned long long tid = 0;
5362 	    pBTreeMng->insertBTree(dp, iv, tid);
5363 
5364 	    moreTuple = getNextTuple(pC, tableSchema, dp);
5365 	}
5366 
5367 	// we also can release the object cursor
5368 	pC->abort();
5369 	delete pC;
5370 	pC = 0;
5371 
5372 	if ( _isAborted )
5373 	{
5374 	    throw Exception(EXLOC, Chain("Btree creation aborted by user"));
5375 	}
5376     }
5377     catch ( Exception e )
5378     {
5379 	if  ( bp.isFixed() )
5380 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
5381 
5382 	if ( pC )
5383 	{
5384 	    pC->abort();
5385 	    delete pC;
5386 	}
5387 	if ( pBTreeMng )
5388 	{
5389 	    pBTreeMng->rollback();
5390 	    delete pBTreeMng;
5391 	}
5392 
5393 	dropBTree(tabSetId, btreeName);
5394 
5395 	if ( doSync )
5396 	    _pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5397 
5398 	Chain msg;
5399 	e.pop(msg);
5400 
5401 	throw Exception(EXLOC, Chain("Create of btree failed (") + msg + Chain(")"));
5402 
5403     }
5404 
5405     if ( doSync )
5406     {
5407 	_pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5408 	_pDBMng->useObject(tabSetId, tableName, CegoObject::TABLE, CegoDatabaseManager::EXCLUSIVE_WRITE, _threadId);
5409     }
5410 
5411     pBTreeMng->commit(sysEntry);
5412 
5413     if ( doSync )
5414     {
5415 	_pDBMng->unuseObject(tabSetId, tableName, CegoObject::TABLE);
5416     }
5417 
5418     // now we can release the index root page
5419     _pDBMng->bufferUnfix(bp, true, _pLockHandle);
5420 
5421     delete pBTreeMng;
5422 
5423     // create log entry
5424 
5425     lr.setObjectInfo(btoe.getName(), btoe.getType());
5426     lr.setAction(CegoLogRecord::LOGREC_CREATE);
5427 
5428     char *buf;
5429     buf = (char*)malloc(btoe.getEntrySize());
5430 
5431     btoe.encode(buf);
5432     lr.setData(buf);
5433     lr.setDataLen(btoe.getEntrySize());
5434     // lr.setTID(0);
5435 
5436     _pDBMng->logIt(btoe.getTabSetId(), lr, _pLockHandle);
5437 
5438     free(buf);
5439 }
5440 
createAVLIndexTable(int tabSetId,const Chain & indexName,const Chain & tableName,ListT<CegoField> & schema,CegoObject::ObjectType type)5441 void CegoTableManager::createAVLIndexTable(int tabSetId, const Chain& indexName, const Chain& tableName, ListT<CegoField>& schema, CegoObject::ObjectType type)
5442 {
5443     if ( getTID(tabSetId) > 0 )
5444     {
5445 	Chain msg = Chain("create avl index in a transaction not allowed");
5446 	throw Exception(EXLOC, msg);
5447     }
5448 
5449     CegoLogRecord lr;
5450     lr.setLSN(_pDBMng->nextLSN(tabSetId));
5451 
5452     CegoTableObject toe;
5453 
5454     getObject(tabSetId, tableName, CegoObject::TABLE, toe);
5455 
5456     CegoField* pF = schema.First();
5457     while (pF)
5458     {
5459 	CegoField* pSF = toe.getSchema().Find(CegoField(tableName, pF->getAttrName()));
5460 
5461 	if ( pSF )
5462 	{
5463 	    pF->setType(pSF->getType());
5464 	    pF->setLength(pSF->getLength());
5465 	    pF->setId(pSF->getId());
5466 	}
5467 	else
5468 	{
5469 	    Chain msg = "Unknown field <" + pF->getAttrName()  + ">";
5470 	    throw Exception(EXLOC, msg);
5471 	}
5472 
5473 	if ( type == CegoObject::PAVLTREE && pSF->isNullable() )
5474 	{
5475 	    Chain msg = "Primary index attribute must be not nullable";
5476 	    throw Exception(EXLOC, msg);
5477 	}
5478 
5479 	pF = schema.Next();
5480     }
5481 
5482     CegoTableObject ioe(tabSetId, type, indexName, schema, tableName);
5483 
5484     createTableObject(ioe);
5485 
5486     CegoAVLIndexEntry base;
5487     CegoDataPointer nil;
5488 
5489     base.initEntry(nil);
5490 
5491     base.setLeftBranch(nil);
5492     base.setParent(nil);
5493     base.setRightBranch(nil);
5494 
5495     CegoDataPointer dp = insertData(ioe, (char*)base.getPtr(), base.getLen(), true);
5496 
5497     CegoBufferPage zp;
5498     // unsigned long recLock = _pLockHandle->lockRecord(zp, dp, CegoLockHandler::WRITE);
5499 
5500     // building up index
5501 
5502     CegoObjectCursor* pC = 0;
5503     CegoBufferPage bp;
5504 
5505     CegoAVLIndexManager idxMng(this);
5506 
5507     try
5508     {
5509 	pC = getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
5510 
5511 	// we have to keep the index object in buffer pool
5512 	getObjectWithFix(tabSetId, indexName, type, ioe, bp);
5513 
5514 	CegoDataPointer dp;
5515 	unsigned long long tid = 0;
5516 
5517 	char idxBuf[TABMNG_MAXINDEXVALUE];
5518 
5519 	bool moreTuple = getFirstTuple(pC, schema, dp);
5520 
5521 	bool isFirst = true;
5522 	CegoDataPointer ritp;
5523 
5524 	CegoDataPointer sysEntry(bp.getPageId(), bp.getEntryPos());
5525 
5526 	while (moreTuple && _isAborted == false)
5527 	{
5528 	    // get Index len
5529 	    int idxLen = 0;
5530 	    CegoField* pF = schema.First();
5531 	    while (pF)
5532 	    {
5533 		idxLen += pF->getValue().getLength() + sizeof(int);
5534 		pF = schema.Next();
5535 	    }
5536 
5537 	    char* idxPtr = idxBuf;
5538 	    pF = schema.First();
5539 	    while (pF)
5540 	    {
5541 		int len = pF->getValue().getLength();
5542 		memcpy(idxPtr, &len, sizeof(int));
5543 		idxPtr+=sizeof(int);
5544 		if ( len > 0 )
5545 		{
5546 		    memcpy(idxPtr, pF->getValue().getValue(), len);
5547 		    idxPtr += len;
5548 		}
5549 		pF = schema.Next();
5550 	    }
5551 
5552 	    if ( isFirst )
5553 	    {
5554 		// since we have locked the index root page in bufferpool, we can call with no resolution of object entry
5555 		idxMng.insertNativeIndexTable(ioe, sysEntry, dp, idxBuf, idxLen, tid, true, ritp);
5556 		isFirst=false;
5557 	    }
5558 	    else
5559 	    {
5560 		bool isUnique = false;
5561 		if ( type == CegoObject::UAVLTREE || type == CegoObject::PAVLTREE )
5562 		    isUnique = true;
5563 
5564 		idxMng.insertIndexTable(ioe, sysEntry, ritp, isUnique, dp, idxBuf, idxLen, tid, true, true);
5565 	    }
5566 
5567 	    moreTuple = getNextTuple(pC, schema, dp);
5568 	}
5569 
5570 	if ( _isAborted )
5571 	{
5572 	    throw Exception(EXLOC, Chain("Index creation aborted by user"));
5573 	}
5574     }
5575     catch ( Exception e )
5576     {
5577 	if  ( bp.isFixed() )
5578 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
5579 	if ( pC )
5580 	    pC->abort();
5581 
5582 	// _pLockHandle->unlockRecord(recLock);
5583 
5584 	delete pC;
5585 	dropIndex(tabSetId, indexName);
5586 
5587 	Chain msg;
5588 	e.pop(msg);
5589 	throw Exception(EXLOC, Chain("Create of index failed (") + msg + Chain(")"));
5590     }
5591 
5592     // now we can release the index root page
5593     _pDBMng->bufferUnfix(bp, true, _pLockHandle);
5594     // _pLockHandle->unlockRecord(recLock);
5595 
5596     // we also can release the object cursor
5597     pC->abort();
5598 
5599     delete pC;
5600 
5601     // create log entry
5602     lr.setObjectInfo(ioe.getName(), ioe.getType());
5603     lr.setAction(CegoLogRecord::LOGREC_CREATE);
5604 
5605     char *buf;
5606     buf = (char*)malloc(ioe.getEntrySize());
5607 
5608     ioe.encode(buf);
5609     lr.setData(buf);
5610     lr.setDataLen(ioe.getEntrySize());
5611     // lr.setTID(0);
5612 
5613     _pDBMng->logIt(ioe.getTabSetId(), lr, _pLockHandle);
5614 
5615     free(buf);
5616 }
5617 
createForeignKey(int tabSetId,const Chain & fkey,const Chain & tableName,const ListT<CegoField> & keyList,const Chain & refTable,const ListT<CegoField> & refList)5618 void CegoTableManager::createForeignKey(int tabSetId, const Chain& fkey, const Chain& tableName, const ListT<CegoField>& keyList, const Chain& refTable, const ListT<CegoField>& refList)
5619 {
5620     if ( getTID(tabSetId) > 0 )
5621     {
5622 	Chain msg = Chain("create foreign key in a transaction not allowed");
5623 	throw Exception(EXLOC, msg);
5624     }
5625 
5626     CegoLogRecord lr;
5627     lr.setLSN(_pDBMng->nextLSN(tabSetId));
5628 
5629     CegoObjectCursor* pC = 0;
5630 
5631     try
5632     {
5633 	// check if key references primary key
5634 
5635 	ListT<CegoTableObject> checkIdxList;
5636 	ListT<CegoBTreeObject> checkBTreeList;
5637 	ListT<CegoKeyObject> checkKeyList;
5638 	ListT<CegoCheckObject> checkList;
5639 	ListT<CegoTriggerObject> triggerList;
5640 	ListT<CegoAliasObject> aliasList;
5641 	int numInvalid;
5642 
5643 	getObjectListByTable(tabSetId, refTable, checkIdxList, checkBTreeList, checkKeyList, checkList, triggerList, aliasList, numInvalid);
5644 	if ( numInvalid > 0 )
5645 	{
5646 	    throw Exception(EXLOC, Chain("Cannot create foreign key on table with invalid index"));
5647 	}
5648 
5649 	CegoTableObject *pIO = checkIdxList.First();
5650 	bool idxFound = false;
5651 	while ( pIO && idxFound == false)
5652 	{
5653 	    if ( pIO->getType() == CegoObject::PAVLTREE )
5654 	    {
5655 		if ( pIO->getSchema().Size() == keyList.Size() )
5656 		{
5657 		    CegoField *pK = refList.First();
5658 		    idxFound = true;
5659 		    while ( pK && idxFound )
5660 		    {
5661 			if ( pIO->getSchema().Find(*pK) )
5662 			{
5663 			    pK = refList.Next();
5664 			}
5665 			else
5666 			{
5667 			    idxFound = false;
5668 			}
5669 		    }
5670 		}
5671 		// just one primary index can be found
5672 		pIO = 0;
5673 	    }
5674 	    else
5675 	    {
5676 		pIO = checkIdxList.Next();
5677 	    }
5678 	}
5679 	if ( idxFound == false )
5680 	{
5681 	    CegoBTreeObject *pBTO = checkBTreeList.First();
5682 	    while ( pBTO && idxFound == false)
5683 	    {
5684 		if ( pBTO->getType() == CegoObject::PBTREE )
5685 		{
5686 		    if ( pBTO->getSchema().Size() == keyList.Size() )
5687 		    {
5688 			CegoField *pK = refList.First();
5689 			idxFound = true;
5690 			while ( pK && idxFound )
5691 			{
5692 			    if ( pBTO->getSchema().Find(*pK) )
5693 			    {
5694 				pK = refList.Next();
5695 			    }
5696 			    else
5697 			    {
5698 				idxFound = false;
5699 			    }
5700 			}
5701 		    }
5702 
5703 		    // just one primary btree can be found
5704 		    pBTO = 0;
5705 		}
5706 		else
5707 		{
5708 		    pBTO = checkBTreeList.Next();
5709 		}
5710 	    }
5711 	}
5712 
5713 	if ( idxFound == false )
5714 	    throw Exception(EXLOC, Chain("Primary index or btree not found"));
5715 
5716 	CegoTableObject toe;
5717 	getObject(tabSetId, tableName, CegoObject::TABLE, toe);
5718 
5719 	ListT<CegoField> schema = toe.getSchema();
5720 
5721 	CegoField *pDF = keyList.First();
5722 	while ( pDF )
5723 	{
5724 	    CegoField *pF = schema.Find(*pDF);
5725 	    if ( pF == 0 )
5726 	    {
5727 		Chain msg = Chain("Unknown key attribute ") + pDF->getAttrName();
5728 		throw Exception(EXLOC, msg);
5729 	    }
5730 	    pDF = keyList.Next();
5731 	}
5732 
5733 	pC = getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
5734 
5735 	CegoDataPointer dp;
5736 
5737 	bool moreTuple = getFirstTuple(pC, schema, dp);
5738 
5739 	while ( moreTuple && _isAborted == false)
5740 	{
5741 	    CegoTableCursor tc(this, tabSetId, refTable);
5742 
5743 	    CegoAttrCond ac;
5744 
5745 	    CegoField *pDF = keyList.First();
5746 	    while ( pDF )
5747 	    {
5748 		CegoField *pF = schema.Find(*pDF);
5749 		if ( pF )
5750 		{
5751 		    ac.add(CegoAttrComp(pF->getTableAlias(), pF->getAttrName(), EQUAL, pF->getValue()));
5752 		}
5753 		else
5754 		{
5755 		    Chain msg = Chain("Unknown key attribute ") + pDF->getAttrName();
5756 		    throw Exception(EXLOC, msg);
5757 		}
5758 		pDF = keyList.Next();
5759 	    }
5760 
5761 	    ListT<CegoField> tfl;
5762             CegoAttrCond::IndexMatch indexMatch = tc.setup(ac);
5763 
5764             if ( indexMatch == CegoAttrCond::FULL || indexMatch == CegoAttrCond::PART )
5765             {
5766 		tc.getIdxSchema(tfl);
5767             }
5768             else
5769             {
5770 		CegoTableObject oe;
5771 		getObject(tabSetId, refTable, CegoObject::TABLE, oe);
5772 		tfl = oe.getSchema();
5773             }
5774 
5775             CegoDataPointer dp;
5776 
5777             bool moreRefTuple = tc.getFirst(tfl, dp);
5778 
5779             bool isMatch = false;
5780             while ( moreRefTuple && ( ! isMatch ) )
5781             {
5782                 CegoField *pF = tfl.First();
5783                 while ( pF )
5784                 {
5785                     isMatch = true;
5786                     CegoField *pD = schema.Find(*pF);
5787                     if ( pD )
5788                     {
5789                         // cout << "Comparing " << pD->getValue() << " == " << pF->getValue()  << endl;
5790                         if ( ! ( (CegoFieldValue)pD->getValue() == (CegoFieldValue)pF->getValue()) )
5791                             isMatch=false;
5792                     }
5793                     pF = tfl.Next();
5794                 }
5795                 moreRefTuple = tc.getNext(tfl, dp);
5796             }
5797             if ( ! isMatch )
5798 		throw Exception(EXLOC, Chain("Foreign key reference does not exist"));
5799 
5800 	    moreTuple = getNextTuple(pC, schema, dp);
5801 	}
5802 
5803 	if ( _isAborted )
5804 	{
5805 	    throw Exception(EXLOC, Chain("Foreign key creation aborted by user"));
5806 	}
5807     }
5808     catch ( Exception e )
5809     {
5810 	if ( pC )
5811 	    pC->abort();
5812 	throw e;
5813     }
5814 
5815     delete pC;
5816 
5817     CegoKeyObject oe(tabSetId, fkey, tableName, keyList, refTable, refList );
5818 
5819     createKeyObject(oe);
5820 
5821     // create log entry
5822     lr.setObjectInfo(oe.getName(), oe.getType());
5823     lr.setAction(CegoLogRecord::LOGREC_CREATE);
5824 
5825     char *buf;
5826     buf = (char*)malloc(oe.getEntrySize());
5827 
5828     oe.encode(buf);
5829     lr.setData(buf);
5830     lr.setDataLen(oe.getEntrySize());
5831     // lr.setTID(0);
5832 
5833     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
5834 
5835     free(buf);
5836 }
5837 
createCheck(int tabSetId,const Chain & checkName,const Chain & tableName,CegoPredDesc * pPredDesc)5838 void CegoTableManager::createCheck(int tabSetId, const Chain& checkName, const Chain& tableName, CegoPredDesc *pPredDesc)
5839 {
5840     if ( getTID(tabSetId) > 0 )
5841     {
5842 	Chain msg = Chain("create check in a transaction not allowed");
5843 	throw Exception(EXLOC, msg);
5844     }
5845 
5846     CegoLogRecord lr;
5847     lr.setLSN(_pDBMng->nextLSN(tabSetId));
5848 
5849     CegoObjectCursor* pC = 0;
5850 
5851     try
5852     {
5853 	CegoTableObject toe;
5854 	getObject(tabSetId, tableName, CegoObject::TABLE, toe);
5855 
5856 	ListT<CegoField> schema = toe.getSchema();
5857 
5858 	// we need to create an additional reference to use the setFieldListArray method
5859 	ListT<CegoField>* xschema[2];
5860 	xschema[0] = &schema;
5861 	xschema[1] = 0;
5862 
5863 	pC = getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
5864 
5865 	CegoDataPointer dp;
5866 
5867 	bool moreTuple = getFirstTuple(pC, schema, dp);
5868 
5869 	if ( moreTuple )
5870 	{
5871 	    while ( moreTuple && _isAborted == false)
5872 	    {
5873 		pPredDesc->clearAttrCache();
5874 		if ( CegoQueryHelper::evalPredicate(0, 0, xschema, 0, pPredDesc ) == false )
5875 		    throw Exception(EXLOC, Chain("Check constraint violated"));
5876 		moreTuple = getNextTuple(pC, schema, dp);
5877 	    }
5878 	}
5879 	else
5880 	{
5881 	    // check attribute match for empty tables
5882 	    CegoExpr *pExpr = pPredDesc->getExpr1();
5883 	    if ( pExpr )
5884 	    {
5885 		ListT<CegoAttrDesc*> adl = pExpr->getAttrRefList();
5886 		CegoAttrDesc **pAD = adl.First();
5887 		while ( pAD )
5888 		{
5889 		    if ( ! schema.Find(CegoField((*pAD)->getTableName(), (*pAD)->getAttrName())))
5890 		    {
5891 			Chain msg = Chain("Unknown attribute " ) + (*pAD)->getAttrName();
5892 			throw Exception(EXLOC, msg);
5893 		    }
5894 		    pAD = adl.Next();
5895 		}
5896 	    }
5897 	    pExpr = pPredDesc->getExpr2();
5898 	    if ( pExpr )
5899 	    {
5900 		ListT<CegoAttrDesc*> adl = pExpr->getAttrRefList();
5901 		CegoAttrDesc **pAD = adl.First();
5902 		while ( pAD )
5903 		{
5904 		    if ( ! schema.Find(CegoField((*pAD)->getTableName(), (*pAD)->getAttrName())))
5905 		    {
5906 			Chain msg = Chain("Unknown attribute " ) + (*pAD)->getAttrName();
5907 			throw Exception(EXLOC, msg);
5908 		    }
5909 		    pAD = adl.Next();
5910 		}
5911 	    }
5912 	    pExpr = pPredDesc->getExpr3();
5913 	    if ( pExpr )
5914 	    {
5915 		ListT<CegoAttrDesc*> adl = pExpr->getAttrRefList();
5916 		CegoAttrDesc **pAD = adl.First();
5917 		while ( pAD )
5918 		{
5919 		    if ( ! schema.Find(CegoField((*pAD)->getTableName(), (*pAD)->getAttrName())))
5920 		    {
5921 			Chain msg = Chain("Unknown attribute " ) + (*pAD)->getAttrName();
5922 			throw Exception(EXLOC, msg);
5923 		    }
5924 		    pAD = adl.Next();
5925 		}
5926 	    }
5927 	}
5928 	if ( _isAborted )
5929 	{
5930 	    throw Exception(EXLOC, Chain("Check constraint creation aborted by user"));
5931 	}
5932 
5933     }
5934     catch ( Exception e )
5935     {
5936 	if ( pC )
5937 	    pC->abort();
5938 
5939 	throw e;
5940     }
5941 
5942     delete pC;
5943 
5944     CegoCheckObject oe(tabSetId, checkName, tableName, pPredDesc );
5945 
5946     createCheckObject(oe);
5947 
5948     // create log entry
5949     lr.setObjectInfo(oe.getName(), oe.getType());
5950     lr.setAction(CegoLogRecord::LOGREC_CREATE);
5951 
5952     char *buf;
5953     buf = (char*)malloc(oe.getEntrySize());
5954 
5955     oe.encode(buf);
5956     lr.setData(buf);
5957     lr.setDataLen(oe.getEntrySize());
5958     // lr.setTID(0);
5959     _pDBMng->logIt(oe.getTabSetId(), lr, _pLockHandle);
5960     free(buf);
5961 }
5962 
5963 
createAlias(int tabSetId,const Chain & aliasName,const Chain & tableName,const ListT<CegoAttrAlias> & aliasList)5964 void CegoTableManager::createAlias(int tabSetId, const Chain& aliasName, const Chain& tableName, const ListT<CegoAttrAlias>& aliasList)
5965 {
5966     if ( aliasName == tableName )
5967     {
5968 	Chain msg = Chain("Table name and alias name cannot be equal");
5969 	throw Exception(EXLOC, msg);
5970     }
5971 
5972     if ( getTID(tabSetId) > 0 )
5973     {
5974 	Chain msg = Chain("create check in a transaction not allowed");
5975 	throw Exception(EXLOC, msg);
5976     }
5977 
5978     try
5979     {
5980 	CegoTableObject toe;
5981 	getObject(tabSetId, tableName, CegoObject::TABLE, toe);
5982     }
5983     catch ( Exception e )
5984     {
5985 	throw e;
5986     }
5987 
5988 
5989 
5990     CegoAliasObject ao(tabSetId, aliasName, tableName, aliasList);
5991 
5992     CegoLogRecord lr;
5993     lr.setLSN(_pDBMng->nextLSN(tabSetId));
5994 
5995     createAliasObject(ao);
5996 
5997     // create log entry
5998     lr.setObjectInfo(ao.getName(), ao.getType());
5999     lr.setAction(CegoLogRecord::LOGREC_CREATE);
6000 
6001     char *buf;
6002     buf = (char*)malloc(ao.getEntrySize());
6003     ao.encode(buf);
6004     lr.setData(buf);
6005     lr.setDataLen(ao.getEntrySize());
6006     // lr.setTID(0);
6007     _pDBMng->logIt(ao.getTabSetId(), lr, _pLockHandle);
6008     free(buf);
6009 }
6010 
createTrigger(int tabSetId,const Chain & triggerName,bool isBefore,bool isOnInsert,bool isOnUpdate,bool isOnDelete,const Chain & tableName,const Chain & triggerText)6011 void CegoTableManager::createTrigger(int tabSetId, const Chain& triggerName,
6012 				     bool isBefore, bool isOnInsert, bool isOnUpdate, bool isOnDelete,
6013 				     const Chain& tableName, const Chain& triggerText)
6014 {
6015     if ( getTID(tabSetId) > 0 )
6016     {
6017 	Chain msg = Chain("create check in a transaction not allowed");
6018 	throw Exception(EXLOC, msg);
6019     }
6020 
6021     try
6022     {
6023 	CegoTableObject toe;
6024 	getObject(tabSetId, tableName, CegoObject::TABLE, toe);
6025     }
6026     catch ( Exception e )
6027     {
6028 	throw e;
6029     }
6030 
6031     CegoTriggerObject to(tabSetId, triggerName, isBefore, isOnInsert, isOnUpdate, isOnDelete, tableName, triggerText);
6032 
6033     CegoLogRecord lr;
6034     lr.setLSN(_pDBMng->nextLSN(tabSetId));
6035 
6036     createTriggerObject(to);
6037 
6038     // create log entry
6039     lr.setObjectInfo(to.getName(), to.getType());
6040     lr.setAction(CegoLogRecord::LOGREC_CREATE);
6041 
6042     char *buf;
6043     buf = (char*)malloc(to.getEntrySize());
6044     to.encode(buf);
6045     lr.setData(buf);
6046     lr.setDataLen(to.getEntrySize());
6047     // lr.setTID(0);
6048     _pDBMng->logIt(to.getTabSetId(), lr, _pLockHandle);
6049     free(buf);
6050 }
6051 
getPoolInfo(CegoTableObject & oe,ListT<ListT<CegoFieldValue>> & info)6052 void CegoTableManager::getPoolInfo(CegoTableObject& oe, ListT< ListT<CegoFieldValue> > &info)
6053 {
6054     ListT<CegoField> schema;
6055     schema.Insert(CegoField(Chain("POOLINFO"), Chain("POOLINFO"), Chain("PARAMETER"),VARCHAR_TYPE, 20));
6056     schema.Insert(CegoField(Chain("POOLINFO"), Chain("POOLINFO"), Chain("VALUE"), VARCHAR_TYPE, 20));
6057     oe = CegoTableObject(0, CegoObject::SYSTEM, Chain("POOLINFO"), schema, Chain("POOLINFO"));
6058 
6059     int pageSize;
6060     unsigned long long totalPages;
6061     unsigned long long usedPages;
6062     unsigned long long freePages;
6063     unsigned long long dirtyPages;
6064     unsigned long long fixedPages;
6065     unsigned long long persistentPages;
6066     unsigned long long noSyncPages;
6067     unsigned long long numDiskRead;
6068     unsigned long long numDiskWrite;
6069     double hitRate;
6070     double spreadRate;
6071     unsigned long long readDelay;
6072     unsigned long long writeDelay;
6073     unsigned long long curFixCount;
6074     unsigned long long maxFixCount;
6075     unsigned long long avgFixTry;
6076 
6077     unsigned long long statStart;
6078     unsigned long long uptime;
6079 
6080     _pDBMng->poolInfo(pageSize, totalPages, usedPages, freePages, dirtyPages, fixedPages, persistentPages, noSyncPages, numDiskRead, numDiskWrite, hitRate, spreadRate, readDelay, writeDelay, curFixCount, maxFixCount, avgFixTry, statStart, uptime);
6081 
6082     CegoFieldValue f1a(VARCHAR_TYPE, Chain("Page Size"));
6083     CegoFieldValue f1b(VARCHAR_TYPE,  Chain(pageSize));
6084     ListT<CegoFieldValue> fl1;
6085     fl1.Insert(f1a);
6086     fl1.Insert(f1b);
6087     info.Insert(fl1);
6088 
6089     CegoFieldValue f2a(VARCHAR_TYPE, Chain("Total Pages"));
6090     CegoFieldValue f2b(VARCHAR_TYPE,  Chain(totalPages));
6091     ListT<CegoFieldValue> fl2;
6092     fl2.Insert(f2a);
6093     fl2.Insert(f2b);
6094     info.Insert(fl2);
6095 
6096     CegoFieldValue f3a(VARCHAR_TYPE, Chain("Used Pages"));
6097     CegoFieldValue f3b(VARCHAR_TYPE, Chain(usedPages));
6098     ListT<CegoFieldValue> fl3;
6099     fl3.Insert(f3a);
6100     fl3.Insert(f3b);
6101     info.Insert(fl3);
6102 
6103     CegoFieldValue f4a(VARCHAR_TYPE, Chain("Free Pages"));
6104     CegoFieldValue f4b(VARCHAR_TYPE, Chain(freePages));
6105     ListT<CegoFieldValue> fl4;
6106     fl4.Insert(f4a);
6107     fl4.Insert(f4b);
6108     info.Insert(fl4);
6109 
6110     CegoFieldValue f5a(VARCHAR_TYPE, Chain("Dirty Pages"));
6111     CegoFieldValue f5b(VARCHAR_TYPE, Chain(dirtyPages));
6112     ListT<CegoFieldValue> fl5;
6113     fl5.Insert(f5a);
6114     fl5.Insert(f5b);
6115     info.Insert(fl5);
6116 
6117     CegoFieldValue f6a(VARCHAR_TYPE, Chain("Fixed Pages"));
6118     CegoFieldValue f6b(VARCHAR_TYPE, Chain(fixedPages));
6119     ListT<CegoFieldValue> fl6;
6120     fl6.Insert(f6a);
6121     fl6.Insert(f6b);
6122     info.Insert(fl6);
6123 
6124     CegoFieldValue f7a(VARCHAR_TYPE, Chain("Persistent Pages"));
6125     CegoFieldValue f7b(VARCHAR_TYPE, Chain(persistentPages));
6126     ListT<CegoFieldValue> fl7;
6127     fl7.Insert(f7a);
6128     fl7.Insert(f7b);
6129     info.Insert(fl7);
6130 
6131     CegoFieldValue f8a(VARCHAR_TYPE, Chain("No Sync Pages"));
6132     CegoFieldValue f8b(VARCHAR_TYPE, Chain(noSyncPages));
6133     ListT<CegoFieldValue> fl8;
6134     fl8.Insert(f8a);
6135     fl8.Insert(f8b);
6136     info.Insert(fl8);
6137 
6138     // format spread rate
6139     Chain srFormated = Chain(spreadRate, "%3.3f");
6140 
6141     CegoFieldValue f9a(VARCHAR_TYPE, Chain("Spread Rate"));
6142     CegoFieldValue f9b(VARCHAR_TYPE, srFormated);
6143     ListT<CegoFieldValue> fl9;
6144     fl9.Insert(f9a);
6145     fl9.Insert(f9b);
6146     info.Insert(fl9);
6147 
6148 
6149     CegoFieldValue f10a(VARCHAR_TYPE, Chain("-------------------"));
6150     CegoFieldValue f10b(VARCHAR_TYPE, Chain("-------------------"));
6151     ListT<CegoFieldValue> fl10;
6152     fl10.Insert(f10a);
6153     fl10.Insert(f10b);
6154     info.Insert(fl10);
6155 
6156     Datetime dt(statStart);
6157     CegoFieldValue f11a(VARCHAR_TYPE, Chain("Stat Start"));
6158     CegoFieldValue f11b(VARCHAR_TYPE, dt.asChain(BUPMNG_STATDTFORMAT));
6159     ListT<CegoFieldValue> fl11;
6160     fl11.Insert(f11a);
6161     fl11.Insert(f11b);
6162     info.Insert(fl11);
6163 
6164     // format hitrate
6165     Chain hrFormated = Chain(hitRate, "%3.2f") + Chain("%");
6166 
6167     CegoFieldValue f12a(VARCHAR_TYPE, Chain("Hit Rate"));
6168     CegoFieldValue f12b(VARCHAR_TYPE, hrFormated);
6169     ListT<CegoFieldValue> fl12;
6170     fl12.Insert(f12a);
6171     fl12.Insert(f12b);
6172     info.Insert(fl12);
6173 
6174     CegoFieldValue f13a(VARCHAR_TYPE, Chain("Cur Fix Count"));
6175     CegoFieldValue f13b(VARCHAR_TYPE, curFixCount);
6176     ListT<CegoFieldValue> fl13;
6177     fl13.Insert(f13a);
6178     fl13.Insert(f13b);
6179     info.Insert(fl13);
6180 
6181     CegoFieldValue f14a(VARCHAR_TYPE, Chain("Max Fix Count"));
6182     CegoFieldValue f14b(VARCHAR_TYPE, maxFixCount);
6183     ListT<CegoFieldValue> fl14;
6184     fl14.Insert(f14a);
6185     fl14.Insert(f14b);
6186     info.Insert(fl14);
6187 
6188     CegoFieldValue f15a(VARCHAR_TYPE, Chain("Avg Fix Try"));
6189     CegoFieldValue f15b(VARCHAR_TYPE, avgFixTry);
6190     ListT<CegoFieldValue> fl15;
6191     fl15.Insert(f15a);
6192     fl15.Insert(f15b);
6193     info.Insert(fl15);
6194 
6195 
6196     CegoFieldValue f16a(VARCHAR_TYPE, Chain("Disk Reads"));
6197     CegoFieldValue f16b(VARCHAR_TYPE, Chain(numDiskRead));
6198     ListT<CegoFieldValue> fl16;
6199     fl16.Insert(f16a);
6200     fl16.Insert(f16b);
6201     info.Insert(fl16);
6202 
6203     CegoFieldValue f17a(VARCHAR_TYPE, Chain("Disk Writes"));
6204     CegoFieldValue f17b(VARCHAR_TYPE, Chain(numDiskWrite));
6205     ListT<CegoFieldValue> fl17;
6206     fl17.Insert(f17a);
6207     fl17.Insert(f17b);
6208     info.Insert(fl17);
6209 
6210     int secDelay;
6211     int msecDelay;
6212     Chain delayStr;
6213     Chain fillStr;
6214 
6215     secDelay = readDelay / 1000;
6216     msecDelay = readDelay % 1000;
6217     fillStr = Chain("000") + Chain(msecDelay);
6218     delayStr = Chain(secDelay) + Chain(".") + fillStr.subChain(fillStr.length()-3, fillStr.length()) + Chain (" msec");
6219 
6220     CegoFieldValue f18a(VARCHAR_TYPE, Chain("Read Delay"));
6221     CegoFieldValue f18b(VARCHAR_TYPE, Chain(delayStr));
6222     ListT<CegoFieldValue> fl18;
6223     fl18.Insert(f18a);
6224     fl18.Insert(f18b);
6225     info.Insert(fl18);
6226 
6227     secDelay = writeDelay / 1000;
6228     msecDelay = writeDelay % 1000;
6229     fillStr = Chain("000") + Chain(msecDelay);
6230     delayStr = Chain(secDelay) + Chain(".") + fillStr.subChain(fillStr.length()-3, fillStr.length()) + Chain (" msec");
6231 
6232     CegoFieldValue f19a(VARCHAR_TYPE, Chain("Write Delay"));
6233     CegoFieldValue f19b(VARCHAR_TYPE, Chain(delayStr));
6234     ListT<CegoFieldValue> fl19;
6235     fl19.Insert(f19a);
6236     fl19.Insert(f19b);
6237     info.Insert(fl19);
6238 
6239 
6240     CegoFieldValue f20a(VARCHAR_TYPE, Chain("-------------------"));
6241     CegoFieldValue f20b(VARCHAR_TYPE, Chain("-------------------"));
6242     ListT<CegoFieldValue> fl20;
6243     fl20.Insert(f20a);
6244     fl20.Insert(f20b);
6245     info.Insert(fl20);
6246 
6247     CegoFieldValue f21a(VARCHAR_TYPE, Chain("Pool Uptime"));
6248 
6249     // calculate time string
6250     unsigned long long d = uptime / ( 3600 * 24 );
6251     unsigned long long h = ( uptime - ( d * 24 * 3600 )) / 3600;
6252     unsigned long long m = ( uptime - ( d * 24 * 3600 ) - ( h * 3600) ) / 60;
6253     unsigned long long s = uptime % 60;
6254 
6255     Chain ss = Chain("0") + Chain(s);
6256     Chain sec = ss.subChain(ss.length()-2,ss.length());
6257 
6258     Chain ms = Chain("0") + Chain(m);
6259     Chain min = ms.subChain(ms.length()-2,ms.length());
6260 
6261     Chain uptimeString = Chain(d) + Chain("d ") + Chain(h) + Chain(":") + min + Chain(":") + sec;
6262     CegoFieldValue f21b(VARCHAR_TYPE, uptimeString);
6263     ListT<CegoFieldValue> fl21;
6264     fl21.Insert(f21a);
6265     fl21.Insert(f21b);
6266     info.Insert(fl21);
6267 }
6268 
getSystemInfo(const Chain & tableSet,CegoTableObject & oe,ListT<ListT<CegoFieldValue>> & fa,Chain & format)6269 void CegoTableManager::getSystemInfo(const Chain& tableSet, CegoTableObject& oe, ListT< ListT<CegoFieldValue> > &fa, Chain& format)
6270 {
6271     int tabSetId = _pDBMng->getTabSetId(tableSet);
6272     int tmpFid = _pDBMng->getTmpFid(tableSet);
6273 
6274     ListT<CegoField> schema;
6275     schema.Insert(CegoField(Chain("SYSINFO"), Chain("SYSINFO"), Chain("SPACE"), VARCHAR_TYPE, 10));
6276     schema.Insert(CegoField(Chain("SYSINFO"), Chain("SYSINFO"), Chain("NUMPAGES"), INT_TYPE, sizeof(int)));
6277     schema.Insert(CegoField(Chain("SYSINFO"), Chain("SYSINFO"), Chain("USEDPAGES"), INT_TYPE, sizeof(int)));
6278 
6279     oe = CegoTableObject(tabSetId, CegoObject::SYSTEM, Chain("SYSINFO"), schema, Chain("SYSINFO"));
6280 
6281     format = Chain("lrr");
6282 
6283     ListT<CegoFieldValue> fv1;
6284 
6285     fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("SYSTEM")));
6286     fv1.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumPages(tabSetId))));
6287     fv1.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumUsedPages(tabSetId, _pLockHandle))));
6288 
6289     fa.Insert(fv1);
6290 
6291     ListT<Chain> dfList;
6292     ListT<int> fidList;
6293     ListT<int> sizeList;
6294 
6295     _pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, sizeList);
6296 
6297     Chain *pDF = dfList.First();
6298     int *pFid = fidList.First();
6299 
6300     while ( pFid && pDF)
6301     {
6302 	ListT<CegoFieldValue> fv;
6303 
6304 	fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("SYSTEM")));
6305 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumPages(*pFid))));
6306 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumUsedPages(*pFid, _pLockHandle))));
6307 
6308 	fa.Insert(fv);
6309 
6310 	pFid = fidList.Next();
6311 	pDF = dfList.Next();
6312     }
6313 
6314     ListT<CegoFieldValue> fv2;
6315 
6316     fv2.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("TEMP")));
6317     fv2.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumPages(tmpFid))));
6318     fv2.Insert(CegoFieldValue(INT_TYPE,  Chain(_pDBMng->getNumUsedPages(tmpFid, _pLockHandle))));
6319 
6320     fa.Insert(fv2);
6321 
6322     dfList.Empty();
6323     fidList.Empty();
6324     sizeList.Empty();
6325 
6326     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
6327 
6328     pDF = dfList.First();
6329     pFid = fidList.First();
6330 
6331     while ( pFid && pDF)
6332     {
6333 	ListT<CegoFieldValue> fv;
6334 
6335 	fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("TEMP")));
6336 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumPages(*pFid))));
6337 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumUsedPages(*pFid, _pLockHandle))));
6338 
6339 	fa.Insert(fv);
6340 
6341 	pFid = fidList.Next();
6342 	pDF = dfList.Next();
6343     }
6344 
6345     dfList.Empty();
6346     fidList.Empty();
6347     sizeList.Empty();
6348 
6349     _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, sizeList);
6350 
6351     pDF = dfList.First();
6352     pFid = fidList.First();
6353 
6354     while ( pFid && pDF)
6355     {
6356 	ListT<CegoFieldValue> fv;
6357 
6358 	fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("DATAFILE")));
6359 
6360 	// fv.Insert(CegoFieldValue(VARCHAR_TYPE, *pDF));
6361 
6362 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumPages(*pFid))));
6363 	fv.Insert(CegoFieldValue(INT_TYPE, Chain(_pDBMng->getNumUsedPages(*pFid, _pLockHandle))));
6364 
6365 	fa.Insert(fv);
6366 
6367 	pFid = fidList.Next();
6368 	pDF = dfList.Next();
6369     }
6370 }
6371 
dumpObject(const Chain & tableSet,const Chain & objName,CegoObject::ObjectType type,Chain & chainDump)6372 void CegoTableManager::dumpObject(const Chain& tableSet, const Chain& objName, CegoObject::ObjectType type, Chain& chainDump)
6373 {
6374     int tabSetId = _pDBMng->getTabSetId(tableSet);
6375     dumpObject(tabSetId, objName, type, chainDump);
6376 }
6377 
dumpObject(int tabSetId,const Chain & objName,CegoObject::ObjectType type,Chain & chainDump)6378 void CegoTableManager::dumpObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, Chain& chainDump)
6379 {
6380 
6381     chainDump = Chain("Name: <") + objName + Chain(">\n");
6382     chainDump += Chain("Type: ");
6383 
6384     switch (type)
6385     {
6386     case CegoObject::TABLE:
6387     case CegoObject::AVLTREE:
6388     case CegoObject::UAVLTREE:
6389     case CegoObject::PAVLTREE:
6390     {
6391 	chainDump += CegoTypeConverter::getObjectTypeString(type) + Chain("\n");
6392 
6393 	CegoTableObject oe;
6394 	getObject(tabSetId, objName, type, oe);
6395 
6396 	chainDump += Chain("Schema:\n");
6397 	CegoField* pF = oe.getSchema().First();
6398 	while (pF)
6399 	{
6400 	    chainDump += Chain("   TableName: <") + pF->getTableName() + Chain(">\n");
6401 	    chainDump += Chain("   TableAlias: <") + pF->getTableAlias() + Chain(">\n");
6402 	    chainDump += Chain("   AttrName: <") + pF->getAttrName() + Chain(">\n");
6403 	    chainDump += Chain("   Id: <") + Chain(pF->getId()) + Chain(">\n");
6404 
6405 	    pF = oe.getSchema().Next();
6406 	}
6407 
6408 	CegoObjectCursor* pC = getObjectCursor(tabSetId, oe.getTabName(), objName, type);
6409 
6410 	CegoDataPointer dp;
6411 	int len;
6412 	char* pc = (char*)pC->getFirst(len, dp);
6413 
6414 	unsigned long long rowCount=0;
6415 	while ( pc && len > 0 )
6416 	{
6417 	    rowCount++;
6418 
6419 	    unsigned long long tid;
6420 	    unsigned long long tastep;
6421 	    CegoTupleState ts;
6422 
6423 	    int toff = CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);
6424 
6425 	    char* tp = pc + toff;
6426 	    int tlen = len - toff;
6427 
6428 
6429 	    chainDump += dp.toChain();
6430 	    chainDump += Chain(" Row=") + Chain(rowCount)
6431 		+ Chain(",Tid=") + Chain(tid)
6432 		+ Chain(",Step=") + Chain(tastep);
6433 
6434 	    if ( ts == COMMITTED )
6435 		chainDump += Chain(",State=C");
6436 	    else if ( ts == INSERTED )
6437 		chainDump += Chain(",State=I");
6438 	    else if ( ts == DELETED )
6439 		chainDump += Chain(",State=D");
6440 	    else if ( ts == OBSOLETE )
6441 		chainDump += Chain(",State=O");
6442 
6443 	    chainDump += Chain(",Data=");
6444 
6445 	    if ( type == CegoObject::TABLE )
6446 	    {
6447 		ListT<CegoField> fl = oe.getSchema();
6448 		CegoQueryHelper::decodeFVL(fl, tp, tlen);
6449 		CegoField *pF = fl.First();
6450 		while ( pF )
6451 		{
6452 		    chainDump += Chain("<") + pF->getValue().toChain() + Chain(">");
6453 		    pF = fl.Next();
6454 		}
6455 		chainDump += Chain("\n");
6456 
6457 	    }
6458 	    else if ( type == CegoObject::AVLTREE || type == CegoObject::UAVLTREE || type == CegoObject::PAVLTREE )
6459 	    {
6460 		CegoAVLIndexEntry ie;
6461 		ie.setPtr(pc,len);
6462 
6463 		chainDump += "Entry " + dp.toChain() + ":  Parent=" + ie.getParent().toChain()  + " Left=" + ie.getLeftBranch().toChain() + " Right=" + ie.getRightBranch().toChain() + " Data=" + ie.getData().toChain();
6464 
6465 		int h = (int)ie.getHeight();
6466 		chainDump += " Height=" + Chain(h);
6467 
6468 		if ( ie.getIdxPtr() != 0 )
6469 		{
6470 		    int l;
6471 		    memcpy(&l, ie.getIdxPtr(), sizeof(int));
6472 		    chainDump += " Len: " + Chain(l);
6473 
6474 		    int v;
6475 		    memcpy(&v, (int*)((long long)ie.getIdxPtr() + sizeof(int)), sizeof(int));
6476 		    chainDump += " Val: " + Chain(v);
6477 
6478 		    // cout << " IdxPtr: " << ie.getIdxPtr();
6479 		}
6480 		chainDump += "\n";
6481 	    }
6482 	    else
6483 	    {
6484 		cout << "Not implemented .." << endl;
6485 	    }
6486 
6487 	    pc = (char*)pC->getNext(len, dp);
6488 	}
6489 
6490 	delete pC;
6491 
6492 	break;
6493     }
6494     case CegoObject::BTREE:
6495     case CegoObject::PBTREE:
6496     case CegoObject::UBTREE:
6497     case CegoObject::PROCEDURE:
6498     case CegoObject::VIEW:
6499     case CegoObject::ALIAS:
6500     case CegoObject::TRIGGER:
6501     case CegoObject::UNDEFINED:
6502     case CegoObject::SYSTEM:
6503     case CegoObject::RBSEG:
6504     case CegoObject::FKEY:
6505     case CegoObject::CHECK:
6506     case CegoObject::JOIN:
6507     {
6508 	chainDump = Chain("Not implemented");
6509 	break;
6510     }
6511     }
6512 }
6513 
regDataFiles(const Chain & tableSet)6514 void CegoTableManager::regDataFiles(const Chain& tableSet)
6515 {
6516     int tmpFileId = _pDBMng->getTmpFid(tableSet);
6517     int tabSetId = _pDBMng->getTabSetId(tableSet);
6518 
6519     Chain dbTempFileName = _pDBMng->getTmpFileName(tableSet);
6520     Chain dbSysFileName = _pDBMng->getSysFileName(tableSet);
6521 
6522     _pDBMng->log(_modId, Logger::NOTICE, Chain("Registering system datafile  ") + dbSysFileName + Chain(" ..."));
6523     _pDBMng->regDataFile(tabSetId, dbSysFileName, tabSetId, _pLockHandle);
6524 
6525     _pDBMng->log(_modId, Logger::NOTICE, Chain("Registering temp datafile  ") + dbTempFileName + Chain(" ..."));
6526     _pDBMng->regDataFile(tabSetId, dbTempFileName, tmpFileId, _pLockHandle);
6527 
6528     ListT<Chain> dfList;
6529     ListT<int> fidList;
6530     ListT<int> sizeList;
6531 
6532     _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, sizeList);
6533 
6534     Chain *pFileName = dfList.First();
6535     int *pFid = fidList.First();
6536     int *pSize = sizeList.First();
6537 
6538     while ( pFileName && pFid && pSize )
6539     {
6540 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
6541 
6542 	pFileName = dfList.Next();
6543 	pFid = fidList.Next();
6544 	pSize = sizeList.Next();
6545     }
6546 
6547     dfList.Empty();
6548     fidList.Empty();
6549     sizeList.Empty();
6550 
6551     _pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, sizeList);
6552 
6553     pFileName = dfList.First();
6554     pFid = fidList.First();
6555     pSize = sizeList.First();
6556 
6557     while ( pFileName && pFid && pSize )
6558     {
6559 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
6560 
6561 	pFileName = dfList.Next();
6562 	pFid = fidList.Next();
6563 	pSize = sizeList.Next();
6564     }
6565 
6566     dfList.Empty();
6567     fidList.Empty();
6568     sizeList.Empty();
6569 
6570     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
6571 
6572     pFileName = dfList.First();
6573     pFid = fidList.First();
6574     pSize = sizeList.First();
6575 
6576     while ( pFileName && pFid && pSize )
6577     {
6578 	_pDBMng->regDataFile(tabSetId, *pFileName, *pFid, _pLockHandle);
6579 
6580 	pFileName = dfList.Next();
6581 	pFid = fidList.Next();
6582 	pSize = sizeList.Next();
6583     }
6584 
6585     dfList.Empty();
6586     fidList.Empty();
6587     sizeList.Empty();
6588 
6589     if ( _pDBMng->checkPointDumpEnabled(tabSetId) )
6590     {
6591 	_pDBMng->restoreCheckpointDump(tabSetId, _pLockHandle);
6592     }
6593 
6594     _pDBMng->log(_modId, Logger::NOTICE, Chain("Registration finished"));
6595 }
6596 
6597 ///////////////////////
6598 // protected methods //
6599 ///////////////////////
6600 
resetTemp(const Chain & tableSet)6601 void CegoTableManager::resetTemp(const Chain& tableSet)
6602 {
6603     int tabSetId = _pDBMng->getTabSetId(tableSet);
6604     int tmpFileId = _pDBMng->getTmpFid(tableSet);
6605 
6606     _pDBMng->resetDataFile(tmpFileId);
6607 
6608     PageIdType pageOffset = _pDBMng->getTempPageOffset(tabSetId);
6609 
6610     for ( PageIdType i = 0 ; i < TABMNG_HASHSIZE ; i++ )
6611     {
6612 	_pDBMng->claimPage(pageOffset + i, _pLockHandle);
6613     }
6614 
6615     ListT<Chain> dfList;
6616     ListT<int> fidList;
6617     ListT<int> sizeList;
6618 
6619     _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, sizeList);
6620 
6621     Chain *pFileName = dfList.First();
6622     int *pFid = fidList.First();
6623     int *pSize = sizeList.First();
6624 
6625     while ( pFileName && pFid && pSize )
6626     {
6627 	_pDBMng->resetDataFile(*pFid);
6628 	pFileName = dfList.Next();
6629 	pFid = fidList.Next();
6630 	pSize = sizeList.Next();
6631     }
6632 }
6633 
6634 
finishOpenTransaction(int tabSetId)6635 void CegoTableManager::finishOpenTransaction(int tabSetId)
6636 {
6637     // ensure that no transaction is active, in case of a crash recovery, this might be
6638     _tid[tabSetId] = 0;
6639     _tastep[tabSetId] = 0;
6640 
6641     _pTM->finishOpenTransaction(tabSetId);
6642 
6643 }
6644 
extractIndexValue(const ListT<CegoField> & tableSchema,const ListT<CegoField> & indexSchema,char * p,int len,int & idxLen)6645 void CegoTableManager::extractIndexValue(const ListT<CegoField>& tableSchema, const ListT<CegoField>& indexSchema, char* p, int len, int& idxLen)
6646 {
6647     CegoField* pIF = indexSchema.First();
6648 
6649     idxLen = 0;
6650 
6651     while (pIF)
6652     {
6653 	CegoField* pTF = tableSchema.First();
6654 
6655 	while (pTF)
6656 	{
6657 	    if ( (Chain)pTF->getAttrName() == (Chain)pIF->getAttrName() )
6658 	    {
6659 		int flen = pTF->getValue().getLength();
6660 
6661 		idxLen += flen + sizeof(int);
6662 		if ( idxLen > len)
6663 		{
6664 		    throw Exception(EXLOC, Chain("Index value too long"));
6665 		}
6666 
6667 		memcpy(p, &flen, sizeof(int));
6668 		p += sizeof(int);
6669 		if ( flen > 0 )
6670 		{
6671 		    memcpy(p, pTF->getValue().getValue(), flen);
6672 		    p += flen;
6673 		}
6674 	    }
6675 	    pTF = tableSchema.Next();
6676 	}
6677 
6678 	pIF = indexSchema.Next();
6679     }
6680 }
6681 
abort()6682 void CegoTableManager::abort()
6683 {
6684     _isAborted = true;
6685 }
6686 
proceed()6687 void CegoTableManager::proceed()
6688 {
6689     _isAborted = false;
6690 }
6691 
isAborted() const6692 bool CegoTableManager::isAborted() const
6693 {
6694     return _isAborted;
6695 }
6696 
poolP()6697 void CegoTableManager::poolP()
6698 {
6699     if ( _pPool )
6700     {
6701 	_pPool->P(_thrIdx);
6702     }
6703 }
6704 
poolV()6705 void CegoTableManager::poolV()
6706 {
6707     if ( _pPool )
6708     {
6709 	_pPool->V(_thrIdx);
6710     }
6711 }
6712 
addCompProcedure(int tabSetId,CegoProcedure * pProc)6713 void CegoTableManager::addCompProcedure(int tabSetId, CegoProcedure *pProc)
6714 {
6715     poolP();
6716 
6717     try
6718     {
6719 	CegoProcedure** pCheckProc = _procList[tabSetId].First();
6720 	while ( pCheckProc )
6721 	{
6722 	    if ( (Chain)(*pCheckProc)->getName() == (Chain)pProc->getName() )
6723 	    {
6724 		throw Exception(EXLOC, Chain("Procedure ") + pProc->getName() + Chain(" already exists"));
6725 	    }
6726 	    pCheckProc = _procList[tabSetId].Next();
6727 	}
6728 	_procList[tabSetId].Insert(pProc);
6729 
6730 	poolV();
6731     }
6732     catch ( Exception e )
6733     {
6734 	poolV();
6735 	throw e;
6736     }
6737 }
6738 
removeCompProcedure(int tabSetId,const Chain & procName)6739 void CegoTableManager::removeCompProcedure(int tabSetId, const Chain& procName)
6740 {
6741     poolP();
6742 
6743     CegoProcedure** pProc = _procList[tabSetId].First();
6744     while ( pProc )
6745     {
6746 	if ( (Chain)(*pProc)->getName() == (Chain)procName )
6747 	{
6748 	    CegoProcedure *pDelProc = *pProc;
6749 	    delete pDelProc;
6750 
6751 	    _procList[tabSetId].Remove(*pProc);
6752 
6753 	    poolV();
6754 	    return;
6755 	}
6756 	pProc = _procList[tabSetId].Next();
6757     }
6758 
6759     poolV();
6760 
6761     return;
6762 }
6763 
checkCompProcedure(int tabSetId,const Chain & procName)6764 bool CegoTableManager::checkCompProcedure(int tabSetId, const Chain& procName)
6765 {
6766     poolP();
6767 
6768     CegoProcedure** pProc = _procList[tabSetId].First();
6769     while ( pProc )
6770     {
6771 	if ( (Chain)(*pProc)->getName() == (Chain)procName )
6772 	{
6773 	    poolV();
6774 	    return true;
6775 	}
6776 	pProc = _procList[tabSetId].Next();
6777     }
6778     poolV();
6779     return false;
6780 }
6781 
getCompProcedure(int tabSetId,const Chain & procName)6782 CegoProcedure* CegoTableManager::getCompProcedure(int tabSetId, const Chain& procName)
6783 {
6784     poolP();
6785     CegoProcedure** pProc = _procList[tabSetId].First();
6786     while ( pProc )
6787     {
6788 	if ( (Chain)(*pProc)->getName() == (Chain)procName )
6789 	{
6790 	    poolV();
6791 	    return *pProc;
6792 	}
6793 	pProc = _procList[tabSetId].Next();
6794     }
6795 
6796     poolV();
6797     Chain msg = Chain("Procedure ") + procName + Chain(" not compiled");
6798     throw Exception(EXLOC, msg);
6799 }
6800 
addCompView(int tabSetId,CegoView * pView)6801 void CegoTableManager::addCompView(int tabSetId, CegoView *pView)
6802 {
6803     poolP();
6804     _viewList[tabSetId].Insert(pView);
6805     poolV();
6806 }
6807 
removeCompView(int tabSetId,const Chain & viewName)6808 void CegoTableManager::removeCompView(int tabSetId, const Chain& viewName)
6809 {
6810     poolP();
6811     CegoView** pView = _viewList[tabSetId].First();
6812     while ( pView )
6813     {
6814 	if ( (Chain)(*pView)->getViewName() == (Chain)viewName )
6815 	{
6816 
6817 	    CegoView *pDelView = *pView;
6818 	    delete pDelView;
6819 
6820 	    _viewList[tabSetId].Remove(*pView);
6821 
6822 	    poolV();
6823 
6824 	    return;
6825 	}
6826 	pView = _viewList[tabSetId].Next();
6827     }
6828     poolV();
6829     return;
6830 }
6831 
checkCompView(int tabSetId,const Chain & viewName)6832 bool CegoTableManager::checkCompView(int tabSetId, const Chain& viewName)
6833 {
6834     poolP();
6835     CegoView** pView = _viewList[tabSetId].First();
6836     while ( pView )
6837     {
6838 	if ( (Chain)(*pView)->getViewName() == (Chain)viewName )
6839 	{
6840 	    poolV();
6841 	    return true;
6842 	}
6843 	pView = _viewList[tabSetId].Next();
6844     }
6845     poolV();
6846     return false;
6847 }
6848 
getCompView(int tabSetId,const Chain & viewName)6849 CegoView* CegoTableManager::getCompView(int tabSetId, const Chain& viewName)
6850 {
6851     poolP();
6852     CegoView** pView = _viewList[tabSetId].First();
6853     while ( pView )
6854     {
6855 	if ( (Chain)(*pView)->getViewName() == (Chain)viewName )
6856 	{
6857 	    poolV();
6858 	    return *pView;
6859 	}
6860 	pView = _viewList[tabSetId].Next();
6861     }
6862     poolV();
6863 
6864     Chain msg = Chain("View ") + viewName + Chain(" not compiled");
6865     throw Exception(EXLOC, msg);
6866 }
6867 
addCompTrigger(int tabSetId,CegoTrigger * pTrigger)6868 void CegoTableManager::addCompTrigger(int tabSetId, CegoTrigger *pTrigger)
6869 {
6870     poolP();
6871     _triggerList[tabSetId].Insert(pTrigger);
6872     poolV();
6873 }
6874 
removeCompTrigger(int tabSetId,const Chain & triggerName)6875 void CegoTableManager::removeCompTrigger(int tabSetId, const Chain& triggerName)
6876 {
6877     poolP();
6878     CegoTrigger** pTrigger = _triggerList[tabSetId].First();
6879     while ( pTrigger )
6880     {
6881 	if ( (Chain)(*pTrigger)->getName() == (Chain)triggerName )
6882 	{
6883 	    CegoTrigger* pDelTrigger = *pTrigger;
6884 	    delete pDelTrigger;
6885 
6886 	    _triggerList[tabSetId].Remove(*pTrigger);
6887 
6888 	    poolV();
6889 
6890 	    return;
6891 	}
6892 	pTrigger = _triggerList[tabSetId].Next();
6893     }
6894     poolV();
6895     return;
6896 }
6897 
checkCompTrigger(int tabSetId,const Chain & triggerName)6898 bool CegoTableManager::checkCompTrigger(int tabSetId, const Chain& triggerName)
6899 {
6900     poolP();
6901     CegoTrigger** pTrigger = _triggerList[tabSetId].First();
6902     while ( pTrigger )
6903     {
6904 	if ( (Chain)(*pTrigger)->getName() == (Chain)triggerName )
6905 	{
6906 	    poolV();
6907 	    return true;
6908 	}
6909 	pTrigger = _triggerList[tabSetId].Next();
6910     }
6911     poolV();
6912     return false;
6913 }
6914 
getCompTrigger(int tabSetId,const Chain & triggerName)6915 CegoTrigger* CegoTableManager::getCompTrigger(int tabSetId, const Chain& triggerName)
6916 {
6917     poolP();
6918     CegoTrigger** pTrigger = _triggerList[tabSetId].First();
6919     while ( pTrigger )
6920     {
6921 	if ( (Chain)(*pTrigger)->getName() == (Chain)triggerName )
6922 	{
6923 	    poolV();
6924 	    return *pTrigger;
6925 	}
6926 	pTrigger = _triggerList[tabSetId].Next();
6927     }
6928     poolV();
6929 
6930     Chain msg = Chain("Trigger ") + triggerName + Chain(" not compiled");
6931     throw Exception(EXLOC, msg);
6932 }
6933 
removeAllComp(int tabSetId)6934 void CegoTableManager::removeAllComp(int tabSetId)
6935 {
6936     poolP();
6937     CegoProcedure** pProc = _procList[tabSetId].First();
6938     while ( pProc )
6939     {
6940 	CegoProcedure *pDelProc = *pProc;
6941 
6942 	// we first have to delete
6943 	delete pDelProc;
6944 
6945 	// the we can remove from the list
6946 	_procList[tabSetId].Remove(*pProc);
6947 
6948 	pProc = _procList[tabSetId].First();
6949     }
6950 
6951     CegoView** pView = _viewList[tabSetId].First();
6952     while ( pView )
6953     {
6954 	CegoView *pDelView = *pView;
6955 
6956 	// we first have to delete
6957 	delete pDelView;
6958 
6959 	// then we can release from the list
6960 	_viewList[tabSetId].Remove(*pView);
6961 
6962 	pView = _viewList[tabSetId].First();
6963     }
6964 
6965     CegoTrigger** pTrigger = _triggerList[tabSetId].First();
6966     while ( pTrigger )
6967     {
6968 	CegoTrigger *pDelTrigger = *pTrigger;
6969 
6970 	// we first have to delete
6971 	delete pDelTrigger;
6972 
6973 	// then we can release from the list
6974 	_triggerList[tabSetId].Remove(*pTrigger);
6975 
6976 	pTrigger = _triggerList[tabSetId].First();
6977     }
6978 
6979     poolV();
6980 }
6981 
getLHLockStat(unsigned long long lockId,Chain & lockName,int & lockCount,unsigned long long & numRdLock,unsigned long long & numWrLock,unsigned long long & sumRdDelay,unsigned long long & sumWrDelay)6982 void CegoTableManager::getLHLockStat(unsigned long long lockId, Chain& lockName, int& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay)
6983 {
6984     _pLockHandle->getLockStat(lockId, lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
6985 }
6986 
getLHAggLockStat(const Chain & lockName,int & numLock,int & lockCount,unsigned long long & numRdLock,unsigned long long & numWrLock,unsigned long long & sumRdDelay,unsigned long long & sumWrDelay)6987 void CegoTableManager::getLHAggLockStat(const Chain& lockName, int& numLock, int& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay)
6988 {
6989     _pLockHandle->getAggLockStat(lockName, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
6990 }
6991 
getTransactionManager()6992 CegoTransactionManager* CegoTableManager::getTransactionManager()
6993 {
6994     return _pTM;
6995 }
6996 
increaseBlobRef(int tabSetId,PageIdType pageId)6997 void CegoTableManager::increaseBlobRef(int tabSetId, PageIdType pageId)
6998 {
6999     CegoBufferPage bp;
7000     _pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7001 
7002     unsigned long long blobRef;
7003 
7004     memcpy (&blobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7005     blobRef++;
7006     memcpy (bp.getChunkEntry(), &blobRef, sizeof(unsigned long long));
7007     _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7008 }
7009 
decreaseBlobRef(int tabSetId,PageIdType pageId)7010 void CegoTableManager::decreaseBlobRef(int tabSetId, PageIdType pageId)
7011 {
7012     CegoBufferPage bp;
7013     _pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7014 
7015     unsigned long long blobRef;
7016     memcpy (&blobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7017 
7018     if ( blobRef <= 1 )
7019     {
7020 	while ( bp.isFixed() )
7021 	{
7022 	    pageId = bp.getNextPageId();
7023 
7024 	    _pDBMng->bufferRelease(bp, _pLockHandle);
7025 
7026 	    if ( pageId )
7027 		_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7028 	}
7029     }
7030     else
7031     {
7032 	blobRef--;
7033 	memcpy (bp.getChunkEntry(), &blobRef, sizeof(unsigned long long));
7034 	_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7035     }
7036 }
7037 
increaseClobRef(int tabSetId,PageIdType pageId)7038 void CegoTableManager::increaseClobRef(int tabSetId, PageIdType pageId)
7039 {
7040     CegoBufferPage bp;
7041     _pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7042 
7043     unsigned long long clobRef;
7044 
7045     memcpy (&clobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7046     clobRef++;
7047     memcpy (bp.getChunkEntry(), &clobRef, sizeof(unsigned long long));
7048     _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7049 }
7050 
decreaseClobRef(int tabSetId,PageIdType pageId)7051 void CegoTableManager::decreaseClobRef(int tabSetId, PageIdType pageId)
7052 {
7053     CegoBufferPage bp;
7054     _pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7055 
7056     unsigned long long clobRef;
7057     memcpy (&clobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7058 
7059     if ( clobRef <= 1 )
7060     {
7061 	while ( bp.isFixed() )
7062 	{
7063 	    pageId = bp.getNextPageId();
7064 
7065 	    _pDBMng->bufferRelease(bp, _pLockHandle);
7066 
7067 	    if ( pageId )
7068 		_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7069 	}
7070     }
7071     else
7072     {
7073 	clobRef--;
7074 	memcpy (bp.getChunkEntry(), &clobRef, sizeof(unsigned long long));
7075 	_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7076     }
7077 }
7078 
getBlobData(int tabSetId,PageIdType pageId,unsigned long long & blobSize)7079 unsigned char* CegoTableManager::getBlobData(int tabSetId, PageIdType pageId, unsigned long long& blobSize)
7080 {
7081     CegoBufferPage bp;
7082     try
7083     {
7084 	_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7085 
7086 	unsigned long long blobRef;
7087 	memcpy (&blobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7088 
7089 	memcpy (&blobSize, (char*)(bp.getChunkEntry() + sizeof(unsigned long long)), sizeof(unsigned long long));
7090 
7091 	// allocate buffer of size blobsize
7092 
7093 	unsigned char* rawBuf = (unsigned char*)malloc(blobSize);
7094 	if (rawBuf == NULL)
7095 	{
7096 	    Chain msg = Chain("Cannot allocate blob data of ") + Chain(blobSize + 1) + Chain(" bytes");
7097 	    throw Exception(EXLOC, msg);
7098 	}
7099 
7100 	unsigned char* rawPtr = rawBuf;
7101 
7102 	unsigned long long writtenByte = 0;
7103 
7104 	while ( bp.isFixed() )
7105 	{
7106 	    int chunkSize;
7107 
7108 	    // first page with written clob size, so we have to sub the size bytes
7109             if ( writtenByte == 0 )
7110             {
7111                 // take the full page chunk ?
7112                 if (  bp.getChunkLen() - 2 * sizeof(unsigned long long ) < blobSize  )
7113                 {
7114 		    chunkSize = bp.getChunkLen() - 2 * sizeof(unsigned long long);
7115                 }
7116                 else // just take the needed chunk
7117                 {
7118 		    chunkSize = blobSize;
7119                 }
7120             }
7121             else // just take the needed
7122             {
7123                 // take the full page chunk ?
7124                 if (  bp.getChunkLen() < blobSize - writtenByte  )
7125                 {
7126 		    chunkSize = bp.getChunkLen();
7127                 }
7128                 else // just take the needed chunk
7129                 {
7130 		    chunkSize = blobSize - writtenByte;
7131                 }
7132             }
7133 
7134 	    char* src = 0;
7135 	    if ( writtenByte == 0 )
7136 	    {
7137 		src = (char*)(bp.getChunkEntry() + 2 * sizeof(unsigned long long));
7138 	    }
7139 	    else
7140 	    {
7141 		src = (char*)(bp.getChunkEntry());
7142 
7143 	    }
7144 	    memcpy(rawPtr, src, chunkSize);
7145 
7146 	    rawPtr += chunkSize;
7147 	    writtenByte += chunkSize;
7148 
7149 	    pageId = bp.getNextPageId();
7150 
7151 	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
7152 
7153 	    if ( pageId )
7154 		_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7155 
7156 	}
7157 	return rawBuf;
7158     }
7159     catch ( Exception e )
7160     {
7161 	if ( bp.isFixed() )
7162 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7163 	throw e;
7164     }
7165     return 0;
7166 }
7167 
getClobData(int tabSetId,PageIdType pageId,unsigned long long & clobSize)7168 char* CegoTableManager::getClobData(int tabSetId, PageIdType pageId, unsigned long long& clobSize)
7169 {
7170     CegoBufferPage bp;
7171     try
7172     {
7173 	_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7174 
7175 	unsigned long long clobRef;
7176 	memcpy (&clobRef, bp.getChunkEntry(), sizeof(unsigned long long));
7177 
7178 	memcpy (&clobSize, (char*)(bp.getChunkEntry() + sizeof(unsigned long long)), sizeof(unsigned long long));
7179 
7180 	// allocate buffer of size clobsize
7181 
7182 	// cout << "Reading " << clobSize << " bytes from page " << pageId << endl;
7183 
7184 	char* rawBuf = (char*)malloc(clobSize + 1);
7185 	if (rawBuf == NULL)
7186 	{
7187 	    Chain msg = Chain("Cannot allocate clob data of ") + Chain(clobSize + 1) + Chain(" bytes");
7188 	    throw Exception(EXLOC, msg);
7189 	}
7190 
7191 	char* rawPtr = rawBuf;
7192 
7193 	unsigned long long writtenByte = 0;
7194 
7195 	while ( bp.isFixed() )
7196 	{
7197 	    int chunkSize;
7198 
7199 	    // first page with written clob size, so we have to sub the size bytes
7200             if ( writtenByte == 0 )
7201             {
7202                 // take the full page chunk ?
7203                 if (  bp.getChunkLen() - 2 * sizeof(unsigned long long ) < clobSize  )
7204                 {
7205 		    chunkSize = bp.getChunkLen() - 2 * sizeof(unsigned long long);
7206                 }
7207                 else // just take the needed chunk
7208                 {
7209 		    chunkSize = clobSize;
7210                 }
7211             }
7212             else // just take the needed
7213             {
7214                 // take the full page chunk ?
7215                 if (  bp.getChunkLen() < clobSize - writtenByte  )
7216                 {
7217 		    chunkSize = bp.getChunkLen();
7218                 }
7219                 else // just take the needed chunk
7220                 {
7221 		    chunkSize = clobSize - writtenByte;
7222                 }
7223             }
7224 
7225 	    char* src = 0;
7226 	    if ( writtenByte == 0 )
7227 	    {
7228 		src = (char*)(bp.getChunkEntry() + 2 * sizeof(unsigned long long));
7229 	    }
7230 	    else
7231 	    {
7232 		src = (char*)(bp.getChunkEntry());
7233 
7234 	    }
7235 	    memcpy(rawPtr, src, chunkSize);
7236 
7237 	    rawPtr += chunkSize;
7238 	    writtenByte += chunkSize;
7239 
7240 	    pageId = bp.getNextPageId();
7241 
7242 	    _pDBMng->bufferUnfix(bp, false, _pLockHandle);
7243 
7244 	    if (  pageId )
7245 		_pDBMng->bufferFix(bp, tabSetId, pageId, CegoBufferPool::SYNC, _pLockHandle);
7246 
7247 	}
7248 	// ensure termination character
7249 	rawBuf[clobSize]=0;
7250 	return rawBuf;
7251     }
7252     catch ( Exception e )
7253     {
7254 	if ( bp.isFixed() )
7255 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7256 	throw e;
7257     }
7258     return 0;
7259 }
7260 
putBlobData(int tabSetId,unsigned char * data,unsigned long long blobSize,PageIdType & pageId)7261 void CegoTableManager::putBlobData(int tabSetId, unsigned char* data, unsigned long long blobSize, PageIdType& pageId)
7262 {
7263     CegoBufferPage bp;
7264 
7265     try
7266     {
7267 	getNewFilePage(bp, tabSetId, CegoObject::TABLE, false, true);
7268 	bp.initPage(CegoBufferPage::BLOB);
7269 
7270 	pageId = bp.getPageId();
7271 
7272 	int freeInPage = bp.getChunkLen();
7273 	char* pagePtr = bp.getChunkEntry();
7274 
7275 	unsigned long long blobRef = 0;
7276 	memcpy(pagePtr, &blobRef, sizeof(unsigned long long));
7277 	pagePtr += sizeof(unsigned long long);
7278 	freeInPage -= sizeof(unsigned long long);
7279 
7280 	memcpy(pagePtr, &blobSize, sizeof(unsigned long long));
7281 	pagePtr += sizeof(unsigned long long);
7282 	freeInPage -= sizeof(unsigned long long);
7283 
7284 	unsigned char *bufPtr = 0;
7285 	unsigned long long availFromBuf = 0;
7286 
7287 	unsigned long long writtenByte = 0;
7288 	while ( writtenByte < blobSize )
7289 	{
7290 	    if ( availFromBuf == 0 )
7291 	    {
7292 		availFromBuf=blobSize;
7293 		bufPtr = data;
7294 	    }
7295 	    if ( freeInPage == 0 )
7296 	    {
7297 		CegoBufferPage nextPage;
7298 		getNewFilePage(nextPage, tabSetId, CegoObject::TABLE, false, true);
7299 		nextPage.initPage(CegoBufferPage::BLOB);
7300 
7301 		bp.setNextPageId(nextPage.getPageId());
7302 
7303 		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7304 
7305 		bp = nextPage;
7306 
7307 		freeInPage = bp.getChunkLen();
7308 		pagePtr = bp.getChunkEntry();
7309 	    }
7310 
7311 	    if ( freeInPage >= availFromBuf )
7312 	    {
7313 		memcpy(pagePtr, bufPtr, availFromBuf);
7314 		writtenByte += availFromBuf;
7315 		pagePtr += availFromBuf;
7316 		freeInPage -= availFromBuf;
7317 		availFromBuf = 0;
7318 	    }
7319 	    else if ( freeInPage < availFromBuf )
7320 	    {
7321 		memcpy(pagePtr, bufPtr, freeInPage);
7322 		writtenByte += freeInPage;
7323 		bufPtr += freeInPage;
7324 		availFromBuf -= freeInPage;
7325 		freeInPage = 0;
7326 	    }
7327 	}
7328 	_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7329     }
7330     catch ( Exception e )
7331     {
7332 	if ( bp.isFixed() )
7333 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7334 	throw e;
7335     }
7336 }
7337 
putClobData(int tabSetId,char * data,unsigned long long clobSize,PageIdType & pageId)7338 void CegoTableManager::putClobData(int tabSetId, char* data, unsigned long long clobSize, PageIdType& pageId)
7339 {
7340     CegoBufferPage bp;
7341 
7342     try
7343     {
7344 	getNewFilePage(bp, tabSetId, CegoObject::TABLE, false, true);
7345 	bp.initPage(CegoBufferPage::CLOB);
7346 
7347 	pageId = bp.getPageId();
7348 
7349 	int freeInPage = bp.getChunkLen();
7350 	char* pagePtr = bp.getChunkEntry();
7351 
7352 	// cout << "Writing " << clobSize << " bytes to page " << pageId << endl;
7353 
7354 	unsigned long long clobRef = 0;
7355 	memcpy(pagePtr, &clobRef, sizeof(unsigned long long));
7356 	pagePtr += sizeof(unsigned long long);
7357 	freeInPage -= sizeof(unsigned long long);
7358 
7359 	memcpy(pagePtr, &clobSize, sizeof(unsigned long long));
7360 	pagePtr += sizeof(unsigned long long);
7361 	freeInPage -= sizeof(unsigned long long);
7362 
7363 	char *bufPtr = 0;
7364 	unsigned long long availFromBuf = 0;
7365 
7366 	unsigned long long writtenByte = 0;
7367 	while ( writtenByte < clobSize )
7368 	{
7369 	    if ( availFromBuf == 0 )
7370 	    {
7371 		availFromBuf=clobSize;
7372 		bufPtr = data;
7373 	    }
7374 	    if ( freeInPage == 0 )
7375 	    {
7376 		CegoBufferPage nextPage;
7377 		getNewFilePage(nextPage, tabSetId, CegoObject::TABLE, false, true);
7378 		nextPage.initPage(CegoBufferPage::CLOB);
7379 
7380 		bp.setNextPageId(nextPage.getPageId());
7381 
7382 		_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7383 
7384 		bp = nextPage;
7385 
7386 		freeInPage = bp.getChunkLen();
7387 		pagePtr = bp.getChunkEntry();
7388 	    }
7389 
7390 	    if ( freeInPage >= availFromBuf )
7391 	    {
7392 		memcpy(pagePtr, bufPtr, availFromBuf);
7393 		writtenByte += availFromBuf;
7394 		pagePtr += availFromBuf;
7395 		freeInPage -= availFromBuf;
7396 		availFromBuf = 0;
7397 	    }
7398 	    else if ( freeInPage < availFromBuf )
7399 	    {
7400 		memcpy(pagePtr, bufPtr, freeInPage);
7401 		writtenByte += freeInPage;
7402 		bufPtr += freeInPage;
7403 		availFromBuf -= freeInPage;
7404 		freeInPage = 0;
7405 	    }
7406 	}
7407 	_pDBMng->bufferUnfix(bp, true, _pLockHandle);
7408     }
7409     catch ( Exception e )
7410     {
7411 	if ( bp.isFixed() )
7412 	    _pDBMng->bufferUnfix(bp, true, _pLockHandle);
7413 	throw e;
7414     }
7415 }
7416 
getBlobs(int tabSetId,const ListT<CegoField> & fvl,ListT<CegoBlob> & blobList)7417 void CegoTableManager::getBlobs(int tabSetId, const ListT<CegoField>& fvl, ListT<CegoBlob>& blobList)
7418 {
7419     CegoField* pF = fvl.First();
7420     while (pF)
7421     {
7422 	if ( pF->getValue().getType() == BLOB_TYPE  )
7423 	{
7424 	    PageIdType pageId;
7425 	    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
7426 
7427 	    unsigned long long blobSize;
7428 	    unsigned char* blobBuf = getBlobData(tabSetId, pageId, blobSize);
7429 
7430 	    blobList.Insert(CegoBlob(pageId, blobBuf, blobSize));
7431 	}
7432 	pF = fvl.Next();
7433     }
7434 }
7435 
getClobs(int tabSetId,const ListT<CegoField> & fvl,ListT<CegoClob> & clobList)7436 void CegoTableManager::getClobs(int tabSetId, const ListT<CegoField>& fvl, ListT<CegoClob>& clobList)
7437 {
7438     CegoField* pF = fvl.First();
7439     while (pF)
7440     {
7441 	if ( pF->getValue().getType() == CLOB_TYPE  )
7442 	{
7443 	    PageIdType pageId;
7444 	    memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
7445 
7446 	    unsigned long long clobSize;
7447 	    char* clobBuf = getClobData(tabSetId, pageId, clobSize);
7448 
7449 	    clobList.Insert(CegoClob(pageId, clobBuf, clobSize));
7450 	}
7451 	pF = fvl.Next();
7452     }
7453 }
7454 
getBlobs(int tabSetId,ListT<CegoExpr * > & exprList,CegoProcBlock * pBlock,ListT<CegoBlob> & blobList)7455 void CegoTableManager::getBlobs(int tabSetId, ListT<CegoExpr*>& exprList, CegoProcBlock* pBlock, ListT<CegoBlob>& blobList )
7456 {
7457     CegoExpr** pExpr = exprList.First();
7458     while ( pExpr )
7459     {
7460 	(*pExpr)->setBlock(pBlock);
7461 
7462 	CegoFieldValue fv;
7463 
7464 	if ( (*pExpr)->checkLob(fv) )
7465 	{
7466 	    if ( fv.getType() == BLOB_TYPE )
7467 	    {
7468 		PageIdType pageId;
7469 		memcpy(&pageId, fv.getValue(), sizeof(PageIdType));
7470 
7471 		unsigned long long blobSize;
7472 		unsigned char* blobBuf = getBlobData(tabSetId, pageId, blobSize);
7473 
7474 		blobList.Insert(CegoBlob(pageId, blobBuf, blobSize));
7475 	    }
7476 	}
7477 	pExpr = exprList.Next();
7478     }
7479 }
7480 
getClobs(int tabSetId,ListT<CegoExpr * > & exprList,CegoProcBlock * pBlock,ListT<CegoClob> & clobList)7481 void CegoTableManager::getClobs(int tabSetId, ListT<CegoExpr*>& exprList, CegoProcBlock* pBlock, ListT<CegoClob>& clobList)
7482 {
7483     CegoExpr** pExpr = exprList.First();
7484     while ( pExpr )
7485     {
7486 	(*pExpr)->setBlock(pBlock);
7487 
7488 	CegoFieldValue fv;
7489 	if ( (*pExpr)->checkLob(fv)  )
7490 	{
7491 	    if ( fv.getType() == CLOB_TYPE)
7492 	    {
7493 		PageIdType pageId;
7494 		memcpy(&pageId, fv.getValue(), sizeof(PageIdType));
7495 
7496 		unsigned long long clobSize;
7497 		char* clobBuf = getClobData(tabSetId, pageId, clobSize);
7498 
7499 		clobList.Insert(CegoClob(pageId, clobBuf, clobSize));
7500 	    }
7501 	}
7502 	pExpr = exprList.Next();
7503     }
7504 }
7505 
addBUStat(int tabSetId,const Chain & butype,const Chain & msg)7506 void CegoTableManager::addBUStat(int tabSetId, const Chain& butype, const Chain& msg)
7507 {
7508     // insert entry in bustat table
7509 
7510     CegoTableObject boe;
7511     getObject(tabSetId, Chain(SYSTAB_BUSTAT_ID), CegoObject::SYSTEM, boe);
7512     ListT<CegoField> fvl = boe.getSchema();
7513     CegoField *pF = fvl.First();
7514     while ( pF )
7515     {
7516 	if (pF->getAttrName() == Chain(SYSTAB_TS_ATTR) )
7517 	{
7518 	    Datetime n;
7519 	    unsigned long long *pDV = new (unsigned long long);
7520 	    *pDV = n.asLong();
7521 	    CegoFieldValue fv(DATETIME_TYPE, pDV, sizeof(unsigned long long), true);
7522 	    pF->setValue(fv);
7523 	}
7524 	else if ( pF->getAttrName() == Chain(SYSTAB_BUINFO_ATTR) )
7525 	{
7526 	    pF->setValue(CegoFieldValue(VARCHAR_TYPE, butype));
7527 	}
7528 	else if ( pF->getAttrName() == Chain(SYSTAB_BUMSG_ATTR) )
7529 	{
7530 	    pF->setValue(CegoFieldValue(VARCHAR_TYPE, msg));
7531 	}
7532 	pF = fvl.Next();
7533     }
7534 
7535     CegoDataPointer bp;
7536     insertDataTable(boe, fvl, bp, true, true);
7537 }
7538 
typeConversionAllowed(CegoDataType fromType,CegoDataType toType)7539 bool CegoTableManager::typeConversionAllowed(CegoDataType fromType, CegoDataType toType)
7540 {
7541     if ( fromType == toType
7542 	 || ( fromType == INT_TYPE && toType == LONG_TYPE )
7543 	 || ( fromType == INT_TYPE && toType == VARCHAR_TYPE )
7544 	 || ( fromType == INT_TYPE && toType == BOOL_TYPE )
7545 	 || ( fromType == INT_TYPE && toType == DATETIME_TYPE )
7546 	 || ( fromType == INT_TYPE && toType == BIGINT_TYPE )
7547 	 || ( fromType == INT_TYPE && toType == FLOAT_TYPE )
7548 	 || ( fromType == INT_TYPE && toType == DOUBLE_TYPE )
7549 	 || ( fromType == INT_TYPE && toType == DECIMAL_TYPE )
7550 	 || ( fromType == BOOL_TYPE && toType == FIXED_TYPE )
7551 	 || ( fromType == LONG_TYPE && toType == VARCHAR_TYPE )
7552 	 || ( fromType == LONG_TYPE && toType == BOOL_TYPE )
7553 	 || ( fromType == LONG_TYPE && toType == BIGINT_TYPE )
7554 	 || ( fromType == LONG_TYPE && toType == DOUBLE_TYPE )
7555 	 || ( fromType == LONG_TYPE && toType == DECIMAL_TYPE )
7556 	 || ( fromType == BOOL_TYPE && toType == FIXED_TYPE )
7557 	 || ( fromType == BOOL_TYPE && toType == INT_TYPE )
7558 	 || ( fromType == BOOL_TYPE && toType == LONG_TYPE )
7559 	 || ( fromType == BOOL_TYPE && toType == VARCHAR_TYPE )
7560 	 || ( fromType == BOOL_TYPE && toType == BIGINT_TYPE )
7561 	 || ( fromType == BOOL_TYPE && toType == FLOAT_TYPE )
7562 	 || ( fromType == BOOL_TYPE && toType == DOUBLE_TYPE )
7563 	 || ( fromType == BOOL_TYPE && toType == DECIMAL_TYPE )
7564 	 || ( fromType == BOOL_TYPE && toType == FIXED_TYPE )
7565 	 || ( fromType == DATETIME_TYPE && toType == INT_TYPE )
7566 	 || ( fromType == DATETIME_TYPE && toType == VARCHAR_TYPE )
7567 	 || ( fromType == DATETIME_TYPE && toType == BIGINT_TYPE )
7568 	 || ( fromType == DATETIME_TYPE && toType == FLOAT_TYPE )
7569 	 || ( fromType == DATETIME_TYPE && toType == DOUBLE_TYPE )
7570 	 || ( fromType == DATETIME_TYPE && toType == DECIMAL_TYPE )
7571 	 || ( fromType == BIGINT_TYPE && toType == VARCHAR_TYPE )
7572 	 || ( fromType == FLOAT_TYPE && toType == VARCHAR_TYPE )
7573 	 || ( fromType == DOUBLE_TYPE && toType == VARCHAR_TYPE )
7574 	 || ( fromType == DECIMAL_TYPE && toType == VARCHAR_TYPE )
7575 	 || ( fromType == FIXED_TYPE && toType == VARCHAR_TYPE )
7576 	 || ( fromType == SMALLINT_TYPE && toType == VARCHAR_TYPE )
7577 	 || ( fromType == TINYINT_TYPE && toType == VARCHAR_TYPE )
7578 	 || ( fromType == TINYINT_TYPE && toType == INT_TYPE )
7579 	 || ( fromType == TINYINT_TYPE && toType == LONG_TYPE )	)
7580     {
7581 	return true;
7582     }
7583 
7584     return false;
7585 }
7586