SQLExpression.hpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2014 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef SQLEXPRESSION_HPP_
  14. #define SQLEXPRESSION_HPP_
  15. #include "ws_sql.hpp"
  16. #include "SQLColumn.hpp"
  17. #include "ECLFunction.hpp"
  18. /* undef SOCKET definitions to avoid collision in Antlrdefs.h*/
  19. #ifdef INVALID_SOCKET
  20. //#pragma message( "UNDEFINING INVALID_SOCKET - Will be redefined by ANTLRDEFS.h" )
  21. #undef INVALID_SOCKET
  22. #endif
  23. #ifdef SOCKET
  24. //#pragma message( "UNDEFINING SOCKET - Will be redefined by ANTLRDEFS.h" )
  25. #undef SOCKET
  26. #endif
  27. #include "HPCCSQLLexer.h"
  28. /* undef SOCKET definitions to avoid collision in Antlrdefs.h*/
  29. typedef enum _SQLExpressionType
  30. {
  31. Unary_ExpressionType,
  32. FieldValue_ExpressionType,
  33. Fields_ExpressionType,
  34. Parenthesis_ExpressionType,
  35. Value_ExpressionType,
  36. Binary_ExpressionType,
  37. ParameterPlaceHolder_ExpressionType,
  38. Function_ExpressionType,
  39. List_ExpressionType
  40. } SQLExpressionType;
  41. typedef enum _SQLLogicType
  42. {
  43. Unknown_LogicType=-1,
  44. Bool_LogicType,
  45. String_LogicType,
  46. QSstring_LogicType,
  47. Unicode_LogicType,
  48. Numeric_LogicType,
  49. Integer_LogicType,
  50. Decimal_LogicType,
  51. NestedDS_LogicType
  52. } SQLLogicType;
  53. interface ISQLExpression : public CInterface, public IInterface
  54. {
  55. public:
  56. IMPLEMENT_IINTERFACE;
  57. /*
  58. * Reports whether this expression contains reference to field 'colname'.
  59. * @param String name of column
  60. *
  61. * @return bool Reports whether this expression contains reference to field 'colname'.
  62. */
  63. virtual bool containsKey(const char * colname) = 0;
  64. /*
  65. * appends string representation of this SQLExpression, fully qualifies field values
  66. * depending on input param's value.
  67. * @param boolean Fully qualify field values.
  68. *
  69. * @return appends string Representation of this SQLExpression, fields fully-qualified baed on in param.
  70. */
  71. virtual void toString(StringBuffer & targetstr, bool fullOutput) = 0;
  72. /*
  73. * Returns number of field value expressions contained within SQL Expression.
  74. *
  75. * @return int number of field value expressions contained within SQL Expression.
  76. */
  77. virtual int getExpressionsCount() = 0;
  78. /*
  79. * Translates SQLExpression to ECL in flat string form.
  80. * @param map IProperties containing source table names as keys and its translation target
  81. * @param ignoreMistranslations option to continue translating expression even if
  82. * current expression contains table.field where table not found in map
  83. * @param forHaving option to translate for ECL HAVING function
  84. * @param funcParam option specifying if expression to be translated is a function parameter
  85. * @param countFuncParam option specifying if expression to be translated is an ECL Count() parameter
  86. *
  87. * @return appends string ECL consumable representation of expression.
  88. */
  89. virtual void toECLStringTranslateSource(StringBuffer & eclStr,
  90. IProperties * map,
  91. bool ignoreMisTranslations,
  92. bool forHaving,
  93. bool funcParam,
  94. bool countFuncParam)=0;
  95. /*
  96. * Reports if this SQL expression contains an equality condition between table first and second.
  97. *
  98. * @param map IProperties containing source table names and their possible ECL translation
  99. * @param String Name of first table.
  100. * @param String Name of second table.
  101. * @return bool True if this expression was found to contain equality condition between
  102. * table 'first' and table 'second'.
  103. */
  104. virtual bool containsEqualityCondition(IProperties * map, const char * first, const char * second)
  105. {
  106. return false;
  107. }
  108. /*
  109. * Attempts to label each parameterized expression placeholder, increases the
  110. * running index value by the number of param placeholder processed.
  111. *
  112. * @param int currentindex index used to as postfix for placeholder label
  113. *
  114. * @return int running index value. To be used for next param placeholder label.
  115. */
  116. virtual int setParameterizedNames(int currentindex)=0;
  117. virtual bool needsColumnExpansion() { return false;}
  118. virtual void appendField(ISQLExpression * field){}
  119. virtual void setECLType(const char * type) {UNIMPLEMENTED;}
  120. virtual const char * getECLType() {UNIMPLEMENTED; return nullptr;}
  121. virtual const char * getName() {UNIMPLEMENTED; return nullptr;}
  122. virtual void setName(const char * name) {UNIMPLEMENTED;}
  123. virtual const char * getNameOrAlias() {UNIMPLEMENTED; return nullptr;}
  124. virtual void setAlias(const char * alias) {UNIMPLEMENTED;}
  125. virtual const char * getAlias() {UNIMPLEMENTED; return nullptr;}
  126. virtual SQLExpressionType getExpType()=0;
  127. virtual SQLLogicType getLogicType(){UNIMPLEMENTED; return Unknown_LogicType;};
  128. virtual void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype){UNIMPLEMENTED;};
  129. virtual void getUniqueExpressionColumnNames(StringArray & uniquenames)=0;
  130. virtual void getExpressionFromColumnName(const char * colname, StringBuffer & str)=0;
  131. /*
  132. * Instructs this expression to be replaced by a typed place holder.
  133. *
  134. * The purpose of this value placeholder replacement (parameterization)
  135. * could be exploited for query normalization, query caching optimization,
  136. * query publishing, etc.
  137. */
  138. virtual bool setValuePlaceHolderType(const char * ecltype){UNIMPLEMENTED; return false;};
  139. /*
  140. * Has this expression been provided a placeholder type?
  141. *
  142. * select * from t1 where f1 = 5; <- the right side of the binary expression f1 = 5 can be
  143. * parameterized as f1 = ${f1.ecltype}
  144. */
  145. virtual bool hasPlaceHolder(){return false;}
  146. /*
  147. * Get this placeholder inferred type
  148. *
  149. * select * from t1 where f1 = 5; <- the right side of the binary expression f1 = 5 can be
  150. * parameterized as f1 = ${f1.ecltype}
  151. * This allows caching of query structure
  152. */
  153. virtual const char * getPlaceHolderType(){UNIMPLEMENTED; return nullptr;}
  154. /*
  155. * Get this placeholder's generated name
  156. */
  157. virtual const char * getPlaceHolderName(){UNIMPLEMENTED; return nullptr;}
  158. static SQLLogicType getLogicTypeFromName(const char * type)
  159. {
  160. if (!type || !*type)
  161. return Unknown_LogicType;
  162. if (strnicmp(type,"STRING",6)==0)
  163. return String_LogicType;
  164. else if (strnicmp(type,"QSTRING",7)==0)
  165. return QSstring_LogicType;
  166. else if (strnicmp(type,"UNICODE",7)==0)
  167. return Unicode_LogicType;
  168. else if (strnicmp(type,"VARUNICODE",10)==0)
  169. return Unicode_LogicType;
  170. else if (strnicmp(type,"VARSTRING",9)==0)
  171. return String_LogicType;
  172. else if (strnicmp(type,"BOOLEAN",7)==0)
  173. return Bool_LogicType;
  174. else if (strnicmp(type,"UNSIGNED",8)==0)
  175. return Integer_LogicType;
  176. else if (strnicmp(type,"REAL",4)==0)
  177. return Decimal_LogicType;
  178. else if (strnicmp(type,"DECIMAL",7)==0)
  179. return Decimal_LogicType;
  180. else if (strnicmp(type,"DATASET",7)==0)
  181. return NestedDS_LogicType;
  182. else
  183. return Unknown_LogicType;
  184. }
  185. };
  186. /*************************************************************************************************/
  187. class SQLListExpression : implements ISQLExpression
  188. {
  189. public:
  190. IMPLEMENT_IINTERFACE;
  191. SQLListExpression();
  192. virtual ~SQLListExpression();
  193. void getExpressionFromColumnName(const char * colname, StringBuffer & str);
  194. void getUniqueExpressionColumnNames(StringArray & uniquenames);
  195. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype);
  196. SQLLogicType getLogicType();
  197. int setParameterizedNames(int currentindex);
  198. void toECLStringTranslateSource(StringBuffer & eclStr, IProperties * map, bool ignoreMisTranslations, bool forHaving, bool funcParam, bool countFuncParam);
  199. SQLExpressionType getExpType() { return List_ExpressionType;}
  200. bool containsKey(const char* colname);
  201. void toString(StringBuffer & targetstr, bool fullOutput);
  202. int getExpressionsCount();
  203. void appendEntry(ISQLExpression * entry);
  204. bool setValuePlaceHolderType(const char * ecltype){return false;}
  205. bool hasPlaceHolder(){ return false;}
  206. const char * getPlaceHolderType() {return nullptr;}
  207. private:
  208. IArrayOf<ISQLExpression> entries;
  209. };
  210. /*************************************************************************************************/
  211. class SQLUnaryExpression : implements ISQLExpression
  212. {
  213. public:
  214. IMPLEMENT_IINTERFACE;
  215. void getExpressionFromColumnName(const char * colname, StringBuffer & str);
  216. void getUniqueExpressionColumnNames(StringArray & uniquenames)
  217. {
  218. operand1->getUniqueExpressionColumnNames(uniquenames);
  219. }
  220. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  221. {
  222. operand1->eclDeclarePlaceHolders(eclstr, op, sibtype);
  223. }
  224. SQLLogicType getLogicType(){ return operand1->getLogicType();}
  225. int setParameterizedNames(int currentindex)
  226. {
  227. return operand1->setParameterizedNames(currentindex);
  228. }
  229. void toECLStringTranslateSource(StringBuffer & eclStr, IProperties * map, bool ignoreMisTranslations, bool forHaving, bool funcParam, bool countFuncParam);
  230. bool containsEqualityCondition(IProperties * map, const char * first, const char * second);
  231. SQLExpressionType getExpType() { return Unary_ExpressionType;}
  232. SQLUnaryExpression();
  233. SQLUnaryExpression(ISQLExpression* operand1, int opname);
  234. virtual ~SQLUnaryExpression();
  235. bool containsKey(const char* colname);
  236. void toString(StringBuffer & targetstr, bool fullOutput);
  237. int getOp() const
  238. {
  239. return op;
  240. }
  241. void setOp(int op)
  242. {
  243. this->op = op;
  244. }
  245. ISQLExpression* getOperand1() const
  246. {
  247. return operand1;
  248. }
  249. void setOperand1(ISQLExpression* operand1)
  250. {
  251. this->operand1 = operand1;
  252. }
  253. int getExpressionsCount() { return operand1->getExpressionsCount();}
  254. bool setValuePlaceHolderType(const char * ecltype){return false;}
  255. bool hasPlaceHolder(){ return false;}
  256. const char * getPlaceHolderType() {return nullptr;}
  257. private:
  258. ISQLExpression * operand1;
  259. int op;
  260. };
  261. /*************************************************************************************************/
  262. class SQLFieldValueExpression : implements ISQLExpression
  263. {
  264. public:
  265. IMPLEMENT_IINTERFACE;
  266. void getExpressionFromColumnName(const char * colname, StringBuffer & str)
  267. {
  268. if(stricmp(getName(),colname)==0)
  269. toString(str, false);
  270. }
  271. void getUniqueExpressionColumnNames(StringArray & uniquenames)
  272. {
  273. uniquenames.appendUniq(getName());
  274. }
  275. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype) {return;}
  276. SQLLogicType getLogicType();
  277. virtual int setParameterizedNames(int currentindex)
  278. {
  279. return currentindex;
  280. }
  281. void toECLStringTranslateSource(StringBuffer & eclStr, IProperties * map, bool ignoreMisTranslations, bool forHaving, bool funcParam, bool countFuncParam);
  282. SQLExpressionType getExpType() { return FieldValue_ExpressionType;}
  283. SQLFieldValueExpression();
  284. SQLFieldValueExpression(const char * parentTableName, const char * fieldName);
  285. virtual ~SQLFieldValueExpression();
  286. const char * getParentTableName();
  287. void setParentTableName(const char * parentTableName);
  288. const char * getName();
  289. void setName(const char * name);
  290. const char * getAlias();
  291. void setAlias(const char * alias);
  292. bool isAscending();
  293. void setAscending(bool ascending);
  294. bool containsKey(const char * colname);
  295. void toString(StringBuffer & targetstr, bool fullOutput);
  296. int getExpressionsCount() { return 1;}
  297. bool isAliasOrName(const char * possiblenameoralias);
  298. void setECLType(const char * type);
  299. const char * getECLType();
  300. const char * getNameOrAlias();
  301. SQLColumn * queryField()
  302. {
  303. return &field;
  304. }
  305. bool setValuePlaceHolderType(const char * ecltype){return false;}
  306. bool hasPlaceHolder(){ return false;}
  307. const char * getPlaceHolderType() {return nullptr;}
  308. private:
  309. SQLColumn field;
  310. };
  311. /*************************************************************************************************/
  312. class SQLFieldsExpression : implements ISQLExpression
  313. {
  314. public:
  315. IMPLEMENT_IINTERFACE;
  316. void getExpressionFromColumnName(const char * colname, StringBuffer & str){ UNIMPLEMENTED_X("This method should never be accessed for SQLFieldsExpression!");}
  317. void getUniqueExpressionColumnNames(StringArray & uniquenames){ UNIMPLEMENTED_X("Method SQLFieldsExpression::getUniqueExpressionColumnNames should never be accessed!");}
  318. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype) {return;}
  319. virtual SQLLogicType getLogicType(){return Unknown_LogicType;}
  320. virtual int setParameterizedNames(int currentindex)
  321. {
  322. return currentindex;
  323. }
  324. void toECLStringTranslateSource(
  325. StringBuffer & eclStr,
  326. IProperties * map,
  327. bool ignoreMisTranslations,
  328. bool forHaving,
  329. bool funcParam,
  330. bool countFuncParam) { UNIMPLEMENTED_X("This method should never be accessed for SQLFieldsExpression!");}
  331. SQLExpressionType getExpType() { return Fields_ExpressionType;}
  332. SQLFieldsExpression(bool allfiles);
  333. SQLFieldsExpression(const char * table);
  334. virtual ~SQLFieldsExpression();
  335. int getExpressionsCount() { return 1;}
  336. void toString(StringBuffer & targetstr, bool fullOutput);
  337. bool containsKey(const char * colname) {return false;}
  338. bool isAll() const
  339. {
  340. return all;
  341. }
  342. void setAll(bool all)
  343. {
  344. this->all = all;
  345. }
  346. const char* getTable() const
  347. {
  348. return this->table.str();
  349. }
  350. void setTable(const char* table)
  351. {
  352. this->table.set(table);
  353. }
  354. bool needsColumnExpansion() { return !isExpanded; }
  355. bool setValuePlaceHolderType(const char * ecltype){return false;}
  356. bool hasPlaceHolder(){ return false;}
  357. const char * getPlaceHolderType() {return nullptr;}
  358. private:
  359. StringBuffer table;
  360. bool all;
  361. bool isExpanded;
  362. };
  363. /*************************************************************************************************/
  364. class SQLParenthesisExpression : implements ISQLExpression
  365. {
  366. public:
  367. IMPLEMENT_IINTERFACE;
  368. void getExpressionFromColumnName(const char * colname, StringBuffer & str)
  369. {
  370. StringBuffer result1;
  371. innerexpression->getExpressionFromColumnName(colname, result1);
  372. //if (result1.length > 0 )
  373. str.appendf("( %s )", result1.str());
  374. }
  375. void getUniqueExpressionColumnNames(StringArray & uniquenames)
  376. {
  377. innerexpression->getUniqueExpressionColumnNames(uniquenames);
  378. }
  379. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  380. {
  381. innerexpression->eclDeclarePlaceHolders(eclstr, op, sibtype);
  382. }
  383. virtual SQLLogicType getLogicType(){return innerexpression->getLogicType();}
  384. virtual int setParameterizedNames(int currentindex)
  385. {
  386. return innerexpression->setParameterizedNames(currentindex);
  387. }
  388. void toECLStringTranslateSource(
  389. StringBuffer & eclStr,
  390. IProperties * map,
  391. bool ignoreMisTranslations,
  392. bool forHaving,
  393. bool funcParam,
  394. bool countFuncParam)
  395. {
  396. eclStr.append("( ");
  397. innerexpression->toECLStringTranslateSource(eclStr, map, ignoreMisTranslations, forHaving, funcParam, countFuncParam);
  398. eclStr.append(" )");
  399. }
  400. ISQLExpression* getInnerExp();
  401. SQLExpressionType getExpType() { return Parenthesis_ExpressionType;}
  402. SQLParenthesisExpression(ISQLExpression * exp);
  403. virtual ~SQLParenthesisExpression();
  404. bool containsKey(const char * colname);
  405. void toString(StringBuffer & targetstr, bool fullOutput);
  406. int getExpressionsCount() { return innerexpression->getExpressionsCount();}
  407. bool setValuePlaceHolderType(const char * ecltype){return false;}
  408. bool hasPlaceHolder(){ return false;}
  409. const char * getPlaceHolderType() {return nullptr;}
  410. private:
  411. ISQLExpression* innerexpression;
  412. };
  413. /*************************************************************************************************/
  414. class SQLValueExpression : implements ISQLExpression
  415. {
  416. public:
  417. IMPLEMENT_IINTERFACE;
  418. void getExpressionFromColumnName(const char * colname, StringBuffer & str)
  419. {
  420. str.appendf(" %s ", value.str());
  421. }
  422. void getUniqueExpressionColumnNames(StringArray & uniquenames) { return; }
  423. virtual SQLLogicType getLogicType()
  424. {
  425. return ISQLExpression::getLogicTypeFromName(field.getColumnType());
  426. }
  427. virtual int setParameterizedNames(int currentindex);
  428. void toECLStringTranslateSource(
  429. StringBuffer & eclStr,
  430. IProperties * map,
  431. bool ignoreMisTranslations,
  432. bool forHaving,
  433. bool funcParam,
  434. bool countFuncParam);
  435. SQLExpressionType getExpType() { return Value_ExpressionType;}
  436. SQLValueExpression();
  437. SQLValueExpression(int type, const char * value);
  438. virtual ~SQLValueExpression();
  439. bool containsKey(const char * colname) {return false;}
  440. void toString(StringBuffer & targetstr, bool fullOutput);
  441. int getType() const
  442. {
  443. return type;
  444. }
  445. void setType(int type)
  446. {
  447. this->type = type;
  448. }
  449. const char * getValue() const
  450. {
  451. return value.str();
  452. }
  453. void setValue(const char * value)
  454. {
  455. this->value.set(value);
  456. }
  457. int getExpressionsCount()
  458. {
  459. return 0;
  460. }
  461. virtual void trimTextQuotes();
  462. virtual void setECLType(const char * type);
  463. virtual const char * getECLType();
  464. virtual const char * getName();
  465. virtual void setName(const char * name);
  466. virtual const char * getNameOrAlias();
  467. virtual void setAlias(const char * alias);
  468. virtual const char * getAlias();
  469. bool setValuePlaceHolderType(const char * ecltype)
  470. {
  471. if (ecltype && *ecltype)
  472. {
  473. placeHolderType.set(ecltype);
  474. return true;
  475. }
  476. return false;
  477. }
  478. bool hasPlaceHolder(){ return placeHolderType.length() > 0;}
  479. const char * getPlaceHolderType() {return placeHolderType.str();}
  480. const char * getPlaceHolderName() {return placeHolderName.str();}
  481. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  482. {
  483. if(hasPlaceHolder())
  484. eclstr.appendf("%s %s := %s : STORED('%s');\n", placeHolderType.str(), placeHolderName.str(), value.str(), placeHolderName.str());
  485. if(isAWildCardPattern)
  486. {
  487. eclstr.appendf("%sTranslated := STD.Str.Translate( %s , '_%%', '?*');", placeHolderName.str(), placeHolderName.str());
  488. placeHolderName.append("Translated");
  489. }
  490. }
  491. void setIsWildCardPattern(bool isthisawildcard) {isAWildCardPattern = isthisawildcard;}
  492. private:
  493. int type; //As defined in HPCCSQLParser.h
  494. StringBuffer value;
  495. SQLColumn field;
  496. StringBuffer placeHolderName;
  497. StringBuffer placeHolderType;
  498. bool isAWildCardPattern;
  499. };
  500. /*************************************************************************************************/
  501. class SQLBinaryExpression : implements ISQLExpression
  502. {
  503. public:
  504. IMPLEMENT_IINTERFACE;
  505. void getExpressionFromColumnName(const char * colname, StringBuffer & str)
  506. {
  507. StringBuffer result1;
  508. StringBuffer result2;
  509. operand1->getExpressionFromColumnName(colname, result1);
  510. if (!result1.length())
  511. return; // no need to waste time fetching the right sub-expression
  512. operand2->getExpressionFromColumnName(colname, result2);
  513. if (result2.length() > 0)
  514. str.appendf(" %s %s %s ", result1.str(), getOpStr(),result2.str());
  515. /* this was meant to provide sub-expressions based on the colname provided,
  516. * however providing the OR'ed sub-expression can be misleading and the logic
  517. * arithmetic can be flawed, therefore this else is taken out, but will keep within
  518. * comment block for reference:
  519. * else if (op == OR_SYM)
  520. {
  521. if (result1.length() > 0)
  522. str.appendf(" %s ", result1.str());
  523. else if (result2.length() > 0)
  524. str.appendf(" %s ", result2.str());
  525. }*/
  526. }
  527. void getUniqueExpressionColumnNames(StringArray & uniquenames)
  528. {
  529. operand1->getUniqueExpressionColumnNames(uniquenames);
  530. operand2->getUniqueExpressionColumnNames(uniquenames);
  531. }
  532. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  533. {
  534. operand1->eclDeclarePlaceHolders(eclstr, this->op, operand2->getLogicType());
  535. operand2->eclDeclarePlaceHolders(eclstr, this->op, operand1->getLogicType());
  536. }
  537. virtual SQLLogicType getLogicType()
  538. {
  539. switch (op)
  540. {
  541. case AND_SYM:
  542. case OR_SYM:
  543. return Bool_LogicType;
  544. case DIVIDE:
  545. case GTH:
  546. case GET:
  547. case LTH:
  548. case LET:
  549. case MINUS:
  550. case MOD:
  551. case ASTERISK:
  552. case PLUS:
  553. return Numeric_LogicType;
  554. case EQ_SYM:
  555. case NOT_EQ:
  556. case IN_SYM:
  557. case NOT_IN:
  558. {
  559. SQLLogicType op1type =operand1->getLogicType();
  560. SQLLogicType op2type =operand2->getLogicType();
  561. if (op1type != Unknown_LogicType)
  562. return op1type;
  563. else if (op2type != Unknown_LogicType)
  564. return op2type;
  565. else
  566. return Unknown_LogicType;
  567. }
  568. default:
  569. return Unknown_LogicType;
  570. }
  571. }
  572. virtual int setParameterizedNames(int currentindex);
  573. bool isEqualityCondition(IProperties * map, const char * first, const char * second);
  574. virtual bool containsEqualityCondition(IProperties * map, const char * first, const char * second);
  575. static bool containsEqualityCondition(ISQLExpression* operand, IProperties * map, const char * first, const char * second);
  576. void toECLStringTranslateSource(
  577. StringBuffer & eclStr,
  578. IProperties * map,
  579. bool ignoreMisTranslations,
  580. bool forHaving,
  581. bool funcParam,
  582. bool countFuncParam);
  583. SQLExpressionType getExpType() { return Binary_ExpressionType;}
  584. SQLBinaryExpression(int op,ISQLExpression* operand1,ISQLExpression* operand2);
  585. virtual ~SQLBinaryExpression();
  586. bool containsKey(const char * colname);
  587. void toString(StringBuffer & targetstr, bool fullOutput);
  588. int getExpressionsCount();
  589. int getOp() const
  590. {
  591. return op;
  592. }
  593. void setOp(int op)
  594. {
  595. this->op = op;
  596. }
  597. ISQLExpression* getOperand1() const
  598. {
  599. return operand1;
  600. }
  601. void setOperand1(ISQLExpression* operand1)
  602. {
  603. this->operand1 = operand1;
  604. }
  605. ISQLExpression* getOperand2() const
  606. {
  607. return operand2;
  608. }
  609. void setOperand2(ISQLExpression* operand2)
  610. {
  611. this->operand2 = operand2;
  612. }
  613. bool setValuePlaceHolderType(const char * ecltype){return false;}
  614. bool hasPlaceHolder(){ return false;}
  615. const char * getPlaceHolderType() {return nullptr;}
  616. private:
  617. const char * getOpStr();
  618. ISQLExpression* operand1;
  619. ISQLExpression* operand2;
  620. int op;
  621. };
  622. /*************************************************************************************************/
  623. class SQLParameterPlaceHolderExpression : implements ISQLExpression
  624. {
  625. public:
  626. static const char * PARAMPREFIX;
  627. IMPLEMENT_IINTERFACE;
  628. void getExpressionFromColumnName(const char * colname, StringBuffer & str) { return; }
  629. void getUniqueExpressionColumnNames(StringArray & uniquenames) { return; }
  630. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  631. {
  632. StringBuffer defaulteclvalue;
  633. switch (op)
  634. {
  635. case AND_SYM:
  636. case OR_SYM:
  637. eclstr.append( "BOOLEAN ");
  638. defaulteclvalue.set(" FALSE ");
  639. break;
  640. case DIVIDE:
  641. case MINUS:
  642. case MOD:
  643. case ASTERISK:
  644. case GTH:
  645. case GET:
  646. case LTH:
  647. case LET:
  648. case PLUS:
  649. case EQ_SYM:
  650. case NOT_EQ:
  651. case IN_SYM:
  652. case NOT_IN:
  653. {
  654. switch (sibtype)
  655. {
  656. case Bool_LogicType:
  657. eclstr.append( "BOOLEAN ");
  658. defaulteclvalue.set(" FALSE ");
  659. break;
  660. case Numeric_LogicType:
  661. case Integer_LogicType:
  662. eclstr.append( "INTEGER ");
  663. defaulteclvalue.set(" 0 ");
  664. break;
  665. case Decimal_LogicType:
  666. eclstr.append( "DECIMAL ");
  667. defaulteclvalue.set(" 0.0 ");
  668. break;
  669. case QSstring_LogicType:
  670. eclstr.append( "QSTRING ");
  671. defaulteclvalue.set(" '' ");
  672. break;
  673. case Unicode_LogicType:
  674. eclstr.append( "UNICODE");
  675. defaulteclvalue.set(" '' ");
  676. break;
  677. case String_LogicType:
  678. default:
  679. eclstr.append( "STRING ");
  680. defaulteclvalue.set(" '' ");
  681. break;
  682. }
  683. break;
  684. }
  685. default:
  686. eclstr.append( "STRING ");
  687. defaulteclvalue.set(" '' ");
  688. break;
  689. }
  690. eclstr.append(value.str());
  691. eclstr.append(" := ");
  692. eclstr.append(defaulteclvalue.str());
  693. eclstr.append(" : STORED('");
  694. eclstr.append(value.str());
  695. eclstr.append("');\n");
  696. }
  697. virtual SQLLogicType getLogicType(){return Unknown_LogicType;}
  698. virtual int setParameterizedNames(int currentindex);
  699. void toECLStringTranslateSource(
  700. StringBuffer & eclStr,
  701. IProperties * map,
  702. bool ignoreMisTranslations,
  703. bool forHaving,
  704. bool funcParam,
  705. bool countFuncParam)
  706. {
  707. eclStr.append( value.str() );
  708. }
  709. SQLExpressionType getExpType()
  710. {
  711. return ParameterPlaceHolder_ExpressionType;
  712. }
  713. SQLParameterPlaceHolderExpression();
  714. virtual ~SQLParameterPlaceHolderExpression ();
  715. bool containsKey(const char * colname) {return false;}
  716. void toString(StringBuffer & targetstr, bool fullOutput);
  717. int getExpressionsCount() {return 0;}
  718. bool setValuePlaceHolderType(const char * ecltype){return false;}
  719. bool hasPlaceHolder(){ return false;}
  720. const char * getPlaceHolderType() {return nullptr;}
  721. private:
  722. int index;
  723. StringBuffer value;
  724. };
  725. /*************************************************************************************************/
  726. class SQLFunctionExpression : public ISQLExpression
  727. {
  728. public:
  729. IMPLEMENT_IINTERFACE;
  730. void getExpressionFromColumnName(const char * colname, StringBuffer & str)
  731. {
  732. StringBuffer paramlist;
  733. StringBuffer paramresult;
  734. for (int i = 0; i < params.length(); i++)
  735. {
  736. params.item(i).getExpressionFromColumnName(colname, paramresult.clear());
  737. if (paramresult.length() <= 0)
  738. return;
  739. if ( i > 0 )
  740. paramlist.append(", ");
  741. paramlist.append(paramresult);
  742. }
  743. if (paramlist.length()>0)
  744. str.appendf(" %s( %s ) ", function.eclFunctionName, paramlist.str());
  745. }
  746. void getUniqueExpressionColumnNames(StringArray & uniquenames)
  747. {
  748. ForEachItemIn(paramidx , params)
  749. {
  750. ISQLExpression & param = params.item(paramidx);
  751. param.getUniqueExpressionColumnNames(uniquenames);
  752. }
  753. }
  754. void eclDeclarePlaceHolders(StringBuffer & eclstr, int op, int sibtype)
  755. {
  756. ForEachItemIn(paramidx , params)
  757. {
  758. ISQLExpression & param = params.item(paramidx);
  759. param.eclDeclarePlaceHolders(eclstr, op, sibtype);
  760. }
  761. }
  762. SQLLogicType getLogicType()
  763. {
  764. if (strcmp(function.returnType,"NUMERIC")==0)
  765. {
  766. if (params.length()>0)
  767. return params.item(0).getLogicType();
  768. else
  769. return Numeric_LogicType;
  770. }
  771. else if (strcmp(function.returnType,"INTEGER")==0)
  772. return Integer_LogicType;
  773. else
  774. return String_LogicType;
  775. }
  776. int setParameterizedNames(int currentindex);
  777. void toECLStringTranslateSource(
  778. StringBuffer & eclStr,
  779. IProperties * map,
  780. bool ignoreMisTranslations,
  781. bool forHaving,
  782. bool funcParam,
  783. bool countFuncParam);
  784. SQLExpressionType getExpType() { return Function_ExpressionType;}
  785. SQLFunctionExpression(const char* funcname);
  786. SQLFunctionExpression(const char* funcname, const IArrayOf<ISQLExpression> &params);
  787. virtual ~SQLFunctionExpression();
  788. bool containsKey(const char* colname);
  789. void toString(StringBuffer & targetstr, bool fullOutput);
  790. void setName(const char * funcname)
  791. {
  792. name.set(funcname);
  793. }
  794. void setNameAndDefaultAlias(const char * funcname)
  795. {
  796. name.set(funcname);
  797. alias.set(funcname);
  798. alias.append("Out");
  799. }
  800. const char * getName()
  801. {
  802. return name.str();
  803. }
  804. ECLFunctionDefCfg getFunction() const
  805. {
  806. return function;
  807. }
  808. void setFunction(const char * funcname)
  809. {
  810. this->function = ECLFunctions::getEclFuntionDef(funcname);
  811. }
  812. IArrayOf<ISQLExpression> * getParams()
  813. {
  814. return &params;
  815. }
  816. virtual const char * getAlias();
  817. virtual void setAlias(const char * alias);
  818. virtual const char * getNameOrAlias();
  819. void addParams(ISQLExpression * param)
  820. {
  821. this->params.append(*param);
  822. }
  823. int getExpressionsCount();
  824. bool isDistinct() {return distinct;}
  825. void setDistinct(bool d) {distinct = d;}
  826. bool setValuePlaceHolderType(const char * ecltype){return false;}
  827. bool hasPlaceHolder(){ return false;}
  828. const char * getPlaceHolderType() {return nullptr;}
  829. private:
  830. bool distinct;
  831. StringBuffer name;
  832. StringBuffer alias;
  833. ECLFunctionDefCfg function;
  834. IArrayOf<ISQLExpression> params;
  835. void getParamsString(StringBuffer & targetstr, bool fullOutput);
  836. };
  837. #endif /* SQLEXPRESSION_HPP_ */