📄 compiler.cpp
字号:
{ if (lex != tkn_start) { return; } int pos = currPos; if (scan() != tkn_from) { error("FROM expected after START", pos); } pos = currPos; switch (scan()) { case tkn_first: query.startFrom = dbCompiledQuery::StartFromFirst; break; case tkn_last: query.startFrom = dbCompiledQuery::StartFromLast; break; case tkn_var: if (varType == dbQueryElement::qVarReference) { if (varRefTable != table) { error("Incompatiable type of reference variable"); } query.startFrom = dbCompiledQuery::StartFromRef; } else if (varType == dbQueryElement::qVarArrayOfRef) { if (varRefTable != table) { error("Incompatiable type of array of reference variable"); } query.startFrom = dbCompiledQuery::StartFromArray; } else if (varType == dbQueryElement::qVarArrayOfRefPtr) { if (varRefTable != table) { error("Incompatiable type of array of reference variable"); } query.startFrom = dbCompiledQuery::StartFromArrayPtr; } else { error("Reference or array of reference variable expected"); } query.root = varPtr; break; default: error("FIRST, LAST or reference varaible expected", pos); } if ((lex = scan()) == tkn_follow) { pos = currPos; if (scan() != tkn_by) { error("BY expected after FOLLOW", pos); } do { pos = currPos; if (scan() != tkn_ident) { error("Field name expected", pos); } dbFieldDescriptor* fd; if ((fd = table->findSymbol(name)) == NULL) { error("Field not found"); } while (fd->type == dbField::tpStructure) { pos = currPos; if (scan() != tkn_dot) { error("'.' expected", pos); } pos = currPos; if (scan() != tkn_ident) { error("Field name expected", pos); } if ((fd = fd->find(name)) == NULL) { error("Field not found"); } } if (!(fd->type == dbField::tpReference && fd->refTable == table) && !(fd->type == dbField::tpArray && fd->components->type == dbField::tpReference && fd->components->refTable == table)) { error("Follow field should be of compatibale reference " "or array of reference type"); } dbFollowByNode* node = new dbFollowByNode; node->field = fd; node->next = query.follow; // list should be inverted query.follow = node; } while ((lex = scan()) == tkn_comma); } }void dbCompiler::deleteNode(dbExprNode* node) { dbMutex& mutex = dbExprNodeAllocator::instance.getMutex(); dbCriticalSection cs(mutex); delete node;}void dbCompiler::compileLimitPart(dbQuery& query){ if (lex == tkn_limit) { int pos = currPos; size_t l1 = 0; int4* lp1 = NULL; switch (scan()) { case tkn_iconst: l1 = (size_t)ivalue; break; case tkn_var: if (varType != dbQueryElement::qVarInt4) { error("LIMIT parameter should have int4 type", pos); } lp1 = (int4*)varPtr; break; default: error("Parameter or integer constant expected", pos); } if ((lex = scan()) == tkn_comma) { pos = currPos; size_t l2 = 0; int4* lp2 = NULL; switch (scan()) { case tkn_iconst: l2 = (size_t)ivalue; break; case tkn_var: if (varType != dbQueryElement::qVarInt4) { error("LIMIT parameter should have int4 type", pos); } lp2 = (int4*)varPtr; break; default: error("Parameter or integer constant expected", pos); } query.stmtLimitStart = l1; query.stmtLimitStartPtr = lp1; query.stmtLimitLen = l2; query.stmtLimitLenPtr = lp2; lex = scan(); } else { query.stmtLimitStart = 0; query.stmtLimitStartPtr = NULL; query.stmtLimitLen = l1; query.stmtLimitLenPtr = lp1; } query.limitSpecified = true; }} void dbCompiler::compileOrderByPart(dbQuery& query){ if (lex == tkn_order) { dbOrderByNode** opp = &query.order; int pos = currPos; if (scan() != tkn_by) { error("BY expected after ORDER", pos); } int parentheses = 0; do { pos = currPos; int tkn = scan(); if (tkn == tkn_lpar) { parentheses += 1; } else { ungetToken(tkn); } dbExprNode* expr = disjunction(); dbOrderByNode* node = new dbOrderByNode; switch (expr->cop) { case dbvmLoadSelfBool: case dbvmLoadSelfInt1: case dbvmLoadSelfInt2: case dbvmLoadSelfInt4: case dbvmLoadSelfInt8: case dbvmLoadSelfReal4: case dbvmLoadSelfReal8: case dbvmLoadSelfString: case dbvmLoadSelfArray: case dbvmLoadSelfReference: case dbvmLoadSelfRawBinary: assert(expr->ref.field != NULL); node->field = expr->ref.field; node->expr = NULL; deleteNode(expr); break; case dbvmLength: if (expr->operand[0]->cop == dbvmLoadSelfArray) { node->field = expr->operand[0]->ref.field; node->expr = NULL; deleteNode(expr); break; } // no break default: if (expr->type > tpReference) { error("Expressions in ORDER BY part should have scalar type", pos); } node->field = NULL; node->expr = expr; } node->table = table; node->ascent = true; *opp = node; opp = &node->next; *opp = NULL; if (lex == tkn_desc) { node->ascent = false; lex = scan(); } else if (lex == tkn_asc) { lex = scan(); } if (lex == tkn_rpar) { if (--parentheses < 0) { error("Unbalanced parentheses "); } lex = scan(); } } while (lex == tkn_comma); }}dbExprNode* dbCompiler::compileExpression(dbTableDescriptor* table, char const* expr, int startPos){ TRACE_MSG(("Compile expression %s for table %s\n", table->name)); if (setjmp(abortCompilation) == 0) { this->table = table; bindings = NULL; nFreeVars = 0; dbQueryElement elem(dbQueryElement::qExpression, expr, NULL); queryElement = &elem; currPos = firstPos = 0; offsetWithinStatement = startPos; return disjunction(); } else { return NULL; }}bool dbCompiler::compile(dbTableDescriptor* table, dbQuery& query){ TRACE_MSG(("Compile query for table %s\n", table->name)); query.destroy(); if (setjmp(abortCompilation) == 0) { this->table = table; bindings = NULL; nFreeVars = 0; queryElement = query.elements; currPos = firstPos = 0; hasToken = false; offsetWithinStatement = query.pos; dbExprNode* expr = disjunction(); if (expr->type != tpBoolean && expr->type != tpVoid) { error("Conditional expression should have boolean type\n"); } compileStartFollowPart(query); compileOrderByPart(query); compileLimitPart(query); if (lex != tkn_eof) { error("START, ORDER BY or LIMIT expected"); } query.tree = expr; query.table = table; return true; } else { dbMutex& mutex = dbExprNodeAllocator::instance.getMutex(); dbCriticalSection cs(mutex); for (dbOrderByNode *op = query.order, *nop; op != NULL; op = nop) { nop = op->next; delete op; } for (dbFollowByNode *fp = query.follow, *nfp; fp != NULL; fp = nfp) { nfp = fp->next; delete fp; } return false; }}dbCompiler::dbCompiler() { static struct { char* name; int tag; } keywords[] = { {"all", tkn_all}, {"abs", tkn_abs}, {"and", tkn_and}, {"area", tkn_area}, {"asc", tkn_asc}, {"between", tkn_between}, {"by", tkn_by}, {"current", tkn_current}, {"desc", tkn_desc}, {"escape", tkn_escape}, {"exists", tkn_exists}, {"first", tkn_first}, {"false", tkn_false}, {"follow", tkn_follow}, {"from", tkn_from}, {"in", tkn_in}, {"is", tkn_is}, {"integer", tkn_integer}, {"insert", tkn_insert}, {"into", tkn_into}, {"last", tkn_last}, {"length", tkn_length}, {"like", tkn_like}, {"limit", tkn_limit}, {"lower", tkn_lower},#ifdef USE_REGEX {"match", tkn_match},#endif {"not", tkn_not}, {"null", tkn_null}, {"or", tkn_or}, {"order", tkn_order}, {"overlaps",tkn_overlaps}, {"real", tkn_real}, {"select", tkn_select}, {"start", tkn_start}, {"string", tkn_string}, {"table", tkn_table}, {"true", tkn_true}, {"upper", tkn_upper}, {"where", tkn_where} }; if (!initialized) { for (unsigned i = 0; i < itemsof(keywords); i++) { dbSymbolTable::add(keywords[i].name, keywords[i].tag, FASTDB_CLONE_ANY_IDENTIFIER); } initialized = true; }}void dbInheritedAttribute::removeTemporaries(){ for (dbStringValue *next, *s = tempStrings; s != NULL; s = next) { next = s->next; delete s; }}END_FASTDB_NAMESPACE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -