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