HPCCSQLTreeWalker.cpp 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522
  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. #include "HPCCSQLTreeWalker.hpp"
  14. void trimSingleQuotes(StringBuffer & quotedString)
  15. {
  16. int len = quotedString.length();
  17. if (len)
  18. {
  19. quotedString.trim();
  20. if (quotedString.charAt(0) == '\'' && quotedString.charAt(len-1) == '\'')
  21. {
  22. quotedString.remove(len-1, 1);
  23. quotedString.remove(0, 1);
  24. }
  25. }
  26. }
  27. void HPCCSQLTreeWalker::limitTreeWalker(pANTLR3_BASE_TREE limitAST)
  28. {
  29. char * limit = NULL;
  30. char * offset = NULL;
  31. if ( limitAST != NULL )
  32. {
  33. int childrenCount = limitAST->getChildCount(limitAST);
  34. if (childrenCount > 0)
  35. {
  36. pANTLR3_BASE_TREE limitnode = (pANTLR3_BASE_TREE)(limitAST->getChild(limitAST, 0));
  37. limit = (char *)limitnode->toString(limitnode)->chars;
  38. setLimit(atoi(limit));
  39. if (childrenCount == 2)
  40. {
  41. pANTLR3_BASE_TREE offsetnode = (pANTLR3_BASE_TREE)limitAST->getChild(limitAST, 1);
  42. if (offsetnode != NULL)
  43. {
  44. offset = (char *)offsetnode->toString(offsetnode)->chars;
  45. setOffset(atoi(offset));
  46. }
  47. }
  48. else if (childrenCount > 2)
  49. throw MakeStringException(-1," Extra token found after LIMIT/OFFSET directive.");
  50. }
  51. else
  52. throw MakeStringException(-1," Missing LIMIT value");
  53. }
  54. }
  55. void HPCCSQLTreeWalker::fromTreeWalker(pANTLR3_BASE_TREE fromsqlAST)
  56. {
  57. char * tablename = NULL;
  58. char * tablealias = NULL;
  59. if ( fromsqlAST != NULL )
  60. {
  61. int childrenCount = fromsqlAST->getChildCount(fromsqlAST);
  62. for ( int i = 0; i < childrenCount; i++ )
  63. {
  64. Owned<SQLTable> temptable = SQLTable::createSQLTable();
  65. pANTLR3_BASE_TREE ithchild = (pANTLR3_BASE_TREE)(fromsqlAST->getChild(fromsqlAST, i));
  66. ANTLR3_UINT32 tokenType = ithchild->getType(ithchild);
  67. pANTLR3_BASE_TREE onclausenode = NULL;
  68. SQLJoinType jointype = SQLJoinTypeUnknown;
  69. if (tokenType == TOKEN_OUTTER_JOIN || tokenType == TOKEN_INNER_JOIN)
  70. {
  71. if (tokenType == TOKEN_OUTTER_JOIN)
  72. jointype = SQLJoinTypeOuter;
  73. else if (tokenType == TOKEN_INNER_JOIN)
  74. jointype = SQLJoinTypeInner;
  75. int joinNodeChildcount = ithchild->getChildCount(ithchild);
  76. if (joinNodeChildcount < 2 )
  77. throw MakeStringException(-1, "Join statement appears to be incomplete");
  78. onclausenode = (pANTLR3_BASE_TREE) ithchild->getFirstChildWithType(ithchild, ON);
  79. ithchild = (pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, 0));
  80. tokenType = ithchild->getType(ithchild);
  81. }
  82. if (tokenType == ID || tokenType == ABSOLUTE_FILE_ID)
  83. {
  84. tablename = (char *)ithchild->toString(ithchild)->chars;
  85. int tablechildcount = ithchild->getChildCount(ithchild);
  86. for ( int tabchildidx = 0; tabchildidx < tablechildcount; tabchildidx++ )
  87. {
  88. pANTLR3_BASE_TREE tablechild = (pANTLR3_BASE_TREE)ithchild->getChild(ithchild, tabchildidx);
  89. ANTLR3_UINT32 childType = tablechild->getType(tablechild);
  90. if (childType == TOKEN_ALIAS)
  91. {
  92. pANTLR3_BASE_TREE alias = (pANTLR3_BASE_TREE)tablechild->getChild(tablechild, 0);
  93. tablealias = (char *)alias->toString(alias)->chars;
  94. temptable->setAlias(tablealias);
  95. }
  96. else if ( childType == TOKEN_INDEX_HINT)
  97. {
  98. pANTLR3_BASE_TREE indexhint = (pANTLR3_BASE_TREE)tablechild->getChild(tablechild, 0);
  99. tablealias = (char *)indexhint->toString(indexhint)->chars;
  100. const char * fullindexhintname = tmpHPCCFileCache->cacheHpccFileByName(tablealias);
  101. if (!fullindexhintname || !*fullindexhintname)
  102. ERRLOG("Invalid index hint found: %s\n", tablealias);
  103. else
  104. temptable->setIndexhint(fullindexhintname);
  105. }
  106. else if ( childType == TOKEN_AVOID_INDEX)
  107. {
  108. temptable->setIndexhint("0");
  109. }
  110. else if ( childType == TOKEN_TABLE_SCHEMA && tablechild->getChildCount(tablechild) == 1)
  111. {
  112. pANTLR3_BASE_TREE schema = (pANTLR3_BASE_TREE)tablechild->getChild(tablechild, 0);
  113. WARNLOG("Table schema detected but ignored: %s\n", (char *)schema->toString(schema)->chars);
  114. }
  115. else
  116. {
  117. ERRLOG("Invalid node found in table node: %s\n", (char *)tablechild->toString(tablechild)->chars);
  118. }
  119. }
  120. const char * fullTableName = tmpHPCCFileCache->cacheHpccFileByName(tablename);
  121. if (!fullTableName || !*fullTableName)
  122. throw MakeStringException(-1, "Invalid table name or file type not supported: %s\n", tablename);
  123. else
  124. temptable->setName(fullTableName);
  125. tableList.append(*temptable.getLink());
  126. if (jointype == -1 && i > 0) //multiple tables
  127. {
  128. temptable->setNewJoin(SQLJoinTypeImplicit);
  129. }
  130. if (jointype != SQLJoinTypeUnknown)
  131. {
  132. Owned<SQLJoin> join = SQLJoin::creatSQLJoin(jointype);
  133. if (onclausenode)
  134. join->setOnClause(expressionTreeWalker((pANTLR3_BASE_TREE)onclausenode->getChild(onclausenode, 0), NULL));
  135. else
  136. throw MakeStringException(-1, "Join statement appears to be missing on clause");
  137. temptable->setJoin(join.getLink());
  138. }
  139. }
  140. }
  141. }
  142. }
  143. ISQLExpression * HPCCSQLTreeWalker::expressionTreeWalker(pANTLR3_BASE_TREE exprAST, pANTLR3_BASE_TREE parent)
  144. {
  145. Owned<ISQLExpression> tmpexp;
  146. if ( exprAST != NULL )
  147. {
  148. Owned<ISQLExpression> leftexp;
  149. Owned<ISQLExpression> rightexp;
  150. bool checkForAlias = false;
  151. ANTLR3_UINT32 exptype = exprAST->getType(exprAST);
  152. switch (exptype)
  153. {
  154. case TOKEN_LISTEXP:
  155. {
  156. Owned<SQLListExpression> tmpexp2 = new SQLListExpression();
  157. for (int i = 0; i < exprAST->getChildCount(exprAST); i++)
  158. {
  159. pANTLR3_BASE_TREE ithentry = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, i));
  160. tmpexp2->appendEntry(expressionTreeWalker(ithentry, exprAST));
  161. }
  162. tmpexp.setown(tmpexp2.getLink());
  163. break;
  164. }
  165. case TOKEN_FUNCEXP:
  166. {
  167. if (exprAST->getChildCount(exprAST) <= 0)
  168. {
  169. if (parent != NULL)
  170. throw MakeStringException(-1, "Error detected while parsing SQL around: %s", (char *)parent->toString(parent)->chars);
  171. else
  172. throw MakeStringException(-1, "Error detected while parsing SQL.");
  173. }
  174. pANTLR3_BASE_TREE tmpNode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0));
  175. Owned<SQLFunctionExpression> tmpexp2 = new SQLFunctionExpression((char *)tmpNode->toString(tmpNode)->chars);
  176. for (int i = 1; i < exprAST->getChildCount(exprAST); i++)
  177. {
  178. pANTLR3_BASE_TREE ithcolumnattributenode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, i));
  179. ANTLR3_UINT32 columnattributetype = ithcolumnattributenode->getType(ithcolumnattributenode);
  180. if (columnattributetype == TOKEN_ALIAS)
  181. {
  182. pANTLR3_BASE_TREE ithcolumnaliasnode = (pANTLR3_BASE_TREE)(ithcolumnattributenode->getChild(ithcolumnattributenode, 0));
  183. tmpexp2->setAlias((char *)ithcolumnaliasnode->toString(ithcolumnaliasnode)->chars);
  184. }
  185. else if (columnattributetype == DISTINCT)
  186. {
  187. tmpexp2->setDistinct(true);
  188. }
  189. else if (columnattributetype == ASTERISK)
  190. {
  191. ForEachItemIn(tableidx, tableList)
  192. {
  193. const char * tablename = tableList.item(tableidx).getName();
  194. HPCCFilePtr file = tmpHPCCFileCache->getHpccFileByName(tablename);
  195. if (file)
  196. {
  197. IArrayOf<HPCCColumnMetaData> * cols = file->getColumns();
  198. ForEachItemIn(colidx, *cols)
  199. {
  200. HPCCColumnMetaData col = cols->item(colidx);
  201. Owned<ISQLExpression> fve = new SQLFieldValueExpression(file->getFullname(),col.getColumnName());
  202. tmpexp2->addParams(fve.getLink());
  203. }
  204. }
  205. }
  206. }
  207. else
  208. {
  209. tmpexp2->addParams(expressionTreeWalker(ithcolumnattributenode, exprAST));
  210. }
  211. }
  212. tmpexp2->setName((char *)tmpNode->toString(tmpNode)->chars);
  213. tmpexp.setown(tmpexp2.getLink());
  214. break;
  215. }
  216. case TOKEN_PARAMPLACEHOLDER:
  217. {
  218. tmpexp.setown(new SQLParameterPlaceHolderExpression());
  219. break;
  220. }
  221. case TRUE_SYM:
  222. case FALSE_SYM:
  223. tmpexp.setown(new SQLValueExpression(exptype, (char *)exprAST->toString(exprAST)->chars));
  224. tmpexp->setName("ConstBool");
  225. tmpexp->setECLType("BOOLEAN");
  226. checkForAlias = true;
  227. break;
  228. case REAL_NUMBER:
  229. tmpexp.setown(new SQLValueExpression(exptype, (char *)exprAST->toString(exprAST)->chars));
  230. tmpexp->setName("ConstNum");
  231. tmpexp->setECLType("REAL");
  232. checkForAlias = true;
  233. break;
  234. case INTEGER_NUM:
  235. case HEX_DIGIT:
  236. tmpexp.setown(new SQLValueExpression(exptype, (char *)exprAST->toString(exprAST)->chars));
  237. tmpexp->setName("ConstNum");
  238. tmpexp->setECLType("INTEGER");
  239. checkForAlias = true;
  240. break;
  241. //case QUOTED_STRING:
  242. case TEXT_STRING:
  243. tmpexp.setown(new SQLValueExpression(exptype, (char *)exprAST->toString(exprAST)->chars));
  244. tmpexp->setName("ConstStr");
  245. tmpexp->setECLType("STRING");
  246. checkForAlias = true;
  247. break;
  248. case IN_SYM:
  249. case NOT_IN:
  250. case EQ_SYM:
  251. case NOT_EQ:
  252. case AND_SYM:
  253. case OR_SYM:
  254. case MINUS:
  255. case PLUS:
  256. case MOD_SYM:
  257. case DIVIDE:
  258. case ASTERISK:
  259. case LET:
  260. case GET:
  261. case GTH:
  262. case LTH:
  263. case LIKE_SYM:
  264. case NOT_LIKE:
  265. leftexp.set(expressionTreeWalker((pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0)),exprAST));
  266. rightexp.set(expressionTreeWalker((pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 1)),exprAST));
  267. tmpexp.setown( new SQLBinaryExpression(exptype,leftexp, rightexp));
  268. if (parameterizeStaticValues)
  269. {
  270. if ( leftexp->getExpType() == Value_ExpressionType && rightexp->getExpType() != Value_ExpressionType)
  271. {
  272. leftexp->setValuePlaceHolderType(rightexp->getECLType());
  273. paramList.append(*leftexp.getLink());
  274. }
  275. else if ( rightexp->getExpType() == Value_ExpressionType && leftexp->getExpType() != Value_ExpressionType)
  276. {
  277. rightexp->setValuePlaceHolderType(leftexp->getECLType());
  278. paramList.append(*rightexp.getLink());
  279. }
  280. }
  281. if (exptype == LIKE_SYM || exptype == NOT_LIKE)
  282. {
  283. if (rightexp->getExpType() == Value_ExpressionType)
  284. {
  285. SQLValueExpression * valexp = static_cast<SQLValueExpression *>(rightexp.get());
  286. valexp->setIsWildCardPattern(true);
  287. }
  288. }
  289. break;
  290. case ISNOTNULL:
  291. case ISNULL:
  292. case NEGATION:
  293. case NOT_SYM:
  294. {
  295. tmpexp.setown(new SQLUnaryExpression(expressionTreeWalker((pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0)),exprAST), exptype ));
  296. break;
  297. }
  298. //case PARENEXP: ANTLR idiosyncrasy prevented using imaginary token as root node
  299. case LPAREN:
  300. tmpexp.setown(new SQLParenthesisExpression(expressionTreeWalker((pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0)),exprAST)));
  301. break;
  302. case TOKEN_COLUMNWILDCARD:
  303. {
  304. if (exprAST->getChildCount(exprAST) > 0)
  305. {
  306. pANTLR3_BASE_TREE table = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0));
  307. const char * tablename = (char *)table->toString(table)->chars;
  308. if (tablename == NULL)
  309. {
  310. tmpexp.setown(new SQLFieldsExpression(true));
  311. }
  312. else
  313. {
  314. //SEARCH FOR possible table name (this could be an aliased parent)
  315. bool found = false;
  316. ForEachItemIn(tableidx, tableList)
  317. {
  318. const char * translated = tableList.item(tableidx).translateIfAlias(tablename);
  319. if (translated && *translated)
  320. {
  321. tmpexp.setown(new SQLFieldsExpression(translated));
  322. found = true;
  323. break;
  324. }
  325. }
  326. if (found == false)
  327. {
  328. throw MakeStringException(-1, "INVALID TABLE NAME FOUND: %s\n", tablename );
  329. }
  330. }
  331. }
  332. else
  333. tmpexp.setown(new SQLFieldsExpression(true));
  334. break;
  335. }
  336. case TOKEN_COLUMN:
  337. {
  338. const char * colparent = NULL;
  339. const char * colname = NULL;
  340. int nodeChildrenCount = exprAST->getChildCount(exprAST);
  341. pANTLR3_BASE_TREE tmpNode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0));
  342. colname = (char *)tmpNode->toString(tmpNode)->chars;
  343. Owned<SQLFieldValueExpression> tmpfve = new SQLFieldValueExpression();
  344. tmpfve->setName(colname);
  345. for (int i = 1; i < nodeChildrenCount; i++)
  346. {
  347. pANTLR3_BASE_TREE ithcolumnattributenode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, i));
  348. ANTLR3_UINT32 columnattributetype = ithcolumnattributenode->getType(ithcolumnattributenode);
  349. if (columnattributetype == DESC)
  350. {
  351. tmpfve->setAscending(false);
  352. }
  353. else if (columnattributetype == TOKEN_ALIAS)
  354. {
  355. pANTLR3_BASE_TREE ithcolumnaliasnode = (pANTLR3_BASE_TREE)(ithcolumnattributenode->getChild(ithcolumnattributenode, 0));
  356. tmpfve->setAlias((char *)ithcolumnaliasnode->toString(ithcolumnaliasnode)->chars);
  357. }
  358. else
  359. {
  360. colparent = (char *)ithcolumnattributenode->toString(ithcolumnattributenode)->chars;
  361. tmpfve->setParentTableName(colparent);
  362. }
  363. }
  364. if (colparent == NULL)
  365. {
  366. if (tableList.length() == 1)
  367. {
  368. colparent = tableList.item(0).getName();
  369. tmpfve->setParentTableName(colparent);
  370. }
  371. else
  372. throw MakeStringException(-1, "AMBIGUOUS COLUMN FOUND: %s\n", colname);
  373. }
  374. else
  375. {
  376. //SEARCH FOR possible table name (this could be an aliased parent)
  377. bool found = false;
  378. ForEachItemIn(tableidx, tableList)
  379. {
  380. const char * translated = tableList.item(tableidx).translateIfAlias(colparent);
  381. if (translated && *translated)
  382. {
  383. tmpfve->setParentTableName(translated);
  384. found = true;
  385. break;
  386. }
  387. }
  388. if (found == false)
  389. {
  390. StringBuffer msg;
  391. tmpfve->toString(msg, true);
  392. throw MakeStringException(-1, "INVALID COLUMN FOUND (parent table unknown): %s\n", msg.str() );
  393. }
  394. }
  395. //Sets the ecltype of the field.
  396. verifyColumn(tmpfve);
  397. tmpexp.setown(tmpfve.getLink());
  398. break;
  399. }
  400. case TOKEN_COLUMN_DEF:
  401. {
  402. const char * colname = NULL;
  403. int nodeChildrenCount = exprAST->getChildCount(exprAST);
  404. if (nodeChildrenCount != 2)
  405. throw MakeStringException(-1, "Invalid column definition encountered");
  406. pANTLR3_BASE_TREE tmpNode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0));
  407. Owned<SQLFieldValueExpression> tmpfve = new SQLFieldValueExpression();
  408. tmpfve->setName((char *)tmpNode->toString(tmpNode)->chars);
  409. tmpNode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 1));
  410. ANTLR3_UINT32 columnattributetype = tmpNode->getType(tmpNode);
  411. bool isunsigned = false;
  412. bool isbinary = false;
  413. const char * length = NULL;
  414. int lengthi = 0;
  415. const char * presicion = NULL;
  416. StringBuffer strList;
  417. int typechildcount = tmpNode->getChildCount(tmpNode);
  418. for (int typechildindex = 0; typechildindex < typechildcount; typechildindex++)
  419. {
  420. pANTLR3_BASE_TREE tmpCNode = (pANTLR3_BASE_TREE)(tmpNode->getChild(tmpNode, typechildindex));
  421. ANTLR3_UINT32 typechildtype = tmpCNode->getType(tmpCNode);
  422. if (typechildtype == UNSIGNED_SYM)
  423. isunsigned = true;
  424. else if (typechildtype == INTEGER_NUM)
  425. {
  426. length = (char *)tmpCNode->toString(tmpCNode)->chars;
  427. lengthi = atoi(length);
  428. if (tmpCNode->getChildCount(tmpCNode)>0)
  429. {
  430. tmpCNode = (pANTLR3_BASE_TREE)(tmpCNode->getChild(tmpCNode, 0));
  431. presicion = (char *)tmpCNode->toString(tmpCNode)->chars;
  432. }
  433. }
  434. else if (typechildtype == TOKEN_PROC_PARAMS)
  435. {
  436. int strListCount = tmpCNode->getChildCount(tmpCNode);
  437. for (int strListIndex = 0; strListIndex < strListCount; strListIndex++)
  438. {
  439. pANTLR3_BASE_TREE strValue = (pANTLR3_BASE_TREE)(tmpCNode->getChild(tmpCNode, strListIndex));
  440. strList.appendf("%s%s", (char *)strValue->toString(strValue)->chars, (strListIndex < strListCount-1) ? "," : "");
  441. }
  442. }
  443. else if (typechildtype == BINARY_SYM)
  444. {
  445. isbinary = true;
  446. }
  447. else
  448. throw MakeStringException(-1, "\n Unexpected type option encountered: %s ", (char *)tmpCNode->toString(tmpCNode)->chars);
  449. }
  450. StringBuffer ecltype;
  451. switch (columnattributetype)
  452. {
  453. case BIT_SYM:
  454. ecltype.set("BOOlEAN");
  455. break;
  456. case TINYINT:
  457. ecltype.setf("%s", isunsigned ? "UNSIGNED1" : "INTEGER1");
  458. break;
  459. case SMALLINT:
  460. ecltype.setf("%s", isunsigned ? "UNSIGNED2" : "INTEGER2");
  461. break;
  462. case MEDIUMINT:
  463. ecltype.setf("%s", isunsigned ? "UNSIGNED3" : "INTEGER3");
  464. break;
  465. case INTEGER_SYM:
  466. ecltype.setf("%s%s", isunsigned ? "UNSIGNED" : "INTEGER", lengthi > 0 && lengthi < 4 ? length : "4");
  467. break;
  468. case BIGINT_SYM:
  469. ecltype.setf("%s%s", isunsigned ? "UNSIGNED" : "INTEGER", lengthi > 0 && lengthi < 8 ? length : "8");
  470. break;
  471. case REAL_SYM:
  472. ecltype.setf("REAL%s", lengthi < 3 ? "4" : "8"); //Ecl real can only be 8 or 4
  473. break;
  474. case DOUBLE_SYM:
  475. ecltype.set("REAL8"); //Ecl real can only be 8 or 4
  476. break;
  477. case FLOAT_SYM:
  478. ecltype.set("REAL4"); //Ecl real can only be 8 or 4
  479. break;
  480. case DECIMAL_SYM:
  481. ecltype.setf("%sDECIMAL", isunsigned ? "UNSIGNED " : "");//A packed decimal value of n total digits (to a maximum of 32).
  482. //If the _y value is present, it defines the number of decimal places
  483. if (lengthi > 0)
  484. {
  485. if (lengthi >= 32)
  486. ecltype.append("32");
  487. else
  488. ecltype.append(length);
  489. if (presicion && *presicion)
  490. ecltype.appendf("_%s", presicion);
  491. }
  492. break;
  493. case NUMERIC_SYM:
  494. throw MakeStringException(-1, "Ambiguous 'NUMERIC' column type encountered, please specify actual type.");
  495. break;
  496. case DATE_SYM:
  497. ecltype.set("std.Date.DATE_T");
  498. break;
  499. case TIME_SYM:
  500. ecltype.set("std.Date.TIME_T");
  501. break;
  502. case TIMESTAMP_SYM:
  503. ecltype.set("DATA8");
  504. break;
  505. case DATETIME_SYM:
  506. ecltype.set("DATETIME_T");
  507. break;
  508. case YEAR_SYM:
  509. throw MakeStringException(-1, "'YEAR' column type not supported in ECL.");
  510. break;
  511. case CHAR_SYM:
  512. ecltype.setf("STRING%s", lengthi > 0 && lengthi < 255 ? length : "255");
  513. break;
  514. case VARCHAR_SYM:
  515. ecltype.setf("STRING%s", lengthi > 0 && lengthi < 65535 ? length : "65535");
  516. break;
  517. case BINARY_SYM:
  518. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 255 ? length : "255"); //DATA[n] A "packed hexadecimal" data block of n bytes,
  519. ecltype.set("DATA");
  520. break;
  521. case VARBINARY_SYM:
  522. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 255 ? length : "255"); //DATA[n] A "packed hexadecimal" data block of n bytes,
  523. ecltype.set("DATA");
  524. break;
  525. case TINYBLOB_SYM: //255 max size
  526. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 255 ? length : "255"); //DATA[n] A "packed hexadecimal" data block of n bytes,
  527. ecltype.set("DATA");
  528. break;
  529. case BLOB_SYM://65535 max size
  530. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 65535 ? length : "65535"); //DATA[n] A "packed hexadecimal" data block of n bytes,
  531. ecltype.set("DATA");
  532. break;
  533. case MEDIUMBLOB_SYM: //16777215 max size
  534. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 16777215 ? length : "16777215");//DATA[n] A "packed hexadecimal" data block of n bytes,
  535. ecltype.set("DATA");
  536. break;
  537. case LONGBLOB_SYM://4294967295 max size
  538. //ecltype.setf("DATA%s", lengthi > 0 && lengthi < 4294967295 ? length : "4294967295");//DATA[n] A "packed hexadecimal" data block of n bytes,
  539. ecltype.set("DATA");
  540. break;
  541. case TINYTEXT_SYM:
  542. //ecltype.setf("%s%s", isbinary ? "DATA" : "STRING", lengthi > 0 && lengthi < 255? length : "255");
  543. ecltype.setf("%s", isbinary ? "DATA" : "STRING");
  544. break;
  545. case TEXT_SYM:
  546. //ecltype.setf("%s%s", isbinary ? "DATA" : "STRING", lengthi > 0 && lengthi < 65535 ? length : "65535");
  547. ecltype.setf("%s", isbinary ? "DATA" : "STRING");
  548. break;
  549. case MEDIUMTEXT_SYM:
  550. //ecltype.setf("%s%s", isbinary ? "DATA" : "STRING", lengthi > 0 && lengthi < 16777215 ? length : "16777215");
  551. ecltype.setf("%s", isbinary ? "DATA" : "STRING");
  552. break;
  553. case LONGTEXT_SYM:
  554. //ecltype.set("DATA"); // Should really be allowed to be a string - max len 4Gig
  555. ecltype.setf("%s", isbinary ? "DATA" : "STRING");
  556. break;
  557. case ENUM_SYM:
  558. if (strList.length())
  559. ecltype.setf("ENUM ( %s )", strList.str());
  560. else
  561. throw MakeStringException(-1, "\n Enumeration definition must contain at least one entry");
  562. break;
  563. case SET_SYM:
  564. if (strList.length())
  565. ecltype.setf("SET OF STRING");
  566. else
  567. throw MakeStringException(-1, "\n SET definition must contain at least one entry");
  568. break;
  569. default:
  570. throw MakeStringException(-1, "\n Unexpected/Unsupported SQL field type encountered");
  571. break;
  572. }
  573. tmpfve->setECLType(ecltype.str());
  574. tmpexp.setown(tmpfve.getLink());
  575. break;
  576. }
  577. default:
  578. throw MakeStringException(-1, "\n Unexpected expression node found : %s ", (char *)exprAST->toString(exprAST)->chars);
  579. break;
  580. }
  581. if (checkForAlias)
  582. {
  583. if(exprAST->getChildCount(exprAST) == 1)//Alias
  584. {
  585. pANTLR3_BASE_TREE tmpNode = (pANTLR3_BASE_TREE)(exprAST->getChild(exprAST, 0));
  586. ANTLR3_UINT32 columnattributetype = tmpNode->getType(tmpNode);
  587. if (columnattributetype == TOKEN_ALIAS && tmpNode->getChildCount(tmpNode) == 1)
  588. {
  589. pANTLR3_BASE_TREE ithcolumnaliasnode = (pANTLR3_BASE_TREE)(tmpNode->getChild(tmpNode, 0));
  590. tmpexp->setAlias((char *)ithcolumnaliasnode->toString(ithcolumnaliasnode)->chars);
  591. }
  592. else
  593. {
  594. throw MakeStringException(-1, "INVALID NODE: '%s' found while processing possible expression alias \n", (char *)tmpNode->toString(tmpNode)->chars);
  595. }
  596. }
  597. }
  598. }
  599. return tmpexp.getLink();
  600. }
  601. void HPCCSQLTreeWalker::createAndLoadStatementTreeWalker(pANTLR3_BASE_TREE clsqlAST)
  602. {
  603. if ( clsqlAST != NULL )
  604. {
  605. char * tokenText = NULL;
  606. if (clsqlAST->getChildCount(clsqlAST) != 2 || clsqlAST->getType(clsqlAST) != TOKEN_CREATE_LOAD_TABLE_STATEMENT)
  607. throw MakeStringException(-1, "\nError in Create and Load command(s). WsSQL requires CREATE command to be accompanied by a LOAD command.\n");
  608. pANTLR3_BASE_TREE createPart = (pANTLR3_BASE_TREE)(clsqlAST->getChild(clsqlAST, 0));
  609. if ( createPart->getType(createPart) == TOKEN_CREATE_TABLE)
  610. {
  611. int createPartCount = createPart->getChildCount(createPart);
  612. if (createPartCount >= 1)
  613. {
  614. pANTLR3_BASE_TREE newTableName = (pANTLR3_BASE_TREE)(createPart->getChild(createPart, 0));
  615. tokenText = (char *)newTableName->toString(newTableName)->chars;
  616. if (!tokenText || !*tokenText)
  617. throw MakeStringException(-1, "Error detected in CREATE and LOAD: New table name cannot be empty.");
  618. tableName.set(tokenText);
  619. for (int createAttributesIndex = 1; createAttributesIndex < createPartCount; createAttributesIndex++)
  620. {
  621. pANTLR3_BASE_TREE ithTableAttribute = (pANTLR3_BASE_TREE)(createPart->getChild(createPart, createAttributesIndex));
  622. ANTLR3_UINT32 ithTableAttributeType = ithTableAttribute->getType(ithTableAttribute);
  623. if ( ithTableAttributeType == TOKEN_DONOT_OVERWRITE)
  624. {
  625. overwrite = false;
  626. }
  627. else if (ithTableAttributeType == COMMENT_SYM)
  628. {
  629. pANTLR3_BASE_TREE commentNode = (pANTLR3_BASE_TREE)(ithTableAttribute->getChild(ithTableAttribute, 0));
  630. comment = (char *)commentNode->toString(commentNode)->chars;
  631. trimSingleQuotes(comment);
  632. }
  633. else if (ithTableAttributeType == TOKEN_COLUMN_DEF_LIST)
  634. {
  635. int fieldsCount = ithTableAttribute->getChildCount(ithTableAttribute);
  636. for (int fieldIndex = 0; fieldIndex < fieldsCount; fieldIndex++)
  637. {
  638. pANTLR3_BASE_TREE ithField = (pANTLR3_BASE_TREE)(ithTableAttribute->getChild(ithTableAttribute, fieldIndex));
  639. Owned<ISQLExpression> exp = expressionTreeWalker(ithField,NULL);
  640. if (exp.get())
  641. recordDefinition.appendf("%s\t%s;\n", exp->getECLType(), exp->getName());
  642. else
  643. throw MakeStringException(-1, "\nError in call list\n");
  644. }
  645. }
  646. }
  647. }
  648. else
  649. throw MakeStringException(-1, "Error detected in CREATE and LOAD: Missing CREATE information.");
  650. pANTLR3_BASE_TREE loadPart = (pANTLR3_BASE_TREE)(clsqlAST->getChild(clsqlAST, 1));
  651. if ( loadPart->getType(loadPart) == TOKEN_LOAD_TABLE)
  652. {
  653. int loadPartCount = loadPart->getChildCount(loadPart);
  654. if (loadPartCount < 2)
  655. throw MakeStringException(-1, "Error detected in CREATE and LOAD: Missing LOAD information.");
  656. pANTLR3_BASE_TREE loadPartIthChild = (pANTLR3_BASE_TREE)(loadPart->getChild(loadPart, 0));
  657. if (strcmp((char *)loadPartIthChild->toString(loadPartIthChild)->chars, tableName.str()) != 0)
  658. throw MakeStringException(-1, "Error detected in CREATE and LOAD: LOAD must target newly created table.");
  659. loadPartIthChild = (pANTLR3_BASE_TREE)(loadPart->getChild(loadPart, 1));
  660. sourceDataTableName = (char *)loadPartIthChild->toString(loadPartIthChild)->chars;
  661. trimSingleQuotes(sourceDataTableName);
  662. if (loadPartCount > 2)
  663. {
  664. for (int loadPartIndex = 2; loadPartIndex < loadPartCount; loadPartIndex++)
  665. {
  666. loadPartIthChild = (pANTLR3_BASE_TREE)(loadPart->getChild(loadPart, loadPartIndex));
  667. ANTLR3_UINT32 loadPartIthChildType = loadPartIthChild->getType(loadPartIthChild);
  668. if (loadPartIthChildType == TOKEN_LANDING_ZONE)
  669. {
  670. int sourcetypechildcount = loadPartIthChild->getChildCount(loadPartIthChild);
  671. if (sourcetypechildcount != 2)
  672. throw MakeStringException(-1, "Error detected in CREATE and LOAD: LOAD Landing Zone clause requires IP and Directory.");
  673. pANTLR3_BASE_TREE lzinfo = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, 0));
  674. landingZoneIP.set((char *)lzinfo->toString(lzinfo)->chars);
  675. trimSingleQuotes(landingZoneIP);
  676. lzinfo = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, 1));
  677. landingZonePath.set((char *)lzinfo->toString(lzinfo)->chars);
  678. trimSingleQuotes(landingZonePath);
  679. }
  680. else if (loadPartIthChildType == TYPE_SYM)
  681. {
  682. pANTLR3_BASE_TREE typeDeclaration = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, 0));
  683. sourceDataType.set((char *)typeDeclaration->toString(typeDeclaration)->chars);
  684. int sourcetypechildcount = typeDeclaration->getChildCount(typeDeclaration);
  685. if (sourcetypechildcount > 0)
  686. {
  687. sourceDataType.append('(');
  688. for (int sourcetypechildindex = 0; sourcetypechildindex < sourcetypechildcount; sourcetypechildindex++)
  689. {
  690. pANTLR3_BASE_TREE sourcetypechild = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, sourcetypechildindex));
  691. sourceDataType.append((char *)sourcetypechild->toString(sourcetypechild)->chars);
  692. sourceDataType.append(" = ");
  693. sourcetypechild = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, ++sourcetypechildindex));
  694. StringBuffer value((char *)sourcetypechild->toString(sourcetypechild)->chars);
  695. trimSingleQuotes(value);
  696. sourceDataType.append(value.str());
  697. if (sourcetypechildindex < sourcetypechildcount - 1)
  698. sourceDataType.append(", ");
  699. }
  700. sourceDataType.append(" )");
  701. }
  702. }
  703. else if (loadPartIthChildType == TOKEN_VARIABLE_FILE)
  704. {
  705. sourceDataType.setf("CSV");
  706. pANTLR3_BASE_TREE typeDeclaration = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, 0));
  707. int sourcetypechildcount = typeDeclaration->getChildCount(typeDeclaration);
  708. if (sourcetypechildcount > 0)
  709. {
  710. sourceDataType.append('(');
  711. for (int sourcetypechildindex = 0; sourcetypechildindex < sourcetypechildcount; sourcetypechildindex++)
  712. {
  713. pANTLR3_BASE_TREE sourcetypechild = (pANTLR3_BASE_TREE)(loadPartIthChild->getChild(loadPartIthChild, sourcetypechildindex));
  714. ANTLR3_UINT32 csvoption = sourcetypechild->getType(sourcetypechild);
  715. if (csvoption == TOKEN_VAR_SEPERATOR)
  716. {
  717. sourceDataType.append("SEPARATOR( ");
  718. }
  719. else if (csvoption == TOKEN_VAR_ESCAPED)
  720. {
  721. sourceDataType.append("ESCAPE( ");
  722. }
  723. else if (csvoption == TOKEN_VAR_ENCLOSED)
  724. {
  725. sourceDataType.append("QUOTE( ");
  726. }
  727. else if (csvoption == TOKEN_VAR_TERMINATOR)
  728. {
  729. sourceDataType.append("TERMINATOR( ");
  730. }
  731. else
  732. throw MakeStringException(-1, "Unknown variable file data type option encountered.");
  733. sourcetypechild = (pANTLR3_BASE_TREE)(sourcetypechild->getChild(sourcetypechild, 0));
  734. sourceDataType.append((char *)sourcetypechild->toString(sourcetypechild)->chars);
  735. sourceDataType.append(" )");
  736. if (sourcetypechildindex < sourcetypechildcount - 1)
  737. sourceDataType.append(", ");
  738. }
  739. sourceDataType.append(" )");
  740. }
  741. }
  742. }
  743. }
  744. }
  745. else
  746. throw MakeStringException(-1, "Error detected in CREATE and LOAD: LOAD clause not found.");
  747. }
  748. else
  749. throw MakeStringException(-1, "Error detected in CREATE and LOAD: CREATE clause not found.");
  750. }
  751. }
  752. void HPCCSQLTreeWalker::callStatementTreeWalker(pANTLR3_BASE_TREE callsqlAST)
  753. {
  754. char * tokenText = NULL;
  755. if ( callsqlAST != NULL )
  756. {
  757. int childrenCount = callsqlAST->getChildCount(callsqlAST);
  758. ANTLR3_UINT32 tokenType = callsqlAST->getType(callsqlAST);
  759. if (childrenCount >=1 && tokenType == TOKEN_CALL_STATEMENT)
  760. {
  761. pANTLR3_BASE_TREE procedurePart = (pANTLR3_BASE_TREE)(callsqlAST->getChild(callsqlAST, 0));
  762. if ( procedurePart->getType(procedurePart) == TOKEN_PROC_NAME)
  763. {
  764. int namepartcount = procedurePart->getChildCount(procedurePart);
  765. if (namepartcount >= 1)
  766. {
  767. pANTLR3_BASE_TREE procedureNameAST = (pANTLR3_BASE_TREE)(procedurePart->getChild(procedurePart, 0));
  768. tokenText = (char *)procedureNameAST->toString(procedureNameAST)->chars;
  769. procedureName.set(tokenText);
  770. if (namepartcount == 2)
  771. {
  772. procedureNameAST = (pANTLR3_BASE_TREE)(procedurePart->getChild(procedurePart, 1));
  773. tokenText = (char *)procedureNameAST->toString(procedureNameAST)->chars;
  774. querySetName.set(tokenText);
  775. }
  776. else if (namepartcount > 2)
  777. throw MakeStringException(-1, "Error detected in CALL: Invalid Procedure name.");
  778. }
  779. else
  780. throw MakeStringException(-1, "Error detected in CALL: Procedure name is empty.");
  781. }
  782. else
  783. throw MakeStringException(-1, "Error detected in CALL: Procedure name not found.");
  784. if (childrenCount == 2)
  785. {
  786. procedurePart = (pANTLR3_BASE_TREE)(callsqlAST->getChild(callsqlAST, 1));
  787. if ( procedurePart->getType(procedurePart) == TOKEN_PROC_PARAMS)
  788. {
  789. int paramCount = procedurePart->getChildCount(procedurePart);
  790. for ( int i = 0; i < paramCount; i++ )
  791. {
  792. pANTLR3_BASE_TREE ithchild = (pANTLR3_BASE_TREE)(procedurePart->getChild(procedurePart, i));
  793. ANTLR3_UINT32 tokenType = ithchild->getType(ithchild);
  794. tokenText = (char *)ithchild->toString(ithchild)->chars;
  795. Owned<ISQLExpression> exp = expressionTreeWalker(ithchild,NULL);
  796. if (exp.get())
  797. {
  798. //Call parameter strings have to be single quoted in order to be distinguished from
  799. //Identifiers, however, the string parameters passed to the stored procedures are not quoted.
  800. //If the content needs to be quoted, they have to be escaped, within the first set of single quotes.
  801. //The first set of single quotes are stripped here.
  802. if (tokenType == TEXT_STRING)
  803. {
  804. SQLValueExpression * valexp = static_cast<SQLValueExpression *>(exp.get());
  805. if (valexp)
  806. valexp->trimTextQuotes();
  807. }
  808. paramList.append(*exp.getLink());
  809. }
  810. else
  811. throw MakeStringException(-1, "\nError in call list\n");
  812. }
  813. }
  814. }
  815. else if (childrenCount > 2)
  816. throw MakeStringException(-1, "Error detected in CALL: Error in param list.");
  817. }
  818. else
  819. throw MakeStringException(-1, "\nError detected in CALL.");
  820. }
  821. }
  822. void HPCCSQLTreeWalker::selectStatementTreeWalker(pANTLR3_BASE_TREE selectsqlAST)
  823. {
  824. char * tokenText = NULL;
  825. if ( selectsqlAST != NULL )
  826. {
  827. int childrenCount = selectsqlAST->getChildCount(selectsqlAST);
  828. //processing the table list first helps process other portions in one pass
  829. pANTLR3_BASE_TREE fromchild = (pANTLR3_BASE_TREE) selectsqlAST->getFirstChildWithType(selectsqlAST, FROM);
  830. if (fromchild != NULL)
  831. fromTreeWalker(fromchild);
  832. for ( int i = 0; i < childrenCount; i++ )
  833. {
  834. pANTLR3_BASE_TREE ithchild = (pANTLR3_BASE_TREE)(selectsqlAST->getChild(selectsqlAST, i));
  835. ANTLR3_UINT32 tokenType = ithchild->getType(ithchild);
  836. tokenText = (char *)ithchild->toString(ithchild)->chars;
  837. switch (ithchild->getType(ithchild))
  838. {
  839. case SELECT:
  840. {
  841. int columnCount = ithchild->getChildCount(ithchild);
  842. for ( int i = 0; i < columnCount; i++ )
  843. {
  844. pANTLR3_BASE_TREE ithnode = (pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, i));
  845. ANTLR3_UINT32 tokenType = ithnode->getType(ithnode);
  846. if (tokenType == DISTINCT)
  847. {
  848. selectDistinct = true;
  849. }
  850. else
  851. {
  852. Owned<ISQLExpression> exp = expressionTreeWalker(ithnode,NULL);
  853. if (exp.get())
  854. selectList.append(*exp.getLink());
  855. else
  856. throw MakeStringException(-1, "\nError in select list\n");
  857. }
  858. }
  859. break;
  860. }
  861. case FROM:
  862. // FROM list is parsed first. See top of function.
  863. break;
  864. case WHERE:
  865. {
  866. Owned<ISQLExpression> logicexpression = expressionTreeWalker((pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, 0)),NULL);
  867. if (logicexpression.get())
  868. {
  869. SQLExpressionType expressiontype = logicexpression->getExpType();
  870. switch (expressiontype)
  871. {
  872. case Unary_ExpressionType:
  873. case Parenthesis_ExpressionType:
  874. case Value_ExpressionType:
  875. case Binary_ExpressionType:
  876. case Function_ExpressionType:
  877. whereClause.setown(logicexpression.getLink());
  878. break;
  879. case FieldValue_ExpressionType:
  880. case Fields_ExpressionType:
  881. case ParameterPlaceHolder_ExpressionType:
  882. default:
  883. {
  884. StringBuffer tmp;
  885. logicexpression->toString(tmp, false);
  886. throw MakeStringException(-1, "Invalid expression type detected in Where clause: %s", tmp.str());
  887. }
  888. break;
  889. }
  890. }
  891. else
  892. throw MakeStringException(-1, "Error in Where clause");
  893. break;
  894. }
  895. case GROUP_SYM:
  896. {
  897. int groupByCount = ithchild->getChildCount(ithchild);
  898. for ( int i = 0; i < groupByCount; i++ )
  899. {
  900. Owned<ISQLExpression> exp = expressionTreeWalker((pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, i)),NULL);
  901. if (!exp)
  902. throw MakeStringException(-1, "Error in order by list.");
  903. if (exp->getExpType() == FieldValue_ExpressionType)
  904. {
  905. SQLFieldValueExpression * fielvalexp = static_cast<SQLFieldValueExpression *>(exp.getLink());
  906. groupbyList.append(*fielvalexp);
  907. }
  908. else
  909. {
  910. StringBuffer fieldvalue;
  911. exp->toString(fieldvalue, true);
  912. throw MakeStringException(-1, "Encountered invalid entry '%s' in 'GROUP BY' clause", fieldvalue.str());
  913. }
  914. }
  915. break;
  916. }
  917. case HAVING:
  918. havingClause.setown(expressionTreeWalker((pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, 0)),NULL));
  919. break;
  920. case ORDER_SYM:
  921. {
  922. int orderByCount = ithchild->getChildCount(ithchild);
  923. for ( int i = 0; i < orderByCount; i++ )
  924. {
  925. Owned<ISQLExpression> exp = expressionTreeWalker((pANTLR3_BASE_TREE)(ithchild->getChild(ithchild, i)),NULL);
  926. if (!exp)
  927. throw MakeStringException(-1, "Error in order by list.");
  928. if (exp->getExpType() == FieldValue_ExpressionType)
  929. {
  930. SQLFieldValueExpression * fielvalexp = static_cast<SQLFieldValueExpression *>(exp.getLink());
  931. orderbyList.append(*fielvalexp);
  932. }
  933. else
  934. {
  935. StringBuffer fieldvalue;
  936. exp->toString(fieldvalue, true);
  937. throw MakeStringException(-1, "Encountered invalid entry '%s' in 'ORDER BY' clause", fieldvalue.str());
  938. }
  939. }
  940. break;
  941. }
  942. case LIMIT:
  943. limitTreeWalker(ithchild);
  944. break;
  945. default:
  946. throw MakeStringException(-1, "Error in SQL Statement.");
  947. break;
  948. }
  949. }
  950. }
  951. }
  952. void HPCCSQLTreeWalker::sqlTreeWalker(pANTLR3_BASE_TREE sqlAST)
  953. {
  954. pANTLR3_BASE_TREE firstchild = NULL;
  955. char * tokenText = NULL;
  956. if ( sqlAST != NULL && sqlAST->getChildCount(sqlAST) > 0)
  957. {
  958. pANTLR3_BASE_TREE firstchild = (pANTLR3_BASE_TREE)(sqlAST->getChild(sqlAST, 0));
  959. switch (firstchild->getType(firstchild))
  960. {
  961. case TOKEN_SELECT_STATEMENT:
  962. setSqlType(SQLTypeSelect);
  963. selectStatementTreeWalker(firstchild);
  964. break;
  965. case TOKEN_CALL_STATEMENT:
  966. setSqlType(SQLTypeCall);
  967. callStatementTreeWalker(firstchild);
  968. break;
  969. case TOKEN_CREATE_LOAD_TABLE_STATEMENT:
  970. setSqlType(SQLTypeCreateAndLoad);
  971. createAndLoadStatementTreeWalker(firstchild);
  972. break;
  973. default:
  974. setSqlType(SQLTypeUnknown);
  975. throw MakeStringException(-1, "Invalid sql tree root node found: %s\n", (char *)firstchild->toString(firstchild)->chars);
  976. break;
  977. }
  978. }
  979. else
  980. throw MakeStringException(-1, "Error could not parse SQL Statement.");
  981. }
  982. void HPCCSQLTreeWalker::assignParameterIndexes()
  983. {
  984. int paramIndex = 1;
  985. if (sqlType == SQLTypeSelect)
  986. {
  987. if (whereClause != NULL)
  988. paramIndex = whereClause->setParameterizedNames(paramIndex);
  989. if (havingClause != NULL)
  990. paramIndex = havingClause->setParameterizedNames(paramIndex);
  991. }
  992. else if (sqlType == SQLTypeCall)
  993. {
  994. ForEachItemIn(paramlistidx, paramList)
  995. {
  996. ISQLExpression * paramexp = &paramList.item(paramlistidx);
  997. paramIndex = paramexp->setParameterizedNames(paramIndex);
  998. }
  999. }
  1000. parameterizedCount = paramIndex - 1;
  1001. }
  1002. HPCCSQLTreeWalker::HPCCSQLTreeWalker() : sqlType(SQLTypeUnknown), parameterizeStaticValues(true), limit(-1)
  1003. ,offset(-1), selectDistinct(false)
  1004. ,overwrite(true), sourceDataType(""), parameterizedCount(-1)
  1005. {
  1006. normalizedSQL.clear();
  1007. }
  1008. HPCCSQLTreeWalker::HPCCSQLTreeWalker(pANTLR3_BASE_TREE ast, IEspContext &context, bool attemptParameterization) :
  1009. limit(-1), offset(-1), selectDistinct(false), overwrite(true), sourceDataType("FLAT")
  1010. {
  1011. parameterizeStaticValues = attemptParameterization;
  1012. normalizedSQL.clear();
  1013. StringBuffer username;
  1014. StringBuffer password;
  1015. context.getUserID(username);
  1016. context.getPassword(password);
  1017. tmpHPCCFileCache.setown(HPCCFileCache::createFileCache(username.str(), password.str()));
  1018. sqlTreeWalker(ast);
  1019. if (sqlType == SQLTypeSelect)
  1020. {
  1021. assignParameterIndexes();
  1022. expandWildCardColumn();
  1023. verifyColAndDisambiguateName();
  1024. }
  1025. else if (sqlType == SQLTypeCall)
  1026. {
  1027. assignParameterIndexes();
  1028. }
  1029. }
  1030. HPCCSQLTreeWalker::~HPCCSQLTreeWalker()
  1031. {
  1032. #if defined _DEBUG
  1033. fprintf(stderr, "\nDestroying hpccsql object\n");
  1034. #endif
  1035. switch(sqlType)
  1036. {
  1037. case SQLTypeSelect:
  1038. tableList.kill(false);
  1039. whereClause.clear();
  1040. havingClause.clear();
  1041. tmpHPCCFileCache.clear();
  1042. selectList.kill(false);
  1043. groupbyList.kill(false);
  1044. orderbyList.kill(false);
  1045. tableList.kill(false);
  1046. paramList.kill(false);
  1047. break;
  1048. case SQLTypeCall:
  1049. paramList.kill(false);
  1050. break;
  1051. default:
  1052. break;
  1053. }
  1054. }
  1055. void HPCCSQLTreeWalker::expandWildCardColumn()
  1056. {
  1057. ForEachItemIn(selectcolidx, selectList)
  1058. {
  1059. ISQLExpression * currexp = &selectList.item(selectcolidx);
  1060. bool replaced = false;
  1061. if (currexp && currexp->needsColumnExpansion())
  1062. {
  1063. if (currexp->getExpType()== Fields_ExpressionType && ((SQLFieldsExpression*)currexp)->isAll())
  1064. {
  1065. ForEachItemIn(tableidx, tableList)
  1066. {
  1067. SQLTable tab = (SQLTable)tableList.item(tableidx);
  1068. HPCCFilePtr file = tmpHPCCFileCache->getHpccFileByName(tab.getName());
  1069. if (file)
  1070. {
  1071. IArrayOf<HPCCColumnMetaData> * cols = file->getColumns();
  1072. ForEachItemIn(colidx, *cols)
  1073. {
  1074. HPCCColumnMetaData col = cols->item(colidx);
  1075. Owned<ISQLExpression> fve = new SQLFieldValueExpression(file->getFullname(),col.getColumnName());
  1076. if (tableidx == 0 && colidx == 0)
  1077. {
  1078. selectList.replace(*fve.getLink(), selectcolidx, true);
  1079. replaced = true;
  1080. }
  1081. else
  1082. selectList.add(*fve.getLink(),selectcolidx+ colidx );
  1083. }
  1084. }
  1085. else
  1086. throw MakeStringException(-1, "INVALID TABLE FOUND");
  1087. }
  1088. }
  1089. else
  1090. {
  1091. const char * tablename = ((SQLFieldsExpression * )currexp)->getTable();
  1092. HPCCFilePtr file = tmpHPCCFileCache->getHpccFileByName(tablename);
  1093. if (file)
  1094. {
  1095. IArrayOf<HPCCColumnMetaData> * cols = file->getColumns();
  1096. ForEachItemIn(colidx, *cols)
  1097. {
  1098. HPCCColumnMetaData col = cols->item(colidx);
  1099. Owned<ISQLExpression> fve = new SQLFieldValueExpression(tablename, col.getColumnName());
  1100. if (colidx == 0)
  1101. {
  1102. selectList.replace(*fve.getLink(), selectcolidx, true);
  1103. replaced = true;
  1104. }
  1105. else
  1106. selectList.add(*fve.getLink(),selectcolidx+ colidx );
  1107. }
  1108. break;
  1109. }
  1110. }
  1111. break; //only one select all ??
  1112. }
  1113. if (replaced && currexp)
  1114. currexp->Release();
  1115. }
  1116. }
  1117. void HPCCSQLTreeWalker::getWhereClauseString(StringBuffer & str)
  1118. {
  1119. if (whereClause.get())
  1120. {
  1121. whereClause->toString(str, false);
  1122. }
  1123. }
  1124. void HPCCSQLTreeWalker::getHavingClauseString(StringBuffer & str)
  1125. {
  1126. if (havingClause.get())
  1127. {
  1128. havingClause->toString(str, false);
  1129. }
  1130. }
  1131. ISQLExpression * HPCCSQLTreeWalker::getHavingClause()
  1132. {
  1133. return havingClause.get();
  1134. }
  1135. void HPCCSQLTreeWalker::verifyAndDisambiguateNameFromList(IArrayOf<SQLFieldValueExpression> * explist)
  1136. {
  1137. if (explist)
  1138. {
  1139. int bycount = explist->length();
  1140. for (int i = 0; i < bycount; i++)
  1141. {
  1142. bool found = false;
  1143. SQLFieldValueExpression * coltoverify = &explist->item(i);
  1144. //we're trying to verify the list (groupby or sortby) contains only coloumns which appear in the select list
  1145. ForEachItemIn(sellistidx, selectList)
  1146. {
  1147. ISQLExpression * selcolexp = &selectList.item(sellistidx);
  1148. if (selcolexp && selcolexp->getExpType() == Function_ExpressionType)
  1149. {
  1150. SQLFunctionExpression * currentfunccol = (SQLFunctionExpression *)selcolexp;
  1151. IArrayOf<ISQLExpression> * funcparams = currentfunccol->getParams();
  1152. ForEachItemIn(paramidx, *funcparams)
  1153. {
  1154. ISQLExpression * param = &(funcparams->item(paramidx));
  1155. if (param)
  1156. {
  1157. const char * paramname = param->getName();
  1158. if (stricmp (coltoverify->getName(), paramname)==0)
  1159. {
  1160. found = true;
  1161. break;
  1162. }
  1163. }
  1164. }
  1165. }
  1166. else if (selcolexp && selcolexp->getExpType() == Value_ExpressionType)
  1167. continue;
  1168. else
  1169. {
  1170. const char * selcolname = selcolexp->getName();
  1171. if (selcolname && *selcolname)
  1172. {
  1173. const char * selcolalias = selcolexp->getAlias();
  1174. if (stricmp (coltoverify->getName(), selcolname)==0 ||
  1175. (selcolalias != NULL && stricmp (coltoverify->getName(), selcolalias)==0))
  1176. {
  1177. coltoverify->setName(selcolname);
  1178. if (selcolalias && *selcolalias)
  1179. {
  1180. coltoverify->setAlias(selcolalias);
  1181. }
  1182. found = true;
  1183. break;
  1184. }
  1185. }
  1186. }
  1187. }
  1188. if (!found)
  1189. throw MakeStringException(-1, "Could not verify field: %s. It does not appear in SELECT list.", coltoverify->getName());
  1190. }
  1191. }
  1192. }
  1193. void HPCCSQLTreeWalker::verifyColumn(SQLFieldValueExpression * col)
  1194. {
  1195. if (col)
  1196. {
  1197. const char * selcolname = col->getName();
  1198. const char * selcolparent = col->getParentTableName();
  1199. if (selcolname && *selcolname)
  1200. {
  1201. HPCCFilePtr file = tmpHPCCFileCache->getHpccFileByName(selcolparent);
  1202. if (file)
  1203. {
  1204. if (selcolname && *selcolname)
  1205. {
  1206. HPCCColumnMetaData * fcol = file->getColumn(selcolname);
  1207. if (fcol)
  1208. col->setECLType(fcol->getColumnType());
  1209. else //This exception doesn't allows us to validate direct references to aliases from select list
  1210. throw MakeStringException(-1, "INVALID COLUMN FOUND: %s.%s\n", selcolparent, selcolname );
  1211. }
  1212. else
  1213. throw MakeStringException(-1, "Could not verify a column\n");
  1214. }
  1215. else
  1216. throw MakeStringException(-1, "INVALID COLUMN PARENT FOUND: %s.%s\n", selcolparent, selcolname );
  1217. }
  1218. else
  1219. throw MakeStringException(-1, "Could not verify a column\n");
  1220. }
  1221. else
  1222. throw MakeStringException(-1, "Could not verify a column\n");
  1223. }
  1224. void HPCCSQLTreeWalker::verifyColAndDisambiguateName()
  1225. {
  1226. ForEachItemIn(sellistidx, selectList)
  1227. {
  1228. ISQLExpression * selcolexp = &selectList.item(sellistidx);
  1229. if (selcolexp && selcolexp->getExpType() == FieldValue_ExpressionType)
  1230. {
  1231. verifyColumn((SQLFieldValueExpression * )selcolexp);
  1232. }
  1233. else if (selcolexp && selcolexp->getExpType() == Function_ExpressionType)
  1234. {
  1235. SQLFunctionExpression * currentfunccol = (SQLFunctionExpression *)selcolexp;
  1236. IArrayOf<ISQLExpression> * funcparams = currentfunccol->getParams();
  1237. ForEachItemIn(paramidx, *funcparams)
  1238. {
  1239. ISQLExpression * param = &(funcparams->item(paramidx));
  1240. if (param && param->getExpType() == FieldValue_ExpressionType)
  1241. verifyColumn((SQLFieldValueExpression *)param);
  1242. }
  1243. }
  1244. else if (selcolexp && selcolexp->getExpType() == Value_ExpressionType)
  1245. {
  1246. continue;
  1247. }
  1248. else
  1249. throw MakeStringException(-1, "Could not process an entry on the select list");
  1250. }
  1251. if (orderbyList.length())
  1252. verifyAndDisambiguateNameFromList(&orderbyList);
  1253. if (groupbyList.length())
  1254. verifyAndDisambiguateNameFromList(&groupbyList);
  1255. }
  1256. bool HPCCSQLTreeWalker::normalizeSQL()
  1257. {
  1258. bool success = true;
  1259. if (normalizedSQL.length() <= 0)
  1260. {
  1261. try
  1262. {
  1263. if (sqlType == SQLTypeSelect)
  1264. {
  1265. normalizedSQL.append("SELECT ");
  1266. if (isSelectDistinct())
  1267. normalizedSQL.append("DISTINCT ");
  1268. ForEachItemIn(idx1, selectList)
  1269. {
  1270. if (idx1 > 0)
  1271. normalizedSQL.append(", ");
  1272. selectList.item(idx1).toString(normalizedSQL, true);
  1273. }
  1274. normalizedSQL.append(" FROM ");
  1275. ForEachItemIn(idxt, tableList)
  1276. {
  1277. if (idxt > 0)
  1278. normalizedSQL.append(", ");
  1279. SQLTable tab = (SQLTable)tableList.item(idxt);
  1280. normalizedSQL.append(tab.getName());
  1281. if (tab.hasIndexHint())
  1282. normalizedSQL.append(" USE INDEX ( ").append(tab.getIndexhint()).append(" ) ");
  1283. if (tab.hasJoin())
  1284. {
  1285. tab.getJoin()->toString(normalizedSQL);
  1286. }
  1287. }
  1288. if (whereClause.get())
  1289. {
  1290. normalizedSQL.append(" WHERE ");
  1291. whereClause->toString(normalizedSQL, true);
  1292. }
  1293. if (!orderbyList.empty())
  1294. {
  1295. normalizedSQL.append(" ORDER BY ");
  1296. getOrderByString(normalizedSQL);
  1297. }
  1298. if (!groupbyList.empty())
  1299. {
  1300. normalizedSQL.append(" GROUP BY ");
  1301. getGroupByString(normalizedSQL);
  1302. if ( havingClause.get())
  1303. {
  1304. normalizedSQL.append(" HAVING ");
  1305. havingClause->toString(normalizedSQL, true);
  1306. }
  1307. }
  1308. if (getLimit()>0)
  1309. normalizedSQL.append(" LIMIT ").append(getLimit());
  1310. if ( getOffset()>0)
  1311. normalizedSQL.append(" OFFSET ").append(getOffset());
  1312. }
  1313. else if (sqlType == SQLTypeCall)
  1314. {
  1315. normalizedSQL.append("CALL ");
  1316. normalizedSQL.append(querySetName.str());
  1317. normalizedSQL.append("::");
  1318. normalizedSQL.append(procedureName.str());
  1319. ForEachItemIn(idparams, paramList)
  1320. {
  1321. if (idparams > 0)
  1322. normalizedSQL.append(", ");
  1323. paramList.item(idparams).toString(normalizedSQL, true);
  1324. }
  1325. }
  1326. if (sqlType == SQLTypeCreateAndLoad)
  1327. {
  1328. normalizedSQL.appendf("CREATE %s TABLE %s \n( %s )\n%s;\n", isOverwrite() ? "" : "IF NOT EXISTS", tableName.str(), recordDefinition.str(), comment.length() ? comment.str() : "");
  1329. normalizedSQL.appendf("LOAD DATA INFILE %s %s %s %s INTO TABLE %s", sourceDataTableName.str(), landingZoneIP.length() ? landingZoneIP.str() : "", landingZonePath.length() ? landingZonePath.str() : "", sourceDataType.str(), tableName.str());
  1330. }
  1331. else
  1332. success = false;
  1333. }
  1334. catch (...)
  1335. {
  1336. success = false;
  1337. }
  1338. }
  1339. return success;
  1340. }
  1341. bool HPCCSQLTreeWalker::isParameterizedCall()
  1342. {
  1343. if (sqlType == SQLTypeCall)
  1344. {
  1345. if (paramList.length() == 0)
  1346. return false;
  1347. ForEachItemIn(idparams, paramList)
  1348. {
  1349. if (paramList.item(idparams).getExpType() != ParameterPlaceHolder_ExpressionType)
  1350. return false;
  1351. }
  1352. return true;
  1353. }
  1354. return false;
  1355. }
  1356. const char * HPCCSQLTreeWalker::getNormalizedSQL()
  1357. {
  1358. normalizeSQL();
  1359. return normalizedSQL.str();
  1360. }
  1361. /*
  1362. unsigned HPCCSQLTreeWalker::getQueryHash()
  1363. {
  1364. unsigned hashed;
  1365. if (normalizeSQL())
  1366. hashed = hashc((const byte *)normalizedSQL.str(), normalizedSQL.length(), 0);
  1367. Owned<IProperties> completedGraphs = createProperties(true);
  1368. return hashed;
  1369. }
  1370. */