PageRenderTime 74ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 1ms

/connectivity/source/parse/sqlnode.cxx

https://bitbucket.org/mst/ooo340
C++ | 2829 lines | 2333 code | 241 blank | 255 comment | 779 complexity | 7147a23ca9fe06cd985031abbf1341a9 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*************************************************************************
  2. *
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * Copyright 2000, 2010 Oracle and/or its affiliates.
  6. *
  7. * OpenOffice.org - a multi-platform office productivity suite
  8. *
  9. * This file is part of OpenOffice.org.
  10. *
  11. * OpenOffice.org is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Lesser General Public License version 3
  13. * only, as published by the Free Software Foundation.
  14. *
  15. * OpenOffice.org is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License version 3 for more details
  19. * (a copy is included in the LICENSE file that accompanied this code).
  20. *
  21. * You should have received a copy of the GNU Lesser General Public License
  22. * version 3 along with OpenOffice.org. If not, see
  23. * <http://www.openoffice.org/license.html>
  24. * for a copy of the LGPLv3 License.
  25. *
  26. ************************************************************************/
  27. // MARKER(update_precomp.py): autogen include statement, do not remove
  28. #include "precompiled_connectivity.hxx"
  29. #include <connectivity/sqlnode.hxx>
  30. #include <connectivity/sqlerror.hxx>
  31. #include <internalnode.hxx>
  32. #define YYBISON 1
  33. #ifndef BISON_INCLUDED
  34. #define BISON_INCLUDED
  35. #include <sqlbison.hxx>
  36. #endif
  37. #include <connectivity/sqlparse.hxx>
  38. #include <com/sun/star/lang/Locale.hpp>
  39. #include <com/sun/star/util/XNumberFormatter.hpp>
  40. #include <com/sun/star/util/XNumberFormatTypes.hpp>
  41. #include <com/sun/star/i18n/NumberFormatIndex.hpp>
  42. #include <com/sun/star/beans/XPropertySet.hpp>
  43. #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
  44. #include <com/sun/star/sdbc/DataType.hpp>
  45. #include <com/sun/star/sdb/XQueriesSupplier.hpp>
  46. #include <com/sun/star/sdb/ErrorCondition.hpp>
  47. #include <com/sun/star/util/XNumberFormatter.hpp>
  48. #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
  49. #include <com/sun/star/util/XNumberFormats.hpp>
  50. #include <com/sun/star/util/NumberFormat.hpp>
  51. #include <com/sun/star/util/XNumberFormatTypes.hpp>
  52. #include <com/sun/star/lang/Locale.hpp>
  53. #include <com/sun/star/i18n/KParseType.hpp>
  54. #include <com/sun/star/i18n/KParseTokens.hpp>
  55. #include "connectivity/dbconversion.hxx"
  56. #include <com/sun/star/util/DateTime.hpp>
  57. #include <com/sun/star/util/Time.hpp>
  58. #include <com/sun/star/util/Date.hpp>
  59. #include "TConnection.hxx"
  60. #include "sqlscan.hxx"
  61. #include <comphelper/numbers.hxx>
  62. #include <comphelper/processfactory.hxx>
  63. #include <comphelper/stl_types.hxx>
  64. #include "connectivity/dbtools.hxx"
  65. #include "connectivity/dbmetadata.hxx"
  66. #include "connectivity/sqlerror.hxx"
  67. #include <tools/diagnose_ex.h>
  68. #include <string.h>
  69. #include <boost/bind.hpp>
  70. #include <algorithm>
  71. #include <functional>
  72. #include <rtl/logfile.hxx>
  73. #include <rtl/ustrbuf.hxx>
  74. using namespace ::com::sun::star::sdbc;
  75. using namespace ::com::sun::star::util;
  76. using namespace ::com::sun::star::beans;
  77. using namespace ::com::sun::star::sdb;
  78. using namespace ::com::sun::star::uno;
  79. using namespace ::com::sun::star::lang;
  80. using namespace ::com::sun::star::i18n;
  81. using namespace ::com::sun::star;
  82. using namespace ::osl;
  83. using namespace ::dbtools;
  84. using namespace ::comphelper;
  85. extern int SQLyyparse (void);
  86. extern ::rtl::OUString ConvertLikeToken(const ::connectivity::OSQLParseNode* pTokenNode, const ::connectivity::OSQLParseNode* pEscapeNode, sal_Bool bInternational);
  87. extern void setParser( ::connectivity::OSQLParser* );
  88. namespace
  89. {
  90. // -----------------------------------------------------------------------------
  91. sal_Bool lcl_saveConvertToNumber(const Reference< XNumberFormatter > & _xFormatter,sal_Int32 _nKey,const ::rtl::OUString& _sValue,double& _nrValue)
  92. {
  93. sal_Bool bRet = sal_False;
  94. try
  95. {
  96. _nrValue = _xFormatter->convertStringToNumber(_nKey, _sValue);
  97. bRet = sal_True;
  98. }
  99. catch(Exception&)
  100. {
  101. }
  102. return bRet;
  103. }
  104. // -----------------------------------------------------------------------------
  105. void replaceAndReset(connectivity::OSQLParseNode*& _pResetNode,connectivity::OSQLParseNode* _pNewNode)
  106. {
  107. _pResetNode->getParent()->replace(_pResetNode, _pNewNode);
  108. delete _pResetNode;
  109. _pResetNode = _pNewNode;
  110. }
  111. // -----------------------------------------------------------------------------
  112. /** quotes a string and search for quotes inside the string and replace them with the new quote
  113. @param rValue
  114. The value to be quoted.
  115. @param rQuot
  116. The quote
  117. @param rQuotToReplace
  118. The quote to replace with
  119. @return
  120. The quoted string.
  121. */
  122. ::rtl::OUString SetQuotation(const ::rtl::OUString& rValue, const ::rtl::OUString& rQuot, const ::rtl::OUString& rQuotToReplace)
  123. {
  124. ::rtl::OUString rNewValue = rQuot;
  125. rNewValue += rValue;
  126. sal_Int32 nIndex = (sal_Int32)-1; // Quotes durch zweifache Quotes ersetzen, sonst kriegt der Parser Probleme
  127. if (rQuot.getLength())
  128. {
  129. do
  130. {
  131. nIndex += 2;
  132. nIndex = rNewValue.indexOf(rQuot,nIndex);
  133. if(nIndex != -1)
  134. rNewValue = rNewValue.replaceAt(nIndex,rQuot.getLength(),rQuotToReplace);
  135. } while (nIndex != -1);
  136. }
  137. rNewValue += rQuot;
  138. return rNewValue;
  139. }
  140. }
  141. namespace connectivity
  142. {
  143. //=============================================================================
  144. struct OSQLParser_Data
  145. {
  146. ::com::sun::star::lang::Locale aLocale;
  147. ::connectivity::SQLError aErrors;
  148. OSQLParser_Data( const Reference< XMultiServiceFactory >& _xServiceFactory )
  149. :aErrors( _xServiceFactory )
  150. {
  151. }
  152. };
  153. //=============================================================================
  154. //= SQLParseNodeParameter
  155. //=============================================================================
  156. //-----------------------------------------------------------------------------
  157. SQLParseNodeParameter::SQLParseNodeParameter( const Reference< XConnection >& _rxConnection,
  158. const Reference< XNumberFormatter >& _xFormatter, const Reference< XPropertySet >& _xField,
  159. const Locale& _rLocale, const IParseContext* _pContext,
  160. bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, bool _bParseToSDBC )
  161. :rLocale(_rLocale)
  162. ,aMetaData( _rxConnection )
  163. ,pParser( NULL )
  164. ,pSubQueryHistory( new QueryNameSet )
  165. ,xFormatter(_xFormatter)
  166. ,xField(_xField)
  167. ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const IParseContext&)OSQLParser::s_aDefaultContext )
  168. ,cDecSep(_cDecSep)
  169. ,bQuote(_bQuote)
  170. ,bInternational(_bIntl)
  171. ,bPredicate(_bPredicate)
  172. ,bParseToSDBCLevel( _bParseToSDBC )
  173. {
  174. }
  175. //-----------------------------------------------------------------------------
  176. SQLParseNodeParameter::~SQLParseNodeParameter()
  177. {
  178. }
  179. //=============================================================================
  180. //= OSQLParseNode
  181. //=============================================================================
  182. //-----------------------------------------------------------------------------
  183. ::rtl::OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const
  184. {
  185. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertDateString" );
  186. Date aDate = DBTypeConversion::toDate(rString);
  187. Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
  188. Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
  189. double fDate = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
  190. sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 36; // XXX hack
  191. return rParam.xFormatter->convertNumberToString(nKey, fDate);
  192. }
  193. //-----------------------------------------------------------------------------
  194. ::rtl::OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const
  195. {
  196. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertDateTimeString" );
  197. DateTime aDate = DBTypeConversion::toDateTime(rString);
  198. Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
  199. Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
  200. double fDateTime = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
  201. sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 51; // XXX hack
  202. return rParam.xFormatter->convertNumberToString(nKey, fDateTime);
  203. }
  204. //-----------------------------------------------------------------------------
  205. ::rtl::OUString OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const
  206. {
  207. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertTimeString" );
  208. Time aTime = DBTypeConversion::toTime(rString);
  209. Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
  210. Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
  211. double fTime = DBTypeConversion::toDouble(aTime);
  212. sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 41; // XXX hack
  213. return rParam.xFormatter->convertNumberToString(nKey, fTime);
  214. }
  215. //-----------------------------------------------------------------------------
  216. void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString,
  217. const Reference< XConnection >& _rxConnection,
  218. const IParseContext* pContext,
  219. sal_Bool _bIntl,
  220. sal_Bool _bQuote) const
  221. {
  222. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToStr" );
  223. parseNodeToStr(
  224. rString, _rxConnection, NULL, NULL,
  225. pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(),
  226. pContext, _bIntl, _bQuote, '.', false, false );
  227. }
  228. //-----------------------------------------------------------------------------
  229. void OSQLParseNode::parseNodeToPredicateStr(::rtl::OUString& rString,
  230. const Reference< XConnection >& _rxConnection,
  231. const Reference< XNumberFormatter > & xFormatter,
  232. const ::com::sun::star::lang::Locale& rIntl,
  233. sal_Char _cDec,
  234. const IParseContext* pContext ) const
  235. {
  236. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToPredicateStr" );
  237. OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
  238. if (xFormatter.is())
  239. parseNodeToStr(rString, _rxConnection, xFormatter, NULL, rIntl, pContext, sal_True, sal_True, _cDec, true, false);
  240. }
  241. //-----------------------------------------------------------------------------
  242. void OSQLParseNode::parseNodeToPredicateStr(::rtl::OUString& rString,
  243. const Reference< XConnection > & _rxConnection,
  244. const Reference< XNumberFormatter > & xFormatter,
  245. const Reference< XPropertySet > & _xField,
  246. const ::com::sun::star::lang::Locale& rIntl,
  247. sal_Char _cDec,
  248. const IParseContext* pContext ) const
  249. {
  250. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToPredicateStr" );
  251. OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
  252. if (xFormatter.is())
  253. parseNodeToStr( rString, _rxConnection, xFormatter, _xField, rIntl, pContext, true, true, _cDec, true, false );
  254. }
  255. //-----------------------------------------------------------------------------
  256. void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString,
  257. const Reference< XConnection > & _rxConnection,
  258. const Reference< XNumberFormatter > & xFormatter,
  259. const Reference< XPropertySet > & _xField,
  260. const ::com::sun::star::lang::Locale& rIntl,
  261. const IParseContext* pContext,
  262. bool _bIntl,
  263. bool _bQuote,
  264. sal_Char _cDecSep,
  265. bool _bPredicate,
  266. bool _bSubstitute) const
  267. {
  268. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToStr" );
  269. OSL_ENSURE( _rxConnection.is(), "OSQLParseNode::parseNodeToStr: invalid connection!" );
  270. if ( _rxConnection.is() )
  271. {
  272. ::rtl::OUStringBuffer sBuffer = rString;
  273. try
  274. {
  275. OSQLParseNode::impl_parseNodeToString_throw( sBuffer,
  276. SQLParseNodeParameter(
  277. _rxConnection, xFormatter, _xField, rIntl, pContext,
  278. _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute
  279. ) );
  280. }
  281. catch( const SQLException& )
  282. {
  283. OSL_ENSURE( false, "OSQLParseNode::parseNodeToStr: this should not throw!" );
  284. // our callers don't expect this method to throw anything. The only known situation
  285. // where impl_parseNodeToString_throw can throw is when there is a cyclic reference
  286. // in the sub queries, but this cannot be the case here, as we do not parse to
  287. // SDBC level.
  288. }
  289. rString = sBuffer.makeStringAndClear();
  290. }
  291. }
  292. //-----------------------------------------------------------------------------
  293. bool OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& _out_rString, const Reference< XConnection >& _rxConnection,
  294. OSQLParser& _rParser, ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const
  295. {
  296. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToExecutableStatement" );
  297. OSL_PRECOND( _rxConnection.is(), "OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" );
  298. SQLParseNodeParameter aParseParam( _rxConnection,
  299. NULL, NULL, OParseContext::getDefaultLocale(), NULL, false, true, '.', false, true );
  300. if ( aParseParam.aMetaData.supportsSubqueriesInFrom() )
  301. {
  302. Reference< XQueriesSupplier > xSuppQueries( _rxConnection, UNO_QUERY );
  303. OSL_ENSURE( xSuppQueries.is(), "OSQLParseNode::parseNodeToExecutableStatement: cannot substitute everything without a QueriesSupplier!" );
  304. if ( xSuppQueries.is() )
  305. aParseParam.xQueries = xSuppQueries->getQueries();
  306. }
  307. aParseParam.pParser = &_rParser;
  308. _out_rString = ::rtl::OUString();
  309. ::rtl::OUStringBuffer sBuffer;
  310. bool bSuccess = false;
  311. try
  312. {
  313. impl_parseNodeToString_throw( sBuffer, aParseParam );
  314. bSuccess = true;
  315. }
  316. catch( const SQLException& e )
  317. {
  318. if ( _pErrorHolder )
  319. *_pErrorHolder = e;
  320. }
  321. _out_rString = sBuffer.makeStringAndClear();
  322. return bSuccess;
  323. }
  324. //-----------------------------------------------------------------------------
  325. namespace
  326. {
  327. bool lcl_isAliasNamePresent( const OSQLParseNode& _rTableNameNode )
  328. {
  329. return OSQLParseNode::getTableRange(_rTableNameNode.getParent()).getLength() != 0;
  330. }
  331. }
  332. //-----------------------------------------------------------------------------
  333. void OSQLParseNode::impl_parseNodeToString_throw(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
  334. {
  335. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getTableRange" );
  336. if ( isToken() )
  337. {
  338. parseLeaf(rString,rParam);
  339. return;
  340. }
  341. // einmal auswerten wieviel Subtrees dieser Knoten besitzt
  342. sal_uInt32 nCount = count();
  343. bool bHandled = false;
  344. switch ( getKnownRuleID() )
  345. {
  346. // special handling for parameters
  347. case parameter:
  348. {
  349. if(rString.getLength())
  350. rString.appendAscii(" ");
  351. if (nCount == 1) // ?
  352. m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam );
  353. else if (nCount == 2) // :Name
  354. {
  355. m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam );
  356. rString.append(m_aChildren[1]->m_aNodeValue);
  357. } // [Name]
  358. else
  359. {
  360. m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam );
  361. rString.append(m_aChildren[1]->m_aNodeValue);
  362. rString.append(m_aChildren[2]->m_aNodeValue);
  363. }
  364. bHandled = true;
  365. }
  366. break;
  367. // table refs
  368. case table_ref:
  369. if ( ( nCount == 2 ) || ( nCount == 3 ) || ( nCount == 5 ) )
  370. {
  371. impl_parseTableRangeNodeToString_throw( rString, rParam );
  372. bHandled = true;
  373. }
  374. break;
  375. // table name - might be a query name
  376. case table_name:
  377. bHandled = impl_parseTableNameNodeToString_throw( rString, rParam );
  378. break;
  379. case as:
  380. if ( rParam.aMetaData.generateASBeforeCorrelationName() )
  381. rString.append(::rtl::OUString::createFromAscii( " AS" ));
  382. bHandled = true;
  383. break;
  384. case like_predicate:
  385. // je nachdem ob international angegeben wird oder nicht wird like anders behandelt
  386. // interanational: *, ? sind Platzhalter
  387. // sonst SQL92 konform: %, _
  388. impl_parseLikeNodeToString_throw( rString, rParam );
  389. bHandled = true;
  390. break;
  391. case general_set_fct:
  392. case set_fct_spec:
  393. case position_exp:
  394. case extract_exp:
  395. case length_exp:
  396. case char_value_fct:
  397. {
  398. if (!addDateValue(rString, rParam))
  399. {
  400. // Funktionsname nicht quoten
  401. SQLParseNodeParameter aNewParam(rParam);
  402. aNewParam.bQuote = ( SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct) );
  403. m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam );
  404. aNewParam.bQuote = rParam.bQuote;
  405. //aNewParam.bPredicate = sal_False; // disable [ ] around names // look at i73215
  406. ::rtl::OUStringBuffer aStringPara;
  407. for (sal_uInt32 i=1; i<nCount; i++)
  408. {
  409. const OSQLParseNode * pSubTree = m_aChildren[i];
  410. if (pSubTree)
  411. {
  412. pSubTree->impl_parseNodeToString_throw( aStringPara, aNewParam );
  413. // bei den CommaListen zwischen alle Subtrees Commas setzen
  414. if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1)))
  415. aStringPara.appendAscii(",");
  416. }
  417. else
  418. i++;
  419. }
  420. rString.append(aStringPara.makeStringAndClear());
  421. }
  422. bHandled = true;
  423. }
  424. break;
  425. default:
  426. break;
  427. } // switch ( getKnownRuleID() )
  428. if ( !bHandled )
  429. {
  430. for (OSQLParseNodes::const_iterator i = m_aChildren.begin();
  431. i != m_aChildren.end();)
  432. {
  433. const OSQLParseNode* pSubTree = *i;
  434. if ( !pSubTree )
  435. {
  436. ++i;
  437. continue;
  438. }
  439. SQLParseNodeParameter aNewParam(rParam);
  440. // don't replace the field for subqueries
  441. if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery))
  442. aNewParam.xField = NULL;
  443. // if there is a field given we don't display the fieldname, if there is any
  444. if (rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref))
  445. {
  446. sal_Bool bFilter = sal_False;
  447. // retrieve the fields name
  448. ::rtl::OUString aFieldName;
  449. try
  450. {
  451. sal_Int32 nNamePropertyId = PROPERTY_ID_NAME;
  452. if ( rParam.xField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) )
  453. nNamePropertyId = PROPERTY_ID_REALNAME;
  454. rParam.xField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( nNamePropertyId ) ) >>= aFieldName;
  455. }
  456. catch ( Exception& )
  457. {
  458. }
  459. if(pSubTree->count())
  460. {
  461. const OSQLParseNode* pCol = pSubTree->m_aChildren[pSubTree->count()-1];
  462. if ( ( SQL_ISRULE(pCol,column_val)
  463. && pCol->getChild(0)->getTokenValue().equalsIgnoreAsciiCase(aFieldName)
  464. )
  465. || pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName)
  466. )
  467. bFilter = sal_True;
  468. }
  469. // ok we found the field, if the following node is the
  470. // comparision operator '=' we filter it as well
  471. if (bFilter)
  472. {
  473. if (SQL_ISRULE(this, comparison_predicate))
  474. {
  475. ++i;
  476. if(i != m_aChildren.end())
  477. {
  478. pSubTree = *i;
  479. if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL)
  480. i++;
  481. }
  482. }
  483. else
  484. i++;
  485. }
  486. else
  487. {
  488. pSubTree->impl_parseNodeToString_throw( rString, aNewParam );
  489. i++;
  490. // bei den CommaListen zwischen alle Subtrees Commas setzen
  491. if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end()))
  492. rString.appendAscii(",");
  493. }
  494. }
  495. else
  496. {
  497. pSubTree->impl_parseNodeToString_throw( rString, aNewParam );
  498. i++;
  499. // bei den CommaListen zwischen alle Subtrees Commas setzen
  500. if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end()))
  501. {
  502. if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate)
  503. rString.appendAscii(";");
  504. else
  505. rString.appendAscii(",");
  506. }
  507. }
  508. }
  509. }
  510. }
  511. //-----------------------------------------------------------------------------
  512. bool OSQLParseNode::impl_parseTableNameNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
  513. {
  514. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseTableNameNodeToString_throw" );
  515. // is the table_name part of a table_ref?
  516. OSL_ENSURE( getParent(), "OSQLParseNode::impl_parseTableNameNodeToString_throw: table_name without parent?" );
  517. if ( !getParent() || ( getParent()->getKnownRuleID() != table_ref ) )
  518. return false;
  519. // if it's a query, maybe we need to substitute the SQL statement ...
  520. if ( !rParam.bParseToSDBCLevel )
  521. return false;
  522. if ( !rParam.xQueries.is() )
  523. // connection does not support queries in queries, or was no query supplier
  524. return false;
  525. try
  526. {
  527. ::rtl::OUString sTableOrQueryName( getChild(0)->getTokenValue() );
  528. bool bIsQuery = rParam.xQueries->hasByName( sTableOrQueryName );
  529. if ( !bIsQuery )
  530. return false;
  531. // avoid recursion (e.g. "foo" defined as "SELECT * FROM bar" and "bar" defined as "SELECT * FROM foo".
  532. if ( rParam.pSubQueryHistory->find( sTableOrQueryName ) != rParam.pSubQueryHistory->end() )
  533. {
  534. ::rtl::OUString sMessage( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cyclic sub queries" ) ) );
  535. OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: no parser?" );
  536. if ( rParam.pParser )
  537. {
  538. const SQLError& rErrors( rParam.pParser->getErrorHelper() );
  539. rErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
  540. }
  541. else
  542. {
  543. SQLError aErrors( ::comphelper::getProcessServiceFactory() );
  544. aErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
  545. }
  546. }
  547. rParam.pSubQueryHistory->insert( sTableOrQueryName );
  548. Reference< XPropertySet > xQuery( rParam.xQueries->getByName( sTableOrQueryName ), UNO_QUERY_THROW );
  549. // substitute the query name with the constituting command
  550. ::rtl::OUString sCommand;
  551. OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sCommand );
  552. sal_Bool bEscapeProcessing = sal_False;
  553. OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing );
  554. // the query we found here might itself be based on another query, so parse it recursively
  555. OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: cannot analyze sub queries without a parser!" );
  556. if ( bEscapeProcessing && rParam.pParser )
  557. {
  558. ::rtl::OUString sError;
  559. ::std::auto_ptr< OSQLParseNode > pSubQueryNode( rParam.pParser->parseTree( sError, sCommand, sal_False ) );
  560. if ( pSubQueryNode.get() )
  561. {
  562. // parse the sub-select to SDBC level, too
  563. ::rtl::OUStringBuffer sSubSelect;
  564. pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, rParam );
  565. if ( sSubSelect.getLength() )
  566. sCommand = sSubSelect.makeStringAndClear();
  567. }
  568. }
  569. rString.appendAscii( " ( " );
  570. rString.append(sCommand);
  571. rString.appendAscii( " )" );
  572. // append the query name as table alias, since it might be referenced in other
  573. // parts of the statement - but only if there's no other alias name present
  574. if ( !lcl_isAliasNamePresent( *this ) )
  575. {
  576. rString.appendAscii( " AS " );
  577. if ( rParam.bQuote )
  578. rString.append(SetQuotation( sTableOrQueryName,
  579. rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() ));
  580. }
  581. // don't forget to remove the query name from the history, else multiple inclusions
  582. // won't work
  583. // #i69227# / 2006-10-10 / frank.schoenheit@sun.com
  584. rParam.pSubQueryHistory->erase( sTableOrQueryName );
  585. return true;
  586. }
  587. catch( const SQLException& )
  588. {
  589. throw;
  590. }
  591. catch( const Exception& )
  592. {
  593. DBG_UNHANDLED_EXCEPTION();
  594. }
  595. return false;
  596. }
  597. //-----------------------------------------------------------------------------
  598. void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
  599. {
  600. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseTableRangeNodeToString_throw" );
  601. OSL_PRECOND( ( count() == 2 ) || ( count() == 3 ) || ( count() == 5 ) ,"Illegal count");
  602. // rString += ::rtl::OUString::createFromAscii(" ");
  603. ::std::for_each(m_aChildren.begin(),m_aChildren.end(),
  604. boost::bind( &OSQLParseNode::impl_parseNodeToString_throw, _1, boost::ref( rString ), boost::cref( rParam ) ));
  605. }
  606. //-----------------------------------------------------------------------------
  607. void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
  608. {
  609. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseLikeNodeToString_throw" );
  610. OSL_ENSURE(count() >= 4,"count != 5: Prepare for GPF");
  611. const OSQLParseNode* pEscNode = NULL;
  612. const OSQLParseNode* pParaNode = NULL;
  613. SQLParseNodeParameter aNewParam(rParam);
  614. //aNewParam.bQuote = sal_True; // why setting this to true? @see http://www.openoffice.org/issues/show_bug.cgi?id=75557
  615. // if there is a field given we don't display the fieldname, if there are any
  616. sal_Bool bAddName = sal_True;
  617. if (rParam.xField.is())
  618. {
  619. // retrieve the fields name
  620. ::rtl::OUString aFieldName;
  621. try
  622. {
  623. // retrieve the fields name
  624. rtl::OUString aString;
  625. rParam.xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString;
  626. aFieldName = aString.getStr();
  627. }
  628. catch ( Exception& )
  629. {
  630. OSL_ENSURE( false, "OSQLParseNode::impl_parseLikeNodeToString_throw Exception occured!" );
  631. }
  632. if ( !m_aChildren[0]->isLeaf() )
  633. {
  634. const OSQLParseNode* pCol = m_aChildren[0]->getChild(m_aChildren[0]->count()-1);
  635. if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().equalsIgnoreAsciiCase(aFieldName)) ||
  636. pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName) )
  637. bAddName = sal_False;
  638. }
  639. }
  640. if (bAddName)
  641. m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam );
  642. m_aChildren[1]->impl_parseNodeToString_throw( rString, aNewParam );
  643. if(count() == 5)
  644. m_aChildren[2]->impl_parseNodeToString_throw( rString, aNewParam );
  645. sal_Int32 nCurentPos = m_aChildren.size()-2;
  646. pParaNode = m_aChildren[nCurentPos];
  647. pEscNode = m_aChildren[nCurentPos+1];
  648. if (pParaNode->isToken())
  649. {
  650. ::rtl::OUString aStr = ConvertLikeToken(pParaNode, pEscNode, rParam.bInternational);
  651. rString.appendAscii(" ");
  652. rString.append(SetQuotation(aStr,::rtl::OUString::createFromAscii("\'"),::rtl::OUString::createFromAscii("\'\'")));
  653. }
  654. else
  655. pParaNode->impl_parseNodeToString_throw( rString, aNewParam );
  656. pEscNode->impl_parseNodeToString_throw( rString, aNewParam );
  657. }
  658. // -----------------------------------------------------------------------------
  659. sal_Bool OSQLParseNode::getTableComponents(const OSQLParseNode* _pTableNode,
  660. ::com::sun::star::uno::Any &_rCatalog,
  661. ::rtl::OUString &_rSchema,
  662. ::rtl::OUString &_rTable,
  663. const Reference< XDatabaseMetaData >& _xMetaData)
  664. {
  665. RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getTableComponents" );
  666. OSL_ENSURE(_pTableNode,"Wrong use of getTableComponents! _pTableNode is not allowed to be null!");
  667. if(_pTableNode)
  668. {
  669. const sal_Bool bSupportsCatalog = _xMetaData.is() && _xMetaData->supportsCatalogsInDataManipulation();
  670. const sal_Bool bSupportsSchema = _xMetaData.is() && _xMetaData->supportsSchemasInDataManipulation();
  671. const OSQLParseNode* pTableNode = _pTableNode;
  672. // clear the parameter given
  673. _rCatalog = Any();
  674. _rSchema = _rTable = ::rtl::OUString();
  675. // see rule catalog_name: in sqlbison.y
  676. if (SQL_ISRULE(pTableNode,catalog_name))
  677. {
  678. OSL_ENSURE(pTableNode->getChild(0) && pTableNode->getChild(0)->isToken(),"Invalid parsenode!");
  679. _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
  680. pTableNode = pTableNode->getChild(2);
  681. }
  682. // check if we have schema_name rule
  683. if(SQL_ISRULE(pTableNode,schema_name))
  684. {
  685. if ( bSupportsCatalog && !bSupportsSchema )
  686. _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
  687. else
  688. _rSchema = pTableNode->getChild(0)->getTokenValue();
  689. pTableNode = pTableNode->getChild(2);
  690. }
  691. // check if we have table_name rule
  692. if(SQL_ISRULE(pTableNode,table_name))
  693. {
  694. _rTable = pTableNode->getChild(0)->getTokenValue();
  695. }
  696. else
  697. {
  698. OSL_ENSURE(0,"Error in parse tree!");
  699. }
  700. }
  701. return _rTable.getLength() != 0;
  702. }
  703. // -----------------------------------------------------------------------------
  704. void OSQLParser::killThousandSeparator(OSQLParseNode* pLiteral)
  705. {
  706. if ( pLiteral )
  707. {
  708. if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
  709. {
  710. pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace('.', sal_Unicode());
  711. // and replace decimal
  712. pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', '.');
  713. }
  714. else
  715. pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', sal_Unicode());
  716. }
  717. }
  718. // -----------------------------------------------------------------------------
  719. OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral)
  720. {
  721. if ( !pLiteral )
  722. return NULL;
  723. OSQLParseNode* pReturn = pLiteral;
  724. if ( ( pLiteral->isRule() && !SQL_ISRULE(pLiteral,value_exp) ) || SQL_ISTOKEN(pLiteral,FALSE) || SQL_ISTOKEN(pLiteral,TRUE) )
  725. {
  726. switch(nType)
  727. {
  728. case DataType::CHAR:
  729. case DataType::VARCHAR:
  730. case DataType::LONGVARCHAR:
  731. case DataType::CLOB:
  732. if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) )
  733. pReturn = NULL;
  734. default:
  735. break;
  736. }
  737. }
  738. else
  739. {
  740. switch(pLiteral->getNodeType())
  741. {
  742. case SQL_NODE_STRING:
  743. switch(nType)
  744. {
  745. case DataType::CHAR:
  746. case DataType::VARCHAR:
  747. case DataType::LONGVARCHAR:
  748. case DataType::CLOB:
  749. break;
  750. case DataType::DATE:
  751. case DataType::TIME:
  752. case DataType::TIMESTAMP:
  753. if (m_xFormatter.is())
  754. pReturn = buildDate( nType, pReturn);
  755. break;
  756. default:
  757. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
  758. break;
  759. }
  760. break;
  761. case SQL_NODE_ACCESS_DATE:
  762. switch(nType)
  763. {
  764. case DataType::DATE:
  765. case DataType::TIME:
  766. case DataType::TIMESTAMP:
  767. if ( m_xFormatter.is() )
  768. pReturn = buildDate( nType, pReturn);
  769. else
  770. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_DATE_COMPARE);
  771. break;
  772. default:
  773. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
  774. break;
  775. }
  776. break;
  777. case SQL_NODE_INTNUM:
  778. switch(nType)
  779. {
  780. case DataType::BIT:
  781. case DataType::BOOLEAN:
  782. case DataType::DECIMAL:
  783. case DataType::NUMERIC:
  784. case DataType::TINYINT:
  785. case DataType::SMALLINT:
  786. case DataType::INTEGER:
  787. case DataType::BIGINT:
  788. case DataType::FLOAT:
  789. case DataType::REAL:
  790. case DataType::DOUBLE:
  791. // kill thousand seperators if any
  792. killThousandSeparator(pReturn);
  793. break;
  794. case DataType::CHAR:
  795. case DataType::VARCHAR:
  796. case DataType::LONGVARCHAR:
  797. case DataType::CLOB:
  798. pReturn = buildNode_STR_NUM(pReturn);
  799. break;
  800. default:
  801. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE);
  802. break;
  803. }
  804. break;
  805. case SQL_NODE_APPROXNUM:
  806. switch(nType)
  807. {
  808. case DataType::DECIMAL:
  809. case DataType::NUMERIC:
  810. case DataType::FLOAT:
  811. case DataType::REAL:
  812. case DataType::DOUBLE:
  813. // kill thousand seperators if any
  814. killThousandSeparator(pReturn);
  815. break;
  816. case DataType::CHAR:
  817. case DataType::VARCHAR:
  818. case DataType::LONGVARCHAR:
  819. case DataType::CLOB:
  820. pReturn = buildNode_STR_NUM(pReturn);
  821. break;
  822. case DataType::INTEGER:
  823. default:
  824. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_REAL_COMPARE);
  825. break;
  826. }
  827. break;
  828. default:
  829. ;
  830. }
  831. }
  832. return pReturn;
  833. }
  834. // -----------------------------------------------------------------------------
  835. sal_Int16 OSQLParser::buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2)
  836. {
  837. OSL_ENSURE(inPredicateCheck(),"Only in predicate check allowed!");
  838. sal_Int16 nErg = 0;
  839. if ( m_xField.is() )
  840. {
  841. sal_Int32 nType = 0;
  842. try
  843. {
  844. m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
  845. }
  846. catch( Exception& )
  847. {
  848. return nErg;
  849. }
  850. OSQLParseNode* pNode1 = convertNode(nType,pLiteral);
  851. if ( pNode1 )
  852. {
  853. OSQLParseNode* pNode2 = convertNode(nType,pLiteral2);
  854. if ( !m_sErrorMessage.getLength() )
  855. nErg = buildNode(pAppend,pCompare,pNode1,pNode2);
  856. }
  857. }
  858. if (!pCompare->getParent()) // I have no parent so I was not used and I must die :-)
  859. delete pCompare;
  860. return nErg;
  861. }
  862. // -----------------------------------------------------------------------------
  863. sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode*& pAppend, OSQLParseNode*& pLiteral, const OSQLParseNode* pEscape)
  864. {
  865. sal_Int16 nErg = 0;
  866. sal_Int32 nType = 0;
  867. if (!m_xField.is())
  868. return nErg;
  869. try
  870. {
  871. Any aValue;
  872. {
  873. aValue = m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE));
  874. aValue >>= nType;
  875. }
  876. }
  877. catch( Exception& )
  878. {
  879. return nErg;
  880. }
  881. switch (nType)
  882. {
  883. case DataType::CHAR:
  884. case DataType::VARCHAR:
  885. case DataType::LONGVARCHAR:
  886. case DataType::CLOB:
  887. if(pLiteral->isRule())
  888. {
  889. pAppend->append(pLiteral);
  890. nErg = 1;
  891. }
  892. else
  893. {
  894. switch(pLiteral->getNodeType())
  895. {
  896. case SQL_NODE_STRING:
  897. pLiteral->m_aNodeValue = ConvertLikeToken(pLiteral, pEscape, sal_False);
  898. pAppend->append(pLiteral);
  899. nErg = 1;
  900. break;
  901. case SQL_NODE_APPROXNUM:
  902. if (m_xFormatter.is() && m_nFormatKey)
  903. {
  904. sal_Int16 nScale = 0;
  905. try
  906. {
  907. Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, ::rtl::OUString::createFromAscii("Decimals") );
  908. aValue >>= nScale;
  909. }
  910. catch( Exception& )
  911. {
  912. }
  913. pAppend->append(new OSQLInternalNode(stringToDouble(pLiteral->getTokenValue(),nScale),SQL_NODE_STRING));
  914. }
  915. else
  916. pAppend->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQL_NODE_STRING));
  917. delete pLiteral;
  918. nErg = 1;
  919. break;
  920. default:
  921. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_VALUE_NO_LIKE);
  922. m_sErrorMessage = m_sErrorMessage.replaceAt(m_sErrorMessage.indexOf(::rtl::OUString::createFromAscii("#1")),2,pLiteral->getTokenValue());
  923. break;
  924. }
  925. }
  926. break;
  927. default:
  928. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_FIELD_NO_LIKE);
  929. break;
  930. }
  931. return nErg;
  932. }
  933. //-----------------------------------------------------------------------------
  934. OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType)
  935. {
  936. ::rtl::OUString aEmptyString;
  937. OSQLParseNode* pNewNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::set_fct_spec));
  938. pNewNode->append(new OSQLInternalNode(::rtl::OUString::createFromAscii("{"), SQL_NODE_PUNCTUATION));
  939. OSQLParseNode* pDateNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::odbc_fct_spec));
  940. pNewNode->append(pDateNode);
  941. pNewNode->append(new OSQLInternalNode(::rtl::OUString::createFromAscii("}"), SQL_NODE_PUNCTUATION));
  942. switch (nType)
  943. {
  944. case DataType::DATE:
  945. {
  946. Date aDate = DBTypeConversion::toDate(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
  947. ::rtl::OUString aString = DBTypeConversion::toDateString(aDate);
  948. pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
  949. pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
  950. break;
  951. }
  952. case DataType::TIME:
  953. {
  954. Time aTime = DBTypeConversion::toTime(fValue);
  955. ::rtl::OUString aString = DBTypeConversion::toTimeString(aTime);
  956. pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_T));
  957. pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
  958. break;
  959. }
  960. case DataType::TIMESTAMP:
  961. {
  962. DateTime aDateTime = DBTypeConversion::toDateTime(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
  963. if (aDateTime.Seconds || aDateTime.Minutes || aDateTime.Hours)
  964. {
  965. ::rtl::OUString aString = DBTypeConversion::toDateTimeString(aDateTime);
  966. pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_TS));
  967. pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
  968. }
  969. else
  970. {
  971. Date aDate(aDateTime.Day,aDateTime.Month,aDateTime.Year);
  972. pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
  973. pDateNode->append(new OSQLInternalNode(DBTypeConversion::toDateString(aDate), SQL_NODE_STRING));
  974. }
  975. break;
  976. }
  977. }
  978. return pNewNode;
  979. }
  980. // -----------------------------------------------------------------------------
  981. OSQLParseNode* OSQLParser::buildNode_STR_NUM(OSQLParseNode*& _pLiteral)
  982. {
  983. OSQLParseNode* pReturn = NULL;
  984. if ( _pLiteral )
  985. {
  986. if (m_nFormatKey)
  987. {
  988. sal_Int16 nScale = 0;
  989. ::rtl::OUString aDec;
  990. try
  991. {
  992. Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Decimals")) );
  993. aValue >>= nScale;
  994. }
  995. catch( Exception& )
  996. {
  997. }
  998. pReturn = new OSQLInternalNode(stringToDouble(_pLiteral->getTokenValue(),nScale),SQL_NODE_STRING);
  999. }
  1000. else
  1001. pReturn = new OSQLInternalNode(_pLiteral->getTokenValue(),SQL_NODE_STRING);
  1002. delete _pLiteral;
  1003. _pLiteral = NULL;
  1004. }
  1005. return pReturn;
  1006. }
  1007. // -----------------------------------------------------------------------------
  1008. ::rtl::OUString OSQLParser::stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale)
  1009. {
  1010. ::rtl::OUString aValue;
  1011. if(!m_xCharClass.is())
  1012. m_xCharClass = Reference<XCharacterClassification>(m_xServiceFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.CharacterClassification")),UNO_QUERY);
  1013. if(m_xCharClass.is() && s_xLocaleData.is())
  1014. {
  1015. try
  1016. {
  1017. ParseResult aResult = m_xCharClass->parsePredefinedToken(KParseType::ANY_NUMBER,_rValue,0,m_pData->aLocale,0,::rtl::OUString(),KParseType::ANY_NUMBER,::rtl::OUString());
  1018. if((aResult.TokenType & KParseType::IDENTNAME) && aResult.EndPos == _rValue.getLength())
  1019. {
  1020. aValue = ::rtl::OUString::valueOf(aResult.Value);
  1021. sal_Int32 nPos = aValue.lastIndexOf(::rtl::OUString::createFromAscii("."));
  1022. if((nPos+_nScale) < aValue.getLength())
  1023. aValue = aValue.replaceAt(nPos+_nScale,aValue.getLength()-nPos-_nScale,::rtl::OUString());
  1024. aValue = aValue.replaceAt(aValue.lastIndexOf(::rtl::OUString::createFromAscii(".")),1,s_xLocaleData->getLocaleItem(m_pData->aLocale).decimalSeparator);
  1025. return aValue;
  1026. }
  1027. }
  1028. catch(Exception&)
  1029. {
  1030. }
  1031. }
  1032. return aValue;
  1033. }
  1034. // -----------------------------------------------------------------------------
  1035. ::osl::Mutex& OSQLParser::getMutex()
  1036. {
  1037. static ::osl::Mutex aMutex;
  1038. return aMutex;
  1039. }
  1040. //-----------------------------------------------------------------------------
  1041. OSQLParseNode* OSQLParser::predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement,
  1042. const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
  1043. const Reference< XPropertySet > & xField)
  1044. {
  1045. // mutex for parsing
  1046. static ::osl::Mutex aMutex;
  1047. // Guard the parsing
  1048. ::osl::MutexGuard aGuard(getMutex());
  1049. // must be reset
  1050. setParser(this);
  1051. // reset the parser
  1052. m_xField = xField;
  1053. m_xFormatter = xFormatter;
  1054. if (m_xField.is())
  1055. {
  1056. sal_Int32 nType=0;
  1057. try
  1058. {
  1059. // get the field name
  1060. rtl::OUString aString;
  1061. // retrieve the fields name
  1062. // #75243# use the RealName of the column if there is any otherwise the name which could be the alias
  1063. // of the field
  1064. Reference< XPropertySetInfo> xInfo = m_xField->getPropertySetInfo();
  1065. if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)))
  1066. m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)) >>= aString;
  1067. else
  1068. m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString;
  1069. m_sFieldName = aString;
  1070. // get the field format key
  1071. if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)))
  1072. m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) >>= m_nFormatKey;
  1073. else
  1074. m_nFormatKey = 0;
  1075. // get the field type
  1076. m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
  1077. }
  1078. catch ( Exception& )
  1079. {
  1080. OSL_ASSERT(0);
  1081. }
  1082. if (m_nFormatKey && m_xFormatter.is())
  1083. {
  1084. Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LOCALE) );
  1085. OSL_ENSURE(aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0), "OSQLParser::PredicateTree : invalid language property !");
  1086. if (aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0))
  1087. aValue >>= m_pData->aLocale;
  1088. }
  1089. else
  1090. m_pData->aLocale = m_pContext->getPreferredLocale();
  1091. if ( m_xFormatter.is() )
  1092. {
  1093. try
  1094. {
  1095. Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
  1096. if ( xFormatSup.is() )
  1097. {
  1098. Reference< ::com::sun::star::util::XNumberFormats > xFormats = xFormatSup->getNumberFormats();
  1099. if ( xFormats.is() )
  1100. {
  1101. ::com::sun::star::lang::Locale aLocale;
  1102. aLocale.Language = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en"));
  1103. aLocale.Country = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US"));
  1104. ::rtl::OUString sFormat(RTL_CONSTASCII_USTRINGPARAM("YYYY-MM-DD"));
  1105. m_nDateFormatKey = xFormats->queryKey(sFormat,aLocale,sal_False);
  1106. if ( m_nDateFormatKey == sal_Int32(-1) )
  1107. m_nDateFormatKey = xFormats->addNew(sFormat, aLocale);
  1108. }
  1109. }
  1110. }
  1111. catch ( Exception& )
  1112. {
  1113. OSL_ENSURE(0,"DateFormatKey");
  1114. }
  1115. }
  1116. switch (nType)
  1117. {
  1118. case DataType::DATE:
  1119. case DataType::TIME:
  1120. case DataType::TIMESTAMP:
  1121. s_pScanner->SetRule(s_pScanner->GetDATERule());
  1122. break;
  1123. case DataType::CHAR:
  1124. case DataType::VARCHAR:
  1125. case DataType::LONGVARCHAR:
  1126. case DataType::CLOB:
  1127. s_pScanner->SetRule(s_pScanner->GetSTRINGRule());
  1128. break;
  1129. default:
  1130. if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
  1131. s_pScanner->SetRule(s_pScanner->GetGERRule());
  1132. else
  1133. s_pScanner->SetRule(s_pScanner->GetENGRule());
  1134. }
  1135. }
  1136. else
  1137. s_pScanner->SetRule(s_pScanner->GetSQLRule());
  1138. s_pScanner->prepareScan(rStatement, m_pContext, sal_True);
  1139. SQLyylval.pParseNode = NULL;
  1140. // SQLyypvt = NULL;
  1141. m_pParseTree = NULL;
  1142. m_sErrorMessage= ::rtl::OUString();
  1143. // ... und den Parser anwerfen ...
  1144. if (SQLyyparse() != 0)
  1145. {
  1146. m_sFieldName= ::rtl::OUString();
  1147. m_xField.clear();
  1148. m_xFormatter.clear();
  1149. m_nFormatKey = 0;
  1150. m_nDateFormatKey = 0;
  1151. if (!m_sErrorMessage.getLength())
  1152. m_sErrorMessage = s_pScanner->getErrorMessage();
  1153. if (!m_sErrorMessage.getLength())
  1154. m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_GENERAL);
  1155. rErrorMessage = m_sErrorMessage;
  1156. // clear the garbage collector
  1157. (*s_pGarbageCollector)->clearAndDelete();
  1158. return NULL;
  1159. }
  1160. else
  1161. {
  1162. (*s_pGarbageCollector)->clear();
  1163. m_sFieldName= ::rtl::OUString();
  1164. m_xField.clear();
  1165. m_xFormatter.clear();
  1166. m_nFormatKey = 0;
  1167. m_nDateFormatKey = 0;
  1168. // Das Ergebnis liefern (den Root Parse Node):
  1169. // Stattdessen setzt die Parse-Routine jetzt den Member pParseTree
  1170. // - einfach diesen zurueckliefern:
  1171. OSL_ENSURE(m_pParseTree != NULL,"OSQLParser: Parser hat keinen ParseTree geliefert");
  1172. return m_pParseTree;
  1173. }
  1174. }
  1175. //=============================================================================
  1176. //-----------------------------------------------------------------------------
  1177. OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext)
  1178. :m_pContext(_pContext)
  1179. ,m_pParseTree(NULL)
  1180. ,m_pData( new OSQLParser_Data( _xServiceFactory ) )
  1181. ,m_nFormatKey(0)
  1182. ,m_nDateFormatKey(0)
  1183. ,m_xServiceFactory(_xServiceFactory)
  1184. {
  1185. setParser(this);
  1186. #ifdef SQLYYDEBUG
  1187. #ifdef SQLYYDEBUG_ON
  1188. SQLyydebug = 1;
  1189. #endif
  1190. #endif
  1191. ::osl::MutexGuard aGuard(getMutex());
  1192. // do we have to initialize the data
  1193. if (s_nRefCount == 0)
  1194. {
  1195. s_pScanner = new OSQLScanner();
  1196. s_pScanner->setScanner();
  1197. s_pGarbageCollector = new OSQLParseNodesGarbageCollector();
  1198. if(!s_xLocaleData.is())
  1199. s_xLocaleData = Reference<XLocaleData>(m_xServiceFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.LocaleData")),UNO_QUERY);
  1200. // auf 0 zuruecksetzen
  1201. memset(OSQLParser::s_nRuleIDs,0,sizeof(OSQLParser::s_nRuleIDs[0]) * (OSQLParseNode::rule_count+1));
  1202. struct
  1203. {
  1204. OSQLParseNode::Rule eRule; // the parse node's ID for the rule
  1205. ::rtl::OString sRuleName; // the name of the rule ("select_statement")
  1206. } aRuleDescriptions[] =
  1207. {
  1208. { OSQLParseNode::select_statement, "select_statement" },
  1209. { OSQLParseNode::table_exp, "table_exp" },
  1210. { OSQLParseNode::table_ref_commalist, "table_ref_commalist" },
  1211. { OSQLParseNode::table_ref, "table_ref" },
  1212. { OSQLParseNode::catalog_name, "catalog_name" },
  1213. { OSQLParseNode::schema_name, "schema_name" },
  1214. { OSQLParseNode::table_name, "table_name" },
  1215. { OSQLParseNode::opt_column_commalist, "opt_column_commalist" },
  1216. { OSQLParseNode::column_commalist, "column_commalist" },
  1217. { OSQLParseNode::column_ref_commalist, "column_ref_commalist" },
  1218. { OSQLParseNode::column_ref, "column_ref" },
  1219. { OSQLParseNode::opt_order_by_clause, "opt_order_by_clause" },
  1220. { OSQLParseNode::ordering_spec_commalist, "ordering_spec_commalist" },
  1221. { OSQLParseNode::ordering_spec, "ordering_spec" },
  1222. { OSQLParseNode::opt_asc_desc, "opt_asc_desc" },
  1223. { OSQLParseNode::where_clause, "where_clause" },
  1224. { OSQLParseNode::opt_where_clause, "opt_where_clause" },
  1225. { OSQLParseNode::search_condition, "search_condition" },
  1226. { OSQLParseNode::comparison_predicate, "comparison_predicate" },
  1227. { OSQLParseNode::between_predicate, "between_predicate" },
  1228. { OSQLParseNode::like_predicate, "like_predicate" },
  1229. { OSQLParseNode::opt_escape, "opt_escape" },
  1230. { OSQLParseNode::test_for_null, "test_for_null" },
  1231. { OSQLParseNode::scalar_exp_commalist, "scalar_exp_commalist" },
  1232. { OSQLParseNode::scalar_exp, "scalar_exp" },
  1233. { OSQLParseNode::parameter_ref, "parameter_ref" },
  1234. { OSQLParseNode::parameter, "parameter" },
  1235. { OSQLParseNode::general_set_fct, "general_set_fct" },
  1236. { OSQLParseNode::range_vari

Large files files are truncated, but you can click here to view the full file