Main Page   Class Hierarchy   Compound List   File List   Compound Members  

compiler.h

00001 //-< COMPILE.H >-----------------------------------------------------*--------*
00002 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Main Memory Database Management System)                          *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 17-Jan-99    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Conditional expresion compiler
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __COMPILER_H__
00012 #define __COMPILER_H__
00013 
00014 #include <setjmp.h>
00015 #ifdef USE_REGEX
00016 #include <regex.h>
00017 #endif
00018 
00019 BEGIN_FASTDB_NAMESPACE
00020 
00021 #if defined(__osf__) || defined(__FreeBSD__)
00022 #define longjmp(b,s) _longjmp(b,s) // do not restore signal context
00023 #define setjmp(b)  _setjmp(b)
00024 #endif
00025 
00026 enum dbvmCodes { 
00027 #define DBVM(cop, type, n_operands, commutative) cop,
00028 #include "compiler.d"
00029 dbvmLastCode
00030 };
00031 
00032 #define IS_CONSTANT(c) \
00033     (unsigned(c) - dbvmLoadVarBool <= (unsigned)dbvmLoadRectangleConstant - dbvmLoadVarBool)
00034 
00035 enum nodeType { 
00036     tpInteger,
00037     tpBoolean,
00038     tpReal,
00039     tpString,
00040     tpReference,
00041     tpRectangle,
00042     tpArray,
00043     tpRawBinary, 
00044     tpFreeVar,  // index of EXISTS clause 
00045     tpList,     // list of expressions
00046     tpVoid
00047 };
00048 
00049 enum tokens { 
00050     tkn_ident,
00051     tkn_lpar,
00052     tkn_rpar,
00053     tkn_lbr,
00054     tkn_rbr,
00055     tkn_dot,
00056     tkn_comma,
00057     tkn_power,
00058     tkn_iconst,
00059     tkn_sconst,
00060     tkn_fconst,
00061     tkn_add,
00062     tkn_sub,
00063     tkn_mul,
00064     tkn_div,
00065     tkn_and,
00066     tkn_or,
00067     tkn_not,
00068     tkn_null,
00069     tkn_neg,
00070     tkn_eq,
00071     tkn_ne,
00072     tkn_gt,
00073     tkn_ge,
00074     tkn_lt,
00075     tkn_le,
00076     tkn_between,
00077     tkn_escape,
00078     tkn_exists,
00079     tkn_like,
00080     tkn_limit,
00081     tkn_in,
00082     tkn_length,
00083     tkn_lower,
00084     tkn_upper,
00085     tkn_abs,
00086     tkn_area,
00087     tkn_is,
00088     tkn_integer,
00089     tkn_real,
00090     tkn_string,
00091     tkn_first,
00092     tkn_last,
00093     tkn_current,
00094     tkn_var,
00095     tkn_col,
00096     tkn_true,
00097     tkn_false,
00098     tkn_where, 
00099     tkn_follow,
00100     tkn_start,
00101     tkn_from,
00102     tkn_order,
00103     tkn_overlaps,
00104     tkn_by,
00105     tkn_asc,
00106     tkn_desc, 
00107     tkn_eof,
00108     tkn_insert, 
00109     tkn_into, 
00110     tkn_select, 
00111     tkn_table,
00112     tkn_error,
00113     tkn_all, 
00114     tkn_match,
00115     tkn_last_token
00116 };    
00117 
00118 struct dbStrLiteral { 
00119     char* str;
00120     int   len;
00121 };
00122 
00123 
00124 class dbUserFunction;
00125 class dbExprNodeSegment;
00126 
00127 class FASTDB_DLL_ENTRY dbExprNodeAllocator { 
00128   private:
00129     friend class dbExprNodeSegment;
00130     dbExprNode*        freeNodeList;
00131     dbExprNodeSegment* segmentList;
00132     dbMutex            mutex;
00133     
00134   public:  
00135     dbMutex&    getMutex() {
00136         return mutex;
00137     }
00138     dbExprNode* allocate();
00139     void        deallocate(dbExprNode* node);
00140     void        reset();
00141 
00142     ~dbExprNodeAllocator();
00143     static dbExprNodeAllocator instance;
00144 };
00145 
00146 class FASTDB_DLL_ENTRY dbExprNode { 
00147     friend class dbExprNodeSegment;
00148   public:
00149     nat1 cop;
00150     nat1 type;
00151     nat2 offs;
00152 
00153     static const nat1  nodeTypes[];
00154     static const nat1  nodeOperands[];
00155     static const nat1  commutativeOperator[];
00156 
00157     struct ref_operands { 
00158         dbExprNode*         base;  // the same as operand[0]
00159         dbFieldDescriptor*  field;
00160     };
00161 
00162     struct func_operands { 
00163         dbExprNode*         arg[3]; 
00164         void*               fptr;
00165     };
00166 
00167 #ifdef USE_REGEX
00168     struct regex_operands { 
00169         dbExprNode*         opd;  
00170         regex_t             re;
00171     };
00172 #endif
00173 
00174     union { 
00175         dbExprNode*    operand[3];
00176         dbExprNode*    next;
00177         oid_t          oid;
00178         db_int8        ivalue;
00179         real8          fvalue;
00180         rectangle      rvalue;
00181         dbStrLiteral   svalue;
00182         void const*    var;
00183         ref_operands   ref;
00184         func_operands  func;
00185 #ifdef USE_REGEX
00186         regex_operands regex;
00187 #endif
00188     };
00189 
00190     dbExprNode(dbExprNode* node);
00191 
00192     dbExprNode(int cop, dbExprNode* left = NULL, dbExprNode* right = NULL, 
00193                dbExprNode* right2 = NULL)
00194     {
00195         this->cop = cop;
00196         type = nodeTypes[cop];
00197         operand[0] = left;
00198         operand[1] = right;
00199         operand[2] = right2;
00200     }
00201     dbExprNode(int cop, dbExprNode* expr1, dbExprNode* expr2, int offs) { 
00202         this->cop = cop;
00203         this->offs = (nat2)offs;
00204         type = nodeTypes[cop];
00205         operand[0] = expr1;
00206         operand[1] = expr2;
00207     }
00208     dbExprNode(int cop, dbExprNode* expr, int offs) { 
00209         this->cop = cop;
00210         this->offs = (nat2)offs;
00211         type = nodeTypes[cop];
00212         operand[0] = expr;
00213     }
00214     dbExprNode(int cop, dbFieldDescriptor* field, dbExprNode* base = NULL) 
00215     {
00216         this->cop = cop;
00217         this->offs = (nat2)field->dbsOffs;
00218         type = nodeTypes[cop];
00219         ref.field = field;
00220         ref.base = base;
00221     }
00222     dbExprNode(int cop, db_int8 ivalue) { 
00223         this->cop = cop;
00224         this->ivalue = ivalue;
00225         type = tpInteger;
00226     }
00227     dbExprNode(int cop, real8 fvalue) { 
00228         this->cop = cop;
00229         this->fvalue = fvalue;
00230         type = tpReal;
00231     }
00232     dbExprNode(int cop, rectangle rvalue) {
00233         this->cop = cop;
00234         this->rvalue = rvalue;
00235         type = tpRectangle;
00236     }
00237     dbExprNode(int cop, dbStrLiteral& svalue) { 
00238         this->cop = cop;
00239         this->svalue = svalue;
00240         type = tpString;
00241     }
00242     dbExprNode(int cop, void const* var) { 
00243         this->cop = cop;
00244         this->var = var;
00245         type = nodeTypes[cop];
00246     }
00247     dbExprNode(int cop, void* fptr, dbExprNode* expr1, dbExprNode* expr2 = NULL, dbExprNode* expr3 = NULL) { 
00248         this->cop = cop;
00249         func.arg[0] = expr1;
00250         func.arg[1] = expr2;
00251         func.arg[2] = expr3;
00252         func.fptr = fptr;
00253         type = nodeTypes[cop];
00254     }
00255     ~dbExprNode();
00256 
00257     void* operator new(size_t size EXTRA_DEBUG_NEW_PARAMS) { 
00258         return dbExprNodeAllocator::instance.allocate();
00259     }
00260 
00261     void operator delete(void* ptr EXTRA_DEBUG_NEW_PARAMS) { 
00262         dbExprNodeAllocator::instance.deallocate((dbExprNode*)ptr);
00263     }
00264 };
00265 
00266 
00267 class dbExprNodeSegment { 
00268   public:
00269     enum { allocationQuantum = 1024};
00270     char               buf[sizeof(dbExprNode)*allocationQuantum];
00271     dbExprNodeSegment* next;
00272 };
00273 
00274 
00275 class dbBinding { 
00276   public:
00277     dbBinding*  next;
00278     char const* name;
00279     bool        used;
00280     int         index;
00281 };
00282 
00283 class dbOrderByNode { 
00284   public:
00285     dbOrderByNode*     next;
00286     dbFieldDescriptor* field;
00287     dbTableDescriptor* table;
00288     dbExprNode*        expr;
00289     bool               ascent;  // true for ascent order, false for descent 
00290     
00291     ~dbOrderByNode() { 
00292         delete expr;
00293     }
00294 };
00295 
00296 class dbFollowByNode { 
00297   public:
00298     dbFollowByNode*    next;
00299     dbFieldDescriptor* field;
00300 };
00301 
00302 class FASTDB_DLL_ENTRY dbCompiler { 
00303     friend class dbQuery;
00304     friend class dbQueryElement;
00305   public:
00306     enum { 
00307         maxStrLen    = 4096,
00308         maxFreeVars  = 4
00309     };
00310 
00311     dbTableDescriptor* table;
00312     dbQueryElement*    queryElement;
00313     int                currPos;
00314     int                firstPos;
00315     int                offsetWithinStatement;
00316     int                bvalue;
00317     db_int8            ivalue;
00318     real8              fvalue;
00319     dbStrLiteral       svalue;
00320     bool               hasToken;
00321     int                lex;
00322     char*              name;
00323     dbBinding*         bindings;
00324     int                nFreeVars;
00325     int                varType;
00326     void const*        varPtr;
00327     dbTableDescriptor* varRefTable;
00328 
00329     jmp_buf            abortCompilation;
00330     static bool        initialized;
00331 
00332     void        compare(dbExprNode* expr, dbExprNode* list);
00333 
00334     int         scan();
00335     void        ungetToken(int tkn) {
00336         lex = tkn;
00337         hasToken = true;
00338     }
00339     void        error(const char* msg, int pos = -1);
00340     dbExprNode* conjunction();    
00341     dbExprNode* disjunction();
00342     dbExprNode* comparison();    
00343     dbExprNode* addition();    
00344     dbExprNode* multiplication();    
00345     dbExprNode* power();
00346     dbExprNode* term();
00347     dbExprNode* buildList();
00348     dbExprNode* userDefinedOperator();
00349     dbExprNode* field(dbExprNode* expr, dbTableDescriptor* refTable,
00350                       dbFieldDescriptor* fd);
00351 
00352     bool        compile(dbTableDescriptor* table, dbQuery& query);
00353     dbExprNode* compileExpression(dbTableDescriptor* table,  char const* expr, int startPos);
00354     void        compileOrderByPart(dbQuery& query);
00355     void        compileLimitPart(dbQuery& query);
00356     void        compileStartFollowPart(dbQuery& query);
00357 
00358     void        deleteNode(dbExprNode* node);
00359     dbExprNode* rectangleConstant(dbExprNode* head);     
00360 
00361     dbCompiler();
00362 };
00363 
00364 class dbDatabaseThreadContext : public dbL2List { 
00365   public:
00366     int readAccess;
00367     int writeAccess;
00368     int concurrentId;
00369     int mutatorCSLocked;
00370     int isMutator;
00371 
00372     dbL2List cursors; 
00373     
00374     dbCompiler compiler;
00375 
00376     dbProcessId currPid;
00377 
00378     bool     interactive;
00379     bool     catched;
00380     bool     commitDelayed;
00381     bool     removeContext;
00382     jmp_buf  unwind;
00383     
00384     dbDatabaseThreadContext() { 
00385         concurrentId = 0;
00386         readAccess = false;
00387         writeAccess = false;
00388         mutatorCSLocked = false;
00389         isMutator = false;
00390         interactive = false;
00391         catched = false;
00392         commitDelayed = false;
00393         removeContext = false;
00394         currPid = dbProcessId::getCurrent();
00395     }
00396 };
00397 
00398 union dbSynthesizedAttribute { 
00399     byte*     base;
00400     int       bvalue;
00401     db_int8   ivalue;
00402     real8     fvalue;
00403     rectangle rvalue;
00404     void*     raw;
00405     oid_t     oid;
00406 
00407     struct { 
00408         char* base;
00409         int   size;
00410     } array;
00411 };
00412 
00413 struct dbStringValue;
00414 
00415 struct FASTDB_DLL_ENTRY dbInheritedAttribute { 
00416     byte*          record;
00417     oid_t          oid;
00418     dbTable*       table;
00419     dbDatabase*    db;
00420     dbStringValue* tempStrings;
00421     size_t         paramBase;
00422     enum { 
00423         internalStrBufSize = 8*1024 
00424     };
00425     size_t         strBufPos;
00426     char           strBuf[internalStrBufSize];
00427     
00428     struct { 
00429         int     index;
00430         jmp_buf unwind;
00431     } exists_iterator[dbCompiler::maxFreeVars];
00432 
00433     void removeTemporaries();
00434 
00435     dbInheritedAttribute() { 
00436         tempStrings = NULL;
00437         strBufPos = 0;
00438     }
00439 
00440     ~dbInheritedAttribute() { 
00441         removeTemporaries(); 
00442     }
00443 };
00444 
00445 struct dbStringValue { 
00446     dbStringValue* next;
00447     char           str[1];
00448 
00449     static char* create(size_t size, dbInheritedAttribute& attr) { 
00450         if (attr.strBufPos + size > sizeof(attr.strBuf)) { 
00451             dbStringValue* sv = 
00452                 (dbStringValue*)new char[offsetof(dbStringValue, str) + size];
00453             sv->next = attr.tempStrings;
00454             attr.tempStrings = sv;
00455             return sv->str;
00456         } else { 
00457             char* p = attr.strBuf + attr.strBufPos;
00458             attr.strBufPos += size;
00459             return p;
00460         }
00461     }
00462 
00463     static char* create(char const* s, dbInheritedAttribute& attr) {
00464         size_t len = strlen(s) + 1;
00465         char*  buf;
00466         if (attr.strBufPos + len > sizeof(attr.strBuf)) { 
00467             dbStringValue* sv = 
00468                 (dbStringValue*)new char[offsetof(dbStringValue,str)+len];
00469             sv->next = attr.tempStrings;
00470             attr.tempStrings = sv;
00471             buf = sv->str;
00472         } else { 
00473             buf = attr.strBuf + attr.strBufPos;
00474             attr.strBufPos += len;
00475         }
00476         return strcpy(buf, s);
00477     }
00478 };
00479 
00480 inline char* findWildcard(char* pattern, char* escape = NULL) 
00481 {
00482     if (escape == NULL) { 
00483         while (*pattern != dbMatchAnyOneChar &&
00484                *pattern != dbMatchAnySubstring)
00485         {
00486             if (*pattern++ == '\0') { 
00487                 return NULL;
00488             }
00489         }
00490     } else { 
00491         char esc = *escape;
00492         while (*pattern != dbMatchAnyOneChar &&
00493                *pattern != dbMatchAnySubstring &&
00494                *pattern != esc)
00495         {
00496             if (*pattern++ == '\0') { 
00497                 return NULL;
00498             }
00499         }
00500     }
00501     return pattern;
00502 }
00503         
00504 END_FASTDB_NAMESPACE
00505     
00506 #endif

Generated on Mon Oct 23 13:23:58 2006 for FastDB by doxygen1.2.18