bump product version to 5.0.4.1
[LibreOffice.git] / connectivity / source / parse / sqlnode.cxx
blob1293364ba695554c717e52274e1265b3181411bf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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 <algorithm>
59 #include <functional>
60 #include <rtl/ustrbuf.hxx>
62 using namespace ::com::sun::star::sdbc;
63 using namespace ::com::sun::star::util;
64 using namespace ::com::sun::star::beans;
65 using namespace ::com::sun::star::sdb;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::i18n;
69 using namespace ::com::sun::star;
70 using namespace ::osl;
71 using namespace ::dbtools;
72 using namespace ::comphelper;
74 connectivity::OSQLParser* xxx_pGLOBAL_SQLPARSER;
76 namespace
79 bool lcl_saveConvertToNumber(const Reference< XNumberFormatter > & _xFormatter,sal_Int32 _nKey,const OUString& _sValue,double& _nrValue)
81 bool bRet = false;
82 try
84 _nrValue = _xFormatter->convertStringToNumber(_nKey, _sValue);
85 bRet = true;
87 catch(Exception&)
90 return bRet;
93 void replaceAndReset(connectivity::OSQLParseNode*& _pResetNode,connectivity::OSQLParseNode* _pNewNode)
95 _pResetNode->getParent()->replace(_pResetNode, _pNewNode);
96 delete _pResetNode;
97 _pResetNode = _pNewNode;
100 /** quotes a string and search for quotes inside the string and replace them with the new quote
101 @param rValue
102 The value to be quoted.
103 @param rQuot
104 The quote
105 @param rQuotToReplace
106 The quote to replace with
107 @return
108 The quoted string.
110 OUString SetQuotation(const OUString& rValue, const OUString& rQuot, const OUString& rQuotToReplace)
112 OUString rNewValue = rQuot;
113 rNewValue += rValue;
114 sal_Int32 nIndex = (sal_Int32)-1; // Replace quotes with double quotes or the parser gets into problems
116 if (!rQuot.isEmpty())
120 nIndex += 2;
121 nIndex = rNewValue.indexOf(rQuot,nIndex);
122 if(nIndex != -1)
123 rNewValue = rNewValue.replaceAt(nIndex,rQuot.getLength(),rQuotToReplace);
124 } while (nIndex != -1);
127 rNewValue += rQuot;
128 return rNewValue;
131 bool columnMatchP(const connectivity::OSQLParseNode* pSubTree, const connectivity::SQLParseNodeParameter& rParam)
133 using namespace connectivity;
134 assert(SQL_ISRULE(pSubTree,column_ref));
136 if(!rParam.xField.is())
137 return false;
139 // retrieve the field's name & table range
140 OUString aFieldName;
143 sal_Int32 nNamePropertyId = PROPERTY_ID_NAME;
144 if ( rParam.xField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) )
145 nNamePropertyId = PROPERTY_ID_REALNAME;
146 rParam.xField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( nNamePropertyId ) ) >>= aFieldName;
148 catch ( Exception& )
152 if(pSubTree->count())
154 const OSQLParseNode* pCol = pSubTree->getChild(pSubTree->count()-1);
155 if (SQL_ISRULE(pCol,column_val))
157 assert(pCol->count() == 1);
158 pCol = pCol->getChild(0);
160 const OSQLParseNode* pTable(NULL);
161 switch (pSubTree->count())
163 case 1:
164 break;
165 case 3:
166 pTable = pSubTree->getChild(0);
167 break;
168 case 5:
169 case 7:
170 SAL_WARN("connectivity.parse", "SQL: catalog and/or schema in column_ref in predicate");
171 break;
172 default:
173 SAL_WARN("connectivity.parse", "columnMatchP: SQL grammar changed; column_ref has " << pSubTree->count() << " children");
174 assert(false);
175 break;
177 // TODO: not all DBMS match column names case-insensitively...
178 // see XDatabaseMetaData::supportsMixedCaseIdentifiers()
179 // and XDatabaseMetaData::supportsMixedCaseQuotedIdentifiers()
180 if ( // table name matches (or no table name)?
181 ( !pTable || pTable->getTokenValue().equalsIgnoreAsciiCase(rParam.sPredicateTableAlias) )
182 && // column name matches?
183 pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName)
185 return true;
187 return false;
191 namespace connectivity
194 SQLParseNodeParameter::SQLParseNodeParameter( const Reference< XConnection >& _rxConnection,
195 const Reference< XNumberFormatter >& _xFormatter, const Reference< XPropertySet >& _xField,
196 const OUString &_sPredicateTableAlias,
197 const Locale& _rLocale, const IParseContext* _pContext,
198 bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, bool _bParseToSDBC )
199 :rLocale(_rLocale)
200 ,aMetaData( _rxConnection )
201 ,pParser( NULL )
202 ,pSubQueryHistory( new QueryNameSet )
203 ,xFormatter(_xFormatter)
204 ,xField(_xField)
205 ,sPredicateTableAlias(_sPredicateTableAlias)
206 ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const IParseContext&)OSQLParser::s_aDefaultContext )
207 ,cDecSep(_cDecSep)
208 ,bQuote(_bQuote)
209 ,bInternational(_bIntl)
210 ,bPredicate(_bPredicate)
211 ,bParseToSDBCLevel( _bParseToSDBC )
216 SQLParseNodeParameter::~SQLParseNodeParameter()
220 OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const OUString& rString)
222 Date aDate = DBTypeConversion::toDate(rString);
223 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
224 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
226 double fDate = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
227 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 36; // XXX hack
228 return rParam.xFormatter->convertNumberToString(nKey, fDate);
232 OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const OUString& rString)
234 DateTime aDate = DBTypeConversion::toDateTime(rString);
235 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
236 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
238 double fDateTime = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier));
239 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 51; // XXX hack
240 return rParam.xFormatter->convertNumberToString(nKey, fDateTime);
244 OUString OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const OUString& rString)
246 css::util::Time aTime = DBTypeConversion::toTime(rString);
247 Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
249 Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
251 double fTime = DBTypeConversion::toDouble(aTime);
252 sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 41; // XXX hack
253 return rParam.xFormatter->convertNumberToString(nKey, fTime);
257 void OSQLParseNode::parseNodeToStr(OUString& rString,
258 const Reference< XConnection >& _rxConnection,
259 const IParseContext* pContext,
260 bool _bIntl,
261 bool _bQuote) const
263 parseNodeToStr(
264 rString, _rxConnection, NULL, NULL, OUString(),
265 pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(),
266 pContext, _bIntl, _bQuote, '.', false, false );
270 void OSQLParseNode::parseNodeToPredicateStr(OUString& rString,
271 const Reference< XConnection >& _rxConnection,
272 const Reference< XNumberFormatter > & xFormatter,
273 const ::com::sun::star::lang::Locale& rIntl,
274 sal_Char _cDec,
275 const IParseContext* pContext ) const
277 OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
279 if (xFormatter.is())
280 parseNodeToStr(rString, _rxConnection, xFormatter, NULL, OUString(), rIntl, pContext, true, true, _cDec, true, false);
284 void OSQLParseNode::parseNodeToPredicateStr(OUString& rString,
285 const Reference< XConnection > & _rxConnection,
286 const Reference< XNumberFormatter > & xFormatter,
287 const Reference< XPropertySet > & _xField,
288 const OUString &_sPredicateTableAlias,
289 const ::com::sun::star::lang::Locale& rIntl,
290 sal_Char _cDec,
291 const IParseContext* pContext ) const
293 OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
295 if (xFormatter.is())
296 parseNodeToStr( rString, _rxConnection, xFormatter, _xField, _sPredicateTableAlias, rIntl, pContext, true, true, _cDec, true, false );
300 void OSQLParseNode::parseNodeToStr(OUString& rString,
301 const Reference< XConnection > & _rxConnection,
302 const Reference< XNumberFormatter > & xFormatter,
303 const Reference< XPropertySet > & _xField,
304 const OUString &_sPredicateTableAlias,
305 const ::com::sun::star::lang::Locale& rIntl,
306 const IParseContext* pContext,
307 bool _bIntl,
308 bool _bQuote,
309 sal_Char _cDecSep,
310 bool _bPredicate,
311 bool _bSubstitute) const
313 OSL_ENSURE( _rxConnection.is(), "OSQLParseNode::parseNodeToStr: invalid connection!" );
315 if ( _rxConnection.is() )
317 OUStringBuffer sBuffer = rString;
320 OSQLParseNode::impl_parseNodeToString_throw( sBuffer,
321 SQLParseNodeParameter(
322 _rxConnection, xFormatter, _xField, _sPredicateTableAlias, rIntl, pContext,
323 _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute
324 ) );
326 catch( const SQLException& )
328 SAL_WARN( "connectivity.parse", "OSQLParseNode::parseNodeToStr: this should not throw!" );
329 // our callers don't expect this method to throw anything. The only known situation
330 // where impl_parseNodeToString_throw can throw is when there is a cyclic reference
331 // in the sub queries, but this cannot be the case here, as we do not parse to
332 // SDBC level.
334 rString = sBuffer.makeStringAndClear();
338 bool OSQLParseNode::parseNodeToExecutableStatement( OUString& _out_rString, const Reference< XConnection >& _rxConnection,
339 OSQLParser& _rParser, ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const
341 OSL_PRECOND( _rxConnection.is(), "OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" );
342 SQLParseNodeParameter aParseParam( _rxConnection,
343 NULL, NULL, OUString(), OParseContext::getDefaultLocale(), NULL, false, true, '.', false, true );
345 if ( aParseParam.aMetaData.supportsSubqueriesInFrom() )
347 Reference< XQueriesSupplier > xSuppQueries( _rxConnection, UNO_QUERY );
348 OSL_ENSURE( xSuppQueries.is(), "OSQLParseNode::parseNodeToExecutableStatement: cannot substitute everything without a QueriesSupplier!" );
349 if ( xSuppQueries.is() )
350 aParseParam.xQueries = xSuppQueries->getQueries();
353 aParseParam.pParser = &_rParser;
355 _out_rString.clear();
356 OUStringBuffer sBuffer;
357 bool bSuccess = false;
360 impl_parseNodeToString_throw( sBuffer, aParseParam );
361 bSuccess = true;
363 catch( const SQLException& e )
365 if ( _pErrorHolder )
366 *_pErrorHolder = e;
368 _out_rString = sBuffer.makeStringAndClear();
369 return bSuccess;
373 namespace
375 bool lcl_isAliasNamePresent( const OSQLParseNode& _rTableNameNode )
377 return !OSQLParseNode::getTableRange(_rTableNameNode.getParent()).isEmpty();
382 void OSQLParseNode::impl_parseNodeToString_throw(OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple) const
384 if ( isToken() )
386 parseLeaf(rString,rParam);
387 return;
390 // Lets see how many nodes this subtree has
391 sal_uInt32 nCount = count();
393 bool bHandled = false;
394 switch ( getKnownRuleID() )
396 // special handling for parameters
397 case parameter:
399 bSimple=false;
400 if(!rString.isEmpty())
401 rString.appendAscii(" ");
402 if (nCount == 1) // ?
403 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
404 else if (nCount == 2) // :Name
406 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
407 rString.append(m_aChildren[1]->m_aNodeValue);
408 } // [Name]
409 else
411 m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam, false );
412 rString.append(m_aChildren[1]->m_aNodeValue);
413 rString.append(m_aChildren[2]->m_aNodeValue);
415 bHandled = true;
417 break;
419 // table refs
420 case table_ref:
421 bSimple=false;
422 if ( ( nCount == 2 ) || ( nCount == 3 ) || ( nCount == 5 ) )
424 impl_parseTableRangeNodeToString_throw( rString, rParam );
425 bHandled = true;
427 break;
429 // table name - might be a query name
430 case table_name:
431 bSimple=false;
432 bHandled = impl_parseTableNameNodeToString_throw( rString, rParam );
433 break;
435 case as_clause:
436 bSimple=false;
437 assert(nCount == 0 || nCount == 2);
438 if (nCount == 2)
440 if ( rParam.aMetaData.generateASBeforeCorrelationName() )
441 rString.append(" AS ");
442 m_aChildren[1]->impl_parseNodeToString_throw( rString, rParam, false );
444 bHandled = true;
445 break;
447 case opt_as:
448 assert(nCount == 0);
449 bHandled = true;
450 break;
452 case like_predicate:
453 // Depending on whether international is given, LIKE is treated differently
454 // international: *, ? are placeholders
455 // else SQL92 conform: %, _
456 impl_parseLikeNodeToString_throw( rString, rParam, bSimple );
457 bHandled = true;
458 break;
460 case general_set_fct:
461 case set_fct_spec:
462 case position_exp:
463 case extract_exp:
464 case length_exp:
465 case char_value_fct:
467 bSimple=false;
468 if (!addDateValue(rString, rParam))
470 // Do not quote function name
471 SQLParseNodeParameter aNewParam(rParam);
472 aNewParam.bQuote = ( SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct) );
474 m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam, false );
475 aNewParam.bQuote = rParam.bQuote;
476 //aNewParam.bPredicate = sal_False; // disable [ ] around names // look at i73215
477 OUStringBuffer aStringPara;
478 for (sal_uInt32 i=1; i<nCount; i++)
480 const OSQLParseNode * pSubTree = m_aChildren[i];
481 if (pSubTree)
483 pSubTree->impl_parseNodeToString_throw( aStringPara, aNewParam, false );
485 // In the comma lists, put commas in-between all subtrees
486 if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1)))
487 aStringPara.appendAscii(",");
489 else
490 i++;
492 rString.append(aStringPara.makeStringAndClear());
494 bHandled = true;
496 //fall-through
497 case odbc_call_spec:
498 case subquery:
499 case term:
500 case factor:
501 case window_function:
502 case cast_spec:
503 case num_value_exp:
504 bSimple = false;
506 break;
507 default:
508 break;
509 } // switch ( getKnownRuleID() )
511 if ( !bHandled )
513 for (OSQLParseNodes::const_iterator i = m_aChildren.begin();
514 i != m_aChildren.end();)
516 const OSQLParseNode* pSubTree = *i;
517 if ( !pSubTree )
519 ++i;
520 continue;
523 SQLParseNodeParameter aNewParam(rParam);
525 // don't replace the field for subqueries
526 if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery))
527 aNewParam.xField = NULL;
529 // When we are building a criterion inside a query view,
530 // simplify criterion display by removing:
531 // "currentFieldName"
532 // "currentFieldName" =
533 // but only in simple expressions.
534 // This means anything that is made of:
535 // (see the rules conditionalised by inPredicateCheck() in sqlbison.y).
536 // - parentheses
537 // - logical operators (and, or, not)
538 // - comparison operators (IS, =, >, <, BETWEEN, LIKE, ...)
539 // but *not* e.g. in function arguments
540 if (bSimple && rParam.bPredicate && rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref))
542 if (columnMatchP(pSubTree, rParam))
544 // skip field
545 ++i;
546 // if the following node is the comparison operator'=',
547 // we filter it as well
548 if (SQL_ISRULE(this, comparison_predicate))
550 if(i != m_aChildren.end())
552 pSubTree = *i;
553 if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL)
554 ++i;
558 else
560 pSubTree->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
561 ++i;
563 // In the comma lists, put commas in-between all subtrees
564 if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end()))
565 rString.appendAscii(",");
568 else
570 pSubTree->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
571 ++i;
573 // In the comma lists, put commas in-between all subtrees
574 if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end()))
576 if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate)
577 rString.appendAscii(";");
578 else
579 rString.appendAscii(",");
582 // The right hand-side of these operators is not simple
583 switch ( getKnownRuleID() )
585 case general_set_fct:
586 case set_fct_spec:
587 case position_exp:
588 case extract_exp:
589 case length_exp:
590 case char_value_fct:
591 case odbc_call_spec:
592 case subquery:
593 case comparison_predicate:
594 case between_predicate:
595 case like_predicate:
596 case test_for_null:
597 case in_predicate:
598 case existence_test:
599 case unique_test:
600 case all_or_any_predicate:
601 case join_condition:
602 case comparison_predicate_part_2:
603 case parenthesized_boolean_value_expression:
604 case other_like_predicate_part_2:
605 case between_predicate_part_2:
606 bSimple=false;
607 break;
608 default:
609 break;
616 bool OSQLParseNode::impl_parseTableNameNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
618 // is the table_name part of a table_ref?
619 OSL_ENSURE( getParent(), "OSQLParseNode::impl_parseTableNameNodeToString_throw: table_name without parent?" );
620 if ( !getParent() || ( getParent()->getKnownRuleID() != table_ref ) )
621 return false;
623 // if it's a query, maybe we need to substitute the SQL statement ...
624 if ( !rParam.bParseToSDBCLevel )
625 return false;
627 if ( !rParam.xQueries.is() )
628 // connection does not support queries in queries, or was no query supplier
629 return false;
633 OUString sTableOrQueryName( getChild(0)->getTokenValue() );
634 bool bIsQuery = rParam.xQueries->hasByName( sTableOrQueryName );
635 if ( !bIsQuery )
636 return false;
638 // avoid recursion (e.g. "foo" defined as "SELECT * FROM bar" and "bar" defined as "SELECT * FROM foo".
639 if ( rParam.pSubQueryHistory->find( sTableOrQueryName ) != rParam.pSubQueryHistory->end() )
641 OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: no parser?" );
642 if ( rParam.pParser )
644 const SQLError& rErrors( rParam.pParser->getErrorHelper() );
645 rErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
647 else
649 SQLError aErrors( ::comphelper::getProcessComponentContext() );
650 aErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES );
653 rParam.pSubQueryHistory->insert( sTableOrQueryName );
655 Reference< XPropertySet > xQuery( rParam.xQueries->getByName( sTableOrQueryName ), UNO_QUERY_THROW );
657 // substitute the query name with the constituting command
658 OUString sCommand;
659 OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sCommand );
661 bool bEscapeProcessing = false;
662 OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing );
664 // the query we found here might itself be based on another query, so parse it recursively
665 OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: cannot analyze sub queries without a parser!" );
666 if ( bEscapeProcessing && rParam.pParser )
668 OUString sError;
669 boost::scoped_ptr< OSQLParseNode > pSubQueryNode( rParam.pParser->parseTree( sError, sCommand, false ) );
670 if ( pSubQueryNode.get() )
672 // parse the sub-select to SDBC level, too
673 OUStringBuffer sSubSelect;
674 pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, rParam, false );
675 if ( !sSubSelect.isEmpty() )
676 sCommand = sSubSelect.makeStringAndClear();
680 rString.appendAscii( " ( " );
681 rString.append(sCommand);
682 rString.appendAscii( " )" );
684 // append the query name as table alias, since it might be referenced in other
685 // parts of the statement - but only if there's no other alias name present
686 if ( !lcl_isAliasNamePresent( *this ) )
688 rString.appendAscii( " AS " );
689 if ( rParam.bQuote )
690 rString.append(SetQuotation( sTableOrQueryName,
691 rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() ));
694 // don't forget to remove the query name from the history, else multiple inclusions
695 // won't work
696 // #i69227# / 2006-10-10 / frank.schoenheit@sun.com
697 rParam.pSubQueryHistory->erase( sTableOrQueryName );
699 return true;
701 catch( const SQLException& )
703 throw;
705 catch( const Exception& )
707 DBG_UNHANDLED_EXCEPTION();
709 return false;
713 void OSQLParseNode::impl_parseTableRangeNodeToString_throw(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
715 OSL_PRECOND( ( count() == 2 ) || ( count() == 3 ) || ( count() == 5 ) ,"Illegal count");
717 // rString += " ";
718 ::std::for_each(m_aChildren.begin(),m_aChildren.end(),
719 boost::bind( &OSQLParseNode::impl_parseNodeToString_throw, _1, boost::ref( rString ), boost::cref( rParam ), false ));
723 void OSQLParseNode::impl_parseLikeNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple ) const
725 assert(SQL_ISRULE(this,like_predicate));
726 OSL_ENSURE(count() == 2,"count != 2: Prepare for GPF");
728 const OSQLParseNode* pEscNode = NULL;
729 const OSQLParseNode* pParaNode = NULL;
731 SQLParseNodeParameter aNewParam(rParam);
732 //aNewParam.bQuote = sal_True; // why setting this to true? @see http://www.openoffice.org/issues/show_bug.cgi?id=75557
734 if ( !(bSimple && rParam.bPredicate && rParam.xField.is() && SQL_ISRULE(m_aChildren[0],column_ref) && columnMatchP(m_aChildren[0], rParam)) )
735 m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam, bSimple );
737 const OSQLParseNode* pPart2 = m_aChildren[1];
738 pPart2->getChild(0)->impl_parseNodeToString_throw( rString, aNewParam, false );
739 pPart2->getChild(1)->impl_parseNodeToString_throw( rString, aNewParam, false );
740 pParaNode = pPart2->getChild(2);
741 pEscNode = pPart2->getChild(3);
743 if (pParaNode->isToken())
745 OUString aStr = ConvertLikeToken(pParaNode, pEscNode, rParam.bInternational);
746 rString.appendAscii(" ");
747 rString.append(SetQuotation(aStr,OUString("\'"),OUString("\'\'")));
749 else
750 pParaNode->impl_parseNodeToString_throw( rString, aNewParam, false );
752 pEscNode->impl_parseNodeToString_throw( rString, aNewParam, false );
757 bool OSQLParseNode::getTableComponents(const OSQLParseNode* _pTableNode,
758 ::com::sun::star::uno::Any &_rCatalog,
759 OUString &_rSchema,
760 OUString &_rTable,
761 const Reference< XDatabaseMetaData >& _xMetaData)
763 OSL_ENSURE(_pTableNode,"Wrong use of getTableComponents! _pTableNode is not allowed to be null!");
764 if(_pTableNode)
766 const bool bSupportsCatalog = _xMetaData.is() && _xMetaData->supportsCatalogsInDataManipulation();
767 const bool bSupportsSchema = _xMetaData.is() && _xMetaData->supportsSchemasInDataManipulation();
768 const OSQLParseNode* pTableNode = _pTableNode;
769 // clear the parameter given
770 _rCatalog = Any();
771 _rSchema.clear();
772 _rTable.clear();
773 // see rule catalog_name: in sqlbison.y
774 if (SQL_ISRULE(pTableNode,catalog_name))
776 OSL_ENSURE(pTableNode->getChild(0) && pTableNode->getChild(0)->isToken(),"Invalid parsenode!");
777 _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
778 pTableNode = pTableNode->getChild(2);
780 // check if we have schema_name rule
781 if(SQL_ISRULE(pTableNode,schema_name))
783 if ( bSupportsCatalog && !bSupportsSchema )
784 _rCatalog <<= pTableNode->getChild(0)->getTokenValue();
785 else
786 _rSchema = pTableNode->getChild(0)->getTokenValue();
787 pTableNode = pTableNode->getChild(2);
789 // check if we have table_name rule
790 if(SQL_ISRULE(pTableNode,table_name))
792 _rTable = pTableNode->getChild(0)->getTokenValue();
794 else
796 SAL_WARN( "connectivity.parse","Error in parse tree!");
799 return !_rTable.isEmpty();
802 void OSQLParser::killThousandSeparator(OSQLParseNode* pLiteral)
804 if ( pLiteral )
806 if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
808 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace('.', sal_Unicode());
809 // and replace decimal
810 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', '.');
812 else
813 pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', sal_Unicode());
817 OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType, OSQLParseNode* pLiteral)
819 if ( !pLiteral )
820 return NULL;
822 OSQLParseNode* pReturn = pLiteral;
824 if ( ( pLiteral->isRule() && !SQL_ISRULE(pLiteral,value_exp) ) || SQL_ISTOKEN(pLiteral,FALSE) || SQL_ISTOKEN(pLiteral,TRUE) )
826 switch(nType)
828 case DataType::CHAR:
829 case DataType::VARCHAR:
830 case DataType::LONGVARCHAR:
831 case DataType::CLOB:
832 if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) )
833 pReturn = NULL;
834 default:
835 break;
838 else
840 switch(pLiteral->getNodeType())
842 case SQL_NODE_STRING:
843 switch(nType)
845 case DataType::CHAR:
846 case DataType::VARCHAR:
847 case DataType::LONGVARCHAR:
848 case DataType::CLOB:
849 break;
850 case DataType::DATE:
851 case DataType::TIME:
852 case DataType::TIMESTAMP:
853 if (m_xFormatter.is())
854 pReturn = buildDate( nType, pReturn);
855 break;
856 default:
857 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
858 break;
860 break;
861 case SQL_NODE_ACCESS_DATE:
862 switch(nType)
864 case DataType::DATE:
865 case DataType::TIME:
866 case DataType::TIMESTAMP:
867 if ( m_xFormatter.is() )
868 pReturn = buildDate( nType, pReturn);
869 else
870 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_DATE_COMPARE);
871 break;
872 default:
873 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
874 break;
876 break;
877 case SQL_NODE_INTNUM:
878 switch(nType)
880 case DataType::BIT:
881 case DataType::BOOLEAN:
882 case DataType::DECIMAL:
883 case DataType::NUMERIC:
884 case DataType::TINYINT:
885 case DataType::SMALLINT:
886 case DataType::INTEGER:
887 case DataType::BIGINT:
888 case DataType::FLOAT:
889 case DataType::REAL:
890 case DataType::DOUBLE:
891 // kill thousand separators if any
892 killThousandSeparator(pReturn);
893 break;
894 case DataType::CHAR:
895 case DataType::VARCHAR:
896 case DataType::LONGVARCHAR:
897 case DataType::CLOB:
898 pReturn = buildNode_STR_NUM(pReturn);
899 break;
900 default:
901 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE);
902 break;
904 break;
905 case SQL_NODE_APPROXNUM:
906 switch(nType)
908 case DataType::DECIMAL:
909 case DataType::NUMERIC:
910 case DataType::FLOAT:
911 case DataType::REAL:
912 case DataType::DOUBLE:
913 // kill thousand separators if any
914 killThousandSeparator(pReturn);
915 break;
916 case DataType::CHAR:
917 case DataType::VARCHAR:
918 case DataType::LONGVARCHAR:
919 case DataType::CLOB:
920 pReturn = buildNode_STR_NUM(pReturn);
921 break;
922 case DataType::INTEGER:
923 default:
924 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_REAL_COMPARE);
925 break;
927 break;
928 default:
932 return pReturn;
935 sal_Int16 OSQLParser::buildPredicateRule(OSQLParseNode*& pAppend, OSQLParseNode* pLiteral, OSQLParseNode* pCompare, OSQLParseNode* pLiteral2)
937 OSL_ENSURE(inPredicateCheck(),"Only in predicate check allowed!");
938 sal_Int16 nErg = 0;
939 if ( m_xField.is() )
941 sal_Int32 nType = 0;
944 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
946 catch( Exception& )
948 return nErg;
951 OSQLParseNode* pNode1 = convertNode(nType,pLiteral);
952 if ( pNode1 )
954 OSQLParseNode* pNode2 = convertNode(nType,pLiteral2);
955 if ( m_sErrorMessage.isEmpty() )
956 nErg = buildNode(pAppend,pCompare,pNode1,pNode2);
959 if (!pCompare->getParent()) // I have no parent so I was not used and I must die :-)
960 delete pCompare;
961 return nErg;
964 sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode* pAppend, OSQLParseNode*& pLiteral, const OSQLParseNode* pEscape)
966 sal_Int16 nErg = 0;
967 sal_Int32 nType = 0;
969 if (!m_xField.is())
970 return nErg;
973 Any aValue;
975 aValue = m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE));
976 aValue >>= nType;
979 catch( Exception& )
981 return nErg;
984 switch (nType)
986 case DataType::CHAR:
987 case DataType::VARCHAR:
988 case DataType::LONGVARCHAR:
989 case DataType::CLOB:
990 if(pLiteral->isRule())
992 pAppend->append(pLiteral);
993 nErg = 1;
995 else
997 switch(pLiteral->getNodeType())
999 case SQL_NODE_STRING:
1000 pLiteral->m_aNodeValue = ConvertLikeToken(pLiteral, pEscape, false);
1001 pAppend->append(pLiteral);
1002 nErg = 1;
1003 break;
1004 case SQL_NODE_APPROXNUM:
1005 if (m_xFormatter.is() && m_nFormatKey)
1007 sal_Int16 nScale = 0;
1010 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OUString("Decimals") );
1011 aValue >>= nScale;
1013 catch( Exception& )
1017 pAppend->append(new OSQLInternalNode(stringToDouble(pLiteral->getTokenValue(),nScale),SQL_NODE_STRING));
1019 else
1020 pAppend->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQL_NODE_STRING));
1022 delete pLiteral;
1023 nErg = 1;
1024 break;
1025 default:
1026 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_VALUE_NO_LIKE);
1027 m_sErrorMessage = m_sErrorMessage.replaceAt(m_sErrorMessage.indexOf("#1"),2,pLiteral->getTokenValue());
1028 break;
1031 break;
1032 default:
1033 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_FIELD_NO_LIKE);
1034 break;
1036 return nErg;
1039 OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType)
1041 OUString aEmptyString;
1042 OSQLParseNode* pNewNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::set_fct_spec));
1043 pNewNode->append(new OSQLInternalNode(OUString("{"), SQL_NODE_PUNCTUATION));
1044 OSQLParseNode* pDateNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::odbc_fct_spec));
1045 pNewNode->append(pDateNode);
1046 pNewNode->append(new OSQLInternalNode(OUString("}"), SQL_NODE_PUNCTUATION));
1048 switch (nType)
1050 case DataType::DATE:
1052 Date aDate = DBTypeConversion::toDate(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
1053 OUString aString = DBTypeConversion::toDateString(aDate);
1054 pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
1055 pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
1056 break;
1058 case DataType::TIME:
1060 css::util::Time aTime = DBTypeConversion::toTime(fValue);
1061 OUString aString = DBTypeConversion::toTimeString(aTime);
1062 pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_T));
1063 pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
1064 break;
1066 case DataType::TIMESTAMP:
1068 DateTime aDateTime = DBTypeConversion::toDateTime(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier()));
1069 if (aDateTime.Seconds || aDateTime.Minutes || aDateTime.Hours)
1071 OUString aString = DBTypeConversion::toDateTimeString(aDateTime);
1072 pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_TS));
1073 pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING));
1075 else
1077 Date aDate(aDateTime.Day,aDateTime.Month,aDateTime.Year);
1078 pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D));
1079 pDateNode->append(new OSQLInternalNode(DBTypeConversion::toDateString(aDate), SQL_NODE_STRING));
1081 break;
1085 return pNewNode;
1088 OSQLParseNode* OSQLParser::buildNode_STR_NUM(OSQLParseNode*& _pLiteral)
1090 OSQLParseNode* pReturn = NULL;
1091 if ( _pLiteral )
1093 if (m_nFormatKey)
1095 sal_Int16 nScale = 0;
1098 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OUString("Decimals") );
1099 aValue >>= nScale;
1101 catch( Exception& )
1105 pReturn = new OSQLInternalNode(stringToDouble(_pLiteral->getTokenValue(),nScale),SQL_NODE_STRING);
1107 else
1108 pReturn = new OSQLInternalNode(_pLiteral->getTokenValue(),SQL_NODE_STRING);
1110 delete _pLiteral;
1111 _pLiteral = NULL;
1113 return pReturn;
1116 OUString OSQLParser::stringToDouble(const OUString& _rValue,sal_Int16 _nScale)
1118 OUString aValue;
1119 if(!m_xCharClass.is())
1120 m_xCharClass = CharacterClassification::create( m_xContext );
1121 if( s_xLocaleData.is() )
1125 ParseResult aResult = m_xCharClass->parsePredefinedToken(KParseType::ANY_NUMBER,_rValue,0,m_pData->aLocale,0,OUString(),KParseType::ANY_NUMBER,OUString());
1126 if((aResult.TokenType & KParseType::IDENTNAME) && aResult.EndPos == _rValue.getLength())
1128 aValue = OUString::number(aResult.Value);
1129 sal_Int32 nPos = aValue.lastIndexOf('.');
1130 if((nPos+_nScale) < aValue.getLength())
1131 aValue = aValue.replaceAt(nPos+_nScale,aValue.getLength()-nPos-_nScale,OUString());
1132 aValue = aValue.replaceAt(aValue.lastIndexOf('.'),1,s_xLocaleData->getLocaleItem(m_pData->aLocale).decimalSeparator);
1133 return aValue;
1136 catch(Exception&)
1140 return aValue;
1144 ::osl::Mutex& OSQLParser::getMutex()
1146 static ::osl::Mutex aMutex;
1147 return aMutex;
1151 OSQLParseNode* OSQLParser::predicateTree(OUString& rErrorMessage, const OUString& rStatement,
1152 const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
1153 const Reference< XPropertySet > & xField,
1154 bool bUseRealName)
1156 // Guard the parsing
1157 ::osl::MutexGuard aGuard(getMutex());
1158 // must be reset
1159 setParser(this);
1162 // reset the parser
1163 m_xField = xField;
1164 m_xFormatter = xFormatter;
1166 if (m_xField.is())
1168 sal_Int32 nType=0;
1171 // get the field name
1172 OUString aString;
1174 // retrieve the fields name
1175 // #75243# use the RealName of the column if there is any otherwise the name which could be the alias
1176 // of the field
1177 Reference< XPropertySetInfo> xInfo = m_xField->getPropertySetInfo();
1178 if ( bUseRealName && xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)))
1179 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)) >>= aString;
1180 else
1181 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString;
1183 m_sFieldName = aString;
1185 // get the field format key
1186 if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)))
1187 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) >>= m_nFormatKey;
1188 else
1189 m_nFormatKey = 0;
1191 // get the field type
1192 m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType;
1194 catch ( Exception& )
1196 OSL_ASSERT(false);
1199 if (m_nFormatKey && m_xFormatter.is())
1201 Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LOCALE) );
1202 OSL_ENSURE(aValue.getValueType() == cppu::UnoType<com::sun::star::lang::Locale>::get(), "OSQLParser::PredicateTree : invalid language property !");
1204 if (aValue.getValueType() == cppu::UnoType<com::sun::star::lang::Locale>::get())
1205 aValue >>= m_pData->aLocale;
1207 else
1208 m_pData->aLocale = m_pContext->getPreferredLocale();
1210 if ( m_xFormatter.is() )
1214 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
1215 if ( xFormatSup.is() )
1217 Reference< ::com::sun::star::util::XNumberFormats > xFormats = xFormatSup->getNumberFormats();
1218 if ( xFormats.is() )
1220 ::com::sun::star::lang::Locale aLocale;
1221 aLocale.Language = "en";
1222 aLocale.Country = "US";
1223 OUString sFormat("YYYY-MM-DD");
1224 m_nDateFormatKey = xFormats->queryKey(sFormat,aLocale,sal_False);
1225 if ( m_nDateFormatKey == sal_Int32(-1) )
1226 m_nDateFormatKey = xFormats->addNew(sFormat, aLocale);
1230 catch ( Exception& )
1232 SAL_WARN( "connectivity.parse","DateFormatKey");
1236 switch (nType)
1238 case DataType::DATE:
1239 case DataType::TIME:
1240 case DataType::TIMESTAMP:
1241 s_pScanner->SetRule(s_pScanner->GetDATERule());
1242 break;
1243 case DataType::CHAR:
1244 case DataType::VARCHAR:
1245 case DataType::LONGVARCHAR:
1246 case DataType::CLOB:
1247 s_pScanner->SetRule(s_pScanner->GetSTRINGRule());
1248 break;
1249 default:
1250 if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' )
1251 s_pScanner->SetRule(s_pScanner->GetGERRule());
1252 else
1253 s_pScanner->SetRule(s_pScanner->GetENGRule());
1257 else
1258 s_pScanner->SetRule(s_pScanner->GetSQLRule());
1260 s_pScanner->prepareScan(rStatement, m_pContext, true);
1262 SQLyylval.pParseNode = NULL;
1263 // SQLyypvt = NULL;
1264 m_pParseTree = NULL;
1265 m_sErrorMessage.clear();
1267 // Start the parser
1268 if (SQLyyparse() != 0)
1270 m_sFieldName.clear();
1271 m_xField.clear();
1272 m_xFormatter.clear();
1273 m_nFormatKey = 0;
1274 m_nDateFormatKey = 0;
1276 if (m_sErrorMessage.isEmpty())
1277 m_sErrorMessage = s_pScanner->getErrorMessage();
1278 if (m_sErrorMessage.isEmpty())
1279 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_GENERAL);
1281 rErrorMessage = m_sErrorMessage;
1283 // clear the garbage collector
1284 (*s_pGarbageCollector)->clearAndDelete();
1285 return NULL;
1287 else
1289 (*s_pGarbageCollector)->clear();
1291 m_sFieldName.clear();
1292 m_xField.clear();
1293 m_xFormatter.clear();
1294 m_nFormatKey = 0;
1295 m_nDateFormatKey = 0;
1297 // Return the result (the root parse node):
1299 // Instead, the parse method sets the member pParseTree and simply returns that
1300 OSL_ENSURE(m_pParseTree != NULL,"OSQLParser: Parser did not return a ParseTree!");
1301 return m_pParseTree;
1307 OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, const IParseContext* _pContext)
1308 :m_pContext(_pContext)
1309 ,m_pParseTree(NULL)
1310 ,m_pData( new OSQLParser_Data( rxContext ) )
1311 ,m_nFormatKey(0)
1312 ,m_nDateFormatKey(0)
1313 ,m_xContext(rxContext)
1317 setParser(this);
1319 #ifdef SQLYYDEBUG
1320 #ifdef SQLYYDEBUG_ON
1321 SQLyydebug = 1;
1322 #endif
1323 #endif
1325 ::osl::MutexGuard aGuard(getMutex());
1326 // Do we have to initialize the data?
1327 if (s_nRefCount == 0)
1329 s_pScanner = new OSQLScanner();
1330 s_pScanner->setScanner();
1331 s_pGarbageCollector = new OSQLParseNodesGarbageCollector();
1333 if(!s_xLocaleData.is())
1334 s_xLocaleData = LocaleData::create(m_xContext);
1336 // reset to UNKNOWN_RULE
1337 static_assert(OSQLParseNode::UNKNOWN_RULE==0, "UNKNOWN_RULE must be 0 for memset to 0 to work");
1338 memset(OSQLParser::s_nRuleIDs,0,sizeof(OSQLParser::s_nRuleIDs));
1340 struct
1342 OSQLParseNode::Rule eRule; // the parse node's ID for the rule
1343 OString sRuleName; // the name of the rule ("select_statement")
1344 } aRuleDescriptions[] =
1346 { OSQLParseNode::select_statement, "select_statement" },
1347 { OSQLParseNode::table_exp, "table_exp" },
1348 { OSQLParseNode::table_ref_commalist, "table_ref_commalist" },
1349 { OSQLParseNode::table_ref, "table_ref" },
1350 { OSQLParseNode::catalog_name, "catalog_name" },
1351 { OSQLParseNode::schema_name, "schema_name" },
1352 { OSQLParseNode::table_name, "table_name" },
1353 { OSQLParseNode::opt_column_commalist, "opt_column_commalist" },
1354 { OSQLParseNode::column_commalist, "column_commalist" },
1355 { OSQLParseNode::column_ref_commalist, "column_ref_commalist" },
1356 { OSQLParseNode::column_ref, "column_ref" },
1357 { OSQLParseNode::opt_order_by_clause, "opt_order_by_clause" },
1358 { OSQLParseNode::ordering_spec_commalist, "ordering_spec_commalist" },
1359 { OSQLParseNode::ordering_spec, "ordering_spec" },
1360 { OSQLParseNode::opt_asc_desc, "opt_asc_desc" },
1361 { OSQLParseNode::where_clause, "where_clause" },
1362 { OSQLParseNode::opt_where_clause, "opt_where_clause" },
1363 { OSQLParseNode::search_condition, "search_condition" },
1364 { OSQLParseNode::comparison, "comparison" },
1365 { OSQLParseNode::comparison_predicate, "comparison_predicate" },
1366 { OSQLParseNode::between_predicate, "between_predicate" },
1367 { OSQLParseNode::like_predicate, "like_predicate" },
1368 { OSQLParseNode::opt_escape, "opt_escape" },
1369 { OSQLParseNode::test_for_null, "test_for_null" },
1370 { OSQLParseNode::scalar_exp_commalist, "scalar_exp_commalist" },
1371 { OSQLParseNode::scalar_exp, "scalar_exp" },
1372 { OSQLParseNode::parameter_ref, "parameter_ref" },
1373 { OSQLParseNode::parameter, "parameter" },
1374 { OSQLParseNode::general_set_fct, "general_set_fct" },
1375 { OSQLParseNode::range_variable, "range_variable" },
1376 { OSQLParseNode::column, "column" },
1377 { OSQLParseNode::delete_statement_positioned, "delete_statement_positioned" },
1378 { OSQLParseNode::delete_statement_searched, "delete_statement_searched" },
1379 { OSQLParseNode::update_statement_positioned, "update_statement_positioned" },
1380 { OSQLParseNode::update_statement_searched, "update_statement_searched" },
1381 { OSQLParseNode::assignment_commalist, "assignment_commalist" },
1382 { OSQLParseNode::assignment, "assignment" },
1383 { OSQLParseNode::values_or_query_spec, "values_or_query_spec" },
1384 { OSQLParseNode::insert_statement, "insert_statement" },
1385 { OSQLParseNode::insert_atom_commalist, "insert_atom_commalist" },
1386 { OSQLParseNode::insert_atom, "insert_atom" },
1387 { OSQLParseNode::from_clause, "from_clause" },
1388 { OSQLParseNode::qualified_join, "qualified_join" },
1389 { OSQLParseNode::cross_union, "cross_union" },
1390 { OSQLParseNode::select_sublist, "select_sublist" },
1391 { OSQLParseNode::derived_column, "derived_column" },
1392 { OSQLParseNode::column_val, "column_val" },
1393 { OSQLParseNode::set_fct_spec, "set_fct_spec" },
1394 { OSQLParseNode::boolean_term, "boolean_term" },
1395 { OSQLParseNode::boolean_primary, "boolean_primary" },
1396 { OSQLParseNode::num_value_exp, "num_value_exp" },
1397 { OSQLParseNode::join_type, "join_type" },
1398 { OSQLParseNode::position_exp, "position_exp" },
1399 { OSQLParseNode::extract_exp, "extract_exp" },
1400 { OSQLParseNode::length_exp, "length_exp" },
1401 { OSQLParseNode::char_value_fct, "char_value_fct" },
1402 { OSQLParseNode::odbc_call_spec, "odbc_call_spec" },
1403 { OSQLParseNode::in_predicate, "in_predicate" },
1404 { OSQLParseNode::existence_test, "existence_test" },
1405 { OSQLParseNode::unique_test, "unique_test" },
1406 { OSQLParseNode::all_or_any_predicate, "all_or_any_predicate" },
1407 { OSQLParseNode::named_columns_join, "named_columns_join" },
1408 { OSQLParseNode::join_condition, "join_condition" },
1409 { OSQLParseNode::joined_table, "joined_table" },
1410 { OSQLParseNode::boolean_factor, "boolean_factor" },
1411 { OSQLParseNode::sql_not, "sql_not" },
1412 { OSQLParseNode::manipulative_statement, "manipulative_statement" },
1413 { OSQLParseNode::subquery, "subquery" },
1414 { OSQLParseNode::value_exp_commalist, "value_exp_commalist" },
1415 { OSQLParseNode::odbc_fct_spec, "odbc_fct_spec" },
1416 { OSQLParseNode::union_statement, "union_statement" },
1417 { OSQLParseNode::outer_join_type, "outer_join_type" },
1418 { OSQLParseNode::char_value_exp, "char_value_exp" },
1419 { OSQLParseNode::term, "term" },
1420 { OSQLParseNode::value_exp_primary, "value_exp_primary" },
1421 { OSQLParseNode::value_exp, "value_exp" },
1422 { OSQLParseNode::selection, "selection" },
1423 { OSQLParseNode::fold, "fold" },
1424 { OSQLParseNode::char_substring_fct, "char_substring_fct" },
1425 { OSQLParseNode::factor, "factor" },
1426 { OSQLParseNode::base_table_def, "base_table_def" },
1427 { OSQLParseNode::base_table_element_commalist, "base_table_element_commalist" },
1428 { OSQLParseNode::data_type, "data_type" },
1429 { OSQLParseNode::column_def, "column_def" },
1430 { OSQLParseNode::table_node, "table_node" },
1431 { OSQLParseNode::as_clause, "as_clause" },
1432 { OSQLParseNode::opt_as, "opt_as" },
1433 { OSQLParseNode::op_column_commalist, "op_column_commalist" },
1434 { OSQLParseNode::table_primary_as_range_column, "table_primary_as_range_column" },
1435 { OSQLParseNode::datetime_primary, "datetime_primary" },
1436 { OSQLParseNode::concatenation, "concatenation" },
1437 { OSQLParseNode::char_factor, "char_factor" },
1438 { OSQLParseNode::bit_value_fct, "bit_value_fct" },
1439 { OSQLParseNode::comparison_predicate_part_2, "comparison_predicate_part_2" },
1440 { OSQLParseNode::parenthesized_boolean_value_expression, "parenthesized_boolean_value_expression" },
1441 { OSQLParseNode::character_string_type, "character_string_type" },
1442 { OSQLParseNode::other_like_predicate_part_2, "other_like_predicate_part_2" },
1443 { OSQLParseNode::between_predicate_part_2, "between_predicate_part_2" },
1444 { OSQLParseNode::null_predicate_part_2, "null_predicate_part_2" },
1445 { OSQLParseNode::cast_spec, "cast_spec" },
1446 { OSQLParseNode::window_function, "window_function" }
1448 const size_t nRuleMapCount = sizeof( aRuleDescriptions ) / sizeof( aRuleDescriptions[0] );
1449 // added a new rule? Adjust this map!
1450 // +1 for UNKNOWN_RULE
1451 static_assert(nRuleMapCount + 1 == static_cast<size_t>(OSQLParseNode::rule_count), "must be equal");
1453 for ( size_t mapEntry = 0; mapEntry < nRuleMapCount; ++mapEntry )
1455 // look up the rule description in the our identifier map
1456 sal_uInt32 nParserRuleID = StrToRuleID( aRuleDescriptions[ mapEntry ].sRuleName );
1457 // map the parser's rule ID to the OSQLParseNode::Rule
1458 s_aReverseRuleIDLookup[ nParserRuleID ] = aRuleDescriptions[ mapEntry ].eRule;
1459 // and map the OSQLParseNode::Rule to the parser's rule ID
1460 s_nRuleIDs[ aRuleDescriptions[ mapEntry ].eRule ] = nParserRuleID;
1463 ++s_nRefCount;
1465 if (m_pContext == NULL)
1466 // take the default context
1467 m_pContext = &s_aDefaultContext;
1469 m_pData->aLocale = m_pContext->getPreferredLocale();
1473 OSQLParser::~OSQLParser()
1476 ::osl::MutexGuard aGuard(getMutex());
1477 OSL_ENSURE(s_nRefCount > 0, "OSQLParser::~OSQLParser() : suspicious call : has a refcount of 0 !");
1478 if (!--s_nRefCount)
1480 s_pScanner->setScanner(true);
1481 delete s_pScanner;
1482 s_pScanner = NULL;
1484 delete s_pGarbageCollector;
1485 s_pGarbageCollector = NULL;
1486 // Is only set the first time, so we should delete it only when there are no more instances
1487 s_xLocaleData = NULL;
1489 RuleIDMap aEmpty;
1490 s_aReverseRuleIDLookup.swap( aEmpty );
1492 m_pParseTree = NULL;
1496 void OSQLParseNode::substituteParameterNames(OSQLParseNode* _pNode)
1498 sal_Int32 nCount = _pNode->count();
1499 for(sal_Int32 i=0;i < nCount;++i)
1501 OSQLParseNode* pChildNode = _pNode->getChild(i);
1502 if(SQL_ISRULE(pChildNode,parameter) && pChildNode->count() > 1)
1504 OSQLParseNode* pNewNode = new OSQLParseNode(OUString("?") ,SQL_NODE_PUNCTUATION,0);
1505 delete pChildNode->replace(pChildNode->getChild(0),pNewNode);
1506 sal_Int32 nChildCount = pChildNode->count();
1507 for(sal_Int32 j=1;j < nChildCount;++j)
1508 delete pChildNode->removeAt(1);
1510 else
1511 substituteParameterNames(pChildNode);
1516 bool OSQLParser::extractDate(OSQLParseNode* pLiteral,double& _rfValue)
1518 Reference< XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier();
1519 Reference< XNumberFormatTypes > xFormatTypes;
1520 if ( xFormatSup.is() )
1521 xFormatTypes.set(xFormatSup->getNumberFormats(), css::uno::UNO_QUERY);
1523 // if there is no format key, yet, make sure we have a feasible one for our locale
1526 if ( !m_nFormatKey && xFormatTypes.is() )
1527 m_nFormatKey = ::dbtools::getDefaultNumberFormat( m_xField, xFormatTypes, m_pData->aLocale );
1529 catch( Exception& ) { }
1530 OUString sValue = pLiteral->getTokenValue();
1531 sal_Int32 nTryFormat = m_nFormatKey;
1532 bool bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1534 // If our format key didn't do, try the default date format for our locale.
1535 if ( !bSuccess && xFormatTypes.is() )
1539 nTryFormat = xFormatTypes->getStandardFormat( NumberFormat::DATE, m_pData->aLocale );
1541 catch( Exception& ) { }
1542 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1545 // if this also didn't do, try ISO format
1546 if ( !bSuccess && xFormatTypes.is() )
1550 nTryFormat = xFormatTypes->getFormatIndex( NumberFormatIndex::DATE_DIN_YYYYMMDD, m_pData->aLocale );
1552 catch( Exception& ) { }
1553 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1556 // if this also didn't do, try fallback date format (en-US)
1557 if ( !bSuccess )
1559 nTryFormat = m_nDateFormatKey;
1560 bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue );
1562 return bSuccess;
1565 OSQLParseNode* OSQLParser::buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral)
1567 // try converting the string into a date, according to our format key
1568 double fValue = 0.0;
1569 OSQLParseNode* pFCTNode = NULL;
1571 if ( extractDate(pLiteral,fValue) )
1572 pFCTNode = buildNode_Date( fValue, _nType);
1574 delete pLiteral;
1575 pLiteral = NULL;
1577 if ( !pFCTNode )
1578 m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_DATE_COMPARE);
1580 return pFCTNode;
1584 OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue,
1585 SQLNodeType eNewNodeType,
1586 sal_uInt32 nNewNodeID)
1587 :m_pParent(NULL)
1588 ,m_aNodeValue(pNewValue,strlen(pNewValue),RTL_TEXTENCODING_UTF8)
1589 ,m_eNodeType(eNewNodeType)
1590 ,m_nNodeID(nNewNodeID)
1592 OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: created with invalid NodeType");
1595 OSQLParseNode::OSQLParseNode(const OString &_rNewValue,
1596 SQLNodeType eNewNodeType,
1597 sal_uInt32 nNewNodeID)
1598 :m_pParent(NULL)
1599 ,m_aNodeValue(OStringToOUString(_rNewValue,RTL_TEXTENCODING_UTF8))
1600 ,m_eNodeType(eNewNodeType)
1601 ,m_nNodeID(nNewNodeID)
1603 OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: created with invalid NodeType");
1606 OSQLParseNode::OSQLParseNode(const OUString &_rNewValue,
1607 SQLNodeType eNewNodeType,
1608 sal_uInt32 nNewNodeID)
1609 :m_pParent(NULL)
1610 ,m_aNodeValue(_rNewValue)
1611 ,m_eNodeType(eNewNodeType)
1612 ,m_nNodeID(nNewNodeID)
1614 OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: created with invalid NodeType");
1617 OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode)
1619 // Set the getParent to NULL
1620 m_pParent = NULL;
1622 // Copy the members
1623 m_aNodeValue = rParseNode.m_aNodeValue;
1624 m_eNodeType = rParseNode.m_eNodeType;
1625 m_nNodeID = rParseNode.m_nNodeID;
1628 // Remember that we derived from Container. According to SV-Help the Container's
1629 // copy ctor creates a new Container with the same pointers for content.
1630 // This means after copying the Container, for all non-NULL pointers a copy is
1631 // created and reattached instead of the old pointer.
1633 // If not a leaf, then process SubTrees
1634 for (OSQLParseNodes::const_iterator i = rParseNode.m_aChildren.begin();
1635 i != rParseNode.m_aChildren.end(); ++i)
1636 append(new OSQLParseNode(**i));
1640 OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode)
1642 if (this != &rParseNode)
1644 // Copy the members - pParent remains the same
1645 m_aNodeValue = rParseNode.m_aNodeValue;
1646 m_eNodeType = rParseNode.m_eNodeType;
1647 m_nNodeID = rParseNode.m_nNodeID;
1649 for (OSQLParseNodes::const_iterator i = m_aChildren.begin();
1650 i != m_aChildren.end(); ++i)
1651 delete *i;
1653 m_aChildren.clear();
1655 for (OSQLParseNodes::const_iterator j = rParseNode.m_aChildren.begin();
1656 j != rParseNode.m_aChildren.end(); ++j)
1657 append(new OSQLParseNode(**j));
1659 return *this;
1663 bool OSQLParseNode::operator==(OSQLParseNode& rParseNode) const
1665 // The members must be equal
1666 bool bResult = (m_nNodeID == rParseNode.m_nNodeID) &&
1667 (m_eNodeType == rParseNode.m_eNodeType) &&
1668 (m_aNodeValue == rParseNode.m_aNodeValue) &&
1669 count() == rParseNode.count();
1671 // Parameters are not equal!
1672 bResult = bResult && !SQL_ISRULE(this, parameter);
1674 // compare children
1675 for (sal_uInt32 i=0; bResult && i < count(); i++)
1676 bResult = *getChild(i) == *rParseNode.getChild(i);
1678 return bResult;
1682 OSQLParseNode::~OSQLParseNode()
1684 for (OSQLParseNodes::const_iterator i = m_aChildren.begin();
1685 i != m_aChildren.end(); ++i)
1686 delete *i;
1687 m_aChildren.clear();
1691 void OSQLParseNode::append(OSQLParseNode* pNewNode)
1693 OSL_ENSURE(pNewNode != NULL, "OSQLParseNode: invalid NewSubTree");
1694 OSL_ENSURE(pNewNode->getParent() == NULL, "OSQLParseNode: Node is not an orphan");
1695 OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pNewNode) == m_aChildren.end(),
1696 "OSQLParseNode::append() Node already element of parent");
1698 // Create connection to getParent
1699 pNewNode->setParent( this );
1700 // and attach the SubTree at the end
1701 m_aChildren.push_back(pNewNode);
1704 bool OSQLParseNode::addDateValue(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
1706 // special display for date/time values
1707 if (SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChildren[0],"{"))
1709 const OSQLParseNode* pODBCNode = m_aChildren[1];
1710 const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChildren[0];
1712 if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && (
1713 SQL_ISTOKEN(pODBCNodeChild, D) ||
1714 SQL_ISTOKEN(pODBCNodeChild, T) ||
1715 SQL_ISTOKEN(pODBCNodeChild, TS) ))
1717 OUString suQuote("'");
1718 if (rParam.bPredicate)
1720 if (rParam.aMetaData.shouldEscapeDateTime())
1722 suQuote = "#";
1725 else
1727 if (rParam.aMetaData.shouldEscapeDateTime())
1729 // suQuote = "'";
1730 return false;
1734 if (!rString.isEmpty())
1735 rString.appendAscii(" ");
1736 rString.append(suQuote);
1737 const OUString sTokenValue = pODBCNode->m_aChildren[1]->getTokenValue();
1738 if (SQL_ISTOKEN(pODBCNodeChild, D))
1740 rString.append(rParam.bPredicate ? convertDateString(rParam, sTokenValue) : sTokenValue);
1742 else if (SQL_ISTOKEN(pODBCNodeChild, T))
1744 rString.append(rParam.bPredicate ? convertTimeString(rParam, sTokenValue) : sTokenValue);
1746 else
1748 rString.append(rParam.bPredicate ? convertDateTimeString(rParam, sTokenValue) : sTokenValue);
1750 rString.append(suQuote);
1751 return true;
1754 return false;
1757 void OSQLParseNode::replaceNodeValue(const OUString& rTableAlias, const OUString& rColumnName)
1759 for (sal_uInt32 i=0;i<count();++i)
1761 if (SQL_ISRULE(this,column_ref) && count() == 1 && getChild(0)->getTokenValue() == rColumnName)
1763 OSQLParseNode * pCol = removeAt((sal_uInt32)0);
1764 append(new OSQLParseNode(rTableAlias,SQL_NODE_NAME));
1765 append(new OSQLParseNode(OUString("."),SQL_NODE_PUNCTUATION));
1766 append(pCol);
1768 else
1769 getChild(i)->replaceNodeValue(rTableAlias,rColumnName);
1773 OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const
1775 OSQLParseNode* pRetNode = 0;
1776 if (isRule() && OSQLParser::RuleID(eRule) == getRuleID())
1777 pRetNode = const_cast<OSQLParseNode*>(this);
1778 else
1780 for (OSQLParseNodes::const_iterator i = m_aChildren.begin();
1781 !pRetNode && i != m_aChildren.end(); ++i)
1782 pRetNode = (*i)->getByRule(eRule);
1784 return pRetNode;
1787 OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
1789 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
1790 pNewNode->append(pLeftLeaf);
1791 pNewNode->append(new OSQLParseNode(OUString("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
1792 pNewNode->append(pRightLeaf);
1793 return pNewNode;
1796 OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
1798 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
1799 pNewNode->append(pLeftLeaf);
1800 pNewNode->append(new OSQLParseNode(OUString("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
1801 pNewNode->append(pRightLeaf);
1802 return pNewNode;
1805 void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition)
1807 if(!pSearchCondition) // no where condition at entry point
1808 return;
1810 OSQLParseNode::absorptions(pSearchCondition);
1811 // '(' search_condition ')'
1812 if (SQL_ISRULE(pSearchCondition,boolean_primary))
1814 OSQLParseNode* pLeft = pSearchCondition->getChild(1);
1815 disjunctiveNormalForm(pLeft);
1817 // search_condition SQL_TOKEN_OR boolean_term
1818 else if (SQL_ISRULE(pSearchCondition,search_condition))
1820 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1821 disjunctiveNormalForm(pLeft);
1823 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1824 disjunctiveNormalForm(pRight);
1826 // boolean_term SQL_TOKEN_AND boolean_factor
1827 else if (SQL_ISRULE(pSearchCondition,boolean_term))
1829 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1830 disjunctiveNormalForm(pLeft);
1832 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1833 disjunctiveNormalForm(pRight);
1835 OSQLParseNode* pNewNode = NULL;
1836 // '(' search_condition ')' on left side
1837 if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition))
1839 // and-or tree on left side
1840 OSQLParseNode* pOr = pLeft->getChild(1);
1841 OSQLParseNode* pNewLeft = NULL;
1842 OSQLParseNode* pNewRight = NULL;
1844 // cut right from parent
1845 pSearchCondition->removeAt(2);
1847 pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight);
1848 pNewLeft = MakeANDNode(pOr->removeAt((sal_uInt32)0) ,new OSQLParseNode(*pRight));
1849 pNewNode = MakeORNode(pNewLeft,pNewRight);
1850 // and append new Node
1851 replaceAndReset(pSearchCondition,pNewNode);
1853 disjunctiveNormalForm(pSearchCondition);
1855 else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition))
1856 { // '(' search_condition ')' on right side
1857 // and-or tree on right side
1858 // a and (b or c)
1859 OSQLParseNode* pOr = pRight->getChild(1);
1860 OSQLParseNode* pNewLeft = NULL;
1861 OSQLParseNode* pNewRight = NULL;
1863 // cut left from parent
1864 pSearchCondition->removeAt((sal_uInt32)0);
1866 pNewRight = MakeANDNode(pLeft,pOr->removeAt(2));
1867 pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt((sal_uInt32)0));
1868 pNewNode = MakeORNode(pNewLeft,pNewRight);
1870 // and append new Node
1871 replaceAndReset(pSearchCondition,pNewNode);
1872 disjunctiveNormalForm(pSearchCondition);
1874 else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term)))
1875 pSearchCondition->replace(pLeft, pLeft->removeAt(1));
1876 else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term)))
1877 pSearchCondition->replace(pRight, pRight->removeAt(1));
1881 void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition, bool bNegate)
1883 if(!pSearchCondition) // no where condition at entry point
1884 return;
1885 // '(' search_condition ')'
1886 if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary))
1888 OSQLParseNode* pRight = pSearchCondition->getChild(1);
1889 negateSearchCondition(pRight,bNegate);
1891 // search_condition SQL_TOKEN_OR boolean_term
1892 else if (SQL_ISRULE(pSearchCondition,search_condition))
1894 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1895 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1896 if(bNegate)
1898 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
1899 pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
1900 pNewNode->append(new OSQLParseNode(OUString("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
1901 pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
1902 replaceAndReset(pSearchCondition,pNewNode);
1904 pLeft = pNewNode->getChild(0);
1905 pRight = pNewNode->getChild(2);
1908 negateSearchCondition(pLeft,bNegate);
1909 negateSearchCondition(pRight,bNegate);
1911 // boolean_term SQL_TOKEN_AND boolean_factor
1912 else if (SQL_ISRULE(pSearchCondition,boolean_term))
1914 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
1915 OSQLParseNode* pRight = pSearchCondition->getChild(2);
1916 if(bNegate)
1918 OSQLParseNode* pNewNode = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
1919 pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
1920 pNewNode->append(new OSQLParseNode(OUString("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
1921 pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
1922 replaceAndReset(pSearchCondition,pNewNode);
1924 pLeft = pNewNode->getChild(0);
1925 pRight = pNewNode->getChild(2);
1928 negateSearchCondition(pLeft,bNegate);
1929 negateSearchCondition(pRight,bNegate);
1931 // SQL_TOKEN_NOT ( boolean_primary )
1932 else if (SQL_ISRULE(pSearchCondition,boolean_factor))
1934 OSQLParseNode *pNot = pSearchCondition->removeAt((sal_uInt32)0);
1935 delete pNot;
1936 OSQLParseNode *pBooleanTest = pSearchCondition->removeAt((sal_uInt32)0);
1937 // TODO is this needed // pBooleanTest->setParent(NULL);
1938 replaceAndReset(pSearchCondition,pBooleanTest);
1940 if (!bNegate)
1941 negateSearchCondition(pSearchCondition, true); // negate all deeper values
1943 // row_value_constructor comparison row_value_constructor
1944 // row_value_constructor comparison any_all_some subquery
1945 else if(bNegate && (SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate)))
1947 assert(pSearchCondition->count() == 3);
1948 OSQLParseNode* pComparison = pSearchCondition->getChild(1);
1949 if(SQL_ISRULE(pComparison, comparison))
1951 assert(pComparison->count() == 2 ||
1952 pComparison->count() == 4);
1953 assert(SQL_ISTOKEN(pComparison->getChild(0), IS));
1955 OSQLParseNode* pNot = pComparison->getChild(1);
1956 OSQLParseNode* pNotNot = NULL;
1957 if(pNot->isRule()) // no NOT token (empty rule)
1958 pNotNot = new OSQLParseNode(OUString("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
1959 else
1961 assert(SQL_ISTOKEN(pNot,NOT));
1962 pNotNot = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
1964 pComparison->replace(pNot, pNotNot);
1965 delete pNot;
1967 else
1969 OSQLParseNode* pNewComparison;
1970 switch(pComparison->getNodeType())
1972 default:
1973 assert(false && "OSQLParseNode::negateSearchCondition: unexpected node type!");
1974 // fall-through
1975 case SQL_NODE_EQUAL:
1976 pNewComparison = new OSQLParseNode(OUString("<>"),SQL_NODE_NOTEQUAL,SQL_NOTEQUAL);
1977 break;
1978 case SQL_NODE_LESS:
1979 pNewComparison = new OSQLParseNode(OUString(">="),SQL_NODE_GREATEQ,SQL_GREATEQ);
1980 break;
1981 case SQL_NODE_GREAT:
1982 pNewComparison = new OSQLParseNode(OUString("<="),SQL_NODE_LESSEQ,SQL_LESSEQ);
1983 break;
1984 case SQL_NODE_LESSEQ:
1985 pNewComparison = new OSQLParseNode(OUString(">"),SQL_NODE_GREAT,SQL_GREAT);
1986 break;
1987 case SQL_NODE_GREATEQ:
1988 pNewComparison = new OSQLParseNode(OUString("<"),SQL_NODE_LESS,SQL_LESS);
1989 break;
1990 case SQL_NODE_NOTEQUAL:
1991 pNewComparison = new OSQLParseNode(OUString("="),SQL_NODE_EQUAL,SQL_EQUAL);
1992 break;
1994 pSearchCondition->replace(pComparison, pNewComparison);
1995 delete pComparison;
1999 else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) ||
2000 SQL_ISRULE(pSearchCondition,in_predicate) ||
2001 SQL_ISRULE(pSearchCondition,between_predicate) ))
2003 OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
2004 sal_uInt32 nNotPos = 0;
2005 if ( SQL_ISRULE( pSearchCondition, test_for_null ) )
2006 nNotPos = 1;
2008 OSQLParseNode* pNot = pPart2->getChild(nNotPos);
2009 OSQLParseNode* pNotNot = NULL;
2010 if(pNot->isRule()) // no NOT token (empty rule)
2011 pNotNot = new OSQLParseNode(OUString("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
2012 else
2014 assert(SQL_ISTOKEN(pNot,NOT));
2015 pNotNot = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
2017 pPart2->replace(pNot, pNotNot);
2018 delete pNot;
2020 else if(bNegate && (SQL_ISRULE(pSearchCondition,like_predicate)))
2022 OSQLParseNode* pNot = pSearchCondition->getChild( 1 )->getChild( 0 );
2023 OSQLParseNode* pNotNot = NULL;
2024 if(pNot->isRule())
2025 pNotNot = new OSQLParseNode(OUString("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
2026 else
2027 pNotNot = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
2028 pSearchCondition->getChild( 1 )->replace(pNot, pNotNot);
2029 delete pNot;
2033 void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition)
2035 if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
2036 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))))
2038 OSQLParseNode* pRight = pSearchCondition->getChild(1);
2039 absorptions(pRight);
2040 // if child is not an or and tree then delete () around child
2041 if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
2042 SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without ()
2043 (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
2045 OSQLParseNode* pNode = pSearchCondition->removeAt(1);
2046 replaceAndReset(pSearchCondition,pNode);
2051 void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition)
2053 if(!pSearchCondition) // no where condition at entry point
2054 return;
2056 eraseBraces(pSearchCondition);
2058 if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2060 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
2061 absorptions(pLeft);
2062 OSQLParseNode* pRight = pSearchCondition->getChild(2);
2063 absorptions(pRight);
2066 sal_uInt32 nPos = 0;
2067 // a and a || a or a
2068 OSQLParseNode* pNewNode = NULL;
2069 if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2070 && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2))
2072 pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
2073 replaceAndReset(pSearchCondition,pNewNode);
2075 // (a or b) and a || ( b or c ) and a
2076 // a and ( a or b) || a and ( b or c )
2077 else if ( SQL_ISRULE(pSearchCondition,boolean_term)
2078 && (
2079 ( SQL_ISRULE(pSearchCondition->getChild(nPos = 0),boolean_primary)
2080 || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition)
2082 || ( SQL_ISRULE(pSearchCondition->getChild(nPos = 2),boolean_primary)
2083 || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition)
2088 OSQLParseNode* p2ndSearch = pSearchCondition->getChild(nPos);
2089 if ( SQL_ISRULE(p2ndSearch,boolean_primary) )
2090 p2ndSearch = p2ndSearch->getChild(1);
2092 if ( *p2ndSearch->getChild(0) == *pSearchCondition->getChild(2-nPos) ) // a and ( a or b) -> a or b
2094 pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
2095 replaceAndReset(pSearchCondition,pNewNode);
2098 else if ( *p2ndSearch->getChild(2) == *pSearchCondition->getChild(2-nPos) ) // a and ( b or a) -> a or b
2100 pNewNode = pSearchCondition->removeAt((sal_uInt32)2);
2101 replaceAndReset(pSearchCondition,pNewNode);
2103 else if ( p2ndSearch->getByRule(OSQLParseNode::search_condition) )
2105 // a and ( b or c ) -> ( a and b ) or ( a and c )
2106 // ( b or c ) and a -> ( a and b ) or ( a and c )
2107 OSQLParseNode* pC = p2ndSearch->removeAt((sal_uInt32)2);
2108 OSQLParseNode* pB = p2ndSearch->removeAt((sal_uInt32)0);
2109 OSQLParseNode* pA = pSearchCondition->removeAt((sal_uInt32)2-nPos);
2111 OSQLParseNode* p1stAnd = MakeANDNode(pA,pB);
2112 OSQLParseNode* p2ndAnd = MakeANDNode(new OSQLParseNode(*pA),pC);
2113 pNewNode = MakeORNode(p1stAnd,p2ndAnd);
2114 OSQLParseNode* pNode = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2115 pNode->append(new OSQLParseNode(OUString("("),SQL_NODE_PUNCTUATION));
2116 pNode->append(pNewNode);
2117 pNode->append(new OSQLParseNode(OUString(")"),SQL_NODE_PUNCTUATION));
2118 OSQLParseNode::eraseBraces(p1stAnd);
2119 OSQLParseNode::eraseBraces(p2ndAnd);
2120 replaceAndReset(pSearchCondition,pNode);
2123 // a or a and b || a or b and a
2124 else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
2126 if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0))
2128 pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
2129 replaceAndReset(pSearchCondition,pNewNode);
2131 else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0))
2133 pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
2134 replaceAndReset(pSearchCondition,pNewNode);
2137 // a and b or a || b and a or a
2138 else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term))
2140 if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2))
2142 pNewNode = pSearchCondition->removeAt((sal_uInt32)2);
2143 replaceAndReset(pSearchCondition,pNewNode);
2145 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2))
2147 pNewNode = pSearchCondition->removeAt((sal_uInt32)2);
2148 replaceAndReset(pSearchCondition,pNewNode);
2151 eraseBraces(pSearchCondition);
2154 void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition)
2156 if(!pSearchCondition) // no WHERE condition at entry point
2157 return;
2159 OSQLParseNode::eraseBraces(pSearchCondition);
2161 if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
2163 OSQLParseNode* pLeft = pSearchCondition->getChild(0);
2164 compress(pLeft);
2166 OSQLParseNode* pRight = pSearchCondition->getChild(2);
2167 compress(pRight);
2169 else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
2170 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))
2172 OSQLParseNode* pRight = pSearchCondition->getChild(1);
2173 compress(pRight);
2174 // if child is not an or and tree then delete () around child
2175 if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
2176 (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) ||
2177 (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
2179 OSQLParseNode* pNode = pSearchCondition->removeAt(1);
2180 replaceAndReset(pSearchCondition,pNode);
2184 // or with two and trees where one element of the and trees are equal
2185 if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
2187 if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0))
2189 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
2190 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
2191 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2193 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2194 pNewRule->append(new OSQLParseNode(OUString("("),SQL_NODE_PUNCTUATION));
2195 pNewRule->append(pNode);
2196 pNewRule->append(new OSQLParseNode(OUString(")"),SQL_NODE_PUNCTUATION));
2198 OSQLParseNode::eraseBraces(pLeft);
2199 OSQLParseNode::eraseBraces(pRight);
2201 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
2202 replaceAndReset(pSearchCondition,pNode);
2204 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0))
2206 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
2207 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
2208 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2210 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2211 pNewRule->append(new OSQLParseNode(OUString("("),SQL_NODE_PUNCTUATION));
2212 pNewRule->append(pNode);
2213 pNewRule->append(new OSQLParseNode(OUString(")"),SQL_NODE_PUNCTUATION));
2215 OSQLParseNode::eraseBraces(pLeft);
2216 OSQLParseNode::eraseBraces(pRight);
2218 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
2219 replaceAndReset(pSearchCondition,pNode);
2221 else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2))
2223 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
2224 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
2225 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2227 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2228 pNewRule->append(new OSQLParseNode(OUString("("),SQL_NODE_PUNCTUATION));
2229 pNewRule->append(pNode);
2230 pNewRule->append(new OSQLParseNode(OUString(")"),SQL_NODE_PUNCTUATION));
2232 OSQLParseNode::eraseBraces(pLeft);
2233 OSQLParseNode::eraseBraces(pRight);
2235 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
2236 replaceAndReset(pSearchCondition,pNode);
2238 else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2))
2240 OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
2241 OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
2242 OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
2244 OSQLParseNode* pNewRule = new OSQLParseNode(OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
2245 pNewRule->append(new OSQLParseNode(OUString("("),SQL_NODE_PUNCTUATION));
2246 pNewRule->append(pNode);
2247 pNewRule->append(new OSQLParseNode(OUString(")"),SQL_NODE_PUNCTUATION));
2249 OSQLParseNode::eraseBraces(pLeft);
2250 OSQLParseNode::eraseBraces(pRight);
2252 pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
2253 replaceAndReset(pSearchCondition,pNode);
2257 #if OSL_DEBUG_LEVEL > 1
2259 void OSQLParseNode::showParseTree( OUString& rString ) const
2261 OUStringBuffer aBuf;
2262 showParseTree( aBuf, 0 );
2263 rString = aBuf.makeStringAndClear();
2267 void OSQLParseNode::showParseTree( OUStringBuffer& _inout_rBuffer, sal_uInt32 nLevel ) const
2269 for ( sal_uInt32 j=0; j<nLevel; ++j)
2270 _inout_rBuffer.appendAscii( " " );
2272 if ( !isToken() )
2274 // Rule name as rule
2275 _inout_rBuffer.appendAscii( "RULE_ID: " );
2276 _inout_rBuffer.append( (sal_Int32)getRuleID() );
2277 _inout_rBuffer.append( '(' );
2278 _inout_rBuffer.append( OSQLParser::RuleIDToStr( getRuleID() ) );
2279 _inout_rBuffer.append( ')' );
2280 _inout_rBuffer.append( '\n' );
2282 // Get the first sub tree
2283 for ( OSQLParseNodes::const_iterator i = m_aChildren.begin();
2284 i != m_aChildren.end();
2287 (*i)->showParseTree( _inout_rBuffer, nLevel+1 );
2289 else
2291 // Found a token
2292 switch (m_eNodeType)
2295 case SQL_NODE_KEYWORD:
2296 _inout_rBuffer.appendAscii( "SQL_KEYWORD: " );
2297 _inout_rBuffer.append( OStringToOUString( OSQLParser::TokenIDToStr( getTokenID() ), RTL_TEXTENCODING_UTF8 ) );
2298 _inout_rBuffer.append( '\n' );
2299 break;
2301 case SQL_NODE_COMPARISON:
2302 _inout_rBuffer.appendAscii( "SQL_COMPARISON: " );
2303 _inout_rBuffer.append( m_aNodeValue );
2304 _inout_rBuffer.append( '\n' );
2305 break;
2307 case SQL_NODE_NAME:
2308 _inout_rBuffer.appendAscii( "SQL_NAME: " );
2309 _inout_rBuffer.append( '"' );
2310 _inout_rBuffer.append( m_aNodeValue );
2311 _inout_rBuffer.append( '"' );
2312 _inout_rBuffer.append( '\n' );
2313 break;
2315 case SQL_NODE_STRING:
2316 _inout_rBuffer.appendAscii( "SQL_STRING: " );
2317 _inout_rBuffer.append( '\'' );
2318 _inout_rBuffer.append( m_aNodeValue );
2319 _inout_rBuffer.append( '\'' );
2320 _inout_rBuffer.append( '\n' );
2321 break;
2323 case SQL_NODE_INTNUM:
2324 _inout_rBuffer.appendAscii( "SQL_INTNUM: " );
2325 _inout_rBuffer.append( m_aNodeValue );
2326 _inout_rBuffer.append( '\n' );
2327 break;
2329 case SQL_NODE_APPROXNUM:
2330 _inout_rBuffer.appendAscii( "SQL_APPROXNUM: " );
2331 _inout_rBuffer.append( m_aNodeValue );
2332 _inout_rBuffer.append( '\n' );
2333 break;
2335 case SQL_NODE_PUNCTUATION:
2336 _inout_rBuffer.appendAscii( "SQL_PUNCTUATION: " );
2337 _inout_rBuffer.append( m_aNodeValue );
2338 _inout_rBuffer.append( '\n' );
2339 break;
2341 case SQL_NODE_AMMSC:
2342 _inout_rBuffer.appendAscii( "SQL_AMMSC: " );
2343 _inout_rBuffer.append( m_aNodeValue );
2344 _inout_rBuffer.append( '\n' );
2345 break;
2347 case SQL_NODE_EQUAL:
2348 case SQL_NODE_LESS:
2349 case SQL_NODE_GREAT:
2350 case SQL_NODE_LESSEQ:
2351 case SQL_NODE_GREATEQ:
2352 case SQL_NODE_NOTEQUAL:
2353 _inout_rBuffer.append( m_aNodeValue );
2354 _inout_rBuffer.append( '\n' );
2355 break;
2357 case SQL_NODE_ACCESS_DATE:
2358 _inout_rBuffer.appendAscii( "SQL_ACCESS_DATE: " );
2359 _inout_rBuffer.append( m_aNodeValue );
2360 _inout_rBuffer.append( '\n' );
2361 break;
2363 case SQL_NODE_DATE:
2364 _inout_rBuffer.appendAscii( "SQL_DATE: " );
2365 _inout_rBuffer.append( m_aNodeValue );
2366 _inout_rBuffer.append( '\n' );
2367 break;
2369 case SQL_NODE_CONCAT:
2370 _inout_rBuffer.appendAscii( "||" );
2371 _inout_rBuffer.append( '\n' );
2372 break;
2374 default:
2375 SAL_INFO( "connectivity.parse", "-- " << int( m_eNodeType ) );
2376 SAL_WARN( "connectivity.parse", "OSQLParser::ShowParseTree: unzulaessiger NodeType" );
2380 #endif // OSL_DEBUG_LEVEL > 0
2382 // Insert methods
2384 void OSQLParseNode::insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree)
2386 OSL_ENSURE(pNewSubTree != NULL, "OSQLParseNode: invalid NewSubTree");
2387 OSL_ENSURE(pNewSubTree->getParent() == NULL, "OSQLParseNode: Node is not an orphan");
2389 // Create connection to getParent
2390 pNewSubTree->setParent( this );
2391 m_aChildren.insert(m_aChildren.begin() + nPos, pNewSubTree);
2394 // removeAt methods
2396 OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos)
2398 OSL_ENSURE(nPos < m_aChildren.size(),"Illegal position for removeAt");
2399 OSQLParseNodes::iterator aPos(m_aChildren.begin() + nPos);
2400 OSQLParseNode* pNode = *aPos;
2402 // Set the getParent of the removed node to NULL
2403 pNode->setParent( NULL );
2405 m_aChildren.erase(aPos);
2406 return pNode;
2409 // Replace methods
2411 OSQLParseNode* OSQLParseNode::replace (OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode )
2413 OSL_ENSURE(pOldSubNode != NULL && pNewSubNode != NULL, "OSQLParseNode: invalid nodes");
2414 OSL_ENSURE(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent");
2415 OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pOldSubNode) != m_aChildren.end(),
2416 "OSQLParseNode::Replace() Node not element of parent");
2417 OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pNewSubNode) == m_aChildren.end(),
2418 "OSQLParseNode::Replace() Node already element of parent");
2420 pOldSubNode->setParent( NULL );
2421 pNewSubNode->setParent( this );
2422 ::std::replace(m_aChildren.begin(), m_aChildren.end(), pOldSubNode, pNewSubNode);
2423 return pOldSubNode;
2426 void OSQLParseNode::parseLeaf(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const
2428 // Found a leaf
2429 // Append content to the output string
2430 switch (m_eNodeType)
2432 case SQL_NODE_KEYWORD:
2434 if (!rString.isEmpty())
2435 rString.appendAscii(" ");
2437 const OString sT = OSQLParser::TokenIDToStr(m_nNodeID, rParam.bInternational ? &rParam.m_rContext : NULL);
2438 rString.append(OStringToOUString(sT,RTL_TEXTENCODING_UTF8));
2439 } break;
2440 case SQL_NODE_STRING:
2441 if (!rString.isEmpty())
2442 rString.appendAscii(" ");
2443 rString.append(SetQuotation(m_aNodeValue,OUString("\'"),OUString("\'\'")));
2444 break;
2445 case SQL_NODE_NAME:
2446 if (!rString.isEmpty())
2448 switch(rString[rString.getLength()-1])
2450 case ' ' :
2451 case '.' : break;
2452 default :
2453 if ( rParam.aMetaData.getCatalogSeparator().isEmpty()
2454 || rString[rString.getLength() - 1] != rParam.aMetaData.getCatalogSeparator().toChar()
2456 rString.appendAscii(" "); break;
2459 if (rParam.bQuote)
2461 if (rParam.bPredicate)
2463 rString.appendAscii("[");
2464 rString.append(m_aNodeValue);
2465 rString.appendAscii("]");
2467 else
2468 rString.append(SetQuotation(m_aNodeValue,
2469 rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() ));
2471 else
2472 rString.append(m_aNodeValue);
2473 break;
2474 case SQL_NODE_ACCESS_DATE:
2475 if (!rString.isEmpty())
2476 rString.appendAscii(" ");
2477 rString.appendAscii("#");
2478 rString.append(m_aNodeValue);
2479 rString.appendAscii("#");
2480 break;
2482 case SQL_NODE_INTNUM:
2483 case SQL_NODE_APPROXNUM:
2485 OUString aTmp = m_aNodeValue;
2486 if (rParam.bInternational && rParam.bPredicate && rParam.cDecSep != '.')
2487 aTmp = aTmp.replace('.', rParam.cDecSep);
2489 if (!rString.isEmpty())
2490 rString.appendAscii(" ");
2491 rString.append(aTmp);
2493 } break;
2494 case SQL_NODE_PUNCTUATION:
2495 if ( getParent() && SQL_ISRULE(getParent(),cast_spec) && m_aNodeValue.toChar() == '(' ) // no spaces in front of '('
2497 rString.append(m_aNodeValue);
2498 break;
2500 // fall through
2501 default:
2502 if (!rString.isEmpty() && m_aNodeValue.toChar() != '.' && m_aNodeValue.toChar() != ':' )
2504 switch( rString[rString.getLength() - 1] )
2506 case ' ' :
2507 case '.' : break;
2508 default :
2509 if ( rParam.aMetaData.getCatalogSeparator().isEmpty()
2510 || rString[rString.getLength() - 1] != rParam.aMetaData.getCatalogSeparator().toChar()
2512 rString.appendAscii(" "); break;
2515 rString.append(m_aNodeValue);
2520 sal_Int32 OSQLParser::getFunctionReturnType(const OUString& _sFunctionName, const IParseContext* pContext)
2522 sal_Int32 nType = DataType::VARCHAR;
2523 OString sFunctionName(OUStringToOString(_sFunctionName,RTL_TEXTENCODING_UTF8));
2525 if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASCII,pContext))) nType = DataType::INTEGER;
2526 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_BIT_LENGTH,pContext))) nType = DataType::INTEGER;
2527 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR,pContext))) nType = DataType::VARCHAR;
2528 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR_LENGTH,pContext))) nType = DataType::INTEGER;
2529 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CONCAT,pContext))) nType = DataType::VARCHAR;
2530 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DIFFERENCE,pContext))) nType = DataType::VARCHAR;
2531 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_INSERT,pContext))) nType = DataType::VARCHAR;
2532 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LCASE,pContext))) nType = DataType::VARCHAR;
2533 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LEFT,pContext))) nType = DataType::VARCHAR;
2534 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LENGTH,pContext))) nType = DataType::INTEGER;
2535 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE,pContext))) nType = DataType::VARCHAR;
2536 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE_2,pContext))) nType = DataType::VARCHAR;
2537 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LTRIM,pContext))) nType = DataType::VARCHAR;
2538 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_OCTET_LENGTH,pContext))) nType = DataType::INTEGER;
2539 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POSITION,pContext))) nType = DataType::INTEGER;
2540 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPEAT,pContext))) nType = DataType::VARCHAR;
2541 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPLACE,pContext))) nType = DataType::VARCHAR;
2542 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RIGHT,pContext))) nType = DataType::VARCHAR;
2543 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RTRIM,pContext))) nType = DataType::VARCHAR;
2544 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SOUNDEX,pContext))) nType = DataType::VARCHAR;
2545 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SPACE,pContext))) nType = DataType::VARCHAR;
2546 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUBSTRING,pContext))) nType = DataType::VARCHAR;
2547 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UCASE,pContext))) nType = DataType::VARCHAR;
2548 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_DATE,pContext))) nType = DataType::DATE;
2549 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIME,pContext))) nType = DataType::TIME;
2550 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIMESTAMP,pContext))) nType = DataType::TIMESTAMP;
2551 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURDATE,pContext))) nType = DataType::DATE;
2552 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEDIFF,pContext))) nType = DataType::INTEGER;
2553 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEVALUE,pContext))) nType = DataType::DATE;
2554 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURTIME,pContext))) nType = DataType::TIME;
2555 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYNAME,pContext))) nType = DataType::VARCHAR;
2556 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFMONTH,pContext))) nType = DataType::INTEGER;
2557 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFWEEK,pContext))) nType = DataType::INTEGER;
2558 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFYEAR,pContext))) nType = DataType::INTEGER;
2559 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXTRACT,pContext))) nType = DataType::VARCHAR;
2560 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_HOUR,pContext))) nType = DataType::INTEGER;
2561 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MINUTE,pContext))) nType = DataType::INTEGER;
2562 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTH,pContext))) nType = DataType::INTEGER;
2563 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTHNAME,pContext))) nType = DataType::VARCHAR;
2564 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_NOW,pContext))) nType = DataType::TIMESTAMP;
2565 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_QUARTER,pContext))) nType = DataType::INTEGER;
2566 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SECOND,pContext))) nType = DataType::INTEGER;
2567 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPADD,pContext))) nType = DataType::TIMESTAMP;
2568 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPDIFF,pContext))) nType = DataType::TIMESTAMP;
2569 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMEVALUE,pContext))) nType = DataType::TIMESTAMP;
2570 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_WEEK,pContext))) nType = DataType::INTEGER;
2571 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_YEAR,pContext))) nType = DataType::INTEGER;
2572 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ABS,pContext))) nType = DataType::DOUBLE;
2573 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ACOS,pContext))) nType = DataType::DOUBLE;
2574 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASIN,pContext))) nType = DataType::DOUBLE;
2575 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN,pContext))) nType = DataType::DOUBLE;
2576 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN2,pContext))) nType = DataType::DOUBLE;
2577 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CEILING,pContext))) nType = DataType::DOUBLE;
2578 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COS,pContext))) nType = DataType::DOUBLE;
2579 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COT,pContext))) nType = DataType::DOUBLE;
2580 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DEGREES,pContext))) nType = DataType::DOUBLE;
2581 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXP,pContext))) nType = DataType::DOUBLE;
2582 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_FLOOR,pContext))) nType = DataType::DOUBLE;
2583 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOGF,pContext))) nType = DataType::DOUBLE;
2584 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG,pContext))) nType = DataType::DOUBLE;
2585 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG10,pContext))) nType = DataType::DOUBLE;
2586 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LN,pContext))) nType = DataType::DOUBLE;
2587 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MOD,pContext))) nType = DataType::DOUBLE;
2588 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_PI,pContext))) nType = DataType::DOUBLE;
2589 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POWER,pContext))) nType = DataType::DOUBLE;
2590 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RADIANS,pContext))) nType = DataType::DOUBLE;
2591 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RAND,pContext))) nType = DataType::DOUBLE;
2592 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUND,pContext))) nType = DataType::DOUBLE;
2593 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUNDMAGIC,pContext))) nType = DataType::DOUBLE;
2594 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIGN,pContext))) nType = DataType::DOUBLE;
2595 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIN,pContext))) nType = DataType::DOUBLE;
2596 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SQRT,pContext))) nType = DataType::DOUBLE;
2597 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TAN,pContext))) nType = DataType::DOUBLE;
2598 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TRUNCATE,pContext))) nType = DataType::DOUBLE;
2599 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COUNT,pContext))) nType = DataType::INTEGER;
2600 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MAX,pContext))) nType = DataType::DOUBLE;
2601 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MIN,pContext))) nType = DataType::DOUBLE;
2602 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_AVG,pContext))) nType = DataType::DOUBLE;
2603 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUM,pContext))) nType = DataType::DOUBLE;
2604 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOWER,pContext))) nType = DataType::VARCHAR;
2605 else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UPPER,pContext))) nType = DataType::VARCHAR;
2607 return nType;
2610 sal_Int32 OSQLParser::getFunctionParameterType(sal_uInt32 _nTokenId, sal_uInt32 _nPos)
2612 sal_Int32 nType = DataType::VARCHAR;
2614 if(_nTokenId == SQL_TOKEN_CHAR) nType = DataType::INTEGER;
2615 else if(_nTokenId == SQL_TOKEN_INSERT)
2617 if ( _nPos == 2 || _nPos == 3 )
2618 nType = DataType::INTEGER;
2620 else if(_nTokenId == SQL_TOKEN_LEFT)
2622 if ( _nPos == 2 )
2623 nType = DataType::INTEGER;
2625 else if(_nTokenId == SQL_TOKEN_LOCATE)
2627 if ( _nPos == 3 )
2628 nType = DataType::INTEGER;
2630 else if(_nTokenId == SQL_TOKEN_LOCATE_2)
2632 if ( _nPos == 3 )
2633 nType = DataType::INTEGER;
2635 else if( _nTokenId == SQL_TOKEN_REPEAT || _nTokenId == SQL_TOKEN_RIGHT )
2637 if ( _nPos == 2 )
2638 nType = DataType::INTEGER;
2640 else if(_nTokenId == SQL_TOKEN_SPACE )
2642 nType = DataType::INTEGER;
2644 else if(_nTokenId == SQL_TOKEN_SUBSTRING)
2646 if ( _nPos != 1 )
2647 nType = DataType::INTEGER;
2649 else if(_nTokenId == SQL_TOKEN_DATEDIFF)
2651 if ( _nPos != 1 )
2652 nType = DataType::TIMESTAMP;
2654 else if(_nTokenId == SQL_TOKEN_DATEVALUE)
2655 nType = DataType::DATE;
2656 else if(_nTokenId == SQL_TOKEN_DAYNAME)
2657 nType = DataType::DATE;
2658 else if(_nTokenId == SQL_TOKEN_DAYOFMONTH)
2659 nType = DataType::DATE;
2660 else if(_nTokenId == SQL_TOKEN_DAYOFWEEK)
2661 nType = DataType::DATE;
2662 else if(_nTokenId == SQL_TOKEN_DAYOFYEAR)
2663 nType = DataType::DATE;
2664 else if(_nTokenId == SQL_TOKEN_EXTRACT) nType = DataType::VARCHAR;
2665 else if(_nTokenId == SQL_TOKEN_HOUR) nType = DataType::TIME;
2666 else if(_nTokenId == SQL_TOKEN_MINUTE) nType = DataType::TIME;
2667 else if(_nTokenId == SQL_TOKEN_MONTH) nType = DataType::DATE;
2668 else if(_nTokenId == SQL_TOKEN_MONTHNAME) nType = DataType::DATE;
2669 else if(_nTokenId == SQL_TOKEN_NOW) nType = DataType::TIMESTAMP;
2670 else if(_nTokenId == SQL_TOKEN_QUARTER) nType = DataType::DATE;
2671 else if(_nTokenId == SQL_TOKEN_SECOND) nType = DataType::TIME;
2672 else if(_nTokenId == SQL_TOKEN_TIMESTAMPADD) nType = DataType::TIMESTAMP;
2673 else if(_nTokenId == SQL_TOKEN_TIMESTAMPDIFF) nType = DataType::TIMESTAMP;
2674 else if(_nTokenId == SQL_TOKEN_TIMEVALUE) nType = DataType::TIMESTAMP;
2675 else if(_nTokenId == SQL_TOKEN_WEEK) nType = DataType::DATE;
2676 else if(_nTokenId == SQL_TOKEN_YEAR) nType = DataType::DATE;
2678 else if(_nTokenId == SQL_TOKEN_ABS) nType = DataType::DOUBLE;
2679 else if(_nTokenId == SQL_TOKEN_ACOS) nType = DataType::DOUBLE;
2680 else if(_nTokenId == SQL_TOKEN_ASIN) nType = DataType::DOUBLE;
2681 else if(_nTokenId == SQL_TOKEN_ATAN) nType = DataType::DOUBLE;
2682 else if(_nTokenId == SQL_TOKEN_ATAN2) nType = DataType::DOUBLE;
2683 else if(_nTokenId == SQL_TOKEN_CEILING) nType = DataType::DOUBLE;
2684 else if(_nTokenId == SQL_TOKEN_COS) nType = DataType::DOUBLE;
2685 else if(_nTokenId == SQL_TOKEN_COT) nType = DataType::DOUBLE;
2686 else if(_nTokenId == SQL_TOKEN_DEGREES) nType = DataType::DOUBLE;
2687 else if(_nTokenId == SQL_TOKEN_EXP) nType = DataType::DOUBLE;
2688 else if(_nTokenId == SQL_TOKEN_FLOOR) nType = DataType::DOUBLE;
2689 else if(_nTokenId == SQL_TOKEN_LOGF) nType = DataType::DOUBLE;
2690 else if(_nTokenId == SQL_TOKEN_LOG) nType = DataType::DOUBLE;
2691 else if(_nTokenId == SQL_TOKEN_LOG10) nType = DataType::DOUBLE;
2692 else if(_nTokenId == SQL_TOKEN_LN) nType = DataType::DOUBLE;
2693 else if(_nTokenId == SQL_TOKEN_MOD) nType = DataType::DOUBLE;
2694 else if(_nTokenId == SQL_TOKEN_PI) nType = DataType::DOUBLE;
2695 else if(_nTokenId == SQL_TOKEN_POWER) nType = DataType::DOUBLE;
2696 else if(_nTokenId == SQL_TOKEN_RADIANS) nType = DataType::DOUBLE;
2697 else if(_nTokenId == SQL_TOKEN_RAND) nType = DataType::DOUBLE;
2698 else if(_nTokenId == SQL_TOKEN_ROUND) nType = DataType::DOUBLE;
2699 else if(_nTokenId == SQL_TOKEN_ROUNDMAGIC) nType = DataType::DOUBLE;
2700 else if(_nTokenId == SQL_TOKEN_SIGN) nType = DataType::DOUBLE;
2701 else if(_nTokenId == SQL_TOKEN_SIN) nType = DataType::DOUBLE;
2702 else if(_nTokenId == SQL_TOKEN_SQRT) nType = DataType::DOUBLE;
2703 else if(_nTokenId == SQL_TOKEN_TAN) nType = DataType::DOUBLE;
2704 else if(_nTokenId == SQL_TOKEN_TRUNCATE) nType = DataType::DOUBLE;
2705 else if(_nTokenId == SQL_TOKEN_COUNT) nType = DataType::INTEGER;
2706 else if(_nTokenId == SQL_TOKEN_MAX) nType = DataType::DOUBLE;
2707 else if(_nTokenId == SQL_TOKEN_MIN) nType = DataType::DOUBLE;
2708 else if(_nTokenId == SQL_TOKEN_AVG) nType = DataType::DOUBLE;
2709 else if(_nTokenId == SQL_TOKEN_SUM) nType = DataType::DOUBLE;
2711 else if(_nTokenId == SQL_TOKEN_LOWER) nType = DataType::VARCHAR;
2712 else if(_nTokenId == SQL_TOKEN_UPPER) nType = DataType::VARCHAR;
2714 return nType;
2718 const SQLError& OSQLParser::getErrorHelper() const
2720 return m_pData->aErrors;
2724 OSQLParseNode::Rule OSQLParseNode::getKnownRuleID() const
2726 if ( !isRule() )
2727 return UNKNOWN_RULE;
2728 return OSQLParser::RuleIDToRule( getRuleID() );
2731 OUString OSQLParseNode::getTableRange(const OSQLParseNode* _pTableRef)
2733 OSL_ENSURE(_pTableRef && _pTableRef->count() > 1 && _pTableRef->getKnownRuleID() == OSQLParseNode::table_ref,"Invalid node give, only table ref is allowed!");
2734 const sal_uInt32 nCount = _pTableRef->count();
2735 OUString sTableRange;
2736 if ( nCount == 2 || (nCount == 3 && !_pTableRef->getChild(0)->isToken()) )
2738 const OSQLParseNode* pNode = _pTableRef->getChild(nCount - (nCount == 2 ? 1 : 2));
2739 OSL_ENSURE(pNode && (pNode->getKnownRuleID() == OSQLParseNode::table_primary_as_range_column
2740 || pNode->getKnownRuleID() == OSQLParseNode::range_variable)
2741 ,"SQL grammar changed!");
2742 if ( !pNode->isLeaf() )
2743 sTableRange = pNode->getChild(1)->getTokenValue();
2744 } // if ( nCount == 2 || nCount == 3 )
2746 return sTableRange;
2749 OSQLParseNodesContainer::OSQLParseNodesContainer()
2753 OSQLParseNodesContainer::~OSQLParseNodesContainer()
2757 void OSQLParseNodesContainer::push_back(OSQLParseNode* _pNode)
2759 ::osl::MutexGuard aGuard(m_aMutex);
2760 m_aNodes.push_back(_pNode);
2763 void OSQLParseNodesContainer::erase(OSQLParseNode* _pNode)
2765 ::osl::MutexGuard aGuard(m_aMutex);
2766 if ( !m_aNodes.empty() )
2768 ::std::vector< OSQLParseNode* >::iterator aFind = ::std::find(m_aNodes.begin(), m_aNodes.end(),_pNode);
2769 if ( aFind != m_aNodes.end() )
2770 m_aNodes.erase(aFind);
2774 void OSQLParseNodesContainer::clear()
2776 ::osl::MutexGuard aGuard(m_aMutex);
2777 m_aNodes.clear();
2780 void OSQLParseNodesContainer::clearAndDelete()
2782 ::osl::MutexGuard aGuard(m_aMutex);
2783 // clear the garbage collector
2784 while ( !m_aNodes.empty() )
2786 OSQLParseNode* pNode = m_aNodes[0];
2787 while ( pNode->getParent() )
2789 pNode = pNode->getParent();
2791 delete pNode;
2794 } // namespace connectivity
2796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */