📄 compiler.h
字号:
//-< COMPILE.H >-----------------------------------------------------*--------*
// FastDB Version 1.0 (c) 1999 GARRET * ? *
// (Main Memory Database Management System) * /\| *
// * / \ *
// Created: 20-Nov-98 K.A. Knizhnik * / [] \ *
// Last update: 17-Jan-99 K.A. Knizhnik * GARRET *
//-------------------------------------------------------------------*--------*
// Conditional expresion compiler
//-------------------------------------------------------------------*--------*
#ifndef __COMPILER_H__
#define __COMPILER_H__
#include <setjmp.h>
#if defined(__osf__) || defined(__FreeBSD__)
#define longjmp(b,s) _longjmp(b,s) // do not restore signal context
#define setjmp(b) _setjmp(b)
#endif
enum dbvmCodes {
#define DBVM(cop, type, n_operands, commutative) cop,
#include "compiler.d"
dbvmLastCode
};
#define IS_CONSTANT(c) \
(unsigned(c) - dbvmLoadVarBool <= (unsigned)dbvmLoadVarStdString - dbvmLoadVarBool)
enum nodeType {
tpInteger,
tpBoolean,
tpReal,
tpString,
tpReference,
tpArray,
tpRawBinary,
tpFreeVar, // index of EXISTS clause
tpList, // list of expressions
tpVoid
};
enum tokens {
tkn_ident,
tkn_lpar,
tkn_rpar,
tkn_lbr,
tkn_rbr,
tkn_dot,
tkn_comma,
tkn_power,
tkn_iconst,
tkn_sconst,
tkn_fconst,
tkn_add,
tkn_sub,
tkn_mul,
tkn_div,
tkn_and,
tkn_or,
tkn_not,
tkn_null,
tkn_neg,
tkn_eq,
tkn_ne,
tkn_gt,
tkn_ge,
tkn_lt,
tkn_le,
tkn_between,
tkn_escape,
tkn_exists,
tkn_like,
tkn_in,
tkn_length,
tkn_lower,
tkn_upper,
tkn_abs,
tkn_is,
tkn_integer,
tkn_real,
tkn_string,
tkn_first,
tkn_last,
tkn_current,
tkn_var,
tkn_col,
tkn_true,
tkn_false,
tkn_where,
tkn_follow,
tkn_start,
tkn_from,
tkn_order,
tkn_by,
tkn_asc,
tkn_desc,
tkn_eof,
tkn_insert,
tkn_into,
tkn_select,
tkn_table,
tkn_error,
tkn_all,
tkn_last_token
};
struct dbStrLiteral
{
char* str;
int len;
};
class dbUserFunction;
class FASTDB_DLL_ENTRY dbExprNodeAllocator
{
private:
friend class dbExprNodeSegment;
dbExprNode* freeNodeList;
dbExprNodeSegment* segmentList;
dbMutex mutex;
public:
dbMutex& getMutex()
{
return mutex;
}
dbExprNode* allocate();
void deallocate(dbExprNode* node);
void reset();
~dbExprNodeAllocator();
static dbExprNodeAllocator instance;
};
class FASTDB_DLL_ENTRY dbExprNode
{
friend class dbExprNodeSegment;
public:
nat1 cop;
nat1 type;
nat2 offs;
static const nat1 nodeTypes[];
static const nat1 nodeOperands[];
static const nat1 commutativeOperator[];
union {
dbExprNode* operand[3];
dbExprNode* next;
oid_t oid;
db_int8 ivalue;
real8 fvalue;
dbStrLiteral svalue;
void const* var;
struct
{
dbExprNode* base; // the same as operand[0]
dbFieldDescriptor* field;
}
ref;
struct
{
dbExprNode* arg[3];
void* fptr;
}
func;
};
dbExprNode(dbExprNode* node);
dbExprNode(int cop, dbExprNode* left = NULL, dbExprNode* right = NULL,
dbExprNode* right2 = NULL)
{
this->cop = cop;
type = nodeTypes[cop];
operand[0] = left;
operand[1] = right;
operand[2] = right2;
}
dbExprNode(int cop, dbExprNode* expr1, dbExprNode* expr2, int offs)
{
this->cop = cop;
this->offs = (nat2)offs;
type = nodeTypes[cop];
operand[0] = expr1;
operand[1] = expr2;
}
dbExprNode(int cop, dbExprNode* expr, int offs)
{
this->cop = cop;
this->offs = (nat2)offs;
type = nodeTypes[cop];
operand[0] = expr;
}
dbExprNode(int cop, dbFieldDescriptor* field, dbExprNode* base = NULL)
{
this->cop = cop;
this->offs = (nat2)field->dbsOffs;
type = nodeTypes[cop];
ref.field = field;
ref.base = base;
}
dbExprNode(int cop, db_int8 ivalue)
{
this->cop = cop;
this->ivalue = ivalue;
type = tpInteger;
}
dbExprNode(int cop, real8 fvalue)
{
this->cop = cop;
this->fvalue = fvalue;
type = tpReal;
}
dbExprNode(int cop, dbStrLiteral& svalue)
{
this->cop = cop;
this->svalue = svalue;
type = tpString;
}
dbExprNode(int cop, void const* var)
{
this->cop = cop;
this->var = var;
type = nodeTypes[cop];
}
dbExprNode(int cop, void* fptr, dbExprNode* expr1, dbExprNode* expr2 = NULL, dbExprNode* expr3 = NULL)
{
this->cop = cop;
func.arg[0] = expr1;
func.arg[1] = expr2;
func.arg[2] = expr3;
func.fptr = fptr;
type = nodeTypes[cop];
}
~dbExprNode();
void* operator new(size_t size EXTRA_DEBUG_NEW_PARAMS)
{
return dbExprNodeAllocator::instance.allocate();
}
void operator delete(void* ptr EXTRA_DEBUG_NEW_PARAMS)
{
dbExprNodeAllocator::instance.deallocate((dbExprNode*)ptr);
}
};
class dbExprNodeSegment
{
public:
enum { allocationQuantum = 1024};
char buf[sizeof(dbExprNode)*allocationQuantum];
dbExprNodeSegment* next;
};
class dbBinding
{
public:
dbBinding* next;
char const* name;
bool used;
int index;
};
class dbOrderByNode
{
public:
dbOrderByNode* next;
dbFieldDescriptor* field;
dbTableDescriptor* table;
dbExprNode* expr;
bool ascent; // true for ascent order, false for descent
};
class dbFollowByNode
{
public:
dbFollowByNode* next;
dbFieldDescriptor* field;
};
class FASTDB_DLL_ENTRY dbCompiler
{
friend class dbQuery;
friend class dbQueryElement;
public:
enum {
maxStrLen = 4096,
maxFreeVars = 4
};
dbTableDescriptor* table;
dbQueryElement* queryElement;
int currPos;
int firstPos;
int offsetWithinStatement;
int bvalue;
db_int8 ivalue;
real8 fvalue;
dbStrLiteral svalue;
bool hasToken;
int lex;
char* name;
dbBinding* bindings;
int nFreeVars;
int varType;
void const* varPtr;
dbTableDescriptor* varRefTable;
jmp_buf abortCompilation;
static bool initialized;
int compare(dbExprNode* expr, dbExprNode* list);
int scan();
void ungetToken(int tkn)
{
lex = tkn;
hasToken = true;
}
void error(const char* msg, int pos = -1);
dbExprNode* conjunction();
dbExprNode* disjunction();
dbExprNode* comparison();
dbExprNode* addition();
dbExprNode* multiplication();
dbExprNode* power();
dbExprNode* term();
dbExprNode* userDefinedOperator();
dbExprNode* field(dbExprNode* expr, dbTableDescriptor* refTable,
dbFieldDescriptor* fd);
bool compile(dbTableDescriptor* table, dbQuery& query);
dbExprNode* compileExpression(dbTableDescriptor* table, char const* expr, int startPos);
void compileOrderByPart(dbQuery& query);
void compileStartFollowPart(dbQuery& query);
dbCompiler();
};
class dbDatabaseThreadContext : public dbL2List
{
public:
int readAccess;
int writeAccess;
int concurrentId;
int mutatorCSLocked;
dbL2List cursors;
dbCompiler compiler;
dbProcessId currPid;
bool interactive;
bool catched;
bool commitDelayed;
bool removeContext;
jmp_buf unwind;
dbDatabaseThreadContext()
{
concurrentId = 0;
readAccess = false;
writeAccess = false;
mutatorCSLocked = false;
interactive = false;
catched = false;
commitDelayed = false;
removeContext = false;
currPid = dbProcessId::getCurrent();
}
};
union dbSynthesizedAttribute {
byte* base;
int bvalue;
db_int8 ivalue;
real8 fvalue;
void* raw;
oid_t oid;
struct
{
char* base;
int size;
}
array;
};
struct dbStringValue;
struct FASTDB_DLL_ENTRY dbInheritedAttribute
{
byte* record;
oid_t oid;
dbTable* table;
dbDatabase* db;
dbStringValue* tempStrings;
size_t paramBase;
enum {
internalStrBufSize = 8*1024
};
size_t strBufPos;
char strBuf[internalStrBufSize];
struct
{
int index;
jmp_buf unwind;
}
exists_iterator[dbCompiler::maxFreeVars];
void removeTemporaries();
dbInheritedAttribute()
{
tempStrings = NULL;
strBufPos = 0;
}
~dbInheritedAttribute()
{
removeTemporaries();
}
};
struct dbStringValue
{
dbStringValue* next;
char str[1];
static char* create(size_t size, dbInheritedAttribute& attr)
{
if (attr.strBufPos + size > sizeof(attr.strBuf))
{
dbStringValue* sv =
(dbStringValue*)new char[offsetof(dbStringValue, str) + size];
sv->next = attr.tempStrings;
attr.tempStrings = sv;
return sv->str;
}
else
{
char* p = attr.strBuf + attr.strBufPos;
attr.strBufPos += size;
return p;
}
}
static char* create(char const* s, dbInheritedAttribute& attr)
{
size_t len = strlen(s) + 1;
char* buf;
if (attr.strBufPos + len > sizeof(attr.strBuf))
{
dbStringValue* sv =
(dbStringValue*)new char[offsetof(dbStringValue,str)+len];
sv->next = attr.tempStrings;
attr.tempStrings = sv;
buf = sv->str;
}
else
{
buf = attr.strBuf + attr.strBufPos;
attr.strBufPos += len;
}
return strcpy(buf, s);
}
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -