summaryrefslogtreecommitdiff
path: root/connectivity/source/parse/sqlnode.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'connectivity/source/parse/sqlnode.cxx')
-rw-r--r--connectivity/source/parse/sqlnode.cxx1399
1 files changed, 1399 insertions, 0 deletions
diff --git a/connectivity/source/parse/sqlnode.cxx b/connectivity/source/parse/sqlnode.cxx
new file mode 100644
index 000000000000..f35c06bf8f25
--- /dev/null
+++ b/connectivity/source/parse/sqlnode.cxx
@@ -0,0 +1,1399 @@
+/*************************************************************************
+ *
+ * $RCSfile: sqlnode.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:14:28 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CONNECTIVITY_SQLNODE_HXX
+#include <connectivity/sqlnode.hxx>
+#endif
+#ifndef _CONNECTIVITY_SQLPARSE_HXX
+#include <connectivity/sqlparse.hxx>
+#endif
+#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
+#include <com/sun/star/lang/Locale.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
+#include <com/sun/star/util/XNumberFormatter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#endif
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
+#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
+#endif
+#ifndef _TOOLS_INTN_HXX //autogen wg. International
+#include <tools/intn.hxx>
+#endif
+#ifndef _ISOLANG_HXX
+#include <tools/isolang.hxx>
+#endif
+
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::osl;
+using namespace connectivity;
+
+extern Any getNumberFormatProperty(const Reference< XNumberFormatsSupplier > & xFormatter,
+ sal_Int32 nKey,
+ const rtl::OUString& );
+extern double ToDouble(const Time& rTime);
+extern double ToDouble(const Reference< XNumberFormatsSupplier > & xSupplier, const Date& rDate);
+extern String ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, sal_Bool bInternational);
+
+//------------------------------------------------------------------
+OSQLParseNode::SQLParseNodeParameter::SQLParseNodeParameter(const String& _rIdentifierQuote, const String& _rCatalogSep,
+ const Reference< XNumberFormatter > & _xFormatter, const Reference< XPropertySet > & _xField, const International& _rIntl,
+ const OParseContext* _pContext, sal_Bool _bIntl, sal_Bool _bQuote, char _cDecSep,
+ sal_Bool _bPredicate)
+ :aIdentifierQuote(_rIdentifierQuote)
+ ,aCatalogSeparator(_rCatalogSep)
+ ,rIntl(_rIntl)
+ ,rContext(_pContext ? *_pContext : OSQLParser::s_aDefaultContext)
+ ,bInternational(_bIntl)
+ ,bQuote(_bQuote)
+ ,cDecSep(_cDecSep)
+ ,xField(_xField)
+ ,xFormatter(_xFormatter)
+ ,bPredicate(_bPredicate)
+{
+}
+
+//------------------------------------------------------------------
+String SetQuotation(const String& rValue, const String& rQuot, const String& rQuotToReplace)
+{
+ String rNewValue = rQuot;
+ rNewValue += rValue;
+
+ xub_StrLen nIndex = (xub_StrLen)-1; // Quotes durch zweifache Quotes ersetzen, sonst kriegt der Parser Probleme
+
+ if (rQuot.Len())
+ {
+ do
+ {
+ nIndex+= 2;
+ nIndex = rNewValue.SearchAndReplace(rQuot,rQuotToReplace,nIndex);
+ } while (nIndex != STRING_NOTFOUND);
+ }
+ // rNewValue.SearchAndReplaceAll(rQuot,rQuotToReplace);
+
+ rNewValue += rQuot;
+ return rNewValue;
+}
+
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nMonth = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nDay = rString.GetToken(0,'-', nIndex).ToInt32();
+
+ Date aDate(nDay,nMonth,nYear);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fDate = ToDouble(xSupplier, aDate);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 36; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fDate);
+}
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nYear = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nMonth = rString.GetToken(0,'-', nIndex).ToInt32(),
+ nDay = rString.GetToken(0,'-', nIndex).ToInt32();
+
+ nIndex = 10; // eat white space
+ sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(),
+ nMinute = rString.GetToken(0,':', nIndex).ToInt32(),
+ nSecond = rString.GetToken(0,':', nIndex).ToInt32();
+
+ Date aDate(nDay,nMonth,nYear);
+ Time aTime(nHour,nMinute,nSecond);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fDateTime = ToDouble(xSupplier, aDate) + ToDouble(aTime);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 51; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fDateTime);
+}
+
+//-----------------------------------------------------------------------------
+String OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const String& rString) const
+{
+ xub_StrLen nIndex = 0;
+ sal_Int32 nHour = rString.GetToken(0,':', nIndex).ToInt32(),
+ nMinute = rString.GetToken(0,':', nIndex).ToInt32(),
+ nSecond = rString.GetToken(0,':', nIndex).ToInt32();
+
+ Time aTime(nHour,nMinute,nSecond);
+ Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier());
+
+ Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY);
+
+ String sLanguage, sCountry;
+ ConvertLanguageToIsoNames(rParam.rIntl.GetLanguage(), sLanguage, sCountry);
+ Locale aLocale(sLanguage,sCountry,rtl::OUString());
+
+ double fTime = ToDouble(aTime);
+ sal_Int32 nKey = xTypes->getStandardIndex(aLocale) + 41; // XXX hack
+ return rParam.xFormatter->convertNumberToString(nKey, fTime);
+}
+
+DBG_NAME(OSQLParseNode);
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(String::CreateFromAscii(pNewValue))
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const ByteString &_rNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(String::CreateFromAscii(_rNewValue.GetBuffer()))
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const sal_Unicode * pNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(pNewValue)
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const String &_rNewValue,
+ SQLNodeType eNewNodeType,
+ sal_uInt32 nNewNodeID)
+ : m_aNodeValue(_rNewValue)
+ , m_eNodeType(eNewNodeType)
+ , m_nNodeID(nNewNodeID)
+ , m_pParent(NULL)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ DBG_ASSERT(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_ACCESS_DATE,"OSQLParseNode: mit unzulaessigem NodeType konstruiert");
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode)
+{
+ DBG_CTOR(OSQLParseNode,NULL);
+ // klemm den getParent auf NULL
+ m_pParent = NULL;
+
+ // kopiere die member
+ m_aNodeValue = rParseNode.m_aNodeValue;
+ m_eNodeType = rParseNode.m_eNodeType;
+ m_nNodeID = rParseNode.m_nNodeID;
+
+
+ // denk dran, dass von Container abgeleitet wurde, laut SV-Help erzeugt
+ // copy-Constructor des Containers einen neuen Container mit den gleichen
+ // Zeigern als Inhalt -> d.h. nach dem Kopieren des Container wird fuer
+ // alle Zeiger ungleich NULL eine Kopie hergestellt und anstelle des alten
+ // Zeigers wieder eingehangen.
+
+ // wenn kein Blatt, dann SubTrees bearbeiten
+ for (::std::vector<OSQLParseNode*>::const_iterator i = rParseNode.m_aChilds.begin();
+ i != rParseNode.m_aChilds.end(); i++)
+ append(new OSQLParseNode(**i));
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (this != &rParseNode)
+ {
+ // kopiere die member - pParent bleibt der alte
+ m_aNodeValue = rParseNode.m_aNodeValue;
+ m_eNodeType = rParseNode.m_eNodeType;
+ m_nNodeID = rParseNode.m_nNodeID;
+
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ delete *i;
+
+ m_aChilds.clear();
+
+ for (::std::vector<OSQLParseNode*>::const_iterator j = rParseNode.m_aChilds.begin();
+ j != rParseNode.m_aChilds.end(); j++)
+ append(new OSQLParseNode(**j));
+ }
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OSQLParseNode::operator==(OSQLParseNode& rParseNode) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ // die member muessen gleich sein
+ sal_Bool bResult = (m_nNodeID == rParseNode.m_nNodeID) &&
+ (m_eNodeType == rParseNode.m_eNodeType) &&
+ (m_aNodeValue == rParseNode.m_aNodeValue) &&
+ count() == rParseNode.count();
+
+ // Parameters are not equal!
+ bResult = bResult && !SQL_ISRULE(this, parameter);
+
+ // compare childs
+ for (sal_uInt32 i=0; bResult && i < count(); i++)
+ bResult = *getChild(i) == *rParseNode.getChild(i);
+
+ return bResult;
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode::~OSQLParseNode()
+{
+ DBG_DTOR(OSQLParseNode,NULL);
+
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ delete *i;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::append(OSQLParseNode* pNewNode)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(pNewNode != NULL, "OSQLParseNode: ungueltiger NewSubTree");
+ DBG_ASSERT(pNewNode->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewNode) == m_aChilds.end(),
+ "OSQLParseNode::append() Node already element of parent");
+
+ // stelle Verbindung zum getParent her:
+ pNewNode->setParent( this );
+ // und haenge den SubTree hinten an
+ m_aChilds.push_back(pNewNode);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ OParseContext* pContext,
+ sal_Bool _bIntl,
+ sal_Bool _bQuote) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ parseNodeToStr(rString, xMeta, Reference< XNumberFormatter >(),
+ Reference< XPropertySet >(), OParseContext::getDefaultInternational(), pContext, _bIntl, _bQuote, '.', sal_False);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToPredicateStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const International& rIntl,
+ OParseContext* pContext ) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
+
+ if (xFormatter.is())
+ parseNodeToStr(rString, xMeta, xFormatter, Reference< XPropertySet >(), rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToPredicateStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const Reference< XPropertySet > & _xField,
+ const International& rIntl,
+ OParseContext* pContext ) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!");
+
+ if (xFormatter.is())
+ parseNodeToStr(rString, xMeta, xFormatter, _xField, rIntl, pContext, sal_True, sal_True, rIntl.GetNumDecimalSep(), sal_True);
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString,
+ const Reference< XDatabaseMetaData > & xMeta,
+ const Reference< XNumberFormatter > & xFormatter,
+ const Reference< XPropertySet > & _xField,
+ const International& rIntl,
+ OParseContext* pContext,
+ sal_Bool _bIntl,
+ sal_Bool _bQuote,
+ char _cDecSep,
+ sal_Bool bPredicate) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+ DBG_ASSERT(xMeta.is(), "OSQLParseNode::parseNodeToStr:: no meta data!");
+
+ if (xMeta.is())
+ {
+ String aIdentifierQuote(xMeta->getIdentifierQuoteString());
+ String aCatalogSeparator(xMeta->getCatalogSeparator());
+
+ OSQLParseNode::parseNodeToStr(rString,
+ SQLParseNodeParameter(aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, bPredicate));
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::parseNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (!isToken())
+ {
+ // einmal auswerten wieviel Subtrees dieser Knoten besitzt
+ sal_uInt32 nCount = count();
+
+ // parameter erhalten sonderbehandlung
+ if (SQL_ISRULE(this,parameter))
+ {
+ if(rString.Len())
+ rString += ' ';
+ if (nCount == 1) // ?
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ else if (nCount == 2) // :Name
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ rString += m_aChilds[1]->m_aNodeValue;
+ } // [Name]
+ else
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ rString += m_aChilds[1]->m_aNodeValue;
+ rString += m_aChilds[2]->m_aNodeValue;
+ }
+ }
+
+ else if(SQL_ISRULE(this,table_ref) &&
+ ((nCount == 4 && SQL_ISPUNCTUATION(m_aChilds[0],"("))|| (nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"("))))
+ tableRangeNodeToStr(rString, rParam);
+ // je nachdem ob international angegeben wird oder nicht wird like anders behandelt
+ // interanational: *, ? sind Platzhalter
+ // sonst SQL92 konform: %, _
+ else if (SQL_ISRULE(this,like_predicate))
+ likeNodeToStr(rString, rParam);
+
+ else if (SQL_ISRULE(this,general_set_fct) || SQL_ISRULE(this,set_fct_spec) ||
+ SQL_ISRULE(this,position_exp) || SQL_ISRULE(this,extract_exp) ||
+ SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct))
+ {
+ if (!addDateValue(rString, rParam))
+ {
+ // Funktionsname nicht quoten
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_False;
+
+ m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+ String aStringPara;
+ for (sal_uInt32 i=1; i<nCount; i++)
+ {
+ const OSQLParseNode * pSubTree = m_aChilds[i];
+ if (pSubTree)
+ {
+ pSubTree->parseNodeToStr(aStringPara, rParam);
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1)))
+ aStringPara += String(',');
+ }
+ }
+ aStringPara.EraseTrailingChars(' ');
+ rString += aStringPara;
+ }
+ }
+ else
+ {
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end();)
+ {
+ const OSQLParseNode* pSubTree = *i;
+ if (pSubTree)
+ {
+ SQLParseNodeParameter aNewParam(rParam);
+
+ // don't replace the field for subqueries
+ if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery))
+ aNewParam.xField = NULL;
+
+ // if there is a field given we don't display the fieldname, if there are any
+ if (rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref))
+ {
+ sal_Bool bFilter = sal_False;
+ // retrieve the fields name
+ String aFieldName;
+ try
+ {
+ // retrieve the fields name
+ rtl::OUString aString;
+ rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString;
+ aFieldName = aString.getStr();
+ }
+ catch ( ... )
+ {
+ }
+
+ const OSQLParseNode* pCol = pSubTree->m_aChilds[pSubTree->count()-1];
+ if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) ||
+ pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName))
+ bFilter = sal_True;
+
+ // ok we found the field, if the following node is the
+ // comparision operator '=' we filter it as well
+ if (bFilter)
+ {
+ if (SQL_ISRULE(this, comparison_predicate))
+ {
+ ++i;
+ if(i != m_aChilds.end())
+ {
+ pSubTree = *i;
+ if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL)
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+ else
+ {
+ pSubTree->parseNodeToStr(rString, aNewParam);
+ i++;
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end()))
+ rString += String(',');
+ }
+ }
+ else
+ {
+ pSubTree->parseNodeToStr(rString, aNewParam);
+ i++;
+
+ // bei den CommaListen zwischen alle Subtrees Commas setzen
+ if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChilds.end()))
+ {
+ if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate)
+ rString += String(';');
+ else
+ rString += String(',');
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // ein Blatt ist gefunden
+ // Inhalt dem Ausgabestring anfuegen
+ switch (m_eNodeType)
+ {
+ case SQL_NODE_KEYWORD:
+ {
+ if (rString.Len())
+ rString += ' ';
+
+ rString += String::CreateFromAscii(
+ OSQLParser::TokenIDToStr(m_nNodeID, &const_cast<OParseContext&>(rParam.rContext)).GetBuffer());
+ } break;
+ case SQL_NODE_STRING:
+ if (rString.Len())
+ rString += ' ';
+ rString += SetQuotation(m_aNodeValue,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'"));
+ break;
+ case SQL_NODE_NAME:
+ if (rString.Len())
+ {
+ switch(ByteString::ConvertFromUnicode(rString.GetChar((rString.Len()-1)),RTL_TEXTENCODING_ASCII_US) )
+ {
+ case ' ' :
+ case '.' : break;
+ default :
+ if (!rParam.aCatalogSeparator.Len() || rString.GetChar((sal_uInt32)(rString.Len()-1)) != rParam.aCatalogSeparator.GetChar(0))
+ rString += ' '; break;
+ }
+ }
+ if (rParam.bQuote)
+ {
+ if (rParam.bPredicate)
+ {
+ rString.AppendAscii("[");
+ rString += m_aNodeValue;
+ rString.AppendAscii("]");
+ }
+ else
+ rString += SetQuotation(m_aNodeValue, rParam.aIdentifierQuote.GetChar(0), rParam.aIdentifierQuote.GetChar(0));
+ }
+ else
+ rString += m_aNodeValue;
+ break;
+ case SQL_NODE_ACCESS_DATE:
+ if (rString.Len())
+ rString += ' ';
+ rString += '#';
+ rString += m_aNodeValue;
+ rString += '#';
+ break;
+ case SQL_NODE_INTNUM:
+ case SQL_NODE_APPROXNUM:
+ {
+ String aTmp = m_aNodeValue;
+ if (rParam.bInternational && rParam.bPredicate && rParam.cDecSep != '.')
+ aTmp.SearchAndReplaceAll('.', rParam.cDecSep);
+
+ if (rString.Len())
+ rString += ' ';
+ rString += aTmp;
+
+ } break;
+ // fall through
+ default:
+ if (rString.Len() && m_aNodeValue.GetChar(0) != '.' && m_aNodeValue.GetChar(0) != ':' )
+ {
+ switch( ByteString::ConvertFromUnicode(rString.GetChar(rString.Len()-1),RTL_TEXTENCODING_ASCII_US) )
+ {
+ case ' ' :
+ case '.' : break;
+ default :
+ if (!rParam.aCatalogSeparator.Len() || rString.GetChar(rString.Len()-1) != rParam.aCatalogSeparator.GetChar(0))
+ rString += ' '; break;
+ }
+ }
+ rString += m_aNodeValue;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool OSQLParseNode::addDateValue(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ // special display for date/time values
+ if (rParam.bPredicate && SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChilds[0],"{"))
+ {
+ const OSQLParseNode* pODBCNode = m_aChilds[1];
+ const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChilds[0];
+
+ if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && (
+ SQL_ISTOKEN(pODBCNodeChild, D) ||
+ SQL_ISTOKEN(pODBCNodeChild, T) ||
+ SQL_ISTOKEN(pODBCNodeChild, TS) ))
+ {
+ if (rString.Len())
+ rString += ' ';
+ rString += '#';
+ if (SQL_ISTOKEN(pODBCNodeChild, D))
+ rString += convertDateString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+ else if (SQL_ISTOKEN(pODBCNodeChild, T))
+ rString += convertTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+ else
+ rString += convertDateTimeString(rParam, pODBCNode->m_aChilds[1]->getTokenValue());
+
+ rString += '#';
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::replaceNodeValue(const String& rTableAlias,const String& rColumnName)
+{
+ for (sal_uInt32 i=0;i<count();++i)
+ {
+ if (SQL_ISRULE(this,column_ref) && count() == 1 && getChild(0)->getTokenValue() == rColumnName)
+ {
+ OSQLParseNode * pCol = removeAt((sal_uInt32)0);
+ append(new OSQLParseNode(rTableAlias,SQL_NODE_NAME));
+ append(new OSQLParseNode(String::CreateFromAscii("."),SQL_NODE_PUNCTUATION));
+ append(pCol);
+ }
+ else
+ getChild(i)->replaceNodeValue(rTableAlias,rColumnName);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::tableRangeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ sal_uInt32 nCount(count());
+ rString += ' ';
+
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_False;
+ if (nCount == 4)
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ m_aChilds[1]->parseNodeToStr(rString, rParam);
+ m_aChilds[2]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[3]->parseNodeToStr(rString, rParam);
+ }
+ else if(nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"("))
+ {
+ m_aChilds[0]->parseNodeToStr(rString, rParam);
+ m_aChilds[1]->parseNodeToStr(rString, rParam);
+ m_aChilds[2]->parseNodeToStr(rString, rParam);
+ m_aChilds[3]->parseNodeToStr(rString, rParam);
+ m_aChilds[4]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[5]->parseNodeToStr(rString, rParam);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseNode::likeNodeToStr(String& rString, const SQLParseNodeParameter& rParam) const
+{
+ DBG_ASSERT(count() == 5,"count != 5: Prepare for GPF");
+
+ const OSQLParseNode* pEscNode = NULL;
+ const OSQLParseNode* pParaNode = NULL;
+
+ SQLParseNodeParameter aNewParam(rParam);
+ aNewParam.bQuote = sal_True;
+
+ // if there is a field given we don't display the fieldname, if there are any
+ sal_Bool bAddName = sal_True;
+ if (rParam.xField.is())
+ {
+ // retrieve the fields name
+ String aFieldName;
+ try
+ {
+ // retrieve the fields name
+ rtl::OUString aString;
+ rParam.xField->getPropertyValue(String::CreateFromAscii("Name")) >>= aString;
+ aFieldName = aString.getStr();
+ }
+ catch ( ... )
+ {
+ }
+
+ const OSQLParseNode* pCol = m_aChilds[0]->getChild(m_aChilds[0]->count()-1);
+ if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().EqualsIgnoreCaseAscii(aFieldName)) ||
+ pCol->getTokenValue().EqualsIgnoreCaseAscii(aFieldName) )
+ bAddName = sal_False;
+ }
+
+ if (bAddName)
+ m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+
+ m_aChilds[1]->parseNodeToStr(rString, aNewParam);
+ m_aChilds[2]->parseNodeToStr(rString, aNewParam);
+
+ pParaNode = m_aChilds[3];
+ pEscNode = m_aChilds[4];
+
+ if (pParaNode->isToken() && rParam.bInternational)
+ {
+ String aStr = ConvertLikeToken(pParaNode, pEscNode, sal_True);
+ rString += ' ';
+ rString += SetQuotation(aStr,String::CreateFromAscii("\'"),String::CreateFromAscii("\'\'"));
+ }
+ else
+ pParaNode->parseNodeToStr(rString, aNewParam);
+
+ pEscNode->parseNodeToStr(rString, aNewParam);
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const
+{
+ OSQLParseNode* pRetNode = 0;
+ if (isRule() && OSQLParser::RuleID(eRule) == getRuleID())
+ pRetNode = (OSQLParseNode*)this;
+ else
+ {
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ !pRetNode && i != m_aChilds.end(); i++)
+ pRetNode = (*i)->getByRule(eRule);
+ }
+ return pRetNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
+{
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
+ pNewNode->append(pLeftLeaf);
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
+ pNewNode->append(pRightLeaf);
+ return pNewNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf)
+{
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
+ pNewNode->append(pLeftLeaf);
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
+ pNewNode->append(pRightLeaf);
+ return pNewNode;
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ OSQLParseNode::absorptions(pSearchCondition);
+ // '(' search_condition ')'
+ if (SQL_ISRULE(pSearchCondition,boolean_primary))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(1);
+ disjunctiveNormalForm(pLeft);
+ }
+ // search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ disjunctiveNormalForm(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ disjunctiveNormalForm(pRight);
+ }
+ // boolean_term SQL_TOKEN_AND boolean_factor
+ else if (SQL_ISRULE(pSearchCondition,boolean_term))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ disjunctiveNormalForm(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ disjunctiveNormalForm(pRight);
+
+ OSQLParseNode* pNewNode = NULL;
+ // '(' search_condition ')'
+ if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition))
+ {
+ // and-or tree on left side
+ OSQLParseNode* pOr = pLeft->getChild(1);
+ OSQLParseNode* pNewLeft = NULL;
+ OSQLParseNode* pNewRight = NULL;
+
+ // cut right from parent
+ pSearchCondition->removeAt(2);
+
+ pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight);
+ pNewLeft = MakeANDNode(pOr->removeAt((sal_uInt32)0) ,new OSQLParseNode(*pRight));
+ pNewNode = MakeORNode(pNewLeft,pNewRight);
+ // and append new Node
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+
+ disjunctiveNormalForm(pNewNode);
+ }
+ else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition))
+ {
+ // and-or tree on right side
+ OSQLParseNode* pOr = pRight->getChild(1);
+ OSQLParseNode* pNewLeft = NULL;
+ OSQLParseNode* pNewRight = NULL;
+
+ // cut left from parent
+ pSearchCondition->removeAt((sal_uInt32)0);
+
+ pNewRight = MakeANDNode(pLeft,pOr->removeAt(2));
+ pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt((sal_uInt32)0));
+ pNewNode = MakeORNode(pNewLeft,pNewRight);
+
+ // and append new Node
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ disjunctiveNormalForm(pNewNode);
+ }
+ else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term)))
+ pSearchCondition->replace(pLeft, pLeft->removeAt(1));
+ else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term)))
+ pSearchCondition->replace(pRight, pRight->removeAt(1));
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_Bool bNegate)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+ OSQLParseNode* pNode = NULL;
+ // '(' search_condition ')'
+ if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // search_condition SQL_TOKEN_OR boolean_term
+ else if (SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ if(bNegate)
+ {
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pLeft = pNewNode->getChild(0);
+ pRight = pNewNode->getChild(2);
+ }
+
+ negateSearchCondition(pLeft,bNegate);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // boolean_term SQL_TOKEN_AND boolean_factor
+ else if (SQL_ISRULE(pSearchCondition,boolean_term))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ if(bNegate)
+ {
+ OSQLParseNode* pNewNode = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0));
+ pNewNode->append(new OSQLParseNode(String::CreateFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR));
+ pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1));
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pLeft = pNewNode->getChild(0);
+ pRight = pNewNode->getChild(2);
+ }
+
+ negateSearchCondition(pLeft,bNegate);
+ negateSearchCondition(pRight,bNegate);
+ }
+ // SQL_TOKEN_NOT boolean_test
+ else if (SQL_ISRULE(pSearchCondition,boolean_factor))
+ {
+ OSQLParseNode *pNot = pSearchCondition->removeAt((sal_uInt32)0);
+ delete pNot;
+ OSQLParseNode *pBooleanTest = pSearchCondition->removeAt((sal_uInt32)0);
+ pBooleanTest->setParent(NULL);
+ pSearchCondition->getParent()->replace(pSearchCondition, pBooleanTest);
+ delete pSearchCondition;
+ if (!bNegate)
+ negateSearchCondition(pBooleanTest,sal_True); // negate all deeper values
+ }
+ // row_value_constructor comparison row_value_constructor
+ // row_value_constructor comparison any_all_some subquery
+ else if(bNegate && SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate))
+ {
+ OSQLParseNode* pComparison = pSearchCondition->getChild(1);
+ OSQLParseNode* pNewComparison = NULL;
+ switch(pComparison->getNodeType())
+ {
+ case SQL_NODE_EQUAL:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<>"),SQL_NODE_NOTEQUAL,NOTEQUAL);
+ break;
+ case SQL_NODE_LESS:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii(">="),SQL_NODE_GREATEQ,GREATEQ);
+ break;
+ case SQL_NODE_GREAT:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<="),SQL_NODE_LESSEQ,LESSEQ);
+ break;
+ case SQL_NODE_LESSEQ:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii(">"),SQL_NODE_GREAT,GREAT);
+ break;
+ case SQL_NODE_GREATEQ:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("<"),SQL_NODE_LESS,LESS);
+ break;
+ case SQL_NODE_NOTEQUAL:
+ pNewComparison = new OSQLParseNode(String::CreateFromAscii("="),SQL_NODE_EQUAL,EQUAL);
+ break;
+ }
+ pSearchCondition->replace(pComparison, pNewComparison);
+ delete pComparison;
+ }
+
+ else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) ||
+ SQL_ISRULE(pSearchCondition,like_predicate) || SQL_ISRULE(pSearchCondition,between_predicate) ||
+ SQL_ISRULE(pSearchCondition,boolean_test) ))
+ {
+ sal_uInt32 nNotPos = 0;
+ // row_value_constructor not SQL_TOKEN_IN in_predicate_value
+ // row_value_constructor not SQL_TOKEN_LIKE num_value_exp opt_escape
+ // row_value_constructor not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
+ if(SQL_ISRULE(pSearchCondition,in_predicate) || SQL_ISRULE(pSearchCondition,like_predicate) ||
+ SQL_ISRULE(pSearchCondition,between_predicate))
+ nNotPos = 1;
+ // row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL
+ // boolean_primary SQL_TOKEN_IS not truth_value
+ else if(SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,boolean_test))
+ nNotPos = 2;
+
+ OSQLParseNode* pNot = pSearchCondition->getChild(nNotPos);
+ OSQLParseNode* pNotNot = NULL;
+ if(pNot->isRule())
+ pNotNot = new OSQLParseNode(String::CreateFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
+ else
+ pNotNot = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::not));
+ pSearchCondition->replace(pNot, pNotNot);
+ delete pNot;
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition)
+{
+ if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ absorptions(pRight);
+ // if child is not a or or and tree then delete () around child
+ if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
+ SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without ()
+ (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
+ {
+ OSQLParseNode* pNode = pSearchCondition->removeAt(1);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ eraseBraces(pSearchCondition);
+
+ if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ absorptions(pLeft);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ absorptions(pRight);
+ }
+
+ // a and a || a or a
+ OSQLParseNode* pNewNode = NULL;
+ if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pNewNode = pSearchCondition->removeAt((sal_uInt32)0);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode);
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ // (a or b) and a
+ else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_primary) &&
+ SQL_ISRULE(pSearchCondition->getChild(0)->getChild(1),search_condition) &&
+ *pSearchCondition->getChild(0)->getChild(1)->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt(2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ // a and ( a or b)
+ else if(SQL_ISRULE(pSearchCondition,boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_primary) &&
+ SQL_ISRULE(pSearchCondition->getChild(2)->getChild(1),search_condition))
+
+ {
+ if(*pSearchCondition->getChild(2)->getChild(1)->getChild(0) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(2)->getChild(1)->getChild(2) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ // a or a and b || a or b and a
+ else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
+ {
+ if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)0));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ // a and b or a || b and a or a
+ else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term))
+ {
+ if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2))
+ {
+ pSearchCondition->getParent()->replace(pSearchCondition, pNewNode = pSearchCondition->removeAt((sal_uInt32)2));
+ delete pSearchCondition;
+ pSearchCondition = pNewNode;
+ }
+ }
+ eraseBraces(pSearchCondition);
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition)
+{
+ if(!pSearchCondition) // no where condition at entry point
+ return;
+
+ OSQLParseNode::eraseBraces(pSearchCondition);
+
+ if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0);
+ compress(pLeft);
+
+ OSQLParseNode* pRight = pSearchCondition->getChild(2);
+ compress(pRight);
+ }
+ else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))
+ {
+ OSQLParseNode* pRight = pSearchCondition->getChild(1);
+ compress(pRight);
+ // if child is not a or or and tree then delete () around child
+ if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) ||
+ (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) ||
+ (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition)))
+ {
+ OSQLParseNode* pNode = pSearchCondition->removeAt(1);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+
+ OSQLParseNode* pNewNode = NULL;
+ // or with two and trees where one element of the and trees are equal
+ if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term))
+ {
+ if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2))
+ {
+ OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0);
+ OSQLParseNode* pNode = MakeORNode(pLeft,pRight);
+
+ OSQLParseNode* pNewRule = new OSQLParseNode(String(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary));
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii("("),SQL_NODE_PUNCTUATION));
+ pNewRule->append(pNode);
+ pNewRule->append(new OSQLParseNode(String::CreateFromAscii(")"),SQL_NODE_PUNCTUATION));
+
+ OSQLParseNode::eraseBraces(pLeft);
+ OSQLParseNode::eraseBraces(pRight);
+
+ pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule);
+ pSearchCondition->getParent()->replace(pSearchCondition, pNode);
+ delete pSearchCondition;
+ pSearchCondition = pNode;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void OSQLParseNode::showParseTree(String& rString, sal_uInt32 nLevel)
+{
+ DBG_CHKTHIS(OSQLParseNode,NULL);
+
+ if (!isToken())
+ {
+ for (sal_uInt32 j=0; j<nLevel; j++) {rString.AppendAscii("\t");};
+ // Regelnamen als rule: ...
+ rString.AppendAscii("RULE_ID:\t ");
+ rString += (String) getRuleID();
+ rString.AppendAscii("(");
+ rString += OSQLParser::RuleIDToStr(getRuleID());
+ rString.AppendAscii(")");
+ rString.AppendAscii("\n");
+
+ // einmal auswerten wieviel Subtrees dieser Knoten besitzt
+ sal_uInt32 nStop = count();
+ // hol dir den ersten Subtree
+ for (::std::vector<OSQLParseNode*>::const_iterator i = m_aChilds.begin();
+ i != m_aChilds.end(); i++)
+ (*i)->showParseTree(rString, nLevel+1);
+ }
+ else {
+ // ein Token gefunden
+ // tabs fuer das Einruecken entsprechend nLevel
+ for (sal_uInt32 j=0; j<nLevel; j++) {rString.AppendAscii("\t");};
+
+ switch (m_eNodeType) {
+
+ case SQL_NODE_KEYWORD:
+ {rString.AppendAscii("SQL_KEYWORD:\t");
+ rString += String::CreateFromAscii(OSQLParser::TokenIDToStr(getTokenID()).GetBuffer());
+ rString.AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_COMPARISON:
+ {rString.AppendAscii("SQL_COMPARISON:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString.AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ case SQL_NODE_NAME:
+ {rString.AppendAscii("SQL_NAME:\t");
+ rString.AppendAscii("\"");
+ rString += m_aNodeValue;
+ rString.AppendAscii("\"");
+ rString.AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_STRING:
+ {rString .AppendAscii("SQL_STRING:\t'");
+ rString += m_aNodeValue;
+ rString .AppendAscii("'\n");
+ break;}
+
+ case SQL_NODE_INTNUM:
+ {rString .AppendAscii("SQL_INTNUM:\t");
+ rString += m_aNodeValue;
+ rString .AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_APPROXNUM:
+ {rString .AppendAscii("SQL_APPROXNUM:\t");
+ rString += m_aNodeValue;
+ rString .AppendAscii("\n");
+ break;}
+
+ case SQL_NODE_PUNCTUATION:
+ {rString .AppendAscii("SQL_PUNCTUATION:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString .AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ case SQL_NODE_AMMSC:
+ {rString .AppendAscii("SQL_AMMSC:\t");
+ rString += m_aNodeValue; // haenge Nodevalue an
+ rString .AppendAscii("\n"); // und beginne neu Zeile
+ break;}
+
+ default:
+ DBG_ERROR("OSQLParser::ShowParseTree: unzulaessiger NodeType");
+ }
+ };
+}
+
+// Insert-Methoden
+//-----------------------------------------------------------------------------
+void OSQLParseNode::insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree)
+{
+ DBG_ASSERT(pNewSubTree != NULL, "OSQLParseNode: ungueltiger NewSubTree");
+ DBG_ASSERT(pNewSubTree->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise");
+
+ // stelle Verbindung zum getParent her:
+ pNewSubTree->setParent( this );
+ m_aChilds.insert(m_aChilds.begin() + nPos);
+}
+
+// removeAt-Methoden
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos)
+{
+ ::std::vector<OSQLParseNode*>::iterator aPos(m_aChilds.begin() + nPos);
+ OSQLParseNode* pNode = *aPos;
+
+ // setze den getParent des removeten auf NULL
+ pNode->setParent( NULL );
+
+ m_aChilds.erase(aPos);
+ return pNode;
+}
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::remove(OSQLParseNode* pSubTree)
+{
+ DBG_ASSERT(pSubTree != NULL, "OSQLParseNode: ungueltiger SubTree");
+ ::std::vector<OSQLParseNode*>::iterator aPos = ::std::find(m_aChilds.begin(), m_aChilds.end(), pSubTree);
+ if (aPos != m_aChilds.end())
+ {
+ // setze den getParent des removeten auf NULL
+ pSubTree->setParent( NULL );
+ m_aChilds.erase(aPos);
+ return pSubTree;
+ }
+ else
+ return NULL;
+}
+
+// Replace-Methoden
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::replaceAt(sal_uInt32 nPos, OSQLParseNode* pNewSubNode)
+{
+ DBG_ASSERT(pNewSubNode != NULL, "OSQLParseNode: invalid nodes");
+ DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent");
+ DBG_ASSERT(nPos < m_aChilds.size(), "OSQLParseNode: invalid position");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(),
+ "OSQLParseNode::Replace() Node already element of parent");
+
+ OSQLParseNode* pOldSubNode = m_aChilds[nPos];
+
+ // stelle Verbindung zum getParent her:
+ pNewSubNode->setParent( this );
+ pOldSubNode->setParent( NULL );
+
+ m_aChilds[nPos] = pNewSubNode;
+ return pOldSubNode;
+}
+
+//-----------------------------------------------------------------------------
+OSQLParseNode* OSQLParseNode::replace (OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode )
+{
+ DBG_ASSERT(pOldSubNode != NULL && pNewSubNode != NULL, "OSQLParseNode: invalid nodes");
+ DBG_ASSERT(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pOldSubNode) != m_aChilds.end(),
+ "OSQLParseNode::Replace() Node not element of parent");
+ DBG_ASSERT(::std::find(m_aChilds.begin(), m_aChilds.end(), pNewSubNode) == m_aChilds.end(),
+ "OSQLParseNode::Replace() Node already element of parent");
+
+ pOldSubNode->setParent( NULL );
+ pNewSubNode->setParent( this );
+ ::std::replace(m_aChilds.begin(), m_aChilds.end(), pOldSubNode, pNewSubNode);
+ return pOldSubNode;
+}
+
+