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 dbExprNode {
00117 friend class dbExprNodeSegment;
00118 public:
00119 nat1 cop;
00120 nat1 type;
00121 nat2 offs;
00122
00123 static const nat1 nodeTypes[];
00124 static const nat1 nodeOperands[];
00125 static const nat1 commutativeOperator[];
00126 static dbExprNode* freeNodeList;
00127 static dbMutex& mutex;
00128
00129 static dbExprNodeSegment* segmentList;
00130
00131 union {
00132 dbExprNode* operand[3];
00133 dbExprNode* next;
00134 oid_t oid;
00135 db_int8 ivalue;
00136 real8 fvalue;
00137 dbStrLiteral svalue;
00138 void const* var;
00139
00140 struct {
00141 dbExprNode* base;
00142 dbFieldDescriptor* field;
00143 } ref;
00144
00145 struct {
00146 dbExprNode* arg[3];
00147 void* fptr;
00148 } func;
00149 };
00150
00151 dbExprNode(dbExprNode* node);
00152
00153 dbExprNode(int cop, dbExprNode* left = NULL, dbExprNode* right = NULL,
00154 dbExprNode* right2 = NULL)
00155 {
00156 this->cop = cop;
00157 type = nodeTypes[cop];
00158 operand[0] = left;
00159 operand[1] = right;
00160 operand[2] = right2;
00161 }
00162 dbExprNode(int cop, dbExprNode* expr1, dbExprNode* expr2, int offs) {
00163 this->cop = cop;
00164 this->offs = (nat2)offs;
00165 type = nodeTypes[cop];
00166 operand[0] = expr1;
00167 operand[1] = expr2;
00168 }
00169 dbExprNode(int cop, dbExprNode* expr, int offs) {
00170 this->cop = cop;
00171 this->offs = (nat2)offs;
00172 type = nodeTypes[cop];
00173 operand[0] = expr;
00174 }
00175 dbExprNode(int cop, dbFieldDescriptor* field, dbExprNode* base = NULL)
00176 {
00177 this->cop = cop;
00178 this->offs = (nat2)field->dbsOffs;
00179 type = nodeTypes[cop];
00180 ref.field = field;
00181 ref.base = base;
00182 }
00183 dbExprNode(int cop, db_int8 ivalue) {
00184 this->cop = cop;
00185 this->ivalue = ivalue;
00186 type = tpInteger;
00187 }
00188 dbExprNode(int cop, real8 fvalue) {
00189 this->cop = cop;
00190 this->fvalue = fvalue;
00191 type = tpReal;
00192 }
00193 dbExprNode(int cop, dbStrLiteral& svalue) {
00194 this->cop = cop;
00195 this->svalue = svalue;
00196 type = tpString;
00197 }
00198 dbExprNode(int cop, void const* var) {
00199 this->cop = cop;
00200 this->var = var;
00201 type = nodeTypes[cop];
00202 }
00203 dbExprNode(int cop, void* fptr, dbExprNode* expr1, dbExprNode* expr2 = NULL, dbExprNode* expr3 = NULL) {
00204 this->cop = cop;
00205 func.arg[0] = expr1;
00206 func.arg[1] = expr2;
00207 func.arg[2] = expr3;
00208 func.fptr = fptr;
00209 type = nodeTypes[cop];
00210 }
00211 ~dbExprNode();
00212
00213 void* operator new(size_t size);
00214
00215 void operator delete(void* ptr) {
00216 if (ptr != NULL) {
00217 dbExprNode* node = (dbExprNode*)ptr;
00218 node->next = freeNodeList;
00219 freeNodeList = node;
00220 }
00221 }
00222
00223 static void cleanup();
00224 };
00225
00226
00227 class dbExprNodeSegment {
00228 public:
00229 enum { allocationQuantum = 1024};
00230 char buf[sizeof(dbExprNode)*allocationQuantum];
00231 dbExprNodeSegment* next;
00232 };
00233
00234
00235 class dbBinding {
00236 public:
00237 dbBinding* next;
00238 char const* name;
00239 bool used;
00240 int index;
00241 };
00242
00243 class dbOrderByNode {
00244 public:
00245 dbOrderByNode* next;
00246 dbFieldDescriptor* field;
00247 bool stringLength;
00248 bool ascent;
00249 };
00250
00251 class dbFollowByNode {
00252 public:
00253 dbFollowByNode* next;
00254 dbFieldDescriptor* field;
00255 };
00256
00257 class FASTDB_DLL_ENTRY dbCompiler {
00258 friend class dbQuery;
00259 friend class dbQueryElement;
00260 public:
00261 enum {
00262 maxStrLen = 4096,
00263 maxFreeVars = 4
00264 };
00265
00266 dbTableDescriptor* table;
00267 dbQueryElement* queryElement;
00268 int currPos;
00269 int firstPos;
00270 int offsetWithinStatement;
00271 int bvalue;
00272 db_int8 ivalue;
00273 real8 fvalue;
00274 dbStrLiteral svalue;
00275 int lex;
00276 char* name;
00277 dbBinding* bindings;
00278 int nFreeVars;
00279 int varType;
00280 void const* varPtr;
00281 dbTableDescriptor* varRefTable;
00282
00283 jmp_buf abortCompilation;
00284 static bool initialized;
00285
00286 int compare(dbExprNode* expr, dbExprNode* list);
00287
00288 int scan();
00289 void error(const char* msg, int pos = -1);
00290 dbExprNode* conjunction();
00291 dbExprNode* disjunction();
00292 dbExprNode* comparison();
00293 dbExprNode* addition();
00294 dbExprNode* multiplication();
00295 dbExprNode* power();
00296 dbExprNode* term();
00297 dbExprNode* userDefinedOperator();
00298 dbExprNode* field(dbExprNode* expr, dbTableDescriptor* refTable,
00299 dbFieldDescriptor* fd);
00300
00301 bool compile(dbTableDescriptor* table, dbQuery& query);
00302 dbExprNode* compileExpression(dbTableDescriptor* table, char const* expr, int startPos);
00303 void compileOrderByPart(dbQuery& query);
00304 void compileStartFollowPart(dbQuery& query);
00305
00306 dbCompiler();
00307 };
00308
00309 class dbDatabaseThreadContext : public dbL2List {
00310 public:
00311 int readAccess;
00312 int writeAccess;
00313 int concurrentId;
00314 int mutatorCSLocked;
00315
00316 dbL2List cursors;
00317
00318 dbCompiler compiler;
00319
00320 dbProcessId currPid;
00321
00322 bool interactive;
00323 bool catched;
00324 bool commitDelayed;
00325 bool removeContext;
00326 jmp_buf unwind;
00327
00328 dbDatabaseThreadContext() {
00329 concurrentId = 0;
00330 readAccess = false;
00331 writeAccess = false;
00332 mutatorCSLocked = false;
00333 interactive = false;
00334 catched = false;
00335 commitDelayed = false;
00336 removeContext = false;
00337 currPid = dbProcessId::getCurrent();
00338 }
00339 };
00340
00341 union dbSynthesizedAttribute {
00342 byte* base;
00343 int bvalue;
00344 db_int8 ivalue;
00345 real8 fvalue;
00346 void* raw;
00347 oid_t oid;
00348
00349 struct {
00350 char* base;
00351 int size;
00352 } array;
00353 };
00354
00355 struct dbStringValue;
00356
00357 struct FASTDB_DLL_ENTRY dbInheritedAttribute {
00358 byte* record;
00359 oid_t oid;
00360 dbTable* table;
00361 dbDatabase* db;
00362 dbStringValue* tempStrings;
00363 size_t paramBase;
00364 enum {
00365 internalStrBufSize = 8*1024
00366 };
00367 size_t strBufPos;
00368 char strBuf[internalStrBufSize];
00369
00370 struct {
00371 int index;
00372 jmp_buf unwind;
00373 } exists_iterator[dbCompiler::maxFreeVars];
00374
00375 void removeTemporaries();
00376
00377 dbInheritedAttribute() {
00378 tempStrings = NULL;
00379 strBufPos = 0;
00380 }
00381
00382 ~dbInheritedAttribute() {
00383 removeTemporaries();
00384 }
00385 };
00386
00387 struct dbStringValue {
00388 dbStringValue* next;
00389 char str[1];
00390
00391 static char* create(size_t size, dbInheritedAttribute& attr) {
00392 if (attr.strBufPos + size > sizeof(attr.strBuf)) {
00393 dbStringValue* sv =
00394 (dbStringValue*)new char[offsetof(dbStringValue, str) + size];
00395 sv->next = attr.tempStrings;
00396 attr.tempStrings = sv;
00397 return sv->str;
00398 } else {
00399 char* p = attr.strBuf + attr.strBufPos;
00400 attr.strBufPos += size;
00401 return p;
00402 }
00403 }
00404
00405 static char* create(char const* s, dbInheritedAttribute& attr) {
00406 size_t len = strlen(s) + 1;
00407 char* buf;
00408 if (attr.strBufPos + len > sizeof(attr.strBuf)) {
00409 dbStringValue* sv =
00410 (dbStringValue*)new char[offsetof(dbStringValue,str)+len];
00411 sv->next = attr.tempStrings;
00412 attr.tempStrings = sv;
00413 buf = sv->str;
00414 } else {
00415 buf = attr.strBuf + attr.strBufPos;
00416 attr.strBufPos += len;
00417 }
00418 return strcpy(buf, s);
00419 }
00420 };
00421
00422 #endif