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