1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <sal/macros.h>
21 #include <connectivity/sqlnode.hxx>
22 #include <connectivity/sqlerror.hxx>
23 #include <connectivity/sqlbison_exports.hxx>
24 #include <connectivity/internalnode.hxx>
25 #define YYBISON 1
26 #include <sqlbison.hxx>
27 #include <connectivity/sqlparse.hxx>
28 #include <connectivity/sqlscan.hxx>
29 #include <com/sun/star/lang/Locale.hpp>
30 #include <com/sun/star/util/XNumberFormatter.hpp>
31 #include <com/sun/star/util/XNumberFormatTypes.hpp>
32 #include <com/sun/star/i18n/LocaleData.hpp>
33 #include <com/sun/star/i18n/NumberFormatIndex.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
36 #include <com/sun/star/sdbc/DataType.hpp>
37 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
38 #include <com/sun/star/sdb/ErrorCondition.hpp>
39 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
40 #include <com/sun/star/util/XNumberFormats.hpp>
41 #include <com/sun/star/util/NumberFormat.hpp>
42 #include <com/sun/star/i18n/KParseType.hpp>
43 #include <com/sun/star/i18n/KParseTokens.hpp>
44 #include <com/sun/star/i18n/CharacterClassification.hpp>
45 #include <connectivity/dbconversion.hxx>
46 #include <com/sun/star/util/DateTime.hpp>
47 #include <com/sun/star/util/Time.hpp>
48 #include <com/sun/star/util/Date.hpp>
49 #include <TConnection.hxx>
50 #include <comphelper/numbers.hxx>
51 #include <connectivity/dbtools.hxx>
52 #include <connectivity/dbmetadata.hxx>
53 #include <tools/diagnose_ex.h>
54 #include <string.h>
55 #include <algorithm>
56 #include <functional>
57 #include <memory>
58 #include <rtl/ustrbuf.hxx>
59 #include <sal/log.hxx>
60
61 using namespace ::com::sun::star::sdbc;
62 using namespace ::com::sun::star::util;
63 using namespace ::com::sun::star::beans;
64 using namespace ::com::sun::star::sdb;
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::lang;
67 using namespace ::com::sun::star::i18n;
68 using namespace ::com::sun::star;
69 using namespace ::osl;
70 using namespace ::dbtools;
71 using namespace ::comphelper;
72
73 namespace
74 {
75
lcl_saveConvertToNumber(const Reference<XNumberFormatter> & _xFormatter,sal_Int32 _nKey,const OUString & _sValue,double & _nrValue)76 bool lcl_saveConvertToNumber(const Reference< XNumberFormatter > & _xFormatter,sal_Int32 _nKey,const OUString& _sValue,double& _nrValue)
77 {
78 bool bRet = false;
79 try
80 {
81 _nrValue = _xFormatter->convertStringToNumber(_nKey, _sValue);
82 bRet = true;
83 }
84 catch(Exception&)
85 {
86 }
87 return bRet;
88 }
89
replaceAndReset(connectivity::OSQLParseNode * & _pResetNode,connectivity::OSQLParseNode * _pNewNode)90 void replaceAndReset(connectivity::OSQLParseNode*& _pResetNode,connectivity::OSQLParseNode* _pNewNode)
91 {
92 _pResetNode->getParent()->replace(_pResetNode, _pNewNode);
93 delete _pResetNode;
94 _pResetNode = _pNewNode;
95 }
96
97 /** quotes a string and search for quotes inside the string and replace them with the new quote
98 @param rValue
99 The value to be quoted.
100 @param rQuot
101 The quote
102 @param rQuotToReplace
103 The quote to replace with
104 @return
105 The quoted string.
106 */
SetQuotation(const OUString & rValue,const OUString & rQuot,const OUString & rQuotToReplace)107 OUString SetQuotation(const OUString& rValue, const OUString& rQuot, const OUString& rQuotToReplace)
108 {
109 OUString rNewValue = rQuot + rValue;
110 sal_Int32 nIndex = sal_Int32(-1); // Replace quotes with double quotes or the parser gets into problems
111
112 if (!rQuot.isEmpty())
113 {
114 do
115 {
116 nIndex += 2;
117 nIndex = rNewValue.indexOf(rQuot,nIndex);
118 if(nIndex != -1)
119 rNewValue = rNewValue.replaceAt(nIndex,rQuot.getLength(),rQuotToReplace);
120 } while (nIndex != -1);
121 }
122
123 rNewValue += rQuot;
124 return rNewValue;
125 }
126
columnMatchP(const connectivity::OSQLParseNode * pSubTree,const connectivity::SQLParseNodeParameter & rParam)127 bool columnMatchP(const connectivity::OSQLParseNode* pSubTree, const connectivity::SQLParseNodeParameter& rParam)
128 {
129 using namespace connectivity;
130 assert(SQL_ISRULE(pSubTree,column_ref));
131
132 if(!rParam.xField.is())
133 return false;
134
135 // retrieve the field's name & table range
136 OUString aFieldName;
137 try
138 {
139 sal_Int32 nNamePropertyId = PROPERTY_ID_NAME;
140 if ( rParam.xField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) )
141 nNamePropertyId = PROPERTY_ID_REALNAME;
142 rParam.xField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( nNamePropertyId ) ) >>= aFieldName;
143 }
144 catch ( Exception& )
145 {
146 }
147
148 if(pSubTree->count())
149 {
150 const OSQLParseNode* pCol = pSubTree->getChild(pSubTree->count()-1);
151 if (SQL_ISRULE(pCol,column_val))
152 {
153 assert(pCol->count() == 1);
154 pCol = pCol->getChild(0);
155 }
156 const OSQLParseNode* pTable(nullptr);
157 switch (pSubTree->count())
158 {
159 case 1:
160 break;
161 case 3:
162 pTable = pSubTree->getChild(0);
163 break;
164 case 5:
165 case 7:
166 SAL_WARN("connectivity.parse", "SQL: catalog and/or schema in column_ref in predicate");
167 break;
168 default:
169 SAL_WARN("connectivity.parse", "columnMatchP: SQL grammar changed; column_ref has " << pSubTree->count() << " children");
170 assert(false);
171 break;
172 }
173 // TODO: not all DBMS match column names case-insensitively...
174 // see XDatabaseMetaData::supportsMixedCaseIdentifiers()
175 // and XDatabaseMetaData::supportsMixedCaseQuotedIdentifiers()
176 if ( // table name matches (or no table name)?
177 ( !pTable || pTable->getTokenValue().equalsIgnoreAsciiCase(rParam.sPredicateTableAlias) )
178 && // column name matches?
179 pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName)
180 )
181 return true;
182 }
183 return false;
184 }
185 }
186
187 namespace connectivity
188 {
189
SQLParseNodeParameter(const Reference<XConnection> & _rxConnection,const Reference<XNumberFormatter> & _xFormatter,const Reference<XPropertySet> & _xField,const OUString & _sPredicateTableAlias,const Locale & _rLocale,const IParseContext * _pContext,bool _bIntl,bool _bQuote,OUString _sDecSep,bool _bPredicate,bool _bParseToSDBC)190 SQLParseNodeParameter::SQLParseNodeParameter( const Reference< XConnection >& _rxConnection,
191 const Reference< XNumberFormatter >& _xFormatter, const Reference< XPropertySet >& _xField,
192 const OUString &_sPredicateTableAlias,
193 const Locale& _rLocale, const IParseContext* _pContext,
194 bool _bIntl, bool _bQuote, OUString _sDecSep, bool _bPredicate, bool _bParseToSDBC )
195 :rLocale(_rLocale)
196 ,aMetaData( _rxConnection )
197 ,pParser( nullptr )
198 ,pSubQueryHistory( new QueryNameSet )
199 ,xFormatter(_xFormatter)
200 ,xField(_xField)
201 ,sPredicateTableAlias(_sPredicateTableAlias)
202 ,m_rContext( _pContext ? *_pContext : OSQLParser::s_aDefaultContext )
203 ,sDecSep(_sDecSep)
204 ,bQuote(_bQuote)
205 ,bInternational(_bIntl)
206 ,bPredicate(_bPredicate)
207 ,bParseToSDBCLevel( _bParseToSDBC )
208 {
209 }
210
convertDateString(const SQLParseNodeParameter & rParam,const OUString & rString)211 OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const OUString& rString)
212 {
213 Date aDate = DBTypeConversion::toDate(rString);
214 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
215 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
216
217 double fDate = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
218 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 36; // XXX hack
219 return rParam.xFormatter->convertNumberToString(nKey, fDate);
220 }
221
222
convertDateTimeString(const SQLParseNodeParameter & rParam,const OUString & rString)223 OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const OUString& rString)
224 {
225 DateTime aDate = DBTypeConversion::toDateTime(rString);
226 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
227 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
228
229 double fDateTime = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
230 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 51; // XXX hack
231 return rParam.xFormatter->convertNumberToString(nKey, fDateTime);
232 }
233
234
convertTimeString(const SQLParseNodeParameter & rParam,const OUString & rString)235 OUString OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const OUString& rString)
236 {
237 css::util::Time aTime = DBTypeConversion::toTime(rString);
238 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
239
240 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
241
242 double fTime = DBTypeConversion::toDouble(aTime);
243 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 41; // XXX hack
244 return rParam.xFormatter->convertNumberToString(nKey, fTime);
245 }
246
247
parseNodeToStr(OUString & rString,const Reference<XConnection> & _rxConnection,const IParseContext * pContext,bool _bIntl,bool _bQuote) const248 void OSQLParseNode::parseNodeToStr(OUString& rString,
249 const Reference< XConnection >& _rxConnection,
250 const IParseContext* pContext,
251 bool _bIntl,
252 bool _bQuote) const
253 {
254 parseNodeToStr(
255 rString, _rxConnection, nullptr, nullptr, OUString(),
256 pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(),
257 pContext, _bIntl, _bQuote, OUString("."), false );
258 }
259
260
parseNodeToPredicateStr(OUString & rString,const Reference<XConnection> & _rxConnection,const Reference<XNumberFormatter> & xFormatter,const css::lang::Locale & rIntl,OUString _sDec,const IParseContext * pContext) const261 void OSQLParseNode::parseNodeToPredicateStr(OUString& rString,
262 const Reference< XConnection >& _rxConnection,
263 const Reference< XNumberFormatter > & xFormatter,
264 const css::lang::Locale& rIntl,
265 OUString _sDec,
266 const IParseContext* pContext ) const
267 {
268 OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
269
270 if (xFormatter.is())
271 parseNodeToStr(rString, _rxConnection, xFormatter, nullptr, OUString(), rIntl, pContext, true, true, _sDec, true);
272 }
273
274
parseNodeToPredicateStr(OUString & rString,const Reference<XConnection> & _rxConnection,const Reference<XNumberFormatter> & xFormatter,const Reference<XPropertySet> & _xField,const OUString & _sPredicateTableAlias,const css::lang::Locale & rIntl,OUString _sDec,const IParseContext * pContext) const275 void OSQLParseNode::parseNodeToPredicateStr(OUString& rString,
276 const Reference< XConnection > & _rxConnection,
277 const Reference< XNumberFormatter > & xFormatter,
278 const Reference< XPropertySet > & _xField,
279 const OUString &_sPredicateTableAlias,
280 const css::lang::Locale& rIntl,
281 OUString _sDec,
282 const IParseContext* pContext ) const
283 {
284 OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
285
286 if (xFormatter.is())
287 parseNodeToStr( rString, _rxConnection, xFormatter, _xField, _sPredicateTableAlias, rIntl, pContext, true, true, _sDec, true );
288 }
289
290
parseNodeToStr(OUString & rString,const Reference<XConnection> & _rxConnection,const Reference<XNumberFormatter> & xFormatter,const Reference<XPropertySet> & _xField,const OUString & _sPredicateTableAlias,const css::lang::Locale & rIntl,const IParseContext * pContext,bool _bIntl,bool _bQuote,OUString _sDecSep,bool _bPredicate) const291 void OSQLParseNode::parseNodeToStr(OUString& rString,
292 const Reference< XConnection > & _rxConnection,
293 const Reference< XNumberFormatter > & xFormatter,
294 const Reference< XPropertySet > & _xField,
295 const OUString &_sPredicateTableAlias,
296 const css::lang::Locale& rIntl,
297 const IParseContext* pContext,
298 bool _bIntl,
299 bool _bQuote,
300 OUString _sDecSep,
301 bool _bPredicate) const
302 {
303 OSL_ENSURE( _rxConnection.is(), "OSQLParseNode::parseNodeToStr: invalid connection!" );
304
305 if ( _rxConnection.is() )
306 {
307 OUStringBuffer sBuffer = rString;
308 try
309 {
310 OSQLParseNode::impl_parseNodeToString_throw( sBuffer,
311 SQLParseNodeParameter(
312 _rxConnection, xFormatter, _xField, _sPredicateTableAlias, rIntl, pContext,
313 _bIntl, _bQuote, _sDecSep, _bPredicate, false
314 ) );
315 }
316 catch( const SQLException& )
317 {
318 SAL_WARN( "connectivity.parse", "OSQLParseNode::parseNodeToStr: this should not throw!" );
319 // our callers don't expect this method to throw anything. The only known situation
320 // where impl_parseNodeToString_throw can throw is when there is a cyclic reference
321 // in the sub queries, but this cannot be the case here, as we do not parse to
322 // SDBC level.
323 }
324 rString = sBuffer.makeStringAndClear();
325 }
326 }
327
parseNodeToExecutableStatement(OUString & _out_rString,const Reference<XConnection> & _rxConnection,OSQLParser & _rParser,css::sdbc::SQLException * _pErrorHolder) const328 bool OSQLParseNode::parseNodeToExecutableStatement( OUString& _out_rString, const Reference< XConnection >& _rxConnection,
329 OSQLParser& _rParser, css::sdbc::SQLException* _pErrorHolder ) const
330 {
331 OSL_PRECOND( _rxConnection.is(), "OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" );
332 SQLParseNodeParameter aParseParam( _rxConnection,
333 nullptr, nullptr, OUString(), OParseContext::getDefaultLocale(), nullptr, false, true, OUString("."), false, true );
334
335 if ( aParseParam.aMetaData.supportsSubqueriesInFrom() )
336 {
337 Reference< XQueriesSupplier > xSuppQueries( _rxConnection, UNO_QUERY );
338 OSL_ENSURE( xSuppQueries.is(), "OSQLParseNode::parseNodeToExecutableStatement: cannot substitute everything without a QueriesSupplier!" );
339 if ( xSuppQueries.is() )
340 aParseParam.xQueries = xSuppQueries->getQueries();
341 }
342
343 aParseParam.pParser = &_rParser;
344
345 // LIMIT keyword differs in Firebird
346 OSQLParseNode* pTableExp = getChild(3);
347 Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData() );
348 OUString sLimitValue;
349 if( pTableExp->getChild(6)->count() >= 2 && pTableExp->getChild(6)->getChild(1)
350 && (xMeta->getURL().equalsIgnoreAsciiCase("sdbc:embedded:firebird")
351 || xMeta->getURL().startsWithIgnoreAsciiCase("sdbc:firebird:")))
352 {
353 sLimitValue = pTableExp->getChild(6)->getChild(1)->getTokenValue();
354 pTableExp->removeAt(6);
355 }
356
357 _out_rString.clear();
358 OUStringBuffer sBuffer;
359 bool bSuccess = false;
360 try
361 {
362 impl_parseNodeToString_throw( sBuffer, aParseParam );
363 bSuccess = true;
364 }
365 catch( const SQLException& e )
366 {
367 if ( _pErrorHolder )
368 *_pErrorHolder = e;
369 }
370
371 if(sLimitValue.getLength() > 0)
372 {
373 constexpr char SELECT_KEYWORD[] = "SELECT";
374 sBuffer.insert(sBuffer.indexOf(SELECT_KEYWORD) + strlen(SELECT_KEYWORD),
375 " FIRST " + sLimitValue);
376 }
377
378 _out_rString = sBuffer.makeStringAndClear();
379 return bSuccess;
380 }
381
382
383 namespace
384 {
lcl_isAliasNamePresent(const OSQLParseNode & _rTableNameNode)385 bool lcl_isAliasNamePresent( const OSQLParseNode& _rTableNameNode )
386 {
387 return !OSQLParseNode::getTableRange(_rTableNameNode.getParent()).isEmpty();
388 }
389 }
390
391
impl_parseNodeToString_throw(OUStringBuffer & rString,const SQLParseNodeParameter & rParam,bool bSimple) const392 void OSQLParseNode::impl_parseNodeToString_throw(OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple) const
393 {
394 if ( isToken() )
395 {
396 parseLeaf(rString,rParam);
397 return;
398 }
399
400 // Lets see how many nodes this subtree has
401 sal_uInt32 nCount = count();
402
403 bool bHandled = false;
404 switch ( getKnownRuleID() )
405 {
406 // special handling for parameters
407 case parameter:
408 {
409 bSimple=false;
410 if(!rString.isEmpty())
411 rString.append(" ");
412 if (nCount == 1) // ?
413 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
414 else if (rParam.bParseToSDBCLevel && rParam.aMetaData.shouldSubstituteParameterNames())
415 {
416 rString.append("?");
417 }
418 else if (nCount == 2) // :Name
419 {
420 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
421 rString.append(m_aChildren[1]->m_aNodeValue);
422 } // [Name]
423 else
424 {
425 assert (nCount == 3);
426 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
427 rString.append(m_aChildren[1]->m_aNodeValue);
428 rString.append(m_aChildren[2]->m_aNodeValue);
429 }
430 bHandled = true;
431 }
432 break;
433
434 // table refs
435 case table_ref:
436 bSimple=false;
437 if ( ( nCount == 2 ) || ( nCount == 3 ) || ( nCount == 5 ) )
438 {
439 impl_parseTableRangeNodeToString_throw( rString, rParam );
440 bHandled = true;
441 }
442 break;
443
444 // table name - might be a query name
445 case table_name:
446 bSimple=false;
447 bHandled = impl_parseTableNameNodeToString_throw( rString, rParam );
448 break;
449
450 case as_clause:
451 bSimple=false;
452 assert(nCount == 0 || nCount == 2);
453 if (nCount == 2)
454 {
455 if ( rParam.aMetaData.generateASBeforeCorrelationName() )
456 rString.append(" AS ");
457 m_aChildren[1]->impl_parseNodeToString_throw( rString, rParam, false );
458 }
459 bHandled = true;
460 break;
461
462 case opt_as:
463 assert(nCount == 0);
464 bHandled = true;
465 break;
466
467 case like_predicate:
468 // Depending on whether international is given, LIKE is treated differently
469 // international: *, ? are placeholders
470 // else SQL92 conform: %, _
471 impl_parseLikeNodeToString_throw( rString, rParam, bSimple );
472 bHandled = true;
473 break;
474
475 case general_set_fct:
476 case set_fct_spec:
477 case position_exp:
478 case extract_exp:
479 case length_exp:
480 case char_value_fct:
481 bSimple=false;
482 if (!addDateValue(rString, rParam))
483 {
484 // Do not quote function name
485 SQLParseNodeParameter aNewParam(rParam);
486 aNewParam.bQuote = ( SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct) );
487
488 m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam, false );
489 aNewParam.bQuote = rParam.bQuote;
490 //aNewParam.bPredicate = sal_False; // disable [ ] around names // look at i73215
491 OUStringBuffer aStringPara;
492 for (sal_uInt32 i=1; i<nCount; i++)
493 {
494 const OSQLParseNode * pSubTree = m_aChildren[i].get();
495 if (pSubTree)
496 {
497 pSubTree->impl_parseNodeToString_throw( aStringPara, aNewParam, false );
498
499 // In the comma lists, put commas in-between all subtrees
500 if ((m_eNodeType == SQLNodeType::CommaListRule) && (i < (nCount - 1)))
501 aStringPara.append(",");
502 }
503 else
504 i++;
505 }
506 rString.append(aStringPara.makeStringAndClear());
507 }
508 bHandled = true;
509 break;
510 case odbc_call_spec:
511 case subquery:
512 case term:
513 case factor:
514 case window_function:
515 case cast_spec:
516 case num_value_exp:
517 bSimple = false;
518 break;
519 default:
520 break;
521 } // switch ( getKnownRuleID() )
522
523 if ( !bHandled )
524 {
525 for (auto i = m_aChildren.begin(); i != m_aChildren.end();)
526 {
527 const OSQLParseNode* pSubTree = i->get();
528 if ( !pSubTree )
529 {
530 ++i;
531 continue;
532 }
533
534 SQLParseNodeParameter aNewParam(rParam);
535
536 // don't replace the field for subqueries
537 if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery))
538 aNewParam.xField = nullptr;
539
540 // When we are building a criterion inside a query view,
541 // simplify criterion display by removing:
542 // "currentFieldName"
543 // "currentFieldName" =
544 // but only in simple expressions.
545 // This means anything that is made of:
546 // (see the rules conditionalised by inPredicateCheck() in sqlbison.y).
547 // - parentheses
548 // - logical operators (and, or, not)
549 // - comparison operators (IS, =, >, <, BETWEEN, LIKE, ...)
550 // but *not* e.g. in function arguments
551 if (bSimple && rParam.bPredicate && rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref))
552 {
553 if (columnMatchP(pSubTree, rParam))
554 {
555 // skip field
556 ++i;
557 // if the following node is the comparison operator'=',
558 // we filter it as well
559 if (SQL_ISRULE(this, comparison_predicate))
560 {
561 if(i != m_aChildren.end())
562 {
563 pSubTree = i->get();
564 if (pSubTree && pSubTree->getNodeType() == SQLNodeType::Equal)
565 ++i;
566 }
567 }
568 }
569 else
570 {
571 pSubTree->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
572 ++i;
573
574 // In the comma lists, put commas in-between all subtrees
575 if ((m_eNodeType == SQLNodeType::CommaListRule) && (i != m_aChildren.end()))
576 rString.append(",");
577 }
578 }
579 else
580 {
581 pSubTree->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
582 ++i;
583
584 // In the comma lists, put commas in-between all subtrees
585 if ((m_eNodeType == SQLNodeType::CommaListRule) && (i != m_aChildren.end()))
586 {
587 if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate)
588 rString.append(";");
589 else
590 rString.append(",");
591 }
592 }
593 // The right hand-side of these operators is not simple
594 switch ( getKnownRuleID() )
595 {
596 case general_set_fct:
597 case set_fct_spec:
598 case position_exp:
599 case extract_exp:
600 case length_exp:
601 case char_value_fct:
602 case odbc_call_spec:
603 case subquery:
604 case comparison_predicate:
605 case between_predicate:
606 case like_predicate:
607 case test_for_null:
608 case in_predicate:
609 case existence_test:
610 case unique_test:
611 case all_or_any_predicate:
612 case join_condition:
613 case comparison_predicate_part_2:
614 case parenthesized_boolean_value_expression:
615 case other_like_predicate_part_2:
616 case between_predicate_part_2:
617 bSimple=false;
618 break;
619 default:
620 break;
621 }
622 }
623 }
624 }
625
626
impl_parseTableNameNodeToString_throw(OUStringBuffer & rString,const SQLParseNodeParameter & rParam) const627 bool OSQLParseNode::impl_parseTableNameNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
628 {
629 // is the table_name part of a table_ref?
630 OSL_ENSURE( getParent(), "OSQLParseNode::impl_parseTableNameNodeToString_throw: table_name without parent?" );
631 if ( !getParent() || ( getParent()->getKnownRuleID() != table_ref ) )
632 return false;
633
634 // if it's a query, maybe we need to substitute the SQL statement ...
635 if ( !rParam.bParseToSDBCLevel )
636 return false;
637
638 if ( !rParam.xQueries.is() )
639 // connection does not support queries in queries, or was no query supplier
640 return false;
641
642 try
643 {
644 OUString sTableOrQueryName( getChild(0)->getTokenValue() );
645 bool bIsQuery = rParam.xQueries->hasByName( sTableOrQueryName );
646 if ( !bIsQuery )
647 return false;
648
649 // avoid recursion (e.g. "foo" defined as "SELECT * FROM bar" and "bar" defined as "SELECT * FROM foo".
650 if ( rParam.pSubQueryHistory->find( sTableOrQueryName ) != rParam.pSubQueryHistory->end() )
651 {
652 OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: no parser?" );
653 if ( rParam.pParser )
654 {
655 const SQLError& rErrors( rParam.pParser->getErrorHelper() );
656 rErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
657 }
658 else
659 {
660 SQLError aErrors;
661 aErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
662 }
663 }
664 rParam.pSubQueryHistory->insert( sTableOrQueryName );
665
666 Reference< XPropertySet > xQuery( rParam.xQueries->getByName( sTableOrQueryName ), UNO_QUERY_THROW );
667
668 // substitute the query name with the constituting command
669 OUString sCommand;
670 OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sCommand );
671
672 bool bEscapeProcessing = false;
673 OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing );
674
675 // the query we found here might itself be based on another query, so parse it recursively
676 OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: cannot analyze sub queries without a parser!" );
677 if ( bEscapeProcessing && rParam.pParser )
678 {
679 OUString sError;
680 std::unique_ptr< OSQLParseNode > pSubQueryNode( rParam.pParser->parseTree( sError, sCommand ) );
681 if (pSubQueryNode)
682 {
683 // parse the sub-select to SDBC level, too
684 OUStringBuffer sSubSelect;
685 pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, rParam, false );
686 if ( !sSubSelect.isEmpty() )
687 sCommand = sSubSelect.makeStringAndClear();
688 }
689 }
690
691 rString.append( " ( " );
692 rString.append(sCommand);
693 rString.append( " )" );
694
695 // append the query name as table alias, since it might be referenced in other
696 // parts of the statement - but only if there's no other alias name present
697 if ( !lcl_isAliasNamePresent( *this ) )
698 {
699 rString.append( " AS " );
700 if ( rParam.bQuote )
701 rString.append(SetQuotation( sTableOrQueryName,
702 rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() ));
703 }
704
705 // don't forget to remove the query name from the history, else multiple inclusions
706 // won't work
707 // #i69227# / 2006-10-10 / frank.schoenheit@sun.com
708 rParam.pSubQueryHistory->erase( sTableOrQueryName );
709
710 return true;
711 }
712 catch( const SQLException& )
713 {
714 throw;
715 }
716 catch( const Exception& )
717 {
718 DBG_UNHANDLED_EXCEPTION("connectivity.parse");
719 }
720 return false;
721 }
722
723
impl_parseTableRangeNodeToString_throw(OUStringBuffer & rString,const SQLParseNodeParameter & rParam) const724 void OSQLParseNode::impl_parseTableRangeNodeToString_throw(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
725 {
726 OSL_PRECOND( ( count() == 2 ) || ( count() == 3 ) || ( count() == 5 ) ,"Illegal count");
727
728 // rString += " ";
729 std::for_each(m_aChildren.begin(),m_aChildren.end(),
730 [&] (std::unique_ptr<OSQLParseNode> const & pNode) { pNode->impl_parseNodeToString_throw(rString, rParam, false); });
731 }
732
733
impl_parseLikeNodeToString_throw(OUStringBuffer & rString,const SQLParseNodeParameter & rParam,bool bSimple) const734 void OSQLParseNode::impl_parseLikeNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple ) const
735 {
736 assert(SQL_ISRULE(this,like_predicate));
737 OSL_ENSURE(count() == 2,"count != 2: Prepare for GPF");
738
739 const OSQLParseNode* pEscNode = nullptr;
740 const OSQLParseNode* pParaNode = nullptr;
741
742 SQLParseNodeParameter aNewParam(rParam);
743 //aNewParam.bQuote = sal_True; // why setting this to true? @see https://bz.apache.org/ooo/show_bug.cgi?id=75557
744
745 if ( !(bSimple && rParam.bPredicate && rParam.xField.is() && SQL_ISRULE(m_aChildren[0],column_ref) && columnMatchP(m_aChildren[0].get(), rParam)) )
746 m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
747
748 const OSQLParseNode* pPart2 = m_aChildren[1].get();
749 pPart2->getChild(0)->impl_parseNodeToString_throw( rString, aNewParam, false );
750 pPart2->getChild(1)->impl_parseNodeToString_throw( rString, aNewParam, false );
751 pParaNode = pPart2->getChild(2);
752 pEscNode = pPart2->getChild(3);
753
754 if (pParaNode->isToken())
755 {
756 OUString aStr = ConvertLikeToken(pParaNode, pEscNode, rParam.bInternational);
757 rString.append(" ");
758 rString.append(SetQuotation(aStr,"\'","\'\'"));
759 }
760 else
761 pParaNode->impl_parseNodeToString_throw( rString, aNewParam, false );
762
763 pEscNode->impl_parseNodeToString_throw( rString, aNewParam, false );
764 }
765
766
getTableComponents(const OSQLParseNode * _pTableNode,css::uno::Any & _rCatalog,OUString & _rSchema,OUString & _rTable,const Reference<XDatabaseMetaData> & _xMetaData)767 bool OSQLParseNode::getTableComponents(const OSQLParseNode* _pTableNode,
768 css::uno::Any &_rCatalog,
769 OUString &_rSchema,
770 OUString &_rTable,
771 const Reference< XDatabaseMetaData >& _xMetaData)
772 {
773 OSL_ENSURE(_pTableNode,"Wrong use of getTableComponents! _pTableNode is not allowed to be null!");
774 if(_pTableNode)
775 {
776 const bool bSupportsCatalog = _xMetaData.is() && _xMetaData->supportsCatalogsInDataManipulation();
777 const bool bSupportsSchema = _xMetaData.is() && _xMetaData->supportsSchemasInDataManipulation();
778 const OSQLParseNode* pTableNode = _pTableNode;
779 // clear the parameter given
780 _rCatalog = Any();
781 _rSchema.clear();
782 _rTable.clear();
783 // see rule catalog_name: in sqlbison.y
784 if (SQL_ISRULE(pTableNode,catalog_name))
785 {
786 OSL_ENSURE(pTableNode->getChild(0) && pTableNode->getChild(0)->isToken(),"Invalid parsenode!");
787 _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
788 pTableNode = pTableNode->getChild(2);
789 }
790 // check if we have schema_name rule
791 if(SQL_ISRULE(pTableNode,schema_name))
792 {
793 if ( bSupportsCatalog && !bSupportsSchema )
794 _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
795 else
796 _rSchema = pTableNode->getChild(0)->getTokenValue();
797 pTableNode = pTableNode->getChild(2);
798 }
799 // check if we have table_name rule
800 if(SQL_ISRULE(pTableNode,table_name))
801 {
802 _rTable = pTableNode->getChild(0)->getTokenValue();
803 }
804 else
805 {
806 SAL_WARN( "connectivity.parse","Error in parse tree!");
807 }
808 }
809 return !_rTable.isEmpty();
810 }
811
killThousandSeparator(OSQLParseNode * pLiteral)812 void OSQLParser::killThousandSeparator(OSQLParseNode* pLiteral)
813 {
814 if ( pLiteral )
815 {
816 if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
817 {
818 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace('.', sal_Unicode());
819 // and replace decimal
820 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', '.');
821 }
822 else
823 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', sal_Unicode());
824 }
825 }
826
convertNode(sal_Int32 nType,OSQLParseNode * pLiteral)827 OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType, OSQLParseNode* pLiteral)
828 {
829 if ( !pLiteral )
830 return nullptr;
831
832 OSQLParseNode* pReturn = pLiteral;
833
834 if ( ( pLiteral->isRule() && !SQL_ISRULE(pLiteral,value_exp) ) || SQL_ISTOKEN(pLiteral,FALSE) || SQL_ISTOKEN(pLiteral,TRUE) )
835 {
836 switch(nType)
837 {
838 case DataType::CHAR:
839 case DataType::VARCHAR:
840 case DataType::LONGVARCHAR:
841 case DataType::CLOB:
842 if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) )
843 pReturn = nullptr;
844 break;
845 default:
846 break;
847 }
848 }
849 else
850 {
851 switch(pLiteral->getNodeType())
852 {
853 case SQLNodeType::String:
854 switch(nType)
855 {
856 case DataType::CHAR:
857 case DataType::VARCHAR:
858 case DataType::LONGVARCHAR:
859 case DataType::CLOB:
860 break;
861 case DataType::DATE:
862 case DataType::TIME:
863 case DataType::TIMESTAMP:
864 if (m_xFormatter.is())
865 pReturn = buildDate( nType, pReturn);
866 break;
867 default:
868 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidCompare);
869 break;
870 }
871 break;
872 case SQLNodeType::AccessDate:
873 switch(nType)
874 {
875 case DataType::DATE:
876 case DataType::TIME:
877 case DataType::TIMESTAMP:
878 if ( m_xFormatter.is() )
879 pReturn = buildDate( nType, pReturn);
880 else
881 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidDateCompare);
882 break;
883 default:
884 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidCompare);
885 break;
886 }
887 break;
888 case SQLNodeType::IntNum:
889 switch(nType)
890 {
891 case DataType::BIT:
892 case DataType::BOOLEAN:
893 case DataType::DECIMAL:
894 case DataType::NUMERIC:
895 case DataType::TINYINT:
896 case DataType::SMALLINT:
897 case DataType::INTEGER:
898 case DataType::BIGINT:
899 case DataType::FLOAT:
900 case DataType::REAL:
901 case DataType::DOUBLE:
902 // kill thousand separators if any
903 killThousandSeparator(pReturn);
904 break;
905 case DataType::CHAR:
906 case DataType::VARCHAR:
907 case DataType::LONGVARCHAR:
908 case DataType::CLOB:
909 pReturn = buildNode_STR_NUM(pReturn);
910 break;
911 default:
912 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidIntCompare);
913 break;
914 }
915 break;
916 case SQLNodeType::ApproxNum:
917 switch(nType)
918 {
919 case DataType::DECIMAL:
920 case DataType::NUMERIC:
921 case DataType::FLOAT:
922 case DataType::REAL:
923 case DataType::DOUBLE:
924 // kill thousand separators if any
925 killThousandSeparator(pReturn);
926 break;
927 case DataType::CHAR:
928 case DataType::VARCHAR:
929 case DataType::LONGVARCHAR:
930 case DataType::CLOB:
931 pReturn = buildNode_STR_NUM(pReturn);
932 break;
933 case DataType::INTEGER:
934 default:
935 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidRealCompare);
936 break;
937 }
938 break;
939 default:
940 ;
941 }
942 }
943 return pReturn;
944 }
945
buildPredicateRule(OSQLParseNode * & pAppend,OSQLParseNode * pLiteral,OSQLParseNode * pCompare,OSQLParseNode * pLiteral2)946 sal_Int16 OSQLParser::buildPredicateRule(OSQLParseNode*& pAppend, OSQLParseNode* pLiteral, OSQLParseNode* pCompare, OSQLParseNode* pLiteral2)
947 {
948 OSL_ENSURE(inPredicateCheck(),"Only in predicate check allowed!");
949 sal_Int16 nErg = 0;
950 if ( m_xField.is() )
951 {
952 sal_Int32 nType = 0;
953 try
954 {
955 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
956 }
957 catch( Exception& )
958 {
959 return nErg;
960 }
961
962 OSQLParseNode* pNode1 = convertNode(nType,pLiteral);
963 if ( pNode1 )
964 {
965 OSQLParseNode* pNode2 = convertNode(nType,pLiteral2);
966 if ( m_sErrorMessage.isEmpty() )
967 nErg = buildNode(pAppend,pCompare,pNode1,pNode2);
968 }
969 }
970 if (!pCompare->getParent()) // I have no parent so I was not used and I must die :-)
971 delete pCompare;
972 return nErg;
973 }
974
buildLikeRule(OSQLParseNode * pAppend,OSQLParseNode * & pLiteral,const OSQLParseNode * pEscape)975 sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode* pAppend, OSQLParseNode*& pLiteral, const OSQLParseNode* pEscape)
976 {
977 sal_Int16 nErg = 0;
978 sal_Int32 nType = 0;
979
980 if (!m_xField.is())
981 return nErg;
982 try
983 {
984 Any aValue;
985 {
986 aValue = m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE));
987 aValue >>= nType;
988 }
989 }
990 catch( Exception& )
991 {
992 return nErg;
993 }
994
995 switch (nType)
996 {
997 case DataType::CHAR:
998 case DataType::VARCHAR:
999 case DataType::LONGVARCHAR:
1000 case DataType::CLOB:
1001 if(pLiteral->isRule())
1002 {
1003 pAppend->append(pLiteral);
1004 nErg = 1;
1005 }
1006 else
1007 {
1008 switch(pLiteral->getNodeType())
1009 {
1010 case SQLNodeType::String:
1011 pLiteral->m_aNodeValue = ConvertLikeToken(pLiteral, pEscape, false);
1012 pAppend->append(pLiteral);
1013 nErg = 1;
1014 break;
1015 case SQLNodeType::ApproxNum:
1016 if (m_xFormatter.is() && m_nFormatKey)
1017 {
1018 sal_Int16 nScale = 0;
1019 try
1020 {
1021 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, "Decimals" );
1022 aValue >>= nScale;
1023 }
1024 catch( Exception& )
1025 {
1026 }
1027
1028 pAppend->append(new OSQLInternalNode(stringToDouble(pLiteral->getTokenValue(),nScale),SQLNodeType::String));
1029 }
1030 else
1031 pAppend->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQLNodeType::String));
1032
1033 delete pLiteral;
1034 nErg = 1;
1035 break;
1036 default:
1037 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::ValueNoLike);
1038 m_sErrorMessage = m_sErrorMessage.replaceAt(m_sErrorMessage.indexOf("#1"),2,pLiteral->getTokenValue());
1039 break;
1040 }
1041 }
1042 break;
1043 default:
1044 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::FieldNoLike);
1045 break;
1046 }
1047 return nErg;
1048 }
1049
buildNode_Date(const double & fValue,sal_Int32 nType)1050 OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType)
1051 {
1052 OSQLParseNode* pNewNode = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::set_fct_spec));
1053 pNewNode->append(new OSQLInternalNode("{", SQLNodeType::Punctuation));
1054 OSQLParseNode* pDateNode = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::odbc_fct_spec));
1055 pNewNode->append(pDateNode);
1056 pNewNode->append(new OSQLInternalNode("}", SQLNodeType::Punctuation));
1057
1058 switch (nType)
1059 {
1060 case DataType::DATE:
1061 {
1062 Date aDate = DBTypeConversion::toDate(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
1063 OUString aString = DBTypeConversion::toDateString(aDate);
1064 pDateNode->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_D));
1065 pDateNode->append(new OSQLInternalNode(aString, SQLNodeType::String));
1066 break;
1067 }
1068 case DataType::TIME:
1069 {
1070 css::util::Time aTime = DBTypeConversion::toTime(fValue);
1071 OUString aString = DBTypeConversion::toTimeString(aTime);
1072 pDateNode->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_T));
1073 pDateNode->append(new OSQLInternalNode(aString, SQLNodeType::String));
1074 break;
1075 }
1076 case DataType::TIMESTAMP:
1077 {
1078 DateTime aDateTime = DBTypeConversion::toDateTime(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
1079 if (aDateTime.Seconds || aDateTime.Minutes || aDateTime.Hours)
1080 {
1081 OUString aString = DBTypeConversion::toDateTimeString(aDateTime);
1082 pDateNode->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_TS));
1083 pDateNode->append(new OSQLInternalNode(aString, SQLNodeType::String));
1084 }
1085 else
1086 {
1087 Date aDate(aDateTime.Day,aDateTime.Month,aDateTime.Year);
1088 pDateNode->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_D));
1089 pDateNode->append(new OSQLInternalNode(DBTypeConversion::toDateString(aDate), SQLNodeType::String));
1090 }
1091 break;
1092 }
1093 }
1094
1095 return pNewNode;
1096 }
1097
buildNode_STR_NUM(OSQLParseNode * & _pLiteral)1098 OSQLParseNode* OSQLParser::buildNode_STR_NUM(OSQLParseNode*& _pLiteral)
1099 {
1100 OSQLParseNode* pReturn = nullptr;
1101 if ( _pLiteral )
1102 {
1103 if (m_nFormatKey)
1104 {
1105 sal_Int16 nScale = 0;
1106 try
1107 {
1108 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, "Decimals" );
1109 aValue >>= nScale;
1110 }
1111 catch( Exception& )
1112 {
1113 }
1114
1115 pReturn = new OSQLInternalNode(stringToDouble(_pLiteral->getTokenValue(),nScale),SQLNodeType::String);
1116 }
1117 else
1118 pReturn = new OSQLInternalNode(_pLiteral->getTokenValue(),SQLNodeType::String);
1119
1120 delete _pLiteral;
1121 _pLiteral = nullptr;
1122 }
1123 return pReturn;
1124 }
1125
stringToDouble(const OUString & _rValue,sal_Int16 _nScale)1126 OUString OSQLParser::stringToDouble(const OUString& _rValue,sal_Int16 _nScale)
1127 {
1128 OUString aValue;
1129 if(!m_xCharClass.is())
1130 m_xCharClass = CharacterClassification::create( m_xContext );
1131 if( s_xLocaleData.is() )
1132 {
1133 try
1134 {
1135 ParseResult aResult = m_xCharClass->parsePredefinedToken(KParseType::ANY_NUMBER,_rValue,0,m_pData->aLocale,0,OUString(),KParseType::ANY_NUMBER,OUString());
1136 if((aResult.TokenType & KParseType::IDENTNAME) && aResult.EndPos == _rValue.getLength())
1137 {
1138 aValue = OUString::number(aResult.Value);
1139 sal_Int32 nPos = aValue.lastIndexOf('.');
1140 if((nPos+_nScale) < aValue.getLength())
1141 aValue = aValue.replaceAt(nPos+_nScale,aValue.getLength()-nPos-_nScale,OUString());
1142 aValue = aValue.replaceAt(aValue.lastIndexOf('.'),1,s_xLocaleData->getLocaleItem(m_pData->aLocale).decimalSeparator);
1143 return aValue;
1144 }
1145 }
1146 catch(Exception&)
1147 {
1148 }
1149 }
1150 return aValue;
1151 }
1152
1153
getMutex()1154 ::osl::Mutex& OSQLParser::getMutex()
1155 {
1156 static ::osl::Mutex aMutex;
1157 return aMutex;
1158 }
1159
1160
predicateTree(OUString & rErrorMessage,const OUString & rStatement,const Reference<css::util::XNumberFormatter> & xFormatter,const Reference<XPropertySet> & xField,bool bUseRealName)1161 std::unique_ptr<OSQLParseNode> OSQLParser::predicateTree(OUString& rErrorMessage, const OUString& rStatement,
1162 const Reference< css::util::XNumberFormatter > & xFormatter,
1163 const Reference< XPropertySet > & xField,
1164 bool bUseRealName)
1165 {
1166 // Guard the parsing
1167 ::osl::MutexGuard aGuard(getMutex());
1168 // must be reset
1169 setParser(this);
1170
1171
1172 // reset the parser
1173 m_xField = xField;
1174 m_xFormatter = xFormatter;
1175
1176 if (m_xField.is())
1177 {
1178 sal_Int32 nType=0;
1179 try
1180 {
1181 // get the field name
1182 OUString aString;
1183
1184 // retrieve the fields name
1185 // #75243# use the RealName of the column if there is any otherwise the name which could be the alias
1186 // of the field
1187 Reference< XPropertySetInfo> xInfo = m_xField->getPropertySetInfo();
1188 if ( bUseRealName && xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)))
1189 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)) >>= aString;
1190 else
1191 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString;
1192
1193 m_sFieldName = aString;
1194
1195 // get the field format key
1196 if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)))
1197 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) >>= m_nFormatKey;
1198 else
1199 m_nFormatKey = 0;
1200
1201 // get the field type
1202 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
1203 }
1204 catch ( Exception& )
1205 {
1206 OSL_ASSERT(false);
1207 }
1208
1209 if (m_nFormatKey && m_xFormatter.is())
1210 {
1211 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LOCALE) );
1212 OSL_ENSURE(aValue.getValueType() == cppu::UnoType<css::lang::Locale>::get(), "OSQLParser::PredicateTree : invalid language property !");
1213
1214 if (aValue.getValueType() == cppu::UnoType<css::lang::Locale>::get())
1215 aValue >>= m_pData->aLocale;
1216 }
1217 else
1218 m_pData->aLocale = m_pContext->getPreferredLocale();
1219
1220 if ( m_xFormatter.is() )
1221 {
1222 try
1223 {
1224 Reference< css::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
1225 if ( xFormatSup.is() )
1226 {
1227 Reference< css::util::XNumberFormats > xFormats = xFormatSup->getNumberFormats();
1228 if ( xFormats.is() )
1229 {
1230 css::lang::Locale aLocale;
1231 aLocale.Language = "en";
1232 aLocale.Country = "US";
1233 OUString sFormat("YYYY-MM-DD");
1234 m_nDateFormatKey = xFormats->queryKey(sFormat,aLocale,false);
1235 if ( m_nDateFormatKey == sal_Int32(-1) )
1236 m_nDateFormatKey = xFormats->addNew(sFormat, aLocale);
1237 }
1238 }
1239 }
1240 catch ( Exception& )
1241 {
1242 SAL_WARN( "connectivity.parse","DateFormatKey");
1243 }
1244 }
1245
1246 switch (nType)
1247 {
1248 case DataType::DATE:
1249 case DataType::TIME:
1250 case DataType::TIMESTAMP:
1251 s_pScanner->SetRule(OSQLScanner::GetDATERule());
1252 break;
1253 case DataType::CHAR:
1254 case DataType::VARCHAR:
1255 case DataType::LONGVARCHAR:
1256 case DataType::CLOB:
1257 s_pScanner->SetRule(OSQLScanner::GetSTRINGRule());
1258 break;
1259 default:
1260 if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
1261 s_pScanner->SetRule(OSQLScanner::GetGERRule());
1262 else
1263 s_pScanner->SetRule(OSQLScanner::GetENGRule());
1264 }
1265
1266 }
1267 else
1268 s_pScanner->SetRule(OSQLScanner::GetSQLRule());
1269
1270 s_pScanner->prepareScan(rStatement, m_pContext, true);
1271
1272 SQLyylval.pParseNode = nullptr;
1273 // SQLyypvt = NULL;
1274 m_pParseTree = nullptr;
1275 m_sErrorMessage.clear();
1276
1277 // Start the parser
1278 if (SQLyyparse() != 0)
1279 {
1280 m_sFieldName.clear();
1281 m_xField.clear();
1282 m_xFormatter.clear();
1283 m_nFormatKey = 0;
1284 m_nDateFormatKey = 0;
1285
1286 if (m_sErrorMessage.isEmpty())
1287 m_sErrorMessage = s_pScanner->getErrorMessage();
1288 if (m_sErrorMessage.isEmpty())
1289 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::General);
1290
1291 rErrorMessage = m_sErrorMessage;
1292
1293 // clear the garbage collector
1294 (*s_pGarbageCollector)->clearAndDelete();
1295 m_pParseTree.release(); // because the garbage collector deleted it
1296 return nullptr;
1297 }
1298 else
1299 {
1300 (*s_pGarbageCollector)->clear();
1301
1302 m_sFieldName.clear();
1303 m_xField.clear();
1304 m_xFormatter.clear();
1305 m_nFormatKey = 0;
1306 m_nDateFormatKey = 0;
1307
1308 // Return the result (the root parse node):
1309
1310 // Instead, the parse method sets the member pParseTree and simply returns that
1311 OSL_ENSURE(m_pParseTree != nullptr,"OSQLParser: Parser did not return a ParseTree!");
1312 return std::move(m_pParseTree);
1313 }
1314 }
1315
1316
OSQLParser(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const IParseContext * _pContext)1317 OSQLParser::OSQLParser(const css::uno::Reference< css::uno::XComponentContext >& rxContext, const IParseContext* _pContext)
1318 :m_pContext(_pContext)
1319 ,m_pData( new OSQLParser_Data )
1320 ,m_nFormatKey(0)
1321 ,m_nDateFormatKey(0)
1322 ,m_xContext(rxContext)
1323 {
1324
1325
1326 setParser(this);
1327
1328 #ifdef SQLYYDEBUG
1329 #ifdef SQLYYDEBUG_ON
1330 SQLyydebug = 1;
1331 #endif
1332 #endif
1333
1334 ::osl::MutexGuard aGuard(getMutex());
1335 // Do we have to initialize the data?
1336 if (s_nRefCount == 0)
1337 {
1338 s_pScanner = new OSQLScanner();
1339 s_pScanner->setScanner();
1340 s_pGarbageCollector = new OSQLParseNodesGarbageCollector();
1341
1342 if(!s_xLocaleData.is())
1343 s_xLocaleData = LocaleData::create(m_xContext);
1344
1345 // reset to UNKNOWN_RULE
1346 static_assert(OSQLParseNode::UNKNOWN_RULE==0, "UNKNOWN_RULE must be 0 for memset to 0 to work");
1347 memset(OSQLParser::s_nRuleIDs,0,sizeof(OSQLParser::s_nRuleIDs));
1348
1349 const struct
1350 {
1351 OSQLParseNode::Rule eRule; // the parse node's ID for the rule
1352 OString sRuleName; // the name of the rule ("select_statement")
1353 } aRuleDescriptions[] =
1354 {
1355 { OSQLParseNode::select_statement, "select_statement" },
1356 { OSQLParseNode::table_exp, "table_exp" },
1357 { OSQLParseNode::table_ref_commalist, "table_ref_commalist" },
1358 { OSQLParseNode::table_ref, "table_ref" },
1359 { OSQLParseNode::catalog_name, "catalog_name" },
1360 { OSQLParseNode::schema_name, "schema_name" },
1361 { OSQLParseNode::table_name, "table_name" },
1362 { OSQLParseNode::opt_column_commalist, "opt_column_commalist" },
1363 { OSQLParseNode::column_commalist, "column_commalist" },
1364 { OSQLParseNode::column_ref_commalist, "column_ref_commalist" },
1365 { OSQLParseNode::column_ref, "column_ref" },
1366 { OSQLParseNode::opt_order_by_clause, "opt_order_by_clause" },
1367 { OSQLParseNode::ordering_spec_commalist, "ordering_spec_commalist" },
1368 { OSQLParseNode::ordering_spec, "ordering_spec" },
1369 { OSQLParseNode::opt_asc_desc, "opt_asc_desc" },
1370 { OSQLParseNode::where_clause, "where_clause" },
1371 { OSQLParseNode::opt_where_clause, "opt_where_clause" },
1372 { OSQLParseNode::search_condition, "search_condition" },
1373 { OSQLParseNode::comparison, "comparison" },
1374 { OSQLParseNode::comparison_predicate, "comparison_predicate" },
1375 { OSQLParseNode::between_predicate, "between_predicate" },
1376 { OSQLParseNode::like_predicate, "like_predicate" },
1377 { OSQLParseNode::opt_escape, "opt_escape" },
1378 { OSQLParseNode::test_for_null, "test_for_null" },
1379 { OSQLParseNode::scalar_exp_commalist, "scalar_exp_commalist" },
1380 { OSQLParseNode::scalar_exp, "scalar_exp" },
1381 { OSQLParseNode::parameter_ref, "parameter_ref" },
1382 { OSQLParseNode::parameter, "parameter" },
1383 { OSQLParseNode::general_set_fct, "general_set_fct" },
1384 { OSQLParseNode::range_variable, "range_variable" },
1385 { OSQLParseNode::column, "column" },
1386 { OSQLParseNode::delete_statement_positioned, "delete_statement_positioned" },
1387 { OSQLParseNode::delete_statement_searched, "delete_statement_searched" },
1388 { OSQLParseNode::update_statement_positioned, "update_statement_positioned" },
1389 { OSQLParseNode::update_statement_searched, "update_statement_searched" },
1390 { OSQLParseNode::assignment_commalist, "assignment_commalist" },
1391 { OSQLParseNode::assignment, "assignment" },
1392 { OSQLParseNode::values_or_query_spec, "values_or_query_spec" },
1393 { OSQLParseNode::insert_statement, "insert_statement" },
1394 { OSQLParseNode::insert_atom_commalist, "insert_atom_commalist" },
1395 { OSQLParseNode::insert_atom, "insert_atom" },
1396 { OSQLParseNode::from_clause, "from_clause" },
1397 { OSQLParseNode::qualified_join, "qualified_join" },
1398 { OSQLParseNode::cross_union, "cross_union" },
1399 { OSQLParseNode::select_sublist, "select_sublist" },
1400 { OSQLParseNode::derived_column, "derived_column" },
1401 { OSQLParseNode::column_val, "column_val" },
1402 { OSQLParseNode::set_fct_spec, "set_fct_spec" },
1403 { OSQLParseNode::boolean_term, "boolean_term" },
1404 { OSQLParseNode::boolean_primary, "boolean_primary" },
1405 { OSQLParseNode::num_value_exp, "num_value_exp" },
1406 { OSQLParseNode::join_type, "join_type" },
1407 { OSQLParseNode::position_exp, "position_exp" },
1408 { OSQLParseNode::extract_exp, "extract_exp" },
1409 { OSQLParseNode::length_exp, "length_exp" },
1410 { OSQLParseNode::char_value_fct, "char_value_fct" },
1411 { OSQLParseNode::odbc_call_spec, "odbc_call_spec" },
1412 { OSQLParseNode::in_predicate, "in_predicate" },
1413 { OSQLParseNode::existence_test, "existence_test" },
1414 { OSQLParseNode::unique_test, "unique_test" },
1415 { OSQLParseNode::all_or_any_predicate, "all_or_any_predicate" },
1416 { OSQLParseNode::named_columns_join, "named_columns_join" },
1417 { OSQLParseNode::join_condition, "join_condition" },
1418 { OSQLParseNode::joined_table, "joined_table" },
1419 { OSQLParseNode::boolean_factor, "boolean_factor" },
1420 { OSQLParseNode::sql_not, "sql_not" },
1421 { OSQLParseNode::manipulative_statement, "manipulative_statement" },
1422 { OSQLParseNode::subquery, "subquery" },
1423 { OSQLParseNode::value_exp_commalist, "value_exp_commalist" },
1424 { OSQLParseNode::odbc_fct_spec, "odbc_fct_spec" },
1425 { OSQLParseNode::union_statement, "union_statement" },
1426 { OSQLParseNode::outer_join_type, "outer_join_type" },
1427 { OSQLParseNode::char_value_exp, "char_value_exp" },
1428 { OSQLParseNode::term, "term" },
1429 { OSQLParseNode::value_exp_primary, "value_exp_primary" },
1430 { OSQLParseNode::value_exp, "value_exp" },
1431 { OSQLParseNode::selection, "selection" },
1432 { OSQLParseNode::fold, "fold" },
1433 { OSQLParseNode::char_substring_fct, "char_substring_fct" },
1434 { OSQLParseNode::factor, "factor" },
1435 { OSQLParseNode::base_table_def, "base_table_def" },
1436 { OSQLParseNode::base_table_element_commalist, "base_table_element_commalist" },
1437 { OSQLParseNode::data_type, "data_type" },
1438 { OSQLParseNode::column_def, "column_def" },
1439 { OSQLParseNode::table_node, "table_node" },
1440 { OSQLParseNode::as_clause, "as_clause" },
1441 { OSQLParseNode::opt_as, "opt_as" },
1442 { OSQLParseNode::op_column_commalist, "op_column_commalist" },
1443 { OSQLParseNode::table_primary_as_range_column, "table_primary_as_range_column" },
1444 { OSQLParseNode::datetime_primary, "datetime_primary" },
1445 { OSQLParseNode::concatenation, "concatenation" },
1446 { OSQLParseNode::char_factor, "char_factor" },
1447 { OSQLParseNode::bit_value_fct, "bit_value_fct" },
1448 { OSQLParseNode::comparison_predicate_part_2, "comparison_predicate_part_2" },
1449 { OSQLParseNode::parenthesized_boolean_value_expression, "parenthesized_boolean_value_expression" },
1450 { OSQLParseNode::character_string_type, "character_string_type" },
1451 { OSQLParseNode::other_like_predicate_part_2, "other_like_predicate_part_2" },
1452 { OSQLParseNode::between_predicate_part_2, "between_predicate_part_2" },
1453 { OSQLParseNode::null_predicate_part_2, "null_predicate_part_2" },
1454 { OSQLParseNode::cast_spec, "cast_spec" },
1455 { OSQLParseNode::window_function, "window_function" }
1456 };
1457 const size_t nRuleMapCount = SAL_N_ELEMENTS( aRuleDescriptions );
1458 // added a new rule? Adjust this map!
1459 // +1 for UNKNOWN_RULE
1460 static_assert(nRuleMapCount + 1 == static_cast<size_t>(OSQLParseNode::rule_count), "must be equal");
1461
1462 for (const auto & aRuleDescription : aRuleDescriptions)
1463 {
1464 // look up the rule description in the our identifier map
1465 sal_uInt32 nParserRuleID = StrToRuleID( aRuleDescription.sRuleName );
1466 // map the parser's rule ID to the OSQLParseNode::Rule
1467 s_aReverseRuleIDLookup[ nParserRuleID ] = aRuleDescription.eRule;
1468 // and map the OSQLParseNode::Rule to the parser's rule ID
1469 s_nRuleIDs[ aRuleDescription.eRule ] = nParserRuleID;
1470 }
1471 }
1472 ++s_nRefCount;
1473
1474 if (m_pContext == nullptr)
1475 // take the default context
1476 m_pContext = &s_aDefaultContext;
1477
1478 m_pData->aLocale = m_pContext->getPreferredLocale();
1479 }
1480
1481
~OSQLParser()1482 OSQLParser::~OSQLParser()
1483 {
1484 ::osl::MutexGuard aGuard(getMutex());
1485 OSL_ENSURE(s_nRefCount > 0, "OSQLParser::~OSQLParser() : suspicious call : has a refcount of 0 !");
1486 if (!--s_nRefCount)
1487 {
1488 s_pScanner->setScanner(true);
1489 delete s_pScanner;
1490 s_pScanner = nullptr;
1491
1492 delete s_pGarbageCollector;
1493 s_pGarbageCollector = nullptr;
1494 // Is only set the first time, so we should delete it only when there are no more instances
1495 s_xLocaleData = nullptr;
1496
1497 RuleIDMap aEmpty;
1498 s_aReverseRuleIDLookup.swap( aEmpty );
1499 }
1500 m_pParseTree = nullptr;
1501 }
1502
substituteParameterNames(OSQLParseNode const * _pNode)1503 void OSQLParseNode::substituteParameterNames(OSQLParseNode const * _pNode)
1504 {
1505 sal_Int32 nCount = _pNode->count();
1506 for(sal_Int32 i=0;i < nCount;++i)
1507 {
1508 OSQLParseNode* pChildNode = _pNode->getChild(i);
1509 if(SQL_ISRULE(pChildNode,parameter) && pChildNode->count() > 1)
1510 {
1511 OSQLParseNode* pNewNode = new OSQLParseNode("?" ,SQLNodeType::Punctuation,0);
1512 delete pChildNode->replace(pChildNode->getChild(0),pNewNode);
1513 sal_Int32 nChildCount = pChildNode->count();
1514 for(sal_Int32 j=1;j < nChildCount;++j)
1515 delete pChildNode->removeAt(1);
1516 }
1517 else
1518 substituteParameterNames(pChildNode);
1519
1520 }
1521 }
1522
extractDate(OSQLParseNode const * pLiteral,double & _rfValue)1523 bool OSQLParser::extractDate(OSQLParseNode const * pLiteral,double& _rfValue)
1524 {
1525 Reference< XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
1526 Reference< XNumberFormatTypes > xFormatTypes;
1527 if ( xFormatSup.is() )
1528 xFormatTypes.set(xFormatSup->getNumberFormats(), css::uno::UNO_QUERY);
1529
1530 // if there is no format key, yet, make sure we have a feasible one for our locale
1531 try
1532 {
1533 if ( !m_nFormatKey && xFormatTypes.is() )
1534 m_nFormatKey = ::dbtools::getDefaultNumberFormat( m_xField, xFormatTypes, m_pData->aLocale );
1535 }
1536 catch( Exception& ) { }
1537 const OUString& sValue = pLiteral->getTokenValue();
1538 sal_Int32 nTryFormat = m_nFormatKey;
1539 bool bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1540
1541 // If our format key didn't do, try the default date format for our locale.
1542 if ( !bSuccess && xFormatTypes.is() )
1543 {
1544 try
1545 {
1546 nTryFormat = xFormatTypes->getStandardFormat( NumberFormat::DATE, m_pData->aLocale );
1547 }
1548 catch( Exception& ) { }
1549 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1550 }
1551
1552 // if this also didn't do, try ISO format
1553 if ( !bSuccess && xFormatTypes.is() )
1554 {
1555 try
1556 {
1557 nTryFormat = xFormatTypes->getFormatIndex( NumberFormatIndex::DATE_DIN_YYYYMMDD, m_pData->aLocale );
1558 }
1559 catch( Exception& ) { }
1560 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1561 }
1562
1563 // if this also didn't do, try fallback date format (en-US)
1564 if ( !bSuccess )
1565 {
1566 nTryFormat = m_nDateFormatKey;
1567 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1568 }
1569 return bSuccess;
1570 }
1571
buildDate(sal_Int32 _nType,OSQLParseNode * & pLiteral)1572 OSQLParseNode* OSQLParser::buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral)
1573 {
1574 // try converting the string into a date, according to our format key
1575 double fValue = 0.0;
1576 OSQLParseNode* pFCTNode = nullptr;
1577
1578 if ( extractDate(pLiteral,fValue) )
1579 pFCTNode = buildNode_Date( fValue, _nType);
1580
1581 delete pLiteral;
1582 pLiteral = nullptr;
1583
1584 if ( !pFCTNode )
1585 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidDateCompare);
1586
1587 return pFCTNode;
1588 }
1589
1590
OSQLParseNode(const sal_Char * pNewValue,SQLNodeType eNewNodeType,sal_uInt32 nNewNodeID)1591 OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue,
1592 SQLNodeType eNewNodeType,
1593 sal_uInt32 nNewNodeID)
1594 :m_pParent(nullptr)
1595 ,m_aNodeValue(pNewValue,strlen(pNewValue),RTL_TEXTENCODING_UTF8)
1596 ,m_eNodeType(eNewNodeType)
1597 ,m_nNodeID(nNewNodeID)
1598 {
1599 OSL_ENSURE(m_eNodeType >= SQLNodeType::Rule && m_eNodeType <= SQLNodeType::Concat,"OSQLParseNode: created with invalid NodeType");
1600 }
1601
OSQLParseNode(const OString & _rNewValue,SQLNodeType eNewNodeType,sal_uInt32 nNewNodeID)1602 OSQLParseNode::OSQLParseNode(const OString &_rNewValue,
1603 SQLNodeType eNewNodeType,
1604 sal_uInt32 nNewNodeID)
1605 :m_pParent(nullptr)
1606 ,m_aNodeValue(OStringToOUString(_rNewValue,RTL_TEXTENCODING_UTF8))
1607 ,m_eNodeType(eNewNodeType)
1608 ,m_nNodeID(nNewNodeID)
1609 {
1610 OSL_ENSURE(m_eNodeType >= SQLNodeType::Rule && m_eNodeType <= SQLNodeType::Concat,"OSQLParseNode: created with invalid NodeType");
1611 }
1612
OSQLParseNode(const OUString & _rNewValue,SQLNodeType eNewNodeType,sal_uInt32 nNewNodeID)1613 OSQLParseNode::OSQLParseNode(const OUString &_rNewValue,
1614 SQLNodeType eNewNodeType,
1615 sal_uInt32 nNewNodeID)
1616 :m_pParent(nullptr)
1617 ,m_aNodeValue(_rNewValue)
1618 ,m_eNodeType(eNewNodeType)
1619 ,m_nNodeID(nNewNodeID)
1620 {
1621 OSL_ENSURE(m_eNodeType >= SQLNodeType::Rule && m_eNodeType <= SQLNodeType::Concat,"OSQLParseNode: created with invalid NodeType");
1622 }
1623
OSQLParseNode(const OSQLParseNode & rParseNode)1624 OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode)
1625 {
1626 // Set the getParent to NULL
1627 m_pParent = nullptr;
1628
1629 // Copy the members
1630 m_aNodeValue = rParseNode.m_aNodeValue;
1631 m_eNodeType = rParseNode.m_eNodeType;
1632 m_nNodeID = rParseNode.m_nNodeID;
1633
1634
1635 // Remember that we derived from Container. According to SV-Help the Container's
1636 // copy ctor creates a new Container with the same pointers for content.
1637 // This means after copying the Container, for all non-NULL pointers a copy is
1638 // created and reattached instead of the old pointer.
1639
1640 // If not a leaf, then process SubTrees
1641 for (auto const& child : rParseNode.m_aChildren)
1642 append(new OSQLParseNode(*child));
1643 }
1644
1645
operator =(const OSQLParseNode & rParseNode)1646 OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode)
1647 {
1648 if (this != &rParseNode)
1649 {
1650 // Copy the members - pParent remains the same
1651 m_aNodeValue = rParseNode.m_aNodeValue;
1652 m_eNodeType = rParseNode.m_eNodeType;
1653 m_nNodeID = rParseNode.m_nNodeID;
1654
1655 m_aChildren.clear();
1656
1657 for (auto const& child : rParseNode.m_aChildren)
1658 append(new OSQLParseNode(*child));
1659 }
1660 return *this;
1661 }
1662
1663
operator ==(OSQLParseNode const & rParseNode) const1664 bool OSQLParseNode::operator==(OSQLParseNode const & rParseNode) const
1665 {
1666 // The members must be equal
1667 bool bResult = (m_nNodeID == rParseNode.m_nNodeID) &&
1668 (m_eNodeType == rParseNode.m_eNodeType) &&
1669 (m_aNodeValue == rParseNode.m_aNodeValue) &&
1670 count() == rParseNode.count();
1671
1672 // Parameters are not equal!
1673 bResult = bResult && !SQL_ISRULE(this, parameter);
1674
1675 // compare children
1676 for (size_t i=0; bResult && i < count(); i++)
1677 bResult = *getChild(i) == *rParseNode.getChild(i);
1678
1679 return bResult;
1680 }
1681
1682
~OSQLParseNode()1683 OSQLParseNode::~OSQLParseNode()
1684 {
1685 }
1686
1687
append(OSQLParseNode * pNewNode)1688 void OSQLParseNode::append(OSQLParseNode* pNewNode)
1689 {
1690 OSL_ENSURE(pNewNode != nullptr, "OSQLParseNode: invalid NewSubTree");
1691 OSL_ENSURE(pNewNode->getParent() == nullptr, "OSQLParseNode: Node is not an orphan");
1692 OSL_ENSURE(std::none_of(m_aChildren.begin(), m_aChildren.end(),
1693 [&] (std::unique_ptr<OSQLParseNode> const & r) { return r.get() == pNewNode; }),
1694 "OSQLParseNode::append() Node already element of parent");
1695
1696 // Create connection to getParent
1697 pNewNode->setParent( this );
1698 // and attach the SubTree at the end
1699 m_aChildren.emplace_back(pNewNode);
1700 }
1701
addDateValue(OUStringBuffer & rString,const SQLParseNodeParameter & rParam) const1702 bool OSQLParseNode::addDateValue(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
1703 {
1704 // special display for date/time values
1705 if (SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChildren[0],"{"))
1706 {
1707 const OSQLParseNode* pODBCNode = m_aChildren[1].get();
1708 const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChildren[0].get();
1709
1710 if (pODBCNodeChild->getNodeType() == SQLNodeType::Keyword && (
1711 SQL_ISTOKEN(pODBCNodeChild, D) ||
1712 SQL_ISTOKEN(pODBCNodeChild, T) ||
1713 SQL_ISTOKEN(pODBCNodeChild, TS) ))
1714 {
1715 OUString suQuote("'");
1716 if (rParam.bPredicate)
1717 {
1718 if (rParam.aMetaData.shouldEscapeDateTime())
1719 {
1720 suQuote = "#";
1721 }
1722 }
1723 else
1724 {
1725 if (rParam.aMetaData.shouldEscapeDateTime())
1726 {
1727 // suQuote = "'";
1728 return false;
1729 }
1730 }
1731
1732 if (!rString.isEmpty())
1733 rString.append(" ");
1734 rString.append(suQuote);
1735 const OUString sTokenValue = pODBCNode->m_aChildren[1]->getTokenValue();
1736 if (SQL_ISTOKEN(pODBCNodeChild, D))
1737 {
1738 rString.append(rParam.bPredicate ? convertDateString(rParam, sTokenValue) : sTokenValue);
1739 }
1740 else if (SQL_ISTOKEN(pODBCNodeChild, T))
1741 {
1742 rString.append(rParam.bPredicate ? convertTimeString(rParam, sTokenValue) : sTokenValue);
1743 }
1744 else
1745 {
1746 rString.append(rParam.bPredicate ? convertDateTimeString(rParam, sTokenValue) : sTokenValue);
1747 }
1748 rString.append(suQuote);
1749 return true;
1750 }
1751 }
1752 return false;
1753 }
1754
replaceNodeValue(const OUString & rTableAlias,const OUString & rColumnName)1755 void OSQLParseNode::replaceNodeValue(const OUString& rTableAlias, const OUString& rColumnName)
1756 {
1757 for (size_t i=0;i<count();++i)
1758 {
1759 if (SQL_ISRULE(this,column_ref) && count() == 1 && getChild(0)->getTokenValue() == rColumnName)
1760 {
1761 OSQLParseNode * pCol = removeAt(sal_uInt32(0));
1762 append(new OSQLParseNode(rTableAlias,SQLNodeType::Name));
1763 append(new OSQLParseNode(".",SQLNodeType::Punctuation));
1764 append(pCol);
1765 }
1766 else
1767 getChild(i)->replaceNodeValue(rTableAlias,rColumnName);
1768 }
1769 }
1770
getByRule(OSQLParseNode::Rule eRule) const1771 OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const
1772 {
1773 OSQLParseNode* pRetNode = nullptr;
1774 if (isRule() && OSQLParser::RuleID(eRule) == getRuleID())
1775 pRetNode = const_cast<OSQLParseNode*>(this);
1776 else
1777 {
1778 for (auto const& child : m_aChildren)
1779 {
1780 pRetNode = child->getByRule(eRule);
1781 if (pRetNode)
1782 break;
1783 }
1784 }
1785 return pRetNode;
1786 }
1787
MakeANDNode(OSQLParseNode * pLeftLeaf,OSQLParseNode * pRightLeaf)1788 static OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
1789 {
1790 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_term));
1791 pNewNode->append(pLeftLeaf);
1792 pNewNode->append(new OSQLParseNode("AND",SQLNodeType::Keyword,SQL_TOKEN_AND));
1793 pNewNode->append(pRightLeaf);
1794 return pNewNode;
1795 }
1796
MakeORNode(OSQLParseNode * pLeftLeaf,OSQLParseNode * pRightLeaf)1797 static OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
1798 {
1799 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::search_condition));
1800 pNewNode->append(pLeftLeaf);
1801 pNewNode->append(new OSQLParseNode("OR",SQLNodeType::Keyword,SQL_TOKEN_OR));
1802 pNewNode->append(pRightLeaf);
1803 return pNewNode;
1804 }
1805
disjunctiveNormalForm(OSQLParseNode * & pSearchCondition)1806 void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition)
1807 {
1808 if(!pSearchCondition) // no where condition at entry point
1809 return;
1810
1811 OSQLParseNode::absorptions(pSearchCondition);
1812 // '(' search_condition ')'
1813 if (SQL_ISRULE(pSearchCondition,boolean_primary))
1814 {
1815 OSQLParseNode* pLeft = pSearchCondition->getChild(1);
1816 disjunctiveNormalForm(pLeft);
1817 }
1818 // search_condition SQL_TOKEN_OR boolean_term
1819 else if (SQL_ISRULE(pSearchCondition,search_condition))
1820 {
1821 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1822 disjunctiveNormalForm(pLeft);
1823
1824 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1825 disjunctiveNormalForm(pRight);
1826 }
1827 // boolean_term SQL_TOKEN_AND boolean_factor
1828 else if (SQL_ISRULE(pSearchCondition,boolean_term))
1829 {
1830 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1831 disjunctiveNormalForm(pLeft);
1832
1833 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1834 disjunctiveNormalForm(pRight);
1835
1836 OSQLParseNode* pNewNode = nullptr;
1837 // '(' search_condition ')' on left side
1838 if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition))
1839 {
1840 // and-or tree on left side
1841 OSQLParseNode* pOr = pLeft->getChild(1);
1842 OSQLParseNode* pNewLeft = nullptr;
1843 OSQLParseNode* pNewRight = nullptr;
1844
1845 // cut right from parent
1846 pSearchCondition->removeAt(2);
1847
1848 pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight);
1849 pNewLeft = MakeANDNode(pOr->removeAt(sal_uInt32(0)) ,new OSQLParseNode(*pRight));
1850 pNewNode = MakeORNode(pNewLeft,pNewRight);
1851 // and append new Node
1852 replaceAndReset(pSearchCondition,pNewNode);
1853
1854 disjunctiveNormalForm(pSearchCondition);
1855 }
1856 else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition))
1857 { // '(' search_condition ')' on right side
1858 // and-or tree on right side
1859 // a and (b or c)
1860 OSQLParseNode* pOr = pRight->getChild(1);
1861 OSQLParseNode* pNewLeft = nullptr;
1862 OSQLParseNode* pNewRight = nullptr;
1863
1864 // cut left from parent
1865 pSearchCondition->removeAt(sal_uInt32(0));
1866
1867 pNewRight = MakeANDNode(pLeft,pOr->removeAt(2));
1868 pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt(sal_uInt32(0)));
1869 pNewNode = MakeORNode(pNewLeft,pNewRight);
1870
1871 // and append new Node
1872 replaceAndReset(pSearchCondition,pNewNode);
1873 disjunctiveNormalForm(pSearchCondition);
1874 }
1875 else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term)))
1876 pSearchCondition->replace(pLeft, pLeft->removeAt(1));
1877 else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term)))
1878 pSearchCondition->replace(pRight, pRight->removeAt(1));
1879 }
1880 }
1881
negateSearchCondition(OSQLParseNode * & pSearchCondition,bool bNegate)1882 void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition, bool bNegate)
1883 {
1884 if(!pSearchCondition) // no where condition at entry point
1885 return;
1886 // '(' search_condition ')'
1887 if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary))
1888 {
1889 OSQLParseNode* pRight = pSearchCondition->getChild(1);
1890 negateSearchCondition(pRight,bNegate);
1891 }
1892 // search_condition SQL_TOKEN_OR boolean_term
1893 else if (SQL_ISRULE(pSearchCondition,search_condition))
1894 {
1895 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1896 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1897 if(bNegate)
1898 {
1899 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_term));
1900 pNewNode->append(pSearchCondition->removeAt(sal_uInt32(0)));
1901 pNewNode->append(new OSQLParseNode("AND",SQLNodeType::Keyword,SQL_TOKEN_AND));
1902 pNewNode->append(pSearchCondition->removeAt(sal_uInt32(1)));
1903 replaceAndReset(pSearchCondition,pNewNode);
1904
1905 pLeft = pNewNode->getChild(0);
1906 pRight = pNewNode->getChild(2);
1907 }
1908
1909 negateSearchCondition(pLeft,bNegate);
1910 negateSearchCondition(pRight,bNegate);
1911 }
1912 // boolean_term SQL_TOKEN_AND boolean_factor
1913 else if (SQL_ISRULE(pSearchCondition,boolean_term))
1914 {
1915 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1916 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1917 if(bNegate)
1918 {
1919 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::search_condition));
1920 pNewNode->append(pSearchCondition->removeAt(sal_uInt32(0)));
1921 pNewNode->append(new OSQLParseNode("OR",SQLNodeType::Keyword,SQL_TOKEN_OR));
1922 pNewNode->append(pSearchCondition->removeAt(sal_uInt32(1)));
1923 replaceAndReset(pSearchCondition,pNewNode);
1924
1925 pLeft = pNewNode->getChild(0);
1926 pRight = pNewNode->getChild(2);
1927 }
1928
1929 negateSearchCondition(pLeft,bNegate);
1930 negateSearchCondition(pRight,bNegate);
1931 }
1932 // SQL_TOKEN_NOT ( boolean_primary )
1933 else if (SQL_ISRULE(pSearchCondition,boolean_factor))
1934 {
1935 OSQLParseNode *pNot = pSearchCondition->removeAt(sal_uInt32(0));
1936 delete pNot;
1937 OSQLParseNode *pBooleanTest = pSearchCondition->removeAt(sal_uInt32(0));
1938 // TODO is this needed // pBooleanTest->setParent(NULL);
1939 replaceAndReset(pSearchCondition,pBooleanTest);
1940
1941 if (!bNegate)
1942 negateSearchCondition(pSearchCondition, true); // negate all deeper values
1943 }
1944 // row_value_constructor comparison row_value_constructor
1945 // row_value_constructor comparison any_all_some subquery
1946 else if(bNegate && (SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate)))
1947 {
1948 assert(pSearchCondition->count() == 3);
1949 OSQLParseNode* pComparison = pSearchCondition->getChild(1);
1950 if(SQL_ISRULE(pComparison, comparison))
1951 {
1952 assert(pComparison->count() == 2 ||
1953 pComparison->count() == 4);
1954 assert(SQL_ISTOKEN(pComparison->getChild(0), IS));
1955
1956 OSQLParseNode* pNot = pComparison->getChild(1);
1957 OSQLParseNode* pNotNot = nullptr;
1958 if(pNot->isRule()) // no NOT token (empty rule)
1959 pNotNot = new OSQLParseNode("NOT",SQLNodeType::Keyword,SQL_TOKEN_NOT);
1960 else
1961 {
1962 assert(SQL_ISTOKEN(pNot,NOT));
1963 pNotNot = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::sql_not));
1964 }
1965 pComparison->replace(pNot, pNotNot);
1966 delete pNot;
1967 }
1968 else
1969 {
1970 OSQLParseNode* pNewComparison;
1971 switch(pComparison->getNodeType())
1972 {
1973 default:
1974 case SQLNodeType::Equal:
1975 assert(pComparison->getNodeType() == SQLNodeType::Equal &&
1976 "OSQLParseNode::negateSearchCondition: unexpected node type!");
1977 pNewComparison = new OSQLParseNode("<>",SQLNodeType::NotEqual,SQL_NOTEQUAL);
1978 break;
1979 case SQLNodeType::Less:
1980 pNewComparison = new OSQLParseNode(">=",SQLNodeType::GreatEq,SQL_GREATEQ);
1981 break;
1982 case SQLNodeType::Great:
1983 pNewComparison = new OSQLParseNode("<=",SQLNodeType::LessEq,SQL_LESSEQ);
1984 break;
1985 case SQLNodeType::LessEq:
1986 pNewComparison = new OSQLParseNode(">",SQLNodeType::Great,SQL_GREAT);
1987 break;
1988 case SQLNodeType::GreatEq:
1989 pNewComparison = new OSQLParseNode("<",SQLNodeType::Less,SQL_LESS);
1990 break;
1991 case SQLNodeType::NotEqual:
1992 pNewComparison = new OSQLParseNode("=",SQLNodeType::Equal,SQL_EQUAL);
1993 break;
1994 }
1995 pSearchCondition->replace(pComparison, pNewComparison);
1996 delete pComparison;
1997 }
1998 }
1999
2000 else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) ||
2001 SQL_ISRULE(pSearchCondition,in_predicate) ||
2002 SQL_ISRULE(pSearchCondition,between_predicate) ))
2003 {
2004 OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
2005 sal_uInt32 nNotPos = 0;
2006 if ( SQL_ISRULE( pSearchCondition, test_for_null ) )
2007 nNotPos = 1;
2008
2009 OSQLParseNode* pNot = pPart2->getChild(nNotPos);
2010 OSQLParseNode* pNotNot = nullptr;
2011 if(pNot->isRule()) // no NOT token (empty rule)
2012 pNotNot = new OSQLParseNode("NOT",SQLNodeType::Keyword,SQL_TOKEN_NOT);
2013 else
2014 {
2015 assert(SQL_ISTOKEN(pNot,NOT));
2016 pNotNot = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::sql_not));
2017 }
2018 pPart2->replace(pNot, pNotNot);
2019 delete pNot;
2020 }
2021 else if(bNegate && SQL_ISRULE(pSearchCondition,like_predicate))
2022 {
2023 OSQLParseNode* pNot = pSearchCondition->getChild( 1 )->getChild( 0 );
2024 OSQLParseNode* pNotNot = nullptr;
2025 if(pNot->isRule())
2026 pNotNot = new OSQLParseNode("NOT",SQLNodeType::Keyword,SQL_TOKEN_NOT);
2027 else
2028 pNotNot = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::sql_not));
2029 pSearchCondition->getChild( 1 )->replace(pNot, pNotNot);
2030 delete pNot;
2031 }
2032 }
2033
eraseBraces(OSQLParseNode * & pSearchCondition)2034 void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition)
2035 {
2036 if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
2037 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))))
2038 {
2039 OSQLParseNode* pRight = pSearchCondition->getChild(1);
2040 absorptions(pRight);
2041 // if child is not an or and tree then delete () around child
2042 if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
2043 SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without ()
2044 (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
2045 {
2046 OSQLParseNode* pNode = pSearchCondition->removeAt(1);
2047 replaceAndReset(pSearchCondition,pNode);
2048 }
2049 }
2050 }
2051
absorptions(OSQLParseNode * & pSearchCondition)2052 void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition)
2053 {
2054 if(!pSearchCondition) // no where condition at entry point
2055 return;
2056
2057 eraseBraces(pSearchCondition);
2058
2059 if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2060 {
2061 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
2062 absorptions(pLeft);
2063 OSQLParseNode* pRight = pSearchCondition->getChild(2);
2064 absorptions(pRight);
2065 }
2066
2067 sal_uInt32 nPos = 0;
2068 // a and a || a or a
2069 OSQLParseNode* pNewNode = nullptr;
2070 if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2071 && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2))
2072 {
2073 pNewNode = pSearchCondition->removeAt(sal_uInt32(0));
2074 replaceAndReset(pSearchCondition,pNewNode);
2075 }
2076 // ( a or b ) and a || ( b or c ) and a
2077 // a and ( a or b ) || a and ( b or c )
2078 else if ( SQL_ISRULE(pSearchCondition,boolean_term)
2079 && (
2080 ( SQL_ISRULE(pSearchCondition->getChild(nPos = 0),boolean_primary)
2081 || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition)
2082 )
2083 || ( SQL_ISRULE(pSearchCondition->getChild(nPos = 2),boolean_primary)
2084 || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition)
2085 )
2086 )
2087 )
2088 {
2089 OSQLParseNode* p2ndSearch = pSearchCondition->getChild(nPos);
2090 if ( SQL_ISRULE(p2ndSearch,boolean_primary) )
2091 p2ndSearch = p2ndSearch->getChild(1);
2092
2093 if ( *p2ndSearch->getChild(0) == *pSearchCondition->getChild(2-nPos) ) // a and ( a or b) -> a or b
2094 {
2095 pNewNode = pSearchCondition->removeAt(sal_uInt32(0));
2096 replaceAndReset(pSearchCondition,pNewNode);
2097
2098 }
2099 else if ( *p2ndSearch->getChild(2) == *pSearchCondition->getChild(2-nPos) ) // a and ( b or a) -> a or b
2100 {
2101 pNewNode = pSearchCondition->removeAt(sal_uInt32(2));
2102 replaceAndReset(pSearchCondition,pNewNode);
2103 }
2104 else if ( p2ndSearch->getByRule(OSQLParseNode::search_condition) )
2105 {
2106 // a and ( b or c ) -> ( a and b ) or ( a and c )
2107 // ( b or c ) and a -> ( a and b ) or ( a and c )
2108 OSQLParseNode* pC = p2ndSearch->removeAt(sal_uInt32(2));
2109 OSQLParseNode* pB = p2ndSearch->removeAt(sal_uInt32(0));
2110 OSQLParseNode* pA = pSearchCondition->removeAt(sal_uInt32(2)-nPos);
2111
2112 OSQLParseNode* p1stAnd = MakeANDNode(pA,pB);
2113 OSQLParseNode* p2ndAnd = MakeANDNode(new OSQLParseNode(*pA),pC);
2114 pNewNode = MakeORNode(p1stAnd,p2ndAnd);
2115 OSQLParseNode* pNode = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2116 pNode->append(new OSQLParseNode("(",SQLNodeType::Punctuation));
2117 pNode->append(pNewNode);
2118 pNode->append(new OSQLParseNode(")",SQLNodeType::Punctuation));
2119 OSQLParseNode::eraseBraces(p1stAnd);
2120 OSQLParseNode::eraseBraces(p2ndAnd);
2121 replaceAndReset(pSearchCondition,pNode);
2122 }
2123 }
2124 // a or a and b || a or b and a
2125 else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
2126 {
2127 if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0))
2128 {
2129 pNewNode = pSearchCondition->removeAt(sal_uInt32(0));
2130 replaceAndReset(pSearchCondition,pNewNode);
2131 }
2132 else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0))
2133 {
2134 pNewNode = pSearchCondition->removeAt(sal_uInt32(0));
2135 replaceAndReset(pSearchCondition,pNewNode);
2136 }
2137 }
2138 // a and b or a || b and a or a
2139 else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term))
2140 {
2141 if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2))
2142 {
2143 pNewNode = pSearchCondition->removeAt(sal_uInt32(2));
2144 replaceAndReset(pSearchCondition,pNewNode);
2145 }
2146 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2))
2147 {
2148 pNewNode = pSearchCondition->removeAt(sal_uInt32(2));
2149 replaceAndReset(pSearchCondition,pNewNode);
2150 }
2151 }
2152 eraseBraces(pSearchCondition);
2153 }
2154
compress(OSQLParseNode * & pSearchCondition)2155 void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition)
2156 {
2157 if(!pSearchCondition) // no WHERE condition at entry point
2158 return;
2159
2160 OSQLParseNode::eraseBraces(pSearchCondition);
2161
2162 if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2163 {
2164 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
2165 compress(pLeft);
2166
2167 OSQLParseNode* pRight = pSearchCondition->getChild(2);
2168 compress(pRight);
2169 }
2170 else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
2171 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))
2172 {
2173 OSQLParseNode* pRight = pSearchCondition->getChild(1);
2174 compress(pRight);
2175 // if child is not an or and tree then delete () around child
2176 if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
2177 (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) ||
2178 (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
2179 {
2180 OSQLParseNode* pNode = pSearchCondition->removeAt(1);
2181 replaceAndReset(pSearchCondition,pNode);
2182 }
2183 }
2184
2185 // or with two and trees where one element of the and trees are equal
2186 if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
2187 {
2188 if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0))
2189 {
2190 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
2191 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
2192 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2193
2194 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2195 pNewRule->append(new OSQLParseNode("(",SQLNodeType::Punctuation));
2196 pNewRule->append(pNode);
2197 pNewRule->append(new OSQLParseNode(")",SQLNodeType::Punctuation));
2198
2199 OSQLParseNode::eraseBraces(pLeft);
2200 OSQLParseNode::eraseBraces(pRight);
2201
2202 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(sal_uInt32(0)),pNewRule);
2203 replaceAndReset(pSearchCondition,pNode);
2204 }
2205 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0))
2206 {
2207 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(sal_uInt32(0));
2208 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
2209 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2210
2211 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2212 pNewRule->append(new OSQLParseNode("(",SQLNodeType::Punctuation));
2213 pNewRule->append(pNode);
2214 pNewRule->append(new OSQLParseNode(")",SQLNodeType::Punctuation));
2215
2216 OSQLParseNode::eraseBraces(pLeft);
2217 OSQLParseNode::eraseBraces(pRight);
2218
2219 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
2220 replaceAndReset(pSearchCondition,pNode);
2221 }
2222 else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2))
2223 {
2224 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
2225 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(sal_uInt32(0));
2226 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2227
2228 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2229 pNewRule->append(new OSQLParseNode("(",SQLNodeType::Punctuation));
2230 pNewRule->append(pNode);
2231 pNewRule->append(new OSQLParseNode(")",SQLNodeType::Punctuation));
2232
2233 OSQLParseNode::eraseBraces(pLeft);
2234 OSQLParseNode::eraseBraces(pRight);
2235
2236 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(sal_uInt32(0)),pNewRule);
2237 replaceAndReset(pSearchCondition,pNode);
2238 }
2239 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2))
2240 {
2241 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(sal_uInt32(0));
2242 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(sal_uInt32(0));
2243 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2244
2245 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2246 pNewRule->append(new OSQLParseNode("(",SQLNodeType::Punctuation));
2247 pNewRule->append(pNode);
2248 pNewRule->append(new OSQLParseNode(")",SQLNodeType::Punctuation));
2249
2250 OSQLParseNode::eraseBraces(pLeft);
2251 OSQLParseNode::eraseBraces(pRight);
2252
2253 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
2254 replaceAndReset(pSearchCondition,pNode);
2255 }
2256 }
2257 }
2258 #if OSL_DEBUG_LEVEL > 1
2259
showParseTree(OUString & rString) const2260 void OSQLParseNode::showParseTree( OUString& rString ) const
2261 {
2262 OUStringBuffer aBuf;
2263 showParseTree( aBuf, 0 );
2264 rString = aBuf.makeStringAndClear();
2265 }
2266
2267
showParseTree(OUStringBuffer & _inout_rBuffer,sal_uInt32 nLevel) const2268 void OSQLParseNode::showParseTree( OUStringBuffer& _inout_rBuffer, sal_uInt32 nLevel ) const
2269 {
2270 for ( sal_uInt32 j=0; j<nLevel; ++j)
2271 _inout_rBuffer.appendAscii( " " );
2272
2273 if ( !isToken() )
2274 {
2275 // Rule name as rule
2276 _inout_rBuffer.appendAscii( "RULE_ID: " );
2277 _inout_rBuffer.append( (sal_Int32)getRuleID() );
2278 _inout_rBuffer.append( '(' );
2279 _inout_rBuffer.append( OSQLParser::RuleIDToStr( getRuleID() ) );
2280 _inout_rBuffer.append( ')' );
2281 _inout_rBuffer.append( '\n' );
2282
2283 // Get the first sub tree
2284 for (auto const& child : m_aChildren)
2285 child->showParseTree( _inout_rBuffer, nLevel+1 );
2286 }
2287 else
2288 {
2289 // Found a token
2290 switch (m_eNodeType)
2291 {
2292
2293 case SQLNodeType::Keyword:
2294 _inout_rBuffer.appendAscii( "SQL_KEYWORD: " );
2295 _inout_rBuffer.append( OStringToOUString( OSQLParser::TokenIDToStr( getTokenID() ), RTL_TEXTENCODING_UTF8 ) );
2296 _inout_rBuffer.append( '\n' );
2297 break;
2298
2299 case SQLNodeType::Name:
2300 _inout_rBuffer.appendAscii( "SQL_NAME: " );
2301 _inout_rBuffer.append( '"' );
2302 _inout_rBuffer.append( m_aNodeValue );
2303 _inout_rBuffer.append( '"' );
2304 _inout_rBuffer.append( '\n' );
2305 break;
2306
2307 case SQLNodeType::String:
2308 _inout_rBuffer.appendAscii( "SQL_STRING: " );
2309 _inout_rBuffer.append( '\'' );
2310 _inout_rBuffer.append( m_aNodeValue );
2311 _inout_rBuffer.append( '\'' );
2312 _inout_rBuffer.append( '\n' );
2313 break;
2314
2315 case SQLNodeType::IntNum:
2316 _inout_rBuffer.appendAscii( "SQL_INTNUM: " );
2317 _inout_rBuffer.append( m_aNodeValue );
2318 _inout_rBuffer.append( '\n' );
2319 break;
2320
2321 case SQLNodeType::ApproxNum:
2322 _inout_rBuffer.appendAscii( "SQL_APPROXNUM: " );
2323 _inout_rBuffer.append( m_aNodeValue );
2324 _inout_rBuffer.append( '\n' );
2325 break;
2326
2327 case SQLNodeType::Punctuation:
2328 _inout_rBuffer.appendAscii( "SQL_PUNCTUATION: " );
2329 _inout_rBuffer.append( m_aNodeValue );
2330 _inout_rBuffer.append( '\n' );
2331 break;
2332
2333 case SQLNodeType::Equal:
2334 case SQLNodeType::Less:
2335 case SQLNodeType::Great:
2336 case SQLNodeType::LessEq:
2337 case SQLNodeType::GreatEq:
2338 case SQLNodeType::NotEqual:
2339 _inout_rBuffer.append( m_aNodeValue );
2340 _inout_rBuffer.append( '\n' );
2341 break;
2342
2343 case SQLNodeType::AccessDate:
2344 _inout_rBuffer.appendAscii( "SQL_ACCESS_DATE: " );
2345 _inout_rBuffer.append( m_aNodeValue );
2346 _inout_rBuffer.append( '\n' );
2347 break;
2348
2349 case SQLNodeType::Concat:
2350 _inout_rBuffer.appendAscii( "||" );
2351 _inout_rBuffer.append( '\n' );
2352 break;
2353
2354 default:
2355 SAL_INFO( "connectivity.parse", "-- " << int( m_eNodeType ) );
2356 SAL_WARN( "connectivity.parse", "OSQLParser::ShowParseTree: unzulaessiger NodeType" );
2357 }
2358 }
2359 }
2360 #endif // OSL_DEBUG_LEVEL > 0
2361
2362 // Insert methods
2363
insert(sal_uInt32 nPos,OSQLParseNode * pNewSubTree)2364 void OSQLParseNode::insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree)
2365 {
2366 OSL_ENSURE(pNewSubTree != nullptr, "OSQLParseNode: invalid NewSubTree");
2367 OSL_ENSURE(pNewSubTree->getParent() == nullptr, "OSQLParseNode: Node is not an orphan");
2368
2369 // Create connection to getParent
2370 pNewSubTree->setParent( this );
2371 m_aChildren.emplace(m_aChildren.begin() + nPos, pNewSubTree);
2372 }
2373
2374 // removeAt methods
2375
removeAt(sal_uInt32 nPos)2376 OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos)
2377 {
2378 OSL_ENSURE(nPos < m_aChildren.size(),"Illegal position for removeAt");
2379 auto aPos(m_aChildren.begin() + nPos);
2380 auto pNode = std::move(*aPos);
2381
2382 // Set the getParent of the removed node to NULL
2383 pNode->setParent( nullptr );
2384
2385 m_aChildren.erase(aPos);
2386 return pNode.release();
2387 }
2388
2389 // Replace methods
2390
replace(OSQLParseNode * pOldSubNode,OSQLParseNode * pNewSubNode)2391 OSQLParseNode* OSQLParseNode::replace(OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode )
2392 {
2393 OSL_ENSURE(pOldSubNode != nullptr && pNewSubNode != nullptr, "OSQLParseNode: invalid nodes");
2394 OSL_ENSURE(pNewSubNode->getParent() == nullptr, "OSQLParseNode: node already has getParent");
2395 OSL_ENSURE(std::any_of(m_aChildren.begin(), m_aChildren.end(),
2396 [&] (std::unique_ptr<OSQLParseNode> const & r) { return r.get() == pOldSubNode; }),
2397 "OSQLParseNode::Replace() Node not element of parent");
2398 OSL_ENSURE(std::none_of(m_aChildren.begin(), m_aChildren.end(),
2399 [&] (std::unique_ptr<OSQLParseNode> const & r) { return r.get() == pNewSubNode; }),
2400 "OSQLParseNode::Replace() Node already element of parent");
2401
2402 pOldSubNode->setParent( nullptr );
2403 pNewSubNode->setParent( this );
2404 auto it = std::find_if(m_aChildren.begin(), m_aChildren.end(),
2405 [&pOldSubNode](const std::unique_ptr<OSQLParseNode>& rxChild) { return rxChild.get() == pOldSubNode; });
2406 if (it != m_aChildren.end())
2407 {
2408 it->release();
2409 it->reset(pNewSubNode);
2410 }
2411 return pOldSubNode;
2412 }
2413
parseLeaf(OUStringBuffer & rString,const SQLParseNodeParameter & rParam) const2414 void OSQLParseNode::parseLeaf(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
2415 {
2416 // Found a leaf
2417 // Append content to the output string
2418 switch (m_eNodeType)
2419 {
2420 case SQLNodeType::Keyword:
2421 {
2422 if (!rString.isEmpty())
2423 rString.append(" ");
2424
2425 const OString sT = OSQLParser::TokenIDToStr(m_nNodeID, rParam.bInternational ? &rParam.m_rContext : nullptr);
2426 rString.append(OStringToOUString(sT,RTL_TEXTENCODING_UTF8));
2427 } break;
2428 case SQLNodeType::String:
2429 if (!rString.isEmpty())
2430 rString.append(" ");
2431 rString.append(SetQuotation(m_aNodeValue,"\'","\'\'"));
2432 break;
2433 case SQLNodeType::Name:
2434 if (!rString.isEmpty())
2435 {
2436 switch(rString[rString.getLength()-1])
2437 {
2438 case ' ' :
2439 case '.' : break;
2440 default :
2441 if ( rParam.aMetaData.getCatalogSeparator().isEmpty()
2442 || rString[rString.getLength() - 1] != rParam.aMetaData.getCatalogSeparator().toChar()
2443 )
2444 rString.append(" ");
2445 break;
2446 }
2447 }
2448 if (rParam.bQuote)
2449 {
2450 if (rParam.bPredicate)
2451 {
2452 rString.append("[");
2453 rString.append(m_aNodeValue);
2454 rString.append("]");
2455 }
2456 else
2457 rString.append(SetQuotation(m_aNodeValue,
2458 rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() ));
2459 }
2460 else
2461 rString.append(m_aNodeValue);
2462 break;
2463 case SQLNodeType::AccessDate:
2464 if (!rString.isEmpty())
2465 rString.append(" ");
2466 rString.append("#");
2467 rString.append(m_aNodeValue);
2468 rString.append("#");
2469 break;
2470
2471 case SQLNodeType::IntNum:
2472 case SQLNodeType::ApproxNum:
2473 {
2474 OUString aTmp = m_aNodeValue;
2475 static OUString strPoint(".");
2476 if (rParam.bInternational && rParam.bPredicate && rParam.sDecSep != strPoint)
2477 aTmp = aTmp.replaceAll(strPoint, rParam.sDecSep);
2478
2479 if (!rString.isEmpty())
2480 rString.append(" ");
2481 rString.append(aTmp);
2482
2483 } break;
2484 case SQLNodeType::Punctuation:
2485 if ( getParent() && SQL_ISRULE(getParent(),cast_spec) && m_aNodeValue.toChar() == '(' ) // no spaces in front of '('
2486 {
2487 rString.append(m_aNodeValue);
2488 break;
2489 }
2490 [[fallthrough]];
2491 default:
2492 if (!rString.isEmpty() && m_aNodeValue.toChar() != '.' && m_aNodeValue.toChar() != ':' )
2493 {
2494 switch( rString[rString.getLength() - 1] )
2495 {
2496 case ' ' :
2497 case '.' : break;
2498 default :
2499 if ( rParam.aMetaData.getCatalogSeparator().isEmpty()
2500 || rString[rString.getLength() - 1] != rParam.aMetaData.getCatalogSeparator().toChar()
2501 )
2502 rString.append(" ");
2503 break;
2504 }
2505 }
2506 rString.append(m_aNodeValue);
2507 }
2508 }
2509
2510
getFunctionReturnType(const OUString & _sFunctionName,const IParseContext * pContext)2511 sal_Int32 OSQLParser::getFunctionReturnType(const OUString& _sFunctionName, const IParseContext* pContext)
2512 {
2513 sal_Int32 nType = DataType::VARCHAR;
2514 OString sFunctionName(OUStringToOString(_sFunctionName,RTL_TEXTENCODING_UTF8));
2515
2516 if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASCII,pContext))) nType = DataType::INTEGER;
2517 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_BIT_LENGTH,pContext))) nType = DataType::INTEGER;
2518 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR,pContext))) nType = DataType::VARCHAR;
2519 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR_LENGTH,pContext))) nType = DataType::INTEGER;
2520 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CONCAT,pContext))) nType = DataType::VARCHAR;
2521 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DIFFERENCE,pContext))) nType = DataType::VARCHAR;
2522 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_INSERT,pContext))) nType = DataType::VARCHAR;
2523 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LCASE,pContext))) nType = DataType::VARCHAR;
2524 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LEFT,pContext))) nType = DataType::VARCHAR;
2525 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LENGTH,pContext))) nType = DataType::INTEGER;
2526 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE,pContext))) nType = DataType::VARCHAR;
2527 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE_2,pContext))) nType = DataType::VARCHAR;
2528 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LTRIM,pContext))) nType = DataType::VARCHAR;
2529 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_OCTET_LENGTH,pContext))) nType = DataType::INTEGER;
2530 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POSITION,pContext))) nType = DataType::INTEGER;
2531 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPEAT,pContext))) nType = DataType::VARCHAR;
2532 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPLACE,pContext))) nType = DataType::VARCHAR;
2533 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RIGHT,pContext))) nType = DataType::VARCHAR;
2534 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RTRIM,pContext))) nType = DataType::VARCHAR;
2535 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SOUNDEX,pContext))) nType = DataType::VARCHAR;
2536 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SPACE,pContext))) nType = DataType::VARCHAR;
2537 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUBSTRING,pContext))) nType = DataType::VARCHAR;
2538 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UCASE,pContext))) nType = DataType::VARCHAR;
2539 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_DATE,pContext))) nType = DataType::DATE;
2540 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIME,pContext))) nType = DataType::TIME;
2541 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIMESTAMP,pContext))) nType = DataType::TIMESTAMP;
2542 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURDATE,pContext))) nType = DataType::DATE;
2543 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEDIFF,pContext))) nType = DataType::INTEGER;
2544 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEVALUE,pContext))) nType = DataType::DATE;
2545 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURTIME,pContext))) nType = DataType::TIME;
2546 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYNAME,pContext))) nType = DataType::VARCHAR;
2547 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFMONTH,pContext))) nType = DataType::INTEGER;
2548 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFWEEK,pContext))) nType = DataType::INTEGER;
2549 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFYEAR,pContext))) nType = DataType::INTEGER;
2550 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXTRACT,pContext))) nType = DataType::VARCHAR;
2551 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_HOUR,pContext))) nType = DataType::INTEGER;
2552 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MINUTE,pContext))) nType = DataType::INTEGER;
2553 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTH,pContext))) nType = DataType::INTEGER;
2554 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTHNAME,pContext))) nType = DataType::VARCHAR;
2555 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_NOW,pContext))) nType = DataType::TIMESTAMP;
2556 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_QUARTER,pContext))) nType = DataType::INTEGER;
2557 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SECOND,pContext))) nType = DataType::INTEGER;
2558 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPADD,pContext))) nType = DataType::TIMESTAMP;
2559 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPDIFF,pContext))) nType = DataType::TIMESTAMP;
2560 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMEVALUE,pContext))) nType = DataType::TIMESTAMP;
2561 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_WEEK,pContext))) nType = DataType::INTEGER;
2562 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_YEAR,pContext))) nType = DataType::INTEGER;
2563 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ABS,pContext))) nType = DataType::DOUBLE;
2564 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ACOS,pContext))) nType = DataType::DOUBLE;
2565 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASIN,pContext))) nType = DataType::DOUBLE;
2566 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN,pContext))) nType = DataType::DOUBLE;
2567 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN2,pContext))) nType = DataType::DOUBLE;
2568 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CEILING,pContext))) nType = DataType::DOUBLE;
2569 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COS,pContext))) nType = DataType::DOUBLE;
2570 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COT,pContext))) nType = DataType::DOUBLE;
2571 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DEGREES,pContext))) nType = DataType::DOUBLE;
2572 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXP,pContext))) nType = DataType::DOUBLE;
2573 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_FLOOR,pContext))) nType = DataType::DOUBLE;
2574 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOGF,pContext))) nType = DataType::DOUBLE;
2575 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG,pContext))) nType = DataType::DOUBLE;
2576 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG10,pContext))) nType = DataType::DOUBLE;
2577 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LN,pContext))) nType = DataType::DOUBLE;
2578 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MOD,pContext))) nType = DataType::DOUBLE;
2579 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_PI,pContext))) nType = DataType::DOUBLE;
2580 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POWER,pContext))) nType = DataType::DOUBLE;
2581 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RADIANS,pContext))) nType = DataType::DOUBLE;
2582 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RAND,pContext))) nType = DataType::DOUBLE;
2583 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUND,pContext))) nType = DataType::DOUBLE;
2584 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUNDMAGIC,pContext))) nType = DataType::DOUBLE;
2585 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIGN,pContext))) nType = DataType::DOUBLE;
2586 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIN,pContext))) nType = DataType::DOUBLE;
2587 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SQRT,pContext))) nType = DataType::DOUBLE;
2588 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TAN,pContext))) nType = DataType::DOUBLE;
2589 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TRUNCATE,pContext))) nType = DataType::DOUBLE;
2590 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COUNT,pContext))) nType = DataType::INTEGER;
2591 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MAX,pContext))) nType = DataType::DOUBLE;
2592 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MIN,pContext))) nType = DataType::DOUBLE;
2593 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_AVG,pContext))) nType = DataType::DOUBLE;
2594 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUM,pContext))) nType = DataType::DOUBLE;
2595 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOWER,pContext))) nType = DataType::VARCHAR;
2596 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UPPER,pContext))) nType = DataType::VARCHAR;
2597
2598 return nType;
2599 }
2600
getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos)2601 sal_Int32 OSQLParser::getFunctionParameterType(sal_uInt32 _nTokenId, sal_uInt32 _nPos)
2602 {
2603 sal_Int32 nType = DataType::VARCHAR;
2604
2605 if(_nTokenId == SQL_TOKEN_CHAR) nType = DataType::INTEGER;
2606 else if(_nTokenId == SQL_TOKEN_INSERT)
2607 {
2608 if ( _nPos == 2 || _nPos == 3 )
2609 nType = DataType::INTEGER;
2610 }
2611 else if(_nTokenId == SQL_TOKEN_LEFT)
2612 {
2613 if ( _nPos == 2 )
2614 nType = DataType::INTEGER;
2615 }
2616 else if(_nTokenId == SQL_TOKEN_LOCATE)
2617 {
2618 if ( _nPos == 3 )
2619 nType = DataType::INTEGER;
2620 }
2621 else if(_nTokenId == SQL_TOKEN_LOCATE_2)
2622 {
2623 if ( _nPos == 3 )
2624 nType = DataType::INTEGER;
2625 }
2626 else if( _nTokenId == SQL_TOKEN_REPEAT || _nTokenId == SQL_TOKEN_RIGHT )
2627 {
2628 if ( _nPos == 2 )
2629 nType = DataType::INTEGER;
2630 }
2631 else if(_nTokenId == SQL_TOKEN_SPACE )
2632 {
2633 nType = DataType::INTEGER;
2634 }
2635 else if(_nTokenId == SQL_TOKEN_SUBSTRING)
2636 {
2637 if ( _nPos != 1 )
2638 nType = DataType::INTEGER;
2639 }
2640 else if(_nTokenId == SQL_TOKEN_DATEDIFF)
2641 {
2642 if ( _nPos != 1 )
2643 nType = DataType::TIMESTAMP;
2644 }
2645 else if(_nTokenId == SQL_TOKEN_DATEVALUE)
2646 nType = DataType::DATE;
2647 else if(_nTokenId == SQL_TOKEN_DAYNAME)
2648 nType = DataType::DATE;
2649 else if(_nTokenId == SQL_TOKEN_DAYOFMONTH)
2650 nType = DataType::DATE;
2651 else if(_nTokenId == SQL_TOKEN_DAYOFWEEK)
2652 nType = DataType::DATE;
2653 else if(_nTokenId == SQL_TOKEN_DAYOFYEAR)
2654 nType = DataType::DATE;
2655 else if(_nTokenId == SQL_TOKEN_EXTRACT) nType = DataType::VARCHAR;
2656 else if(_nTokenId == SQL_TOKEN_HOUR) nType = DataType::TIME;
2657 else if(_nTokenId == SQL_TOKEN_MINUTE) nType = DataType::TIME;
2658 else if(_nTokenId == SQL_TOKEN_MONTH) nType = DataType::DATE;
2659 else if(_nTokenId == SQL_TOKEN_MONTHNAME) nType = DataType::DATE;
2660 else if(_nTokenId == SQL_TOKEN_NOW) nType = DataType::TIMESTAMP;
2661 else if(_nTokenId == SQL_TOKEN_QUARTER) nType = DataType::DATE;
2662 else if(_nTokenId == SQL_TOKEN_SECOND) nType = DataType::TIME;
2663 else if(_nTokenId == SQL_TOKEN_TIMESTAMPADD) nType = DataType::TIMESTAMP;
2664 else if(_nTokenId == SQL_TOKEN_TIMESTAMPDIFF) nType = DataType::TIMESTAMP;
2665 else if(_nTokenId == SQL_TOKEN_TIMEVALUE) nType = DataType::TIMESTAMP;
2666 else if(_nTokenId == SQL_TOKEN_WEEK) nType = DataType::DATE;
2667 else if(_nTokenId == SQL_TOKEN_YEAR) nType = DataType::DATE;
2668
2669 else if(_nTokenId == SQL_TOKEN_ABS) nType = DataType::DOUBLE;
2670 else if(_nTokenId == SQL_TOKEN_ACOS) nType = DataType::DOUBLE;
2671 else if(_nTokenId == SQL_TOKEN_ASIN) nType = DataType::DOUBLE;
2672 else if(_nTokenId == SQL_TOKEN_ATAN) nType = DataType::DOUBLE;
2673 else if(_nTokenId == SQL_TOKEN_ATAN2) nType = DataType::DOUBLE;
2674 else if(_nTokenId == SQL_TOKEN_CEILING) nType = DataType::DOUBLE;
2675 else if(_nTokenId == SQL_TOKEN_COS) nType = DataType::DOUBLE;
2676 else if(_nTokenId == SQL_TOKEN_COT) nType = DataType::DOUBLE;
2677 else if(_nTokenId == SQL_TOKEN_DEGREES) nType = DataType::DOUBLE;
2678 else if(_nTokenId == SQL_TOKEN_EXP) nType = DataType::DOUBLE;
2679 else if(_nTokenId == SQL_TOKEN_FLOOR) nType = DataType::DOUBLE;
2680 else if(_nTokenId == SQL_TOKEN_LOGF) nType = DataType::DOUBLE;
2681 else if(_nTokenId == SQL_TOKEN_LOG) nType = DataType::DOUBLE;
2682 else if(_nTokenId == SQL_TOKEN_LOG10) nType = DataType::DOUBLE;
2683 else if(_nTokenId == SQL_TOKEN_LN) nType = DataType::DOUBLE;
2684 else if(_nTokenId == SQL_TOKEN_MOD) nType = DataType::DOUBLE;
2685 else if(_nTokenId == SQL_TOKEN_PI) nType = DataType::DOUBLE;
2686 else if(_nTokenId == SQL_TOKEN_POWER) nType = DataType::DOUBLE;
2687 else if(_nTokenId == SQL_TOKEN_RADIANS) nType = DataType::DOUBLE;
2688 else if(_nTokenId == SQL_TOKEN_RAND) nType = DataType::DOUBLE;
2689 else if(_nTokenId == SQL_TOKEN_ROUND) nType = DataType::DOUBLE;
2690 else if(_nTokenId == SQL_TOKEN_ROUNDMAGIC) nType = DataType::DOUBLE;
2691 else if(_nTokenId == SQL_TOKEN_SIGN) nType = DataType::DOUBLE;
2692 else if(_nTokenId == SQL_TOKEN_SIN) nType = DataType::DOUBLE;
2693 else if(_nTokenId == SQL_TOKEN_SQRT) nType = DataType::DOUBLE;
2694 else if(_nTokenId == SQL_TOKEN_TAN) nType = DataType::DOUBLE;
2695 else if(_nTokenId == SQL_TOKEN_TRUNCATE) nType = DataType::DOUBLE;
2696 else if(_nTokenId == SQL_TOKEN_COUNT) nType = DataType::INTEGER;
2697 else if(_nTokenId == SQL_TOKEN_MAX) nType = DataType::DOUBLE;
2698 else if(_nTokenId == SQL_TOKEN_MIN) nType = DataType::DOUBLE;
2699 else if(_nTokenId == SQL_TOKEN_AVG) nType = DataType::DOUBLE;
2700 else if(_nTokenId == SQL_TOKEN_SUM) nType = DataType::DOUBLE;
2701
2702 else if(_nTokenId == SQL_TOKEN_LOWER) nType = DataType::VARCHAR;
2703 else if(_nTokenId == SQL_TOKEN_UPPER) nType = DataType::VARCHAR;
2704
2705 return nType;
2706 }
2707
2708
getErrorHelper() const2709 const SQLError& OSQLParser::getErrorHelper() const
2710 {
2711 return m_pData->aErrors;
2712 }
2713
2714
getKnownRuleID() const2715 OSQLParseNode::Rule OSQLParseNode::getKnownRuleID() const
2716 {
2717 if ( !isRule() )
2718 return UNKNOWN_RULE;
2719 return OSQLParser::RuleIDToRule( getRuleID() );
2720 }
2721
getTableRange(const OSQLParseNode * _pTableRef)2722 OUString OSQLParseNode::getTableRange(const OSQLParseNode* _pTableRef)
2723 {
2724 OSL_ENSURE(_pTableRef && _pTableRef->count() > 1 && _pTableRef->getKnownRuleID() == OSQLParseNode::table_ref,"Invalid node give, only table ref is allowed!");
2725 const sal_uInt32 nCount = _pTableRef->count();
2726 OUString sTableRange;
2727 if ( nCount == 2 || (nCount == 3 && !_pTableRef->getChild(0)->isToken()) )
2728 {
2729 const OSQLParseNode* pNode = _pTableRef->getChild(nCount - (nCount == 2 ? 1 : 2));
2730 OSL_ENSURE(pNode && (pNode->getKnownRuleID() == OSQLParseNode::table_primary_as_range_column
2731 || pNode->getKnownRuleID() == OSQLParseNode::range_variable)
2732 ,"SQL grammar changed!");
2733 if ( !pNode->isLeaf() )
2734 sTableRange = pNode->getChild(1)->getTokenValue();
2735 } // if ( nCount == 2 || nCount == 3 )
2736
2737 return sTableRange;
2738 }
2739
OSQLParseNodesContainer()2740 OSQLParseNodesContainer::OSQLParseNodesContainer()
2741 {
2742 }
2743
~OSQLParseNodesContainer()2744 OSQLParseNodesContainer::~OSQLParseNodesContainer()
2745 {
2746 }
2747
push_back(OSQLParseNode * _pNode)2748 void OSQLParseNodesContainer::push_back(OSQLParseNode* _pNode)
2749 {
2750 ::osl::MutexGuard aGuard(m_aMutex);
2751 m_aNodes.push_back(_pNode);
2752 }
2753
erase(OSQLParseNode * _pNode)2754 void OSQLParseNodesContainer::erase(OSQLParseNode* _pNode)
2755 {
2756 ::osl::MutexGuard aGuard(m_aMutex);
2757 if ( !m_aNodes.empty() )
2758 {
2759 std::vector< OSQLParseNode* >::iterator aFind = std::find(m_aNodes.begin(), m_aNodes.end(),_pNode);
2760 if ( aFind != m_aNodes.end() )
2761 m_aNodes.erase(aFind);
2762 }
2763 }
2764
clear()2765 void OSQLParseNodesContainer::clear()
2766 {
2767 ::osl::MutexGuard aGuard(m_aMutex);
2768 m_aNodes.clear();
2769 }
2770
clearAndDelete()2771 void OSQLParseNodesContainer::clearAndDelete()
2772 {
2773 ::osl::MutexGuard aGuard(m_aMutex);
2774 // clear the garbage collector
2775 while ( !m_aNodes.empty() )
2776 {
2777 OSQLParseNode* pNode = m_aNodes[0];
2778 while ( pNode->getParent() )
2779 {
2780 pNode = pNode->getParent();
2781 }
2782 delete pNode;
2783 }
2784 }
2785 } // namespace connectivity
2786
2787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2788