roxiequerycompiler.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 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. #pragma warning (disable : 4786)
  14. #include "jlib.hpp"
  15. #include "roxiequerycompiler.hpp"
  16. class CRoxieQueryCompileInfo : public CInterface, implements IRoxieQueryCompileInfo
  17. {
  18. private:
  19. unsigned memoryLimit;
  20. unsigned wuTimeOut;
  21. unsigned timeLimit;
  22. unsigned warnTimeLimit;
  23. bool poolGraphs;
  24. bool highPriority;
  25. StringBuffer repositoryLabel;
  26. StringBuffer moduleName;
  27. StringBuffer defaultStyleName;
  28. StringBuffer wuDebugOptions;
  29. StringBuffer userName;
  30. StringBuffer password;
  31. StringBuffer jobName;
  32. StringBuffer ecl;
  33. StringBuffer appName;
  34. StringBuffer clusterName;
  35. int queryPriority;
  36. public:
  37. IMPLEMENT_IINTERFACE;
  38. CRoxieQueryCompileInfo(const char *_ecl, const char *_jobName, const char *_clusterName, const char *_appName)
  39. :ecl(_ecl), jobName(_jobName), clusterName(_clusterName)
  40. {
  41. memoryLimit = 0;
  42. wuTimeOut = 0;
  43. timeLimit = 0;
  44. warnTimeLimit = 0;
  45. poolGraphs = false;
  46. highPriority = false;
  47. queryPriority = UNKNOWN_PRIORITY;
  48. if (_appName && *_appName)
  49. appName.append(_appName);
  50. else
  51. appName.append("RoxieManager");
  52. }
  53. virtual void setMemoryLimit(unsigned val) { memoryLimit = val; }
  54. virtual unsigned getMemoryLimit() { return memoryLimit; }
  55. virtual void setWuTimeOut(unsigned val) { wuTimeOut = val; }
  56. virtual unsigned getWuTimeOut() { return wuTimeOut; }
  57. virtual void setTimeLimit(unsigned val) { timeLimit = val; }
  58. virtual unsigned getTimeLimit() { return timeLimit; }
  59. virtual void setWarnTimeLimit(unsigned val) { warnTimeLimit = val; }
  60. virtual unsigned getWarnTimeLimit() { return warnTimeLimit; }
  61. virtual void setPoolGraphs(bool val) { poolGraphs = val; }
  62. virtual bool getPoolGraphs() { return poolGraphs; }
  63. virtual void setHighPriority(bool val) { highPriority = val; }
  64. virtual bool getHighPriority() { return highPriority; }
  65. virtual void setRepositoryLabel(const char *val) { repositoryLabel.append(val); }
  66. virtual const char * queryRepositoryLabel() { return repositoryLabel.str(); }
  67. virtual void enableWebServiceInfoRetrieval(const char *_moduleName, const char *_defaultStyleName)
  68. { moduleName.append(_moduleName); defaultStyleName.append(_defaultStyleName);}
  69. virtual void setQueryPriority(int val) { queryPriority = val; }
  70. virtual int getQueryPriority() { return queryPriority; }
  71. virtual void setWuDebugOptions(const char *val) { wuDebugOptions.append(val); }
  72. virtual const char * queryWuDebugOptions() { return wuDebugOptions.str(); }
  73. virtual const char * queryUserId() { return userName.str(); }
  74. virtual const char * queryPassword() { return password.str(); }
  75. virtual const char * queryJobName() { return jobName.str(); }
  76. virtual const char * queryEcl() { return ecl.str(); }
  77. virtual const char * queryAppName() { return appName.str(); }
  78. virtual const char * queryClusterName() { return clusterName.str(); }
  79. virtual const char * queryDefaultStyleName() { return defaultStyleName.str(); }
  80. virtual const char * queryModuleName() { return moduleName.str(); }
  81. };
  82. class CRoxieQueryCompiler : public CInterface, implements IRoxieQueryCompiler
  83. {
  84. private:
  85. SocketEndpoint ep;
  86. void processCompilationErrors(IConstWorkUnit *workunit, SCMStringBuffer &errors)
  87. {
  88. if (workunit->getExceptionCount())
  89. {
  90. Owned<IConstWUExceptionIterator> exceptions = &workunit->getExceptions();
  91. StringArray errorStr;
  92. StringArray warnStr;
  93. ForEach (*exceptions)
  94. {
  95. IConstWUException &exception = exceptions->query();
  96. unsigned exceptCode = exception.getExceptionCode();
  97. SCMStringBuffer name;
  98. exception.getExceptionFileName(name);
  99. unsigned lineNo = exception.getExceptionLineNo();
  100. unsigned column = exception.getExceptionColumn();
  101. SCMStringBuffer source, message;
  102. exception.getExceptionSource(source);
  103. exception.getExceptionMessage(message);
  104. if (exception.getSeverity() == ExceptionSeverityWarning)
  105. {
  106. StringBuffer err;
  107. if ( (lineNo != 0) || (column != 0))
  108. err.appendf("WARNING: %s (%d, %d): %d %s", name.str(), lineNo, column, exceptCode, message.str());
  109. else
  110. err.appendf("WARNING: %s: %d %s", name.str(), exceptCode, message.str());
  111. warnStr.append(err.str());
  112. }
  113. else if (exception.getSeverity() == ExceptionSeverityError)
  114. {
  115. StringBuffer err;
  116. if ( (lineNo != 0) || (column != 0))
  117. err.appendf("ERROR: %s (%d, %d): %d %s", name.str(), lineNo, column, exceptCode, message.str());
  118. else
  119. err.appendf("ERROR: %s: %d %s", name.str(), exceptCode, message.str());
  120. errorStr.append(err.str());
  121. }
  122. }
  123. ForEachItemIn(err_idx, errorStr)
  124. {
  125. const char *err = errorStr.item(err_idx);
  126. errors.s.appendf("%s\n", err);
  127. }
  128. ForEachItemIn(warn_idx, warnStr)
  129. {
  130. const char *err = warnStr.item(warn_idx);
  131. errors.s.appendf("%s\n", err);
  132. }
  133. errors.s.appendf("%d error(s), %d warning(s)\n", errorStr.ordinality(), warnStr.ordinality());
  134. }
  135. }
  136. public:
  137. IMPLEMENT_IINTERFACE;
  138. CRoxieQueryCompiler()
  139. {
  140. }
  141. IConstWorkUnit *createWorkunit(SCMStringBuffer &wuid, const char *userName, const char *queryAppName)
  142. {
  143. Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
  144. Owned<IWorkUnit> workunit = factory->createWorkUnit(NULL, queryAppName, userName);
  145. workunit->getWuid(wuid);
  146. workunit->setState(WUStateUnknown);
  147. workunit->setUser(userName);
  148. return workunit.getClear();
  149. }
  150. IConstWorkUnit *compileEcl(SCMStringBuffer &wuid, const char *userName, const char *password, IRoxieQueryCompileInfo &compileInfo, IRoxieQueryProcessingInfo &processingInfo, SCMStringBuffer &status)
  151. {
  152. Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
  153. {
  154. Owned<IWorkUnit> workunit;
  155. if (wuid.length())
  156. workunit.setown(factory->updateWorkUnit(wuid.str()));
  157. else
  158. workunit.setown(factory->createWorkUnit(NULL, compileInfo.queryAppName(), userName));
  159. workunit->setDebugValue("RoxieConfigStatus", "Compiling...", true);
  160. Owned<IWUQuery> query = workunit->updateQuery();
  161. query->setQueryText(compileInfo.queryEcl());
  162. query->setQueryType(QueryTypeEcl);
  163. const char *queryJobName = compileInfo.queryJobName();
  164. if (queryJobName && *queryJobName)
  165. workunit->setJobName(queryJobName);
  166. workunit->setAction(WUActionCompile);
  167. workunit->setUser(userName);
  168. workunit->getWuid(wuid);
  169. // set generic debug options
  170. StringBuffer options(compileInfo.queryWuDebugOptions());
  171. if (options.length())
  172. {
  173. Owned<IPropertyTree> dbgOptions = createPTreeFromXMLString(options, ipt_caseInsensitive);
  174. Owned<IPropertyTreeIterator> iter = dbgOptions->getElements("Option");
  175. ForEach(*iter)
  176. {
  177. IPropertyTree &item = iter->query();
  178. const char *name = item.queryProp("@name");
  179. const char *value = item.queryProp("@value");
  180. workunit->setDebugValue(name, value, true);
  181. }
  182. }
  183. // set specific debug options
  184. workunit->setDebugValueInt("forceRoxie", 1, true);
  185. workunit->setDebugValueInt("traceRowXml", 1, true);
  186. workunit->setDebugValue("targetClusterType", "roxie", true);
  187. workunit->setClusterName(compileInfo.queryClusterName()); // MORE - eclserver should not require cluster set for roxy compiles (probably)
  188. if (compileInfo.getHighPriority())
  189. workunit->setPriority(PriorityClassHigh);
  190. int queryPriority = compileInfo.getQueryPriority();
  191. if (queryPriority != UNKNOWN_PRIORITY) // MORE - if set use queryPriority to set wu priority
  192. {
  193. workunit->setDebugValueInt("queryPriority", queryPriority, true);
  194. if (queryPriority == LOW_PRIORITY)
  195. workunit->setPriority(PriorityClassLow);
  196. else
  197. workunit->setPriority(PriorityClassHigh);
  198. }
  199. else
  200. {
  201. if (!compileInfo.getHighPriority())
  202. workunit->setDebugValue("queryPriority", "High", true);
  203. }
  204. workunit->setDebugValueInt("memoryLimit", compileInfo.getMemoryLimit(), true);
  205. workunit->setDebugValueInt("timeLimit", compileInfo.getTimeLimit(), true);
  206. workunit->setDebugValueInt("warnTimeLimit", compileInfo.getWarnTimeLimit(), true);
  207. workunit->setDebugValueInt("poolGraphs", compileInfo.getPoolGraphs(), true);
  208. workunit->setDebugValue("comment", processingInfo.queryComment(), true);
  209. workunit->setDebugValue("package", processingInfo.queryPackageName(), true);
  210. const char *label = compileInfo.queryRepositoryLabel();
  211. if (label && *label)
  212. workunit->setSnapshot(label);
  213. }
  214. submitWorkUnit(wuid.str(), userName, password);
  215. if (waitForWorkUnitToCompile(wuid.str(), compileInfo.getWuTimeOut()))
  216. {
  217. IConstWorkUnit *workunit = factory->openWorkUnit(wuid.str(), false);
  218. Owned<IWorkUnit> wu = &workunit->lock();
  219. SCMStringBuffer jn;
  220. wu->getJobName(jn);
  221. if (jn.length() == 0)
  222. {
  223. SCMStringBuffer name;
  224. wu->getDebugValue("name", name);
  225. if (name.length())
  226. wu->setJobName(name.str());
  227. else
  228. wu->setJobName(wuid.str());
  229. }
  230. processCompilationErrors(workunit, status);
  231. return workunit;
  232. }
  233. else
  234. {
  235. Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid.str(), false);
  236. WUState wu_state = workunit->getState();
  237. // there was a problem, just report it - either compilation problems, eclserver timeout, etc
  238. processCompilationErrors(workunit, status);
  239. if (!status.length()) // no compilations errors so it must be something else
  240. {
  241. //StringBuffer errStr;
  242. if (wu_state == WUStateCompiling)
  243. status.s.append("Time out trying to compile query - need to increase the wuTimeOut");
  244. else
  245. {
  246. SCMStringBuffer state;
  247. workunit->getStateDesc(state);
  248. status.s.appendf("Unknown error: Could not compile query - make sure eclserver is running - workunit status = %s", state.str());
  249. }
  250. }
  251. return NULL;
  252. }
  253. }
  254. };
  255. IRoxieQueryCompileInfo *createRoxieQueryCompileInfo(const char *_ecl, const char *_jobName, const char *_clusterName, const char *_appName)
  256. {
  257. return new CRoxieQueryCompileInfo(_ecl, _jobName, _clusterName, _appName);
  258. }
  259. IRoxieQueryCompiler *createRoxieQueryCompiler()
  260. {
  261. return new CRoxieQueryCompiler();
  262. }