Example #1
0
	int QueryParser::parseIt(int sessionId, string query, TreeNode *&qTree, string &tcResultString, bool toBeTypeChecked, bool toBeOptimized) {
		QueryParser::setStatEvalRun(0);
		ErrorConsole &ec(ErrorConsole::get_instance(EC_QUERY_PARSER));

		try{
			qTree = parser->parse(query).release();
			debug_print(ec,  "Query not parsed properly...\n");
			debug_print(ec,  (ErrQParser | ENotParsed));
		} catch (LoximException &ex) {
			debug_print(ec, "Query parsed");
			return (ErrQParser | ENotParsed);
		}

		Indexes::QueryOptimizer::optimizeWithIndexes(qTree);

		//Nothing more needs to be done, if this is an internal query. (no screen logging, typechecking, optimization)
		if (!toBeTypeChecked && !toBeOptimized) {
			return 0;
		}

		if (Deb::ugOn()) {
			cout << " Tree before optimization:";
			cout << "\n--------------------------------------\n";
			qTree->putToString();
			cout << "\n--------------------------------------\n";
		}
		if ((shouldTypeCheck || shouldOptimize) && !qTree->skipPreprocessing()) {
			TreeNode *nt = qTree->clone();
			bool metadataCorrect = DataScheme::dScheme(sessionId)->getIsComplete();
			bool metadataUpToDate = DataScheme::dScheme(sessionId)->getIsUpToDate();
			if (!metadataCorrect || !metadataUpToDate) {
				debug_print(ec,  "Data scheme is not complete or not up to date); optimization and typechecking blocked.");
			}

			int typeCheckErrCode = 0;
			if (shouldTypeCheck && toBeTypeChecked && metadataCorrect && metadataUpToDate) {
				if (isTcOffTmp()) { debug_print(ec,  "Typechecking turned off temporarily"); tcResultString = "";}
				else {
					Deb::ug(" \n \n TYPECHECK BEGIN !!! \n \n");
					TypeChecker *tc = new TypeCheck::TypeChecker(nt);
					typeCheckErrCode = tc->doTypeChecking(tcResultString);
					Deb::ug(" \n \n TYPECHECK DONE... \n ");
					if ((typeCheckErrCode != 0) && (typeCheckErrCode != (ErrTypeChecker | ETCNotApplicable))) {
						debug_print(ec,  "TC, Parser: typeCheckErrorCode says general TC error, should return string to user.\n");
						return typeCheckErrCode;
					}
					if (typeCheckErrCode == 0) {
						delete qTree;
						qTree = nt;
					}
				}
			} else {
				if (shouldTypeCheck && toBeTypeChecked && dmlIncompleteAction == DML_AC_RETURN_ERROR) {
					if (!metadataCorrect) return (ErrTypeChecker | EIncompleteMetadata);
					else return (ErrTypeChecker | EMetadataOutdated);
				}
				tcResultString = "";
				Deb::ug("TypeChecking is disabled.");
			}

			if (shouldOptimize && toBeOptimized && metadataCorrect && metadataUpToDate) {
				Deb::ug(" optimisation is set ON !");
				int optres = 0;
				int stat_ev_res;
				nt = qTree->clone();
				if ((stat_ev_res = this->statEvaluate(sessionId, nt)) != 0) {
					Deb::ug("static evaluation did not work out ...");
					optres = -1;
				} else {
					int optres = -2;
					DeathRmver *rmver = new DeathRmver(this);
					rmver->rmvDeath(nt);
					if (this->statEvaluate(sessionId, nt) != 0) optres = -1;
	/* The main optimisation loop - factor out single independent subqueries *
	* as long as ... such exist !                                           */
					while (optres == -2) {
						optres = nt->optimizeTree();
						while (nt->getParent() != NULL) nt = nt->getParent();
						/*one more static eval, to make sure nodes have the right info.. */
						fprintf (stderr, "one more stat eval..\n");
						if (this->statEvaluate(sessionId, nt) != 0) optres = -1;
					}
					AuxRmver *auxRmver = new AuxRmver(this);
					auxRmver->rmvAux(nt);
					JoinRpcer *joinRpcer = new JoinRpcer(this);
					joinRpcer->replaceJoin(nt);
				}
				if (optres != -1) {
					Deb::ug("I'll return optimized tree\n");
					qTree = nt;
					if (Deb::ugOn()) {
						cout << "Tree after optimization:\n--------------------------------------\n";
						qTree->putToString(); cout << "\n--------------------------------------\n";
					}
				} else { Deb::ug("I'll return the tree from before static eval..");}
			} else {
				if (shouldTypeCheck && toBeTypeChecked && dmlIncompleteAction == DML_AC_RETURN_ERROR) {
					if (!metadataCorrect) return (ErrTypeChecker | EIncompleteMetadata);
					else return (ErrTypeChecker | EMetadataOutdated);
				}
				Deb::ug(" optimisation is disabled. \n");
			}
		} else {
			qTree->qpLocalAction(this);
		}
		Deb::ug(" ParseIt() ends successfully!");
		/*			cout << "td1------------------------------------------------------------\n";
					testDeath("EMP.NAME");
					cout << "td2------------------------------------------------------------\n";
					testDeath("(EMP join (WORKS_IN.DEPT)).NAME;");
					cout << "td3------------------------------------------------------------\n";
		*/
		if (Deb::ugOn()) {
			cout << "===================================================================" << endl;
			cout << "P    A    R    S    E    R        R    E    T    U    R    N    S :" << endl;
			qTree->serialize();
			cout << "\n===================================================================" << endl;
		}
		return 0;
	}