00001
00002
00003
00004
00005
00006 #include "SQLPredicateTree.h"
00007
00008 using namespace LcgInfo;
00009 using namespace std;
00010
00011
00012
00013
00014 string const SQLPredicateTree::CHARS_TO_ESCAPE_IN_SQL_LITERALS = "\t ><=!()";
00015
00016
00017
00018 SQLPredicateTree::SQLPredicateTree()
00019 :PredicateTree(){
00020 }
00021
00022 SQLPredicateTree::~SQLPredicateTree(){
00023 }
00024
00025 void SQLPredicateTree::insertPredicate(string const & pPred){
00026 int level=0;
00027 short int lastPosLeft, firstPosRight;
00028 short int offset=0;
00029 string::size_type pos=0, aux;
00030 string predicate, subPredicate;
00031
00032 predicate=pPred;
00033 escapeLiterals(predicate,CHARS_TO_ESCAPE_IN_SQL_LITERALS);
00034 delSurroundingChars(predicate);
00035 aux=predicate.length();
00036
00037
00038 pos=predicate.find_first_of("()",0);
00039 while(pos!=string::npos){
00040 if(predicate.at(pos)=='(') {level++; if((level==1)&&(pos>0)) {aux=pos; break;}}
00041 if(predicate.at(pos)==')') {level--; if((level==0)&&(pos<aux-1)) offset=pos+1;}
00042 pos=predicate.find_first_of("()",pos+1);
00043 }
00044
00045
00046 while((predicate.at(0)=='(') && (predicate.at(aux-1)==')'))
00047 predicate=predicate.substr(1,aux-=2);
00048
00049 processLevel0(predicate.substr(offset,aux-offset),lastPosLeft,firstPosRight);
00050
00051 if(lastPosLeft!=-10){
00052 setLeft(create());
00053 aux=lastPosLeft+offset+1;
00054 subPredicate=predicate.substr(0,aux);
00055 left()->insertPredicate(subPredicate);
00056 }
00057 if(firstPosRight!=-10){
00058 setRight(create());
00059 aux=firstPosRight+offset;
00060 subPredicate=predicate.substr(aux,predicate.length()-aux);
00061 right()->insertPredicate(subPredicate);
00062 }
00063 }
00064
00065
00066
00067
00068 void SQLPredicateTree::processLevel0(string const & pPred, short int& pLastPosLeft,
00069 short int& pFirstPosRight){
00070
00071
00072
00073
00074 vector<string> tokens;
00075 vector<short int> indices;
00076
00077 vector<string>::iterator i;
00078 vector<short int>::iterator j;
00079
00080 tokenizeStrWithIndices(pPred, tokens, indices);
00081
00082
00083 for(i=tokens.begin(), j=indices.begin(); i!=tokens.end(); i++, j++)
00084 if(isBooleanOp(*i)){
00085 setType(BOOLEAN);
00086 setValue(*i);
00087 if(nocaseCompare(*i,"NOT"))
00088 pLastPosLeft=-10;
00089 else
00090 pLastPosLeft=(*j)-1;
00091 pFirstPosRight=(*j)+(*i).length();
00092
00093 if(pFirstPosRight > (indices.back() + (int) tokens.back().size())){
00094 string msg="Parsing error. Missing expression after NOT operator.";
00095 msg+="\nPartial predicate: "+pPred;
00096 throw QueryTranslationException(msg,__FILE__,__LINE__);
00097 }
00098 return;
00099 }
00100
00101
00102 string::size_type pointer;
00103 pointer=pPred.find_first_of("=><");
00104 if(pointer!=string::npos){
00105 setType(COMPARISON);
00106 if(pointer>0) pLastPosLeft=pointer-1;
00107 else{
00108 string msg="Parsing error. Missing expression before comparison operator.";
00109 msg+="\nPartial predicate: "+pPred;
00110 throw QueryTranslationException(msg,__FILE__,__LINE__);
00111 }
00112
00113
00114 if(pPred.find_first_not_of("=>",pointer+1)==pointer+1){
00115 setValue(pPred.substr(pointer,1));
00116 if((pointer+1)<pPred.length()) pFirstPosRight=pointer+1;
00117 else{
00118 string msg="Parsing error. Missing expression after comparison operator.";
00119 msg+="\nPartial predicate: "+pPred;
00120 throw QueryTranslationException(msg,__FILE__,__LINE__);
00121 }
00122 }
00123 else{
00124 setValue(pPred.substr(pointer,2));
00125 if((pointer+2)<pPred.length()) pFirstPosRight=pointer+2;
00126 else{
00127 string msg="Parsing error. Missing expression after comparison operator.";
00128 msg+="\nPartial predicate: "+pPred;
00129 throw QueryTranslationException(msg,__FILE__,__LINE__);
00130 }
00131 }
00132 return;
00133 }
00134
00135
00136 for(i=tokens.begin(), j=indices.begin(); i!=tokens.end(); i++, j++)
00137 if(nocaseCompare(*i,"LIKE")){
00138 setType(COMPARISON);
00139 setValue(*i);
00140 if(j!=indices.begin()) pLastPosLeft=*(j)-1;
00141 if((j+1)!=indices.end()) pFirstPosRight=*(j)+(*i).length();
00142 return;
00143 }
00144
00145
00146 setType(LEAF);
00147 unescapeLiterals(tokens.at(0),CHARS_TO_ESCAPE_IN_SQL_LITERALS);
00148 setValue(tokens.at(0));
00149 pLastPosLeft=-10;
00150 pFirstPosRight=-10;
00151
00152 }
00153
00154 string SQLPredicateTree::getCHARS_TO_TOKENIZE_PREDICATES(){
00155 return "\t ><=!()";
00156 }