1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
30*cdf0e10cSrcweir #ifndef DBAUI_QUERYDESIGNVIEW_HXX
31*cdf0e10cSrcweir #include "QueryDesignView.hxx"
32*cdf0e10cSrcweir #endif
33*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABLEVIEW_HXX
34*cdf0e10cSrcweir #include "QueryTableView.hxx"
35*cdf0e10cSrcweir #endif
36*cdf0e10cSrcweir #ifndef DBAUI_QUERY_TABLEWINDOW_HXX
37*cdf0e10cSrcweir #include "QTableWindow.hxx"
38*cdf0e10cSrcweir #endif
39*cdf0e10cSrcweir #ifndef _SV_TOOLBOX_HXX
40*cdf0e10cSrcweir #include <vcl/toolbox.hxx>
41*cdf0e10cSrcweir #endif
42*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTROLLER_HXX
43*cdf0e10cSrcweir #include "querycontroller.hxx"
44*cdf0e10cSrcweir #endif
45*cdf0e10cSrcweir #ifndef _SV_SPLIT_HXX
46*cdf0e10cSrcweir #include <vcl/split.hxx>
47*cdf0e10cSrcweir #endif
48*cdf0e10cSrcweir #ifndef _UNDO_HXX
49*cdf0e10cSrcweir #include <svl/undo.hxx>
50*cdf0e10cSrcweir #endif
51*cdf0e10cSrcweir #ifndef TOOLS_DIAGNOSE_EX_H
52*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
53*cdf0e10cSrcweir #endif
54*cdf0e10cSrcweir #ifndef DBAUI_QYDLGTAB_HXX
55*cdf0e10cSrcweir #include "adtabdlg.hxx"
56*cdf0e10cSrcweir #endif
57*cdf0e10cSrcweir #ifndef _SV_SVAPP_HXX
58*cdf0e10cSrcweir #include <vcl/svapp.hxx>
59*cdf0e10cSrcweir #endif
60*cdf0e10cSrcweir #ifndef _SV_COMBOBOX_HXX
61*cdf0e10cSrcweir #include <vcl/combobox.hxx>
62*cdf0e10cSrcweir #endif
63*cdf0e10cSrcweir #ifndef _SV_MSGBOX_HXX
64*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
65*cdf0e10cSrcweir #endif
66*cdf0e10cSrcweir #ifndef DBACCESS_UI_BROWSER_ID_HXX
67*cdf0e10cSrcweir #include "browserids.hxx"
68*cdf0e10cSrcweir #endif
69*cdf0e10cSrcweir #ifndef DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
70*cdf0e10cSrcweir #include "SelectionBrowseBox.hxx"
71*cdf0e10cSrcweir #endif
72*cdf0e10cSrcweir #ifndef _DBU_QRY_HRC_
73*cdf0e10cSrcweir #include "dbu_qry.hrc"
74*cdf0e10cSrcweir #endif
75*cdf0e10cSrcweir #ifndef _UTL_CONFIGMGR_HXX_
76*cdf0e10cSrcweir #include <unotools/configmgr.hxx>
77*cdf0e10cSrcweir #endif
78*cdf0e10cSrcweir #ifndef _COMPHELPER_TYPES_HXX_
79*cdf0e10cSrcweir #include <comphelper/types.hxx>
80*cdf0e10cSrcweir #endif
81*cdf0e10cSrcweir #ifndef _CONNECTIVITY_DBTOOLS_HXX_
82*cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
83*cdf0e10cSrcweir #endif
84*cdf0e10cSrcweir #ifndef _DBHELPER_DBEXCEPTION_HXX_
85*cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
86*cdf0e10cSrcweir #endif
87*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_I18N_XLOCALEDATA_HPP_
88*cdf0e10cSrcweir #include <com/sun/star/i18n/XLocaleData.hpp>
89*cdf0e10cSrcweir #endif
90*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
91*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
92*cdf0e10cSrcweir #endif
93*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
94*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
95*cdf0e10cSrcweir #endif
96*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
97*cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
98*cdf0e10cSrcweir #endif
99*cdf0e10cSrcweir #ifndef _CONNECTIVITY_PCOLUMN_HXX_
100*cdf0e10cSrcweir #include <connectivity/PColumn.hxx>
101*cdf0e10cSrcweir #endif
102*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABLECONNECTION_HXX
103*cdf0e10cSrcweir #include "QTableConnection.hxx"
104*cdf0e10cSrcweir #endif
105*cdf0e10cSrcweir #ifndef DBAUI_CONNECTIONLINE_HXX
106*cdf0e10cSrcweir #include "ConnectionLine.hxx"
107*cdf0e10cSrcweir #endif
108*cdf0e10cSrcweir #ifndef DBAUI_CONNECTIONLINEDATA_HXX
109*cdf0e10cSrcweir #include "ConnectionLineData.hxx"
110*cdf0e10cSrcweir #endif
111*cdf0e10cSrcweir #ifndef DBAUI_QTABLECONNECTIONDATA_HXX
112*cdf0e10cSrcweir #include "QTableConnectionData.hxx"
113*cdf0e10cSrcweir #endif
114*cdf0e10cSrcweir #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
115*cdf0e10cSrcweir #include "dbustrings.hrc"
116*cdf0e10cSrcweir #endif
117*cdf0e10cSrcweir #ifndef _COMPHELPER_EXTRACT_HXX_
118*cdf0e10cSrcweir #include <comphelper/extract.hxx>
119*cdf0e10cSrcweir #endif
120*cdf0e10cSrcweir #ifndef DBAUI_TOOLS_HXX
121*cdf0e10cSrcweir #include "UITools.hxx"
122*cdf0e10cSrcweir #endif
123*cdf0e10cSrcweir #ifndef DBAUI_QUERYCONTAINERWINDOW_HXX
124*cdf0e10cSrcweir #include "querycontainerwindow.hxx"
125*cdf0e10cSrcweir #endif
126*cdf0e10cSrcweir #ifndef DBAUI_QUERYTABLEVIEW_HXX
127*cdf0e10cSrcweir #include "QueryTableView.hxx"
128*cdf0e10cSrcweir #endif
129*cdf0e10cSrcweir #ifndef _DBAUI_SQLMESSAGE_HXX_
130*cdf0e10cSrcweir #include "sqlmessage.hxx"
131*cdf0e10cSrcweir #endif
132*cdf0e10cSrcweir #ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
133*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
134*cdf0e10cSrcweir #endif
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir using namespace ::dbaui;
137*cdf0e10cSrcweir using namespace ::utl;
138*cdf0e10cSrcweir using namespace ::connectivity;
139*cdf0e10cSrcweir using namespace ::dbtools;
140*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
141*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
142*cdf0e10cSrcweir using namespace ::com::sun::star::i18n;
143*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
144*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
145*cdf0e10cSrcweir using namespace ::com::sun::star::container;
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir #define SQL_ISRULEOR2(pParseNode, e1,e2) 	((pParseNode)->isRule() && (\
148*cdf0e10cSrcweir 											(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
149*cdf0e10cSrcweir 											(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir // here we define our functions used in the anonymous namespace to get our header file smaller
152*cdf0e10cSrcweir // please look at the book LargeScale C++ to know why
153*cdf0e10cSrcweir namespace
154*cdf0e10cSrcweir {
155*cdf0e10cSrcweir 	static const ::rtl::OUString C_AND = ::rtl::OUString::createFromAscii(" AND ");
156*cdf0e10cSrcweir 	static const ::rtl::OUString C_OR  = ::rtl::OUString::createFromAscii(" OR ");
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	// forward declarations
159*cdf0e10cSrcweir 	sal_Bool InsertJoin(	const OQueryDesignView* _pView,
160*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode *pNode);
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	SqlParseError InstallFields(OQueryDesignView* _pView,
163*cdf0e10cSrcweir 								const ::connectivity::OSQLParseNode* pNode,
164*cdf0e10cSrcweir 								OJoinTableView::OTableWindowMap* pTabList );
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 	SqlParseError GetGroupCriteria(	OQueryDesignView* _pView,
167*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
168*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode* pSelectRoot );
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 	SqlParseError GetHavingCriteria(OQueryDesignView* _pView,
171*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
172*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode* pSelectRoot,
173*cdf0e10cSrcweir 									sal_uInt16& rLevel );
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 	SqlParseError GetOrderCriteria(	OQueryDesignView* _pView,
176*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
177*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode* pParseRoot );
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 	SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
180*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
181*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode * pCondition,
182*cdf0e10cSrcweir 									const sal_uInt16 nLevel,
183*cdf0e10cSrcweir 									sal_Bool bHaving,
184*cdf0e10cSrcweir                                     bool _bAddOrOnOneLine);
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
187*cdf0e10cSrcweir 	::rtl::OUString quoteTableAlias(sal_Bool _bQuote, const ::rtl::OUString& _sAliasName, const ::rtl::OUString& _sQuote)
188*cdf0e10cSrcweir 	{
189*cdf0e10cSrcweir 		::rtl::OUString sRet;
190*cdf0e10cSrcweir 		if ( _bQuote && _sAliasName.getLength() )
191*cdf0e10cSrcweir 		{
192*cdf0e10cSrcweir 			sRet = ::dbtools::quoteName(_sQuote,_sAliasName);
193*cdf0e10cSrcweir 			const static ::rtl::OUString sTableSeparater('.');
194*cdf0e10cSrcweir 			sRet += sTableSeparater;
195*cdf0e10cSrcweir 		}
196*cdf0e10cSrcweir 		return sRet;
197*cdf0e10cSrcweir 	}
198*cdf0e10cSrcweir     //------------------------------------------------------------------------------
199*cdf0e10cSrcweir     ::rtl::OUString getTableRange(const OQueryDesignView* _pView,const ::connectivity::OSQLParseNode* _pTableRef)
200*cdf0e10cSrcweir     {
201*cdf0e10cSrcweir         Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
202*cdf0e10cSrcweir         ::rtl::OUString sTableRange;
203*cdf0e10cSrcweir         if ( _pTableRef )
204*cdf0e10cSrcweir         {
205*cdf0e10cSrcweir             sTableRange = ::connectivity::OSQLParseNode::getTableRange(_pTableRef);
206*cdf0e10cSrcweir             if ( !sTableRange.getLength() )
207*cdf0e10cSrcweir                 _pTableRef->parseNodeToStr(sTableRange,xConnection,NULL,sal_False,sal_False);
208*cdf0e10cSrcweir         }
209*cdf0e10cSrcweir         return sTableRange;
210*cdf0e10cSrcweir     }
211*cdf0e10cSrcweir     //------------------------------------------------------------------------------
212*cdf0e10cSrcweir     void insertConnection(const OQueryDesignView* _pView,const EJoinType& _eJoinType,OTableFieldDescRef _aDragLeft,OTableFieldDescRef _aDragRight,bool _bNatural = false)
213*cdf0e10cSrcweir     {
214*cdf0e10cSrcweir         OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
215*cdf0e10cSrcweir 		OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>( pTableView->GetTabConn(static_cast<OTableWindow*>(_aDragLeft->GetTabWindow()),static_cast<OTableWindow*>(_aDragRight->GetTabWindow()),true));
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 		if ( !pConn )
218*cdf0e10cSrcweir 		{
219*cdf0e10cSrcweir 			OQueryTableConnectionData* pInfoData = new OQueryTableConnectionData();
220*cdf0e10cSrcweir             TTableConnectionData::value_type aInfoData(pInfoData);
221*cdf0e10cSrcweir 			pInfoData->InitFromDrag(_aDragLeft, _aDragRight);
222*cdf0e10cSrcweir 			pInfoData->SetJoinType(_eJoinType);
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir             if ( _bNatural )
225*cdf0e10cSrcweir             {
226*cdf0e10cSrcweir                 aInfoData->ResetConnLines();
227*cdf0e10cSrcweir                 pInfoData->setNatural(_bNatural);
228*cdf0e10cSrcweir                 try
229*cdf0e10cSrcweir                 {
230*cdf0e10cSrcweir                     Reference<XNameAccess> xReferencedTableColumns(aInfoData->getReferencedTable()->getColumns());
231*cdf0e10cSrcweir                     Sequence< ::rtl::OUString> aSeq = aInfoData->getReferencingTable()->getColumns()->getElementNames();
232*cdf0e10cSrcweir                     const ::rtl::OUString* pIter = aSeq.getConstArray();
233*cdf0e10cSrcweir                     const ::rtl::OUString* pEnd	  = pIter + aSeq.getLength();
234*cdf0e10cSrcweir                     for(;pIter != pEnd;++pIter)
235*cdf0e10cSrcweir                     {
236*cdf0e10cSrcweir                         if ( xReferencedTableColumns->hasByName(*pIter) )
237*cdf0e10cSrcweir                             aInfoData->AppendConnLine(*pIter,*pIter);
238*cdf0e10cSrcweir                     }
239*cdf0e10cSrcweir                 }
240*cdf0e10cSrcweir                 catch( const Exception& )
241*cdf0e10cSrcweir                 {
242*cdf0e10cSrcweir                     DBG_UNHANDLED_EXCEPTION();
243*cdf0e10cSrcweir                 }
244*cdf0e10cSrcweir             }
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 			OQueryTableConnection aInfo(pTableView, aInfoData);
247*cdf0e10cSrcweir 			// da ein OQueryTableConnection-Objekt nie den Besitz der uebergebenen Daten uebernimmt, sondern sich nur den Zeiger merkt,
248*cdf0e10cSrcweir 			// ist dieser Zeiger auf eine lokale Variable hier unkritisch, denn aInfoData und aInfo haben die selbe Lebensdauer
249*cdf0e10cSrcweir 			pTableView->NotifyTabConnection( aInfo );
250*cdf0e10cSrcweir 		}
251*cdf0e10cSrcweir 		else
252*cdf0e10cSrcweir 		{
253*cdf0e10cSrcweir 			::rtl::OUString aSourceFieldName(_aDragLeft->GetField());
254*cdf0e10cSrcweir 			::rtl::OUString aDestFieldName(_aDragRight->GetField());
255*cdf0e10cSrcweir 			// the connection could point on the other side
256*cdf0e10cSrcweir 			if(pConn->GetSourceWin() == _aDragRight->GetTabWindow())
257*cdf0e10cSrcweir 			{
258*cdf0e10cSrcweir 				::rtl::OUString aTmp(aSourceFieldName);
259*cdf0e10cSrcweir 				aSourceFieldName = aDestFieldName;
260*cdf0e10cSrcweir 				aDestFieldName = aTmp;
261*cdf0e10cSrcweir 			}
262*cdf0e10cSrcweir 			pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName);
263*cdf0e10cSrcweir 			pConn->UpdateLineList();
264*cdf0e10cSrcweir 			// Modified-Flag
265*cdf0e10cSrcweir 			//	SetModified();
266*cdf0e10cSrcweir 			// und neu zeichnen
267*cdf0e10cSrcweir 			pConn->RecalcLines();
268*cdf0e10cSrcweir 				// fuer das unten folgende Invalidate muss ich dieser neuen Connection erst mal die Moeglichkeit geben,
269*cdf0e10cSrcweir 				// ihr BoundingRect zu ermitteln
270*cdf0e10cSrcweir 			pConn->InvalidateConnection();
271*cdf0e10cSrcweir 		}
272*cdf0e10cSrcweir     }
273*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
274*cdf0e10cSrcweir 	::rtl::OUString ParseCondition(	OQueryController& rController
275*cdf0e10cSrcweir 									,const ::connectivity::OSQLParseNode* pCondition
276*cdf0e10cSrcweir 									,const ::rtl::OUString _sDecimal
277*cdf0e10cSrcweir 									,const ::com::sun::star::lang::Locale& _rLocale
278*cdf0e10cSrcweir 									,sal_uInt32 _nStartIndex)
279*cdf0e10cSrcweir 	{
280*cdf0e10cSrcweir 		::rtl::OUString	aCondition;
281*cdf0e10cSrcweir 		Reference< XConnection> xConnection = rController.getConnection();
282*cdf0e10cSrcweir 		if ( xConnection.is() )
283*cdf0e10cSrcweir 		{
284*cdf0e10cSrcweir 			sal_uInt32 nCount = pCondition->count();
285*cdf0e10cSrcweir 			for(sal_uInt32 i = _nStartIndex ; i < nCount ; ++i)
286*cdf0e10cSrcweir 				pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
287*cdf0e10cSrcweir 								xConnection,
288*cdf0e10cSrcweir 								rController.getNumberFormatter(),
289*cdf0e10cSrcweir 								_rLocale,
290*cdf0e10cSrcweir 								static_cast<sal_Char>(_sDecimal.toChar()),
291*cdf0e10cSrcweir 								&rController.getParser().getContext());
292*cdf0e10cSrcweir 		}
293*cdf0e10cSrcweir 		return aCondition;
294*cdf0e10cSrcweir 	}
295*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
296*cdf0e10cSrcweir 	SqlParseError FillOuterJoins(OQueryDesignView* _pView,
297*cdf0e10cSrcweir 								const ::connectivity::OSQLParseNode* pTableRefList)
298*cdf0e10cSrcweir 	{
299*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
300*cdf0e10cSrcweir 		sal_uInt32 nCount = pTableRefList->count();
301*cdf0e10cSrcweir 		sal_Bool bError = sal_False;
302*cdf0e10cSrcweir 		for (sal_uInt32 i=0; !bError && i < nCount; ++i)
303*cdf0e10cSrcweir 		{
304*cdf0e10cSrcweir 			const ::connectivity::OSQLParseNode* pParseNode = pTableRefList->getChild(i);
305*cdf0e10cSrcweir 			const ::connectivity::OSQLParseNode* pJoinNode = NULL;
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir 			if ( SQL_ISRULE( pParseNode, qualified_join ) || SQL_ISRULE( pParseNode, joined_table ) || SQL_ISRULE( pParseNode, cross_union ) )
308*cdf0e10cSrcweir 				pJoinNode = pParseNode;
309*cdf0e10cSrcweir 			else if(	SQL_ISRULE(pParseNode,table_ref)
310*cdf0e10cSrcweir 					&&	pParseNode->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}'
311*cdf0e10cSrcweir 				pJoinNode = pParseNode->getChild(2);
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 			if ( pJoinNode )
314*cdf0e10cSrcweir 			{
315*cdf0e10cSrcweir 				if ( !InsertJoin(_pView,pJoinNode) )
316*cdf0e10cSrcweir 					bError = sal_True;
317*cdf0e10cSrcweir 			}
318*cdf0e10cSrcweir 		}
319*cdf0e10cSrcweir 		// check if error occured
320*cdf0e10cSrcweir 		if ( bError )
321*cdf0e10cSrcweir 			eErrorCode = eIllegalJoin;
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir 		return eErrorCode;
324*cdf0e10cSrcweir 	}
325*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 	/** FillDragInfo fills the field description out of the table
328*cdf0e10cSrcweir 	*/
329*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
330*cdf0e10cSrcweir 	SqlParseError FillDragInfo(	const OQueryDesignView* _pView,
331*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode* pColumnRef,
332*cdf0e10cSrcweir 							OTableFieldDescRef& _rDragInfo)
333*cdf0e10cSrcweir 	{
334*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir 		sal_Bool bErg = sal_False;
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir 		::rtl::OUString aTableRange,aColumnName;
339*cdf0e10cSrcweir 		sal_uInt16 nCntAccount;
340*cdf0e10cSrcweir 		::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
341*cdf0e10cSrcweir 		rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir 		if ( aTableRange.getLength() )
344*cdf0e10cSrcweir 		{
345*cdf0e10cSrcweir 			OQueryTableWindow*	pSTW = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( aTableRange );
346*cdf0e10cSrcweir 			bErg = (pSTW && pSTW->ExistsField( aColumnName, _rDragInfo ) );
347*cdf0e10cSrcweir 		}
348*cdf0e10cSrcweir 		if ( !bErg )
349*cdf0e10cSrcweir         {
350*cdf0e10cSrcweir 			bErg = static_cast<OQueryTableView*>(_pView->getTableView())->FindTableFromField(aColumnName, _rDragInfo, nCntAccount);
351*cdf0e10cSrcweir             if ( !bErg )
352*cdf0e10cSrcweir                 bErg = _pView->HasFieldByAliasName(aColumnName, _rDragInfo);
353*cdf0e10cSrcweir         }
354*cdf0e10cSrcweir 		if ( !bErg )
355*cdf0e10cSrcweir 		{
356*cdf0e10cSrcweir 			eErrorCode = eColumnNotFound;
357*cdf0e10cSrcweir 			String sError(ModuleRes(STR_QRY_COLUMN_NOT_FOUND));
358*cdf0e10cSrcweir 			sError.SearchAndReplaceAscii("$name$",aColumnName);
359*cdf0e10cSrcweir 			_pView->getController().appendError( sError );
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir 			try
362*cdf0e10cSrcweir 			{
363*cdf0e10cSrcweir 				Reference<XDatabaseMetaData> xMeta = _pView->getController().getConnection()->getMetaData();
364*cdf0e10cSrcweir                 if ( xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() )
365*cdf0e10cSrcweir                     _pView->getController().appendError( String( ModuleRes( STR_QRY_CHECK_CASESENSITIVE ) ) );
366*cdf0e10cSrcweir 			}
367*cdf0e10cSrcweir 			catch(Exception&)
368*cdf0e10cSrcweir 			{
369*cdf0e10cSrcweir 			}
370*cdf0e10cSrcweir 		}
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir 		return eErrorCode;
373*cdf0e10cSrcweir 	}
374*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
375*cdf0e10cSrcweir 	::rtl::OUString BuildJoinCriteria(	const Reference< XConnection>& _xConnection,
376*cdf0e10cSrcweir 										OConnectionLineDataVec* pLineDataList,
377*cdf0e10cSrcweir 										OQueryTableConnectionData* pData)
378*cdf0e10cSrcweir 	{
379*cdf0e10cSrcweir 		::rtl::OUStringBuffer aCondition;
380*cdf0e10cSrcweir 		if ( _xConnection.is() )
381*cdf0e10cSrcweir         {
382*cdf0e10cSrcweir 		    OConnectionLineDataVec::iterator aIter = pLineDataList->begin();
383*cdf0e10cSrcweir             OConnectionLineDataVec::iterator aEnd = pLineDataList->end();
384*cdf0e10cSrcweir 		    try
385*cdf0e10cSrcweir 		    {
386*cdf0e10cSrcweir 			    const Reference< XDatabaseMetaData >  xMetaData = _xConnection->getMetaData();
387*cdf0e10cSrcweir 			    const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
388*cdf0e10cSrcweir                 const ::rtl::OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = "));
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir 			    for(;aIter != aEnd;++aIter)
391*cdf0e10cSrcweir 			    {
392*cdf0e10cSrcweir 				    OConnectionLineDataRef pLineData = *aIter;
393*cdf0e10cSrcweir 				    if(aCondition.getLength())
394*cdf0e10cSrcweir 					    aCondition.append(C_AND);
395*cdf0e10cSrcweir 				    aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_FROM),aQuote));
396*cdf0e10cSrcweir 				    aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_FROM) ));
397*cdf0e10cSrcweir 				    aCondition.append(sEqual);
398*cdf0e10cSrcweir 				    aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_TO),aQuote));
399*cdf0e10cSrcweir 				    aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_TO) ));
400*cdf0e10cSrcweir 			    }
401*cdf0e10cSrcweir 		    }
402*cdf0e10cSrcweir 		    catch(SQLException&)
403*cdf0e10cSrcweir 		    {
404*cdf0e10cSrcweir 			    OSL_ASSERT(!"Failure while building Join criteria!");
405*cdf0e10cSrcweir 		    }
406*cdf0e10cSrcweir         }
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir 		return aCondition.makeStringAndClear();
409*cdf0e10cSrcweir 	}
410*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
411*cdf0e10cSrcweir 	/** JoinCycle looks for a join cycle and append it to the string
412*cdf0e10cSrcweir 		@param	_xConnection	the connection
413*cdf0e10cSrcweir 		@param	_pEntryConn		the table connection which holds the data
414*cdf0e10cSrcweir 		@param	_pEntryTabTo	the corresponding table window
415*cdf0e10cSrcweir 		@param	_rJoin			the String which will contain the resulting string
416*cdf0e10cSrcweir 	*/
417*cdf0e10cSrcweir 	void JoinCycle(	const Reference< XConnection>& _xConnection,
418*cdf0e10cSrcweir 					OQueryTableConnection* _pEntryConn,
419*cdf0e10cSrcweir 					const OQueryTableWindow* _pEntryTabTo,
420*cdf0e10cSrcweir 					::rtl::OUString& _rJoin )
421*cdf0e10cSrcweir 	{
422*cdf0e10cSrcweir 		OSL_ENSURE(_pEntryConn,"TableConnection can not be null!");
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir 		OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pEntryConn->GetData().get());
425*cdf0e10cSrcweir 		if ( pData->GetJoinType() != INNER_JOIN && _pEntryTabTo->ExistsAVisitedConn() )
426*cdf0e10cSrcweir 		{
427*cdf0e10cSrcweir 			sal_Bool bBrace = sal_False;
428*cdf0e10cSrcweir 			if(_rJoin.getLength() && _rJoin.lastIndexOf(')') == (_rJoin.getLength()-1))
429*cdf0e10cSrcweir 			{
430*cdf0e10cSrcweir 				bBrace = sal_True;
431*cdf0e10cSrcweir 				_rJoin = _rJoin.replaceAt(_rJoin.getLength()-1,1,::rtl::OUString(' '));
432*cdf0e10cSrcweir 			}
433*cdf0e10cSrcweir 			(_rJoin += C_AND) += BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData);
434*cdf0e10cSrcweir 			if(bBrace)
435*cdf0e10cSrcweir 				_rJoin += ::rtl::OUString(')');
436*cdf0e10cSrcweir 			_pEntryConn->SetVisited(sal_True);
437*cdf0e10cSrcweir 		}
438*cdf0e10cSrcweir 	}
439*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
440*cdf0e10cSrcweir 	::rtl::OUString BuildTable(	const Reference< XConnection>& _xConnection,
441*cdf0e10cSrcweir 								const OQueryTableWindow* pEntryTab,
442*cdf0e10cSrcweir                                 bool _bForce = false
443*cdf0e10cSrcweir 								)
444*cdf0e10cSrcweir 	{
445*cdf0e10cSrcweir 		::rtl::OUString aDBName(pEntryTab->GetComposedName());
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 		//	Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
448*cdf0e10cSrcweir 		if( _xConnection.is() )
449*cdf0e10cSrcweir 		{
450*cdf0e10cSrcweir 			try
451*cdf0e10cSrcweir 			{
452*cdf0e10cSrcweir 				Reference< XDatabaseMetaData >  xMetaData = _xConnection->getMetaData();
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir                 ::rtl::OUString sCatalog, sSchema, sTable;
455*cdf0e10cSrcweir                 ::dbtools::qualifiedNameComponents( xMetaData, aDBName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
456*cdf0e10cSrcweir 				::rtl::OUString aTableListStr = ::dbtools::composeTableNameForSelect( _xConnection, sCatalog, sSchema, sTable );
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 				::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
459*cdf0e10cSrcweir 				if ( _bForce || isAppendTableAliasEnabled( _xConnection ) || pEntryTab->GetAliasName() != aDBName )
460*cdf0e10cSrcweir 				{
461*cdf0e10cSrcweir                     aTableListStr += ::rtl::OUString::createFromAscii(" ");
462*cdf0e10cSrcweir                     if ( generateAsBeforeTableAlias( _xConnection ) )
463*cdf0e10cSrcweir                         aTableListStr += ::rtl::OUString::createFromAscii("AS ");
464*cdf0e10cSrcweir 					aTableListStr += ::dbtools::quoteName( aQuote, pEntryTab->GetAliasName() );
465*cdf0e10cSrcweir 				}
466*cdf0e10cSrcweir 				aDBName = aTableListStr;
467*cdf0e10cSrcweir 			}
468*cdf0e10cSrcweir 			catch(const SQLException&)
469*cdf0e10cSrcweir 			{
470*cdf0e10cSrcweir                 DBG_UNHANDLED_EXCEPTION();
471*cdf0e10cSrcweir 			}
472*cdf0e10cSrcweir 		}
473*cdf0e10cSrcweir 		return aDBName;
474*cdf0e10cSrcweir 	}
475*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
476*cdf0e10cSrcweir 	::rtl::OUString BuildJoin(	const Reference< XConnection>& _xConnection,
477*cdf0e10cSrcweir 								const ::rtl::OUString& rLh,
478*cdf0e10cSrcweir 								const ::rtl::OUString& rRh,
479*cdf0e10cSrcweir 								OQueryTableConnectionData* pData)
480*cdf0e10cSrcweir 	{
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 		String aErg(rLh);
483*cdf0e10cSrcweir         if ( pData->isNatural() && pData->GetJoinType() != CROSS_JOIN )
484*cdf0e10cSrcweir             aErg.AppendAscii(" NATURAL ");
485*cdf0e10cSrcweir 		switch(pData->GetJoinType())
486*cdf0e10cSrcweir 		{
487*cdf0e10cSrcweir 			case LEFT_JOIN:
488*cdf0e10cSrcweir 				aErg.AppendAscii(" LEFT OUTER ");
489*cdf0e10cSrcweir 				break;
490*cdf0e10cSrcweir 			case RIGHT_JOIN:
491*cdf0e10cSrcweir 				aErg.AppendAscii(" RIGHT OUTER ");
492*cdf0e10cSrcweir 				break;
493*cdf0e10cSrcweir             case CROSS_JOIN:
494*cdf0e10cSrcweir                 OSL_ENSURE(!pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
495*cdf0e10cSrcweir 				aErg.AppendAscii(" CROSS ");
496*cdf0e10cSrcweir 				break;
497*cdf0e10cSrcweir 			case INNER_JOIN:
498*cdf0e10cSrcweir                 OSL_ENSURE(pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
499*cdf0e10cSrcweir 				aErg.AppendAscii(" INNER ");
500*cdf0e10cSrcweir 				break;
501*cdf0e10cSrcweir 			default:
502*cdf0e10cSrcweir 				aErg.AppendAscii(" FULL OUTER ");
503*cdf0e10cSrcweir 				break;
504*cdf0e10cSrcweir 		}
505*cdf0e10cSrcweir 		aErg.AppendAscii("JOIN ");
506*cdf0e10cSrcweir 		aErg += String(rRh);
507*cdf0e10cSrcweir         if ( CROSS_JOIN != pData->GetJoinType() && !pData->isNatural() )
508*cdf0e10cSrcweir         {
509*cdf0e10cSrcweir 		    aErg.AppendAscii(" ON ");
510*cdf0e10cSrcweir 		    aErg += String(BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData));
511*cdf0e10cSrcweir         }
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir 		return aErg;
514*cdf0e10cSrcweir 	}
515*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
516*cdf0e10cSrcweir 	::rtl::OUString BuildJoin(	const Reference< XConnection>& _xConnection,
517*cdf0e10cSrcweir 								OQueryTableWindow* pLh,
518*cdf0e10cSrcweir 								OQueryTableWindow* pRh,
519*cdf0e10cSrcweir 								OQueryTableConnectionData* pData
520*cdf0e10cSrcweir 								)
521*cdf0e10cSrcweir 	{
522*cdf0e10cSrcweir         bool bForce = pData->GetJoinType() == CROSS_JOIN || pData->isNatural();
523*cdf0e10cSrcweir 		return BuildJoin(_xConnection,BuildTable(_xConnection,pLh,bForce),BuildTable(_xConnection,pRh,bForce),pData);
524*cdf0e10cSrcweir 	}
525*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
526*cdf0e10cSrcweir 	::rtl::OUString BuildJoin(	const Reference< XConnection>& _xConnection,
527*cdf0e10cSrcweir 								const ::rtl::OUString &rLh,
528*cdf0e10cSrcweir 								OQueryTableWindow* pRh,
529*cdf0e10cSrcweir 								OQueryTableConnectionData* pData
530*cdf0e10cSrcweir 								)
531*cdf0e10cSrcweir 	{
532*cdf0e10cSrcweir 		return BuildJoin(_xConnection,rLh,BuildTable(_xConnection,pRh),pData);
533*cdf0e10cSrcweir 	}
534*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
535*cdf0e10cSrcweir 	::rtl::OUString BuildJoin(	const Reference< XConnection>& _xConnection,
536*cdf0e10cSrcweir 								OQueryTableWindow* pLh,
537*cdf0e10cSrcweir 								const ::rtl::OUString &rRh,
538*cdf0e10cSrcweir 								OQueryTableConnectionData* pData
539*cdf0e10cSrcweir 								)
540*cdf0e10cSrcweir 	{
541*cdf0e10cSrcweir 		return BuildJoin(_xConnection,BuildTable(_xConnection,pLh),rRh,pData);
542*cdf0e10cSrcweir 	}
543*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
544*cdf0e10cSrcweir 	void GetNextJoin(	const Reference< XConnection>& _xConnection,
545*cdf0e10cSrcweir 						OQueryTableConnection* pEntryConn,
546*cdf0e10cSrcweir 						OQueryTableWindow* pEntryTabTo,
547*cdf0e10cSrcweir 						::rtl::OUString &aJoin)
548*cdf0e10cSrcweir 	{
549*cdf0e10cSrcweir 		OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
550*cdf0e10cSrcweir         if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
551*cdf0e10cSrcweir 			return;
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir 		//	Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir 		if(!aJoin.getLength())
556*cdf0e10cSrcweir 		{
557*cdf0e10cSrcweir 			OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
558*cdf0e10cSrcweir 			aJoin = BuildJoin(_xConnection,pEntryTabFrom,pEntryTabTo,pEntryConnData);
559*cdf0e10cSrcweir 		}
560*cdf0e10cSrcweir 		else if(pEntryTabTo == pEntryConn->GetDestWin())
561*cdf0e10cSrcweir 		{
562*cdf0e10cSrcweir 			aJoin = BuildJoin(_xConnection,aJoin,pEntryTabTo,pEntryConnData);
563*cdf0e10cSrcweir 		}
564*cdf0e10cSrcweir 		else if(pEntryTabTo == pEntryConn->GetSourceWin())
565*cdf0e10cSrcweir 		{
566*cdf0e10cSrcweir 			aJoin = BuildJoin(_xConnection,pEntryTabTo,aJoin,pEntryConnData);
567*cdf0e10cSrcweir 		}
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir 		pEntryConn->SetVisited(sal_True);
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 		// first search for the "to" window
572*cdf0e10cSrcweir 		const ::std::vector<OTableConnection*>* pConnections = pEntryConn->GetParent()->getTableConnections();
573*cdf0e10cSrcweir 		::std::vector<OTableConnection*>::const_iterator aIter = pConnections->begin();
574*cdf0e10cSrcweir         ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
575*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
576*cdf0e10cSrcweir 		{
577*cdf0e10cSrcweir 			OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
578*cdf0e10cSrcweir 			if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabTo || pNext->GetDestWin() == pEntryTabTo))
579*cdf0e10cSrcweir 			{
580*cdf0e10cSrcweir 				OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabTo ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
581*cdf0e10cSrcweir 				// exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
582*cdf0e10cSrcweir 				JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
583*cdf0e10cSrcweir 				if(!pNext->IsVisited())
584*cdf0e10cSrcweir 					GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
585*cdf0e10cSrcweir 			}
586*cdf0e10cSrcweir 		}
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir 		// when nothing found found look for the "from" window
589*cdf0e10cSrcweir 		if(aIter == aEnd)
590*cdf0e10cSrcweir 		{
591*cdf0e10cSrcweir 			OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
592*cdf0e10cSrcweir 			aIter = pConnections->begin();
593*cdf0e10cSrcweir 			for(;aIter != aEnd;++aIter)
594*cdf0e10cSrcweir 			{
595*cdf0e10cSrcweir 				OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
596*cdf0e10cSrcweir 				if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabFrom || pNext->GetDestWin() == pEntryTabFrom))
597*cdf0e10cSrcweir 				{
598*cdf0e10cSrcweir 					OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabFrom ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
599*cdf0e10cSrcweir 					// exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
600*cdf0e10cSrcweir 					JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
601*cdf0e10cSrcweir 					if(!pNext->IsVisited())
602*cdf0e10cSrcweir 						GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
603*cdf0e10cSrcweir 				}
604*cdf0e10cSrcweir 			}
605*cdf0e10cSrcweir 		}
606*cdf0e10cSrcweir 	}
607*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
608*cdf0e10cSrcweir 	SqlParseError InsertJoinConnection(	const OQueryDesignView* _pView,
609*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode *pNode,
610*cdf0e10cSrcweir 									const EJoinType& _eJoinType,
611*cdf0e10cSrcweir                                     const ::connectivity::OSQLParseNode *pLeftTable,
612*cdf0e10cSrcweir                                     const ::connectivity::OSQLParseNode *pRightTable)
613*cdf0e10cSrcweir 	{
614*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
615*cdf0e10cSrcweir 		if (pNode->count() == 3 &&	// Ausdruck is geklammert
616*cdf0e10cSrcweir 			SQL_ISPUNCTUATION(pNode->getChild(0),"(") &&
617*cdf0e10cSrcweir 			SQL_ISPUNCTUATION(pNode->getChild(2),")"))
618*cdf0e10cSrcweir 		{
619*cdf0e10cSrcweir 			eErrorCode = InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType,pLeftTable,pRightTable);
620*cdf0e10cSrcweir 		}
621*cdf0e10cSrcweir 		else if (SQL_ISRULEOR2(pNode,search_condition,boolean_term)	&&			// AND/OR-Verknuepfung:
622*cdf0e10cSrcweir 				 pNode->count() == 3)
623*cdf0e10cSrcweir 		{
624*cdf0e10cSrcweir 			// nur AND Verkn�pfung zulassen
625*cdf0e10cSrcweir 			if (!SQL_ISTOKEN(pNode->getChild(1),AND))
626*cdf0e10cSrcweir 				eErrorCode = eIllegalJoinCondition;
627*cdf0e10cSrcweir 			else if ( eOk == (eErrorCode = InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType,pLeftTable,pRightTable)) )
628*cdf0e10cSrcweir 					eErrorCode = InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType,pLeftTable,pRightTable);
629*cdf0e10cSrcweir 		}
630*cdf0e10cSrcweir 		else if (SQL_ISRULE(pNode,comparison_predicate))
631*cdf0e10cSrcweir 		{
632*cdf0e10cSrcweir 			// only the comparison of columns is allowed
633*cdf0e10cSrcweir 			DBG_ASSERT(pNode->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree");
634*cdf0e10cSrcweir 			if (!(SQL_ISRULE(pNode->getChild(0),column_ref) &&
635*cdf0e10cSrcweir 				  SQL_ISRULE(pNode->getChild(2),column_ref) &&
636*cdf0e10cSrcweir 				   pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL))
637*cdf0e10cSrcweir 			{
638*cdf0e10cSrcweir 				String sError(ModuleRes(STR_QRY_JOIN_COLUMN_COMPARE));
639*cdf0e10cSrcweir 				_pView->getController().appendError( sError );
640*cdf0e10cSrcweir 				return eIllegalJoin;
641*cdf0e10cSrcweir 			}
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir 			OTableFieldDescRef aDragLeft  = new OTableFieldDesc();
644*cdf0e10cSrcweir 			OTableFieldDescRef aDragRight = new OTableFieldDesc();
645*cdf0e10cSrcweir 			if ( eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(0),aDragLeft)) ||
646*cdf0e10cSrcweir 				eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(2),aDragRight)))
647*cdf0e10cSrcweir 				return eErrorCode;
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir             if ( pLeftTable )
650*cdf0e10cSrcweir             {
651*cdf0e10cSrcweir                 OQueryTableWindow*	pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pLeftTable->getByRule(OSQLParseNode::table_ref) ));
652*cdf0e10cSrcweir                 // OQueryTableWindow*	pRightWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pRightTable->getByRule(OSQLParseNode::table_ref) ));
653*cdf0e10cSrcweir                 if ( pLeftWindow == aDragLeft->GetTabWindow() )
654*cdf0e10cSrcweir                     insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
655*cdf0e10cSrcweir                 else
656*cdf0e10cSrcweir                     insertConnection(_pView,_eJoinType,aDragRight,aDragLeft);
657*cdf0e10cSrcweir             }
658*cdf0e10cSrcweir             else
659*cdf0e10cSrcweir                 insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
660*cdf0e10cSrcweir 		}
661*cdf0e10cSrcweir 		else
662*cdf0e10cSrcweir 			eErrorCode = eIllegalJoin;
663*cdf0e10cSrcweir 		return eErrorCode;
664*cdf0e10cSrcweir 	}
665*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
666*cdf0e10cSrcweir 	sal_Bool GetInnerJoinCriteria(	const OQueryDesignView* _pView,
667*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode *pCondition)
668*cdf0e10cSrcweir 	{
669*cdf0e10cSrcweir 		return InsertJoinConnection(_pView,pCondition, INNER_JOIN,NULL,NULL) != eOk;
670*cdf0e10cSrcweir 	}
671*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
672*cdf0e10cSrcweir 	::rtl::OUString GenerateSelectList(	const OQueryDesignView* _pView,
673*cdf0e10cSrcweir 										OTableFields&	_rFieldList,
674*cdf0e10cSrcweir 										sal_Bool bAlias)
675*cdf0e10cSrcweir 	{
676*cdf0e10cSrcweir         Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
677*cdf0e10cSrcweir 		if ( !xConnection.is() )
678*cdf0e10cSrcweir 			return ::rtl::OUString();
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir 		::rtl::OUStringBuffer aTmpStr,aFieldListStr;
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 		sal_Bool bAsterix = sal_False;
683*cdf0e10cSrcweir 		int nVis = 0;
684*cdf0e10cSrcweir 		OTableFields::iterator aIter = _rFieldList.begin();
685*cdf0e10cSrcweir         OTableFields::iterator aEnd = _rFieldList.end();
686*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
687*cdf0e10cSrcweir 		{
688*cdf0e10cSrcweir 			OTableFieldDescRef pEntryField = *aIter;
689*cdf0e10cSrcweir 			if ( pEntryField->IsVisible() )
690*cdf0e10cSrcweir 			{
691*cdf0e10cSrcweir 				if ( pEntryField->GetField().toChar() == '*' )
692*cdf0e10cSrcweir 					bAsterix = sal_True;
693*cdf0e10cSrcweir 				++nVis;
694*cdf0e10cSrcweir 			}
695*cdf0e10cSrcweir 		}
696*cdf0e10cSrcweir 		if(nVis == 1)
697*cdf0e10cSrcweir 			bAsterix = sal_False;
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir 		try
700*cdf0e10cSrcweir 		{
701*cdf0e10cSrcweir 			const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
702*cdf0e10cSrcweir 			const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir 			OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir 			const static ::rtl::OUString sFieldSeparator(RTL_CONSTASCII_USTRINGPARAM(", "));
707*cdf0e10cSrcweir             const static ::rtl::OUString s_sAs(RTL_CONSTASCII_USTRINGPARAM(" AS "));
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir 			aIter = _rFieldList.begin();
710*cdf0e10cSrcweir 		    for(;aIter != aEnd;++aIter)
711*cdf0e10cSrcweir 			{
712*cdf0e10cSrcweir 				OTableFieldDescRef pEntryField = *aIter;
713*cdf0e10cSrcweir 				::rtl::OUString rFieldName = pEntryField->GetField();
714*cdf0e10cSrcweir 				if ( rFieldName.getLength() && pEntryField->IsVisible() )
715*cdf0e10cSrcweir 				{
716*cdf0e10cSrcweir 					aTmpStr = ::rtl::OUString();
717*cdf0e10cSrcweir 					const ::rtl::OUString rAlias = pEntryField->GetAlias();
718*cdf0e10cSrcweir 					const ::rtl::OUString rFieldAlias = pEntryField->GetFieldAlias();
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir 					aTmpStr.append(quoteTableAlias((bAlias || bAsterix),rAlias,aQuote));
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir 					// if we have a none numeric field, the table alias could be in the name
723*cdf0e10cSrcweir 					// otherwise we are not allowed to do this (e.g. 0.1 * PRICE )
724*cdf0e10cSrcweir 					if  ( !pEntryField->isOtherFunction() )
725*cdf0e10cSrcweir 					{
726*cdf0e10cSrcweir 						// we have to look if we have alias.* here but before we have to check if the column doesn't already exist
727*cdf0e10cSrcweir 						String sTemp = rFieldName;
728*cdf0e10cSrcweir 						OTableFieldDescRef	aInfo = new OTableFieldDesc();
729*cdf0e10cSrcweir 						OJoinTableView::OTableWindowMap::iterator tableIter = pTabList->begin();
730*cdf0e10cSrcweir                         OJoinTableView::OTableWindowMap::iterator tableEnd = pTabList->end();
731*cdf0e10cSrcweir 						sal_Bool bFound = sal_False;
732*cdf0e10cSrcweir 						for(;!bFound && tableIter != tableEnd ;++tableIter)
733*cdf0e10cSrcweir 						{
734*cdf0e10cSrcweir 							OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(tableIter->second);
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir                             bFound = pTabWin->ExistsField( rFieldName, aInfo );
737*cdf0e10cSrcweir 							if ( bFound )
738*cdf0e10cSrcweir 								rFieldName = aInfo->GetField();
739*cdf0e10cSrcweir 						}
740*cdf0e10cSrcweir 						if ( ( rFieldName.toChar() != '*' ) && ( rFieldName.indexOf( aQuote ) == -1 ) )
741*cdf0e10cSrcweir 						{
742*cdf0e10cSrcweir 							OSL_ENSURE(pEntryField->GetTable().getLength(),"No table field name!");
743*cdf0e10cSrcweir 							aTmpStr.append(::dbtools::quoteName(aQuote, rFieldName));
744*cdf0e10cSrcweir 						}
745*cdf0e10cSrcweir 						else
746*cdf0e10cSrcweir 							aTmpStr.append(rFieldName);
747*cdf0e10cSrcweir 					}
748*cdf0e10cSrcweir 					else
749*cdf0e10cSrcweir 						aTmpStr.append(rFieldName);
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir 					if  ( pEntryField->isAggreateFunction() )
752*cdf0e10cSrcweir 					{
753*cdf0e10cSrcweir 						DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
754*cdf0e10cSrcweir 						::rtl::OUStringBuffer aTmpStr2( pEntryField->GetFunction());
755*cdf0e10cSrcweir 						aTmpStr2.appendAscii("(");
756*cdf0e10cSrcweir 						aTmpStr2.append(aTmpStr.makeStringAndClear());
757*cdf0e10cSrcweir 						aTmpStr2.appendAscii(")");
758*cdf0e10cSrcweir 						aTmpStr = aTmpStr2;
759*cdf0e10cSrcweir 					}
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir 					if (rFieldAlias.getLength()							&&
762*cdf0e10cSrcweir 						(rFieldName.toChar() != '*'						||
763*cdf0e10cSrcweir 						pEntryField->isNumericOrAggreateFunction()		||
764*cdf0e10cSrcweir 						pEntryField->isOtherFunction()))
765*cdf0e10cSrcweir 					{
766*cdf0e10cSrcweir 						aTmpStr.append(s_sAs);
767*cdf0e10cSrcweir 						aTmpStr.append(::dbtools::quoteName(aQuote, rFieldAlias));
768*cdf0e10cSrcweir 					}
769*cdf0e10cSrcweir 					aFieldListStr.append(aTmpStr.makeStringAndClear());
770*cdf0e10cSrcweir 					aFieldListStr.append(sFieldSeparator);
771*cdf0e10cSrcweir 				}
772*cdf0e10cSrcweir 			}
773*cdf0e10cSrcweir 			if(aFieldListStr.getLength())
774*cdf0e10cSrcweir 				aFieldListStr.setLength(aFieldListStr.getLength()-2);
775*cdf0e10cSrcweir 		}
776*cdf0e10cSrcweir 		catch(SQLException&)
777*cdf0e10cSrcweir 		{
778*cdf0e10cSrcweir 			OSL_ASSERT(!"Failure while building select list!");
779*cdf0e10cSrcweir 		}
780*cdf0e10cSrcweir 		return aFieldListStr.makeStringAndClear();
781*cdf0e10cSrcweir 	}
782*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
783*cdf0e10cSrcweir 	sal_Bool GenerateCriterias(	OQueryDesignView* _pView,
784*cdf0e10cSrcweir 								::rtl::OUStringBuffer& rRetStr,
785*cdf0e10cSrcweir 								::rtl::OUStringBuffer& rHavingStr,
786*cdf0e10cSrcweir 								OTableFields& _rFieldList,
787*cdf0e10cSrcweir 								sal_Bool bMulti )
788*cdf0e10cSrcweir 	{
789*cdf0e10cSrcweir 		// * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
790*cdf0e10cSrcweir 		sal_Bool bCritsOnAsterikWarning = sal_False;		// ** TMFS **
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir 		::rtl::OUString aFieldName,aCriteria,aWhereStr,aHavingStr,aWork/*,aOrderStr*/;
793*cdf0e10cSrcweir 		// Zeilenweise werden die Ausdr"ucke mit AND verknuepft
794*cdf0e10cSrcweir 		sal_uInt16 nMaxCriteria = 0;
795*cdf0e10cSrcweir 		OTableFields::iterator aIter = _rFieldList.begin();
796*cdf0e10cSrcweir 		OTableFields::iterator aEnd = _rFieldList.end();
797*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
798*cdf0e10cSrcweir 		{
799*cdf0e10cSrcweir 			nMaxCriteria = ::std::max<sal_uInt16>(nMaxCriteria,(sal_uInt16)(*aIter)->GetCriteria().size());
800*cdf0e10cSrcweir 		}
801*cdf0e10cSrcweir 		Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
802*cdf0e10cSrcweir 		if(!xConnection.is())
803*cdf0e10cSrcweir 			return sal_False;
804*cdf0e10cSrcweir 		try
805*cdf0e10cSrcweir 		{
806*cdf0e10cSrcweir 			const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
807*cdf0e10cSrcweir 			const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
808*cdf0e10cSrcweir 			const IParseContext& rContext = static_cast<OQueryController&>(_pView->getController()).getParser().getContext();
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir 			for (sal_uInt16 i=0 ; i < nMaxCriteria ; i++)
811*cdf0e10cSrcweir 			{
812*cdf0e10cSrcweir 				aHavingStr = aWhereStr = ::rtl::OUString();
813*cdf0e10cSrcweir 
814*cdf0e10cSrcweir 				for(aIter = _rFieldList.begin();aIter != aEnd;++aIter)
815*cdf0e10cSrcweir 				{
816*cdf0e10cSrcweir 					OTableFieldDescRef	pEntryField = *aIter;
817*cdf0e10cSrcweir 					aFieldName = pEntryField->GetField();
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir 					if (!aFieldName.getLength())
820*cdf0e10cSrcweir 						continue;
821*cdf0e10cSrcweir 					aCriteria = pEntryField->GetCriteria( i );
822*cdf0e10cSrcweir 					if ( aCriteria.getLength() )
823*cdf0e10cSrcweir 					{
824*cdf0e10cSrcweir 						// * is not allowed to contain any filter, only when used in combination an aggregate function
825*cdf0e10cSrcweir 						if ( aFieldName.toChar() == '*' && pEntryField->isNoneFunction() )
826*cdf0e10cSrcweir 						{
827*cdf0e10cSrcweir 							// only show the messagebox the first time
828*cdf0e10cSrcweir 							if (!bCritsOnAsterikWarning)
829*cdf0e10cSrcweir 								ErrorBox(_pView, ModuleRes( ERR_QRY_CRITERIA_ON_ASTERISK)).Execute();
830*cdf0e10cSrcweir 							bCritsOnAsterikWarning = sal_True;
831*cdf0e10cSrcweir 							continue;
832*cdf0e10cSrcweir 						}
833*cdf0e10cSrcweir 						aWork = ::rtl::OUString();
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir 						aWork += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 						if ( (pEntryField->GetFunctionType() & (FKT_OTHER|FKT_NUMERIC)) || (aFieldName.toChar() == '*') )
839*cdf0e10cSrcweir 							aWork += aFieldName;
840*cdf0e10cSrcweir 						else
841*cdf0e10cSrcweir 							aWork += ::dbtools::quoteName(aQuote, aFieldName);
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir 						if ( pEntryField->isAggreateFunction() || pEntryField->IsGroupBy() )
844*cdf0e10cSrcweir 						{
845*cdf0e10cSrcweir 							if (!aHavingStr.getLength())			// noch keine Kriterien
846*cdf0e10cSrcweir 								aHavingStr += ::rtl::OUString('(');			// Klammern
847*cdf0e10cSrcweir 							else
848*cdf0e10cSrcweir 								aHavingStr += C_AND;
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir 							if ( pEntryField->isAggreateFunction() )
851*cdf0e10cSrcweir 							{
852*cdf0e10cSrcweir 								OSL_ENSURE(pEntryField->GetFunction().getLength(),"No function name for aggregate given!");
853*cdf0e10cSrcweir 								aHavingStr += pEntryField->GetFunction();
854*cdf0e10cSrcweir 								aHavingStr += ::rtl::OUString('(');			// Klammern
855*cdf0e10cSrcweir 								aHavingStr += aWork;
856*cdf0e10cSrcweir 								aHavingStr += ::rtl::OUString(')');			// Klammern
857*cdf0e10cSrcweir 							}
858*cdf0e10cSrcweir 							else
859*cdf0e10cSrcweir 								aHavingStr += aWork;
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir 							::rtl::OUString aTmp = aCriteria;
862*cdf0e10cSrcweir 							::rtl::OUString aErrorMsg;
863*cdf0e10cSrcweir 							Reference<XPropertySet> xColumn;
864*cdf0e10cSrcweir                             ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
865*cdf0e10cSrcweir 							if (pParseNode.get())
866*cdf0e10cSrcweir 							{
867*cdf0e10cSrcweir 								if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
868*cdf0e10cSrcweir 									pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
869*cdf0e10cSrcweir 								::rtl::OUString sHavingStr = aHavingStr;
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir 								sal_uInt32 nCount = pParseNode->count();
872*cdf0e10cSrcweir 								for( sal_uInt32 node = 1 ; node < nCount ; ++node)
873*cdf0e10cSrcweir 									pParseNode->getChild(node)->parseNodeToStr(	sHavingStr,
874*cdf0e10cSrcweir 																xConnection,
875*cdf0e10cSrcweir 																&rContext,
876*cdf0e10cSrcweir 																sal_False,
877*cdf0e10cSrcweir 																!pEntryField->isOtherFunction());
878*cdf0e10cSrcweir 								aHavingStr = sHavingStr;
879*cdf0e10cSrcweir 							}
880*cdf0e10cSrcweir 							else
881*cdf0e10cSrcweir 								aHavingStr += aCriteria;
882*cdf0e10cSrcweir 						}
883*cdf0e10cSrcweir 						else
884*cdf0e10cSrcweir 						{
885*cdf0e10cSrcweir 							if ( !aWhereStr.getLength() )			// noch keine Kriterien
886*cdf0e10cSrcweir 								aWhereStr += ::rtl::OUString('(');			// Klammern
887*cdf0e10cSrcweir 							else
888*cdf0e10cSrcweir 								aWhereStr += C_AND;
889*cdf0e10cSrcweir 
890*cdf0e10cSrcweir 							aWhereStr += ::rtl::OUString(' ');
891*cdf0e10cSrcweir 							// aCriteria could have some german numbers so I have to be sure here
892*cdf0e10cSrcweir 							::rtl::OUString aTmp = aCriteria;
893*cdf0e10cSrcweir 							::rtl::OUString aErrorMsg;
894*cdf0e10cSrcweir 							Reference<XPropertySet> xColumn;
895*cdf0e10cSrcweir 							::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode( _pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
896*cdf0e10cSrcweir 							if (pParseNode.get())
897*cdf0e10cSrcweir 							{
898*cdf0e10cSrcweir 								if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
899*cdf0e10cSrcweir 									pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
900*cdf0e10cSrcweir 								::rtl::OUString aWhere = aWhereStr;
901*cdf0e10cSrcweir 								pParseNode->parseNodeToStr(	aWhere,
902*cdf0e10cSrcweir 															xConnection,
903*cdf0e10cSrcweir 															&rContext,
904*cdf0e10cSrcweir 															sal_False,
905*cdf0e10cSrcweir 															!pEntryField->isOtherFunction() );
906*cdf0e10cSrcweir 								aWhereStr = aWhere;
907*cdf0e10cSrcweir 							}
908*cdf0e10cSrcweir 							else
909*cdf0e10cSrcweir 							{
910*cdf0e10cSrcweir 								aWhereStr += aWork;
911*cdf0e10cSrcweir 								aWhereStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
912*cdf0e10cSrcweir 								aWhereStr += aCriteria;
913*cdf0e10cSrcweir 							}
914*cdf0e10cSrcweir 						}
915*cdf0e10cSrcweir 					}
916*cdf0e10cSrcweir 					// nur einmal f�r jedes Feld
917*cdf0e10cSrcweir 					else if ( !i && pEntryField->isCondition() )
918*cdf0e10cSrcweir 					{
919*cdf0e10cSrcweir 						if (!aWhereStr.getLength())			// noch keine Kriterien
920*cdf0e10cSrcweir 							aWhereStr += ::rtl::OUString('(');			// Klammern
921*cdf0e10cSrcweir 						else
922*cdf0e10cSrcweir 							aWhereStr += C_AND;
923*cdf0e10cSrcweir 						aWhereStr += pEntryField->GetField();
924*cdf0e10cSrcweir 					}
925*cdf0e10cSrcweir 				}
926*cdf0e10cSrcweir 				if (aWhereStr.getLength())
927*cdf0e10cSrcweir 				{
928*cdf0e10cSrcweir 					aWhereStr += ::rtl::OUString(')');						// Klammern zu fuer 'AND' Zweig
929*cdf0e10cSrcweir 					if (rRetStr.getLength())							// schon Feldbedingungen ?
930*cdf0e10cSrcweir 						rRetStr.append(C_OR);
931*cdf0e10cSrcweir 					else										// Klammern auf fuer 'OR' Zweig
932*cdf0e10cSrcweir 						rRetStr.append(sal_Unicode('('));
933*cdf0e10cSrcweir 					rRetStr.append(aWhereStr);
934*cdf0e10cSrcweir 				}
935*cdf0e10cSrcweir 				if (aHavingStr.getLength())
936*cdf0e10cSrcweir 				{
937*cdf0e10cSrcweir 					aHavingStr += ::rtl::OUString(')');						// Klammern zu fuer 'AND' Zweig
938*cdf0e10cSrcweir 					if (rHavingStr.getLength())							// schon Feldbedingungen ?
939*cdf0e10cSrcweir 						rHavingStr.append(C_OR);
940*cdf0e10cSrcweir 					else										// Klammern auf fuer 'OR' Zweig
941*cdf0e10cSrcweir 						rHavingStr.append(sal_Unicode('('));
942*cdf0e10cSrcweir 					rHavingStr.append(aHavingStr);
943*cdf0e10cSrcweir 				}
944*cdf0e10cSrcweir 			}
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir 			if (rRetStr.getLength())
947*cdf0e10cSrcweir 				rRetStr.append(sal_Unicode(')'));								// Klammern zu fuer 'OR' Zweig
948*cdf0e10cSrcweir 			if (rHavingStr.getLength())
949*cdf0e10cSrcweir 				rHavingStr.append(sal_Unicode(')'));								// Klammern zu fuer 'OR' Zweig
950*cdf0e10cSrcweir 		}
951*cdf0e10cSrcweir 		catch(SQLException&)
952*cdf0e10cSrcweir 		{
953*cdf0e10cSrcweir 			OSL_ASSERT(!"Failure while building where clause!");
954*cdf0e10cSrcweir 		}
955*cdf0e10cSrcweir 		return sal_True;
956*cdf0e10cSrcweir 	}
957*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
958*cdf0e10cSrcweir 	SqlParseError GenerateOrder(	OQueryDesignView* _pView,
959*cdf0e10cSrcweir 									OTableFields& _rFieldList,
960*cdf0e10cSrcweir 									sal_Bool bMulti,
961*cdf0e10cSrcweir 									::rtl::OUString& _rsRet)
962*cdf0e10cSrcweir 	{
963*cdf0e10cSrcweir         const OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
964*cdf0e10cSrcweir 		Reference< XConnection> xConnection = rController.getConnection();
965*cdf0e10cSrcweir 		if ( !xConnection.is() )
966*cdf0e10cSrcweir 			return eNoConnection;
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir 		::rtl::OUString aColumnName;
971*cdf0e10cSrcweir 		::rtl::OUString aWorkStr;
972*cdf0e10cSrcweir 		try
973*cdf0e10cSrcweir 		{
974*cdf0e10cSrcweir             const bool bColumnAliasInOrderBy = rController.getSdbMetaData().supportsColumnAliasInOrderBy();
975*cdf0e10cSrcweir 			Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
976*cdf0e10cSrcweir 			::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
977*cdf0e10cSrcweir 			// * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
978*cdf0e10cSrcweir 			sal_Bool bCritsOnAsterikWarning = sal_False;		// ** TMFS **
979*cdf0e10cSrcweir 			OTableFields::iterator aIter = _rFieldList.begin();
980*cdf0e10cSrcweir 			OTableFields::iterator aEnd = _rFieldList.end();
981*cdf0e10cSrcweir 		    for(;aIter != aEnd;++aIter)
982*cdf0e10cSrcweir 			{
983*cdf0e10cSrcweir 				OTableFieldDescRef	pEntryField = *aIter;
984*cdf0e10cSrcweir 				EOrderDir eOrder = pEntryField->GetOrderDir();
985*cdf0e10cSrcweir 
986*cdf0e10cSrcweir 				// nur wenn eine Sortierung und ein Tabellenname vorhanden ist-> erzeugen
987*cdf0e10cSrcweir 				// sonst werden die Expressions vom Order By im GenerateCriteria mit erzeugt
988*cdf0e10cSrcweir 				if ( eOrder != ORDER_NONE )
989*cdf0e10cSrcweir 				{
990*cdf0e10cSrcweir 					aColumnName = pEntryField->GetField();
991*cdf0e10cSrcweir 					if(aColumnName.toChar() == '*')
992*cdf0e10cSrcweir 					{
993*cdf0e10cSrcweir 						// die entsprechende MessageBox nur beim ersten mal anzeigen
994*cdf0e10cSrcweir 						if (!bCritsOnAsterikWarning)
995*cdf0e10cSrcweir 							ErrorBox(_pView, ModuleRes( ERR_QRY_ORDERBY_ON_ASTERISK)).Execute();
996*cdf0e10cSrcweir 						bCritsOnAsterikWarning = sal_True;
997*cdf0e10cSrcweir 						continue;
998*cdf0e10cSrcweir 					}
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir 					if ( bColumnAliasInOrderBy && pEntryField->GetFieldAlias().getLength() )
1001*cdf0e10cSrcweir 					{
1002*cdf0e10cSrcweir 						aWorkStr += ::dbtools::quoteName(aQuote, pEntryField->GetFieldAlias());
1003*cdf0e10cSrcweir 					}
1004*cdf0e10cSrcweir 					else if ( pEntryField->isNumericOrAggreateFunction() )
1005*cdf0e10cSrcweir 					{
1006*cdf0e10cSrcweir 						DBG_ASSERT(pEntryField->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
1007*cdf0e10cSrcweir 						aWorkStr += pEntryField->GetFunction();
1008*cdf0e10cSrcweir 						aWorkStr +=  ::rtl::OUString('(');
1009*cdf0e10cSrcweir 						aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
1010*cdf0e10cSrcweir 						// only quote column name when we don't have a numeric
1011*cdf0e10cSrcweir 						if ( pEntryField->isNumeric() )
1012*cdf0e10cSrcweir 							aWorkStr += aColumnName;
1013*cdf0e10cSrcweir 						else
1014*cdf0e10cSrcweir 							aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 						aWorkStr +=  ::rtl::OUString(')');
1017*cdf0e10cSrcweir 					}
1018*cdf0e10cSrcweir                     else if ( pEntryField->isOtherFunction() )
1019*cdf0e10cSrcweir                     {
1020*cdf0e10cSrcweir                         aWorkStr += aColumnName;
1021*cdf0e10cSrcweir                     }
1022*cdf0e10cSrcweir 					else
1023*cdf0e10cSrcweir 					{
1024*cdf0e10cSrcweir 						aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
1025*cdf0e10cSrcweir 						aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
1026*cdf0e10cSrcweir 					}
1027*cdf0e10cSrcweir 					aWorkStr += ::rtl::OUString(' ');
1028*cdf0e10cSrcweir 					aWorkStr += String::CreateFromAscii( ";ASC;DESC" ).GetToken( (sal_uInt16)eOrder );
1029*cdf0e10cSrcweir 					aWorkStr += ::rtl::OUString(',');
1030*cdf0e10cSrcweir 				}
1031*cdf0e10cSrcweir 			}
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir 			{
1034*cdf0e10cSrcweir 				String sTemp(aWorkStr);
1035*cdf0e10cSrcweir 				sTemp.EraseTrailingChars( ',' );
1036*cdf0e10cSrcweir 				aWorkStr = sTemp;
1037*cdf0e10cSrcweir 			}
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir 			if ( aWorkStr.getLength() )
1040*cdf0e10cSrcweir 			{
1041*cdf0e10cSrcweir 				const sal_Int32 nMaxOrder = xMetaData->getMaxColumnsInOrderBy();
1042*cdf0e10cSrcweir 				String sToken(aWorkStr);
1043*cdf0e10cSrcweir 				if ( nMaxOrder && nMaxOrder < sToken.GetTokenCount(',') )
1044*cdf0e10cSrcweir 					eErrorCode = eStatementTooLong;
1045*cdf0e10cSrcweir 				else
1046*cdf0e10cSrcweir 				{
1047*cdf0e10cSrcweir 					_rsRet = ::rtl::OUString::createFromAscii(" ORDER BY ");
1048*cdf0e10cSrcweir 					_rsRet += aWorkStr;
1049*cdf0e10cSrcweir 				}
1050*cdf0e10cSrcweir 			}
1051*cdf0e10cSrcweir 		}
1052*cdf0e10cSrcweir 		catch(SQLException&)
1053*cdf0e10cSrcweir 		{
1054*cdf0e10cSrcweir 			OSL_ASSERT(!"Failure while building group by!");
1055*cdf0e10cSrcweir 		}
1056*cdf0e10cSrcweir 
1057*cdf0e10cSrcweir 		return eErrorCode;
1058*cdf0e10cSrcweir 	}
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1061*cdf0e10cSrcweir 	void GenerateInnerJoinCriterias(const Reference< XConnection>& _xConnection,
1062*cdf0e10cSrcweir 									::rtl::OUString& _rJoinCrit,
1063*cdf0e10cSrcweir 									const ::std::vector<OTableConnection*>* _pConnList)
1064*cdf0e10cSrcweir 	{
1065*cdf0e10cSrcweir 		::std::vector<OTableConnection*>::const_iterator aIter = _pConnList->begin();
1066*cdf0e10cSrcweir         ::std::vector<OTableConnection*>::const_iterator aEnd = _pConnList->end();
1067*cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
1068*cdf0e10cSrcweir 		{
1069*cdf0e10cSrcweir 			const OQueryTableConnection* pEntryConn = static_cast<const OQueryTableConnection*>(*aIter);
1070*cdf0e10cSrcweir 			OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
1071*cdf0e10cSrcweir             if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
1072*cdf0e10cSrcweir 			{
1073*cdf0e10cSrcweir 				if(_rJoinCrit.getLength())
1074*cdf0e10cSrcweir 					_rJoinCrit += C_AND;
1075*cdf0e10cSrcweir 				_rJoinCrit += BuildJoinCriteria(_xConnection,pEntryConnData->GetConnLineDataList(),pEntryConnData);
1076*cdf0e10cSrcweir 			}
1077*cdf0e10cSrcweir 		}
1078*cdf0e10cSrcweir 	}
1079*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1080*cdf0e10cSrcweir 	void searchAndAppendName(const Reference< XConnection>& _xConnection,
1081*cdf0e10cSrcweir 							 const OQueryTableWindow* _pTableWindow,
1082*cdf0e10cSrcweir 							 ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess>& _rTableNames,
1083*cdf0e10cSrcweir 							 ::rtl::OUString& _rsTableListStr
1084*cdf0e10cSrcweir 							 )
1085*cdf0e10cSrcweir 	{
1086*cdf0e10cSrcweir 		::rtl::OUString sTabName(BuildTable(_xConnection,_pTableWindow));
1087*cdf0e10cSrcweir 
1088*cdf0e10cSrcweir 		if(_rTableNames.find(sTabName) == _rTableNames.end())
1089*cdf0e10cSrcweir 		{
1090*cdf0e10cSrcweir 			_rTableNames[sTabName] = sal_True;
1091*cdf0e10cSrcweir 			_rsTableListStr += sTabName;
1092*cdf0e10cSrcweir 			_rsTableListStr += ::rtl::OUString(',');
1093*cdf0e10cSrcweir 		}
1094*cdf0e10cSrcweir 	}
1095*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1096*cdf0e10cSrcweir 	::rtl::OUString GenerateFromClause(	const Reference< XConnection>& _xConnection,
1097*cdf0e10cSrcweir 										const OQueryTableView::OTableWindowMap*	pTabList,
1098*cdf0e10cSrcweir 										const ::std::vector<OTableConnection*>*	pConnList
1099*cdf0e10cSrcweir 										)
1100*cdf0e10cSrcweir 	{
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir 		::rtl::OUString aTableListStr;
1103*cdf0e10cSrcweir 		// wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt
1104*cdf0e10cSrcweir 		::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames;
1105*cdf0e10cSrcweir 
1106*cdf0e10cSrcweir 		// generate outer join clause in from
1107*cdf0e10cSrcweir 		if(!pConnList->empty())
1108*cdf0e10cSrcweir 		{
1109*cdf0e10cSrcweir 			::std::vector<OTableConnection*>::const_iterator aIter = pConnList->begin();
1110*cdf0e10cSrcweir             ::std::vector<OTableConnection*>::const_iterator aEnd = pConnList->end();
1111*cdf0e10cSrcweir             ::std::map<OTableWindow*,sal_Int32> aConnectionCount;
1112*cdf0e10cSrcweir 			for(;aIter != aEnd;++aIter)
1113*cdf0e10cSrcweir             {
1114*cdf0e10cSrcweir 				static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False);
1115*cdf0e10cSrcweir                 if ( aConnectionCount.find((*aIter)->GetSourceWin()) == aConnectionCount.end() )
1116*cdf0e10cSrcweir                     aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetSourceWin(),0));
1117*cdf0e10cSrcweir                 else
1118*cdf0e10cSrcweir                     aConnectionCount[(*aIter)->GetSourceWin()]++;
1119*cdf0e10cSrcweir                 if ( aConnectionCount.find((*aIter)->GetDestWin()) == aConnectionCount.end() )
1120*cdf0e10cSrcweir                     aConnectionCount.insert(::std::map<OTableWindow*,sal_Int32>::value_type((*aIter)->GetDestWin(),0));
1121*cdf0e10cSrcweir                 else
1122*cdf0e10cSrcweir                     aConnectionCount[(*aIter)->GetDestWin()]++;
1123*cdf0e10cSrcweir             }
1124*cdf0e10cSrcweir             ::std::multimap<sal_Int32 , OTableWindow*> aMulti;
1125*cdf0e10cSrcweir             ::std::map<OTableWindow*,sal_Int32>::iterator aCountIter = aConnectionCount.begin();
1126*cdf0e10cSrcweir             ::std::map<OTableWindow*,sal_Int32>::iterator aCountEnd = aConnectionCount.end();
1127*cdf0e10cSrcweir             for(;aCountIter != aCountEnd;++aCountIter)
1128*cdf0e10cSrcweir             {
1129*cdf0e10cSrcweir                 aMulti.insert(::std::multimap<sal_Int32 , OTableWindow*>::value_type(aCountIter->second,aCountIter->first));
1130*cdf0e10cSrcweir             }
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir             const sal_Bool bUseEscape = ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_OUTERJOINESCAPE );
1133*cdf0e10cSrcweir             ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aRIter = aMulti.rbegin();
1134*cdf0e10cSrcweir             ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aREnd = aMulti.rend();
1135*cdf0e10cSrcweir             for(;aRIter != aREnd;++aRIter)
1136*cdf0e10cSrcweir             {
1137*cdf0e10cSrcweir                 ::std::vector<OTableConnection*>::const_iterator aConIter = aRIter->second->getTableView()->getTableConnections(aRIter->second);
1138*cdf0e10cSrcweir                 for(;aConIter != aEnd;++aConIter)
1139*cdf0e10cSrcweir                 {
1140*cdf0e10cSrcweir                     OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aConIter);
1141*cdf0e10cSrcweir 				    if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() == aRIter->second )
1142*cdf0e10cSrcweir 				    {
1143*cdf0e10cSrcweir 					    ::rtl::OUString aJoin;
1144*cdf0e10cSrcweir 					    GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin);
1145*cdf0e10cSrcweir 
1146*cdf0e10cSrcweir 					    if(aJoin.getLength())
1147*cdf0e10cSrcweir 					    {
1148*cdf0e10cSrcweir 						    // insert tables into table list to avoid double entries
1149*cdf0e10cSrcweir 						    OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
1150*cdf0e10cSrcweir 						    OQueryTableWindow* pEntryTabTo = static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin());
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir 						    ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom));
1153*cdf0e10cSrcweir 						    if(aTableNames.find(sTabName) == aTableNames.end())
1154*cdf0e10cSrcweir 							    aTableNames[sTabName] = sal_True;
1155*cdf0e10cSrcweir 						    sTabName = BuildTable(_xConnection,pEntryTabTo);
1156*cdf0e10cSrcweir 						    if(aTableNames.find(sTabName) == aTableNames.end())
1157*cdf0e10cSrcweir 							    aTableNames[sTabName] = sal_True;
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir                             ::rtl::OUString aStr;
1160*cdf0e10cSrcweir                             switch(static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType())
1161*cdf0e10cSrcweir 		                    {
1162*cdf0e10cSrcweir 			                    case LEFT_JOIN:
1163*cdf0e10cSrcweir 			                    case RIGHT_JOIN:
1164*cdf0e10cSrcweir                                 case FULL_JOIN:
1165*cdf0e10cSrcweir                                     {
1166*cdf0e10cSrcweir 						                // create outer join
1167*cdf0e10cSrcweir 						                if ( bUseEscape )
1168*cdf0e10cSrcweir 							                aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("{ OJ "));
1169*cdf0e10cSrcweir 						                aStr += aJoin;
1170*cdf0e10cSrcweir 						                if ( bUseEscape )
1171*cdf0e10cSrcweir 							                aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" }"));
1172*cdf0e10cSrcweir                                     }
1173*cdf0e10cSrcweir                                     break;
1174*cdf0e10cSrcweir                                 default:
1175*cdf0e10cSrcweir                                     aStr += aJoin;
1176*cdf0e10cSrcweir                                     break;
1177*cdf0e10cSrcweir                             }
1178*cdf0e10cSrcweir 						    aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
1179*cdf0e10cSrcweir 						    aTableListStr += aStr;
1180*cdf0e10cSrcweir 					    }
1181*cdf0e10cSrcweir 				    }
1182*cdf0e10cSrcweir 			    }
1183*cdf0e10cSrcweir             }
1184*cdf0e10cSrcweir 
1185*cdf0e10cSrcweir 			// and now all inner joins
1186*cdf0e10cSrcweir 			aIter = pConnList->begin();
1187*cdf0e10cSrcweir 			for(;aIter != aEnd;++aIter)
1188*cdf0e10cSrcweir 			{
1189*cdf0e10cSrcweir 				OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter);
1190*cdf0e10cSrcweir 				if(!pEntryConn->IsVisited())
1191*cdf0e10cSrcweir 				{
1192*cdf0e10cSrcweir 					searchAndAppendName(_xConnection,
1193*cdf0e10cSrcweir 										static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()),
1194*cdf0e10cSrcweir 										aTableNames,
1195*cdf0e10cSrcweir 										aTableListStr);
1196*cdf0e10cSrcweir 
1197*cdf0e10cSrcweir 					searchAndAppendName(_xConnection,
1198*cdf0e10cSrcweir 										static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),
1199*cdf0e10cSrcweir 										aTableNames,
1200*cdf0e10cSrcweir 										aTableListStr);
1201*cdf0e10cSrcweir 				}
1202*cdf0e10cSrcweir 			}
1203*cdf0e10cSrcweir 		}
1204*cdf0e10cSrcweir 		// all tables that haven't a connection to anyone
1205*cdf0e10cSrcweir 		OQueryTableView::OTableWindowMap::const_iterator aTabIter = pTabList->begin();
1206*cdf0e10cSrcweir         OQueryTableView::OTableWindowMap::const_iterator aTabEnd = pTabList->end();
1207*cdf0e10cSrcweir 		for(;aTabIter != aTabEnd;++aTabIter)
1208*cdf0e10cSrcweir 		{
1209*cdf0e10cSrcweir 			const OQueryTableWindow* pEntryTab = static_cast<const OQueryTableWindow*>(aTabIter->second);
1210*cdf0e10cSrcweir 			if(!pEntryTab->ExistsAConn())
1211*cdf0e10cSrcweir 			{
1212*cdf0e10cSrcweir 				aTableListStr += BuildTable(_xConnection,pEntryTab);
1213*cdf0e10cSrcweir 				aTableListStr += ::rtl::OUString(',');
1214*cdf0e10cSrcweir 			}
1215*cdf0e10cSrcweir 		}
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir 		if(aTableListStr.getLength())
1218*cdf0e10cSrcweir 			aTableListStr = aTableListStr.replaceAt(aTableListStr.getLength()-1,1, ::rtl::OUString() );
1219*cdf0e10cSrcweir 		return aTableListStr;
1220*cdf0e10cSrcweir 	}
1221*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1222*cdf0e10cSrcweir 	::rtl::OUString GenerateGroupBy(const OQueryDesignView* _pView,OTableFields& _rFieldList, sal_Bool bMulti )
1223*cdf0e10cSrcweir 	{
1224*cdf0e10cSrcweir         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
1225*cdf0e10cSrcweir 		const Reference< XConnection> xConnection = rController.getConnection();
1226*cdf0e10cSrcweir 		if(!xConnection.is())
1227*cdf0e10cSrcweir 			return ::rtl::OUString();
1228*cdf0e10cSrcweir 
1229*cdf0e10cSrcweir         ::std::map< rtl::OUString,bool> aGroupByNames;
1230*cdf0e10cSrcweir 
1231*cdf0e10cSrcweir 		::rtl::OUString aGroupByStr;
1232*cdf0e10cSrcweir 		try
1233*cdf0e10cSrcweir 		{
1234*cdf0e10cSrcweir 			const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
1235*cdf0e10cSrcweir 			const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir 			OTableFields::iterator aIter = _rFieldList.begin();
1238*cdf0e10cSrcweir 			OTableFields::iterator aEnd = _rFieldList.end();
1239*cdf0e10cSrcweir 		    for(;aIter != aEnd;++aIter)
1240*cdf0e10cSrcweir 			{
1241*cdf0e10cSrcweir 				OTableFieldDescRef	pEntryField = *aIter;
1242*cdf0e10cSrcweir 				if ( pEntryField->IsGroupBy() )
1243*cdf0e10cSrcweir 				{
1244*cdf0e10cSrcweir 					DBG_ASSERT(pEntryField->GetField().getLength(),"Kein FieldName vorhanden!;-(");
1245*cdf0e10cSrcweir 					::rtl::OUString sGroupByPart = quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir 					// only quote the field name when it isn't calculated
1248*cdf0e10cSrcweir 					if ( pEntryField->isNoneFunction() )
1249*cdf0e10cSrcweir                     {
1250*cdf0e10cSrcweir 						sGroupByPart += ::dbtools::quoteName(aQuote, pEntryField->GetField());
1251*cdf0e10cSrcweir                     }
1252*cdf0e10cSrcweir 					else
1253*cdf0e10cSrcweir                     {
1254*cdf0e10cSrcweir                         ::rtl::OUString aTmp = pEntryField->GetField();
1255*cdf0e10cSrcweir 						::rtl::OUString aErrorMsg;
1256*cdf0e10cSrcweir 						Reference<XPropertySet> xColumn;
1257*cdf0e10cSrcweir                         ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
1258*cdf0e10cSrcweir 						if (pParseNode.get())
1259*cdf0e10cSrcweir 						{
1260*cdf0e10cSrcweir 							::rtl::OUString sGroupBy;
1261*cdf0e10cSrcweir 							pParseNode->getChild(0)->parseNodeToStr(	sGroupBy,
1262*cdf0e10cSrcweir 														xConnection,
1263*cdf0e10cSrcweir 														&rController.getParser().getContext(),
1264*cdf0e10cSrcweir 														sal_False,
1265*cdf0e10cSrcweir 														!pEntryField->isOtherFunction());
1266*cdf0e10cSrcweir 							sGroupByPart += sGroupBy;
1267*cdf0e10cSrcweir 						}
1268*cdf0e10cSrcweir 						else
1269*cdf0e10cSrcweir 							sGroupByPart += pEntryField->GetField();
1270*cdf0e10cSrcweir                     }
1271*cdf0e10cSrcweir                     if ( aGroupByNames.find(sGroupByPart) == aGroupByNames.end() )
1272*cdf0e10cSrcweir                     {
1273*cdf0e10cSrcweir                         aGroupByNames.insert(::std::map< rtl::OUString,bool>::value_type(sGroupByPart,true));
1274*cdf0e10cSrcweir                         aGroupByStr += sGroupByPart;
1275*cdf0e10cSrcweir 					    aGroupByStr += ::rtl::OUString(',');
1276*cdf0e10cSrcweir                     }
1277*cdf0e10cSrcweir 				}
1278*cdf0e10cSrcweir 			}
1279*cdf0e10cSrcweir 			if ( aGroupByStr.getLength() )
1280*cdf0e10cSrcweir 			{
1281*cdf0e10cSrcweir 				aGroupByStr = aGroupByStr.replaceAt(aGroupByStr.getLength()-1,1, ::rtl::OUString(' ') );
1282*cdf0e10cSrcweir 				::rtl::OUString aGroupByStr2 = ::rtl::OUString::createFromAscii(" GROUP BY ");
1283*cdf0e10cSrcweir 				aGroupByStr2 += aGroupByStr;
1284*cdf0e10cSrcweir 				aGroupByStr = aGroupByStr2;
1285*cdf0e10cSrcweir 			}
1286*cdf0e10cSrcweir 		}
1287*cdf0e10cSrcweir 		catch(SQLException&)
1288*cdf0e10cSrcweir 		{
1289*cdf0e10cSrcweir 			OSL_ASSERT(!"Failure while building group by!");
1290*cdf0e10cSrcweir 		}
1291*cdf0e10cSrcweir 		return aGroupByStr;
1292*cdf0e10cSrcweir 	}
1293*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
1294*cdf0e10cSrcweir 	SqlParseError GetORCriteria(OQueryDesignView* _pView,
1295*cdf0e10cSrcweir 								OSelectionBrowseBox* _pSelectionBrw,
1296*cdf0e10cSrcweir 								const ::connectivity::OSQLParseNode * pCondition,
1297*cdf0e10cSrcweir 								sal_uInt16& nLevel ,
1298*cdf0e10cSrcweir 								sal_Bool bHaving = sal_False,
1299*cdf0e10cSrcweir                                 bool bAddOrOnOneLine = false);
1300*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
1301*cdf0e10cSrcweir 	SqlParseError GetSelectionCriteria(	OQueryDesignView* _pView,
1302*cdf0e10cSrcweir 										OSelectionBrowseBox* _pSelectionBrw,
1303*cdf0e10cSrcweir 										const ::connectivity::OSQLParseNode* pNode,
1304*cdf0e10cSrcweir 										sal_uInt16& rLevel )
1305*cdf0e10cSrcweir 	{
1306*cdf0e10cSrcweir 		if (!SQL_ISRULE(pNode, select_statement))
1307*cdf0e10cSrcweir 			return eNoSelectStatement;
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir 		// nyi: mehr Pruefung auf korrekte Struktur!
1310*cdf0e10cSrcweir 		pNode = pNode ? pNode->getChild(3)->getChild(1) : NULL;
1311*cdf0e10cSrcweir 		// no where clause found
1312*cdf0e10cSrcweir 		if (!pNode || pNode->isLeaf())
1313*cdf0e10cSrcweir 			return eOk;
1314*cdf0e10cSrcweir 
1315*cdf0e10cSrcweir 		// Naechster freier Satz ...
1316*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
1317*cdf0e10cSrcweir 		::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
1318*cdf0e10cSrcweir 		if ( pCondition ) // no where clause
1319*cdf0e10cSrcweir 		{
1320*cdf0e10cSrcweir 			// now we have to chech the other conditions
1321*cdf0e10cSrcweir 			// first make the logical easier
1322*cdf0e10cSrcweir 			::connectivity::OSQLParseNode::negateSearchCondition(pCondition);
1323*cdf0e10cSrcweir 			::connectivity::OSQLParseNode *pNodeTmp = pNode->getChild(1);
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir 			::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp);
1326*cdf0e10cSrcweir 			pNodeTmp = pNode->getChild(1);
1327*cdf0e10cSrcweir 			::connectivity::OSQLParseNode::absorptions(pNodeTmp);
1328*cdf0e10cSrcweir 			pNodeTmp = pNode->getChild(1);
1329*cdf0e10cSrcweir             // compress sort the criteria @see http://www.openoffice.org/issues/show_bug.cgi?id=24079
1330*cdf0e10cSrcweir             OSQLParseNode::compress(pNodeTmp);
1331*cdf0e10cSrcweir             pNodeTmp = pNode->getChild(1);
1332*cdf0e10cSrcweir 
1333*cdf0e10cSrcweir 			// first extract the inner joins conditions
1334*cdf0e10cSrcweir 			GetInnerJoinCriteria(_pView,pNodeTmp);
1335*cdf0e10cSrcweir 			// now simplify again, join are checked in ComparisonPredicate
1336*cdf0e10cSrcweir 			::connectivity::OSQLParseNode::absorptions(pNodeTmp);
1337*cdf0e10cSrcweir 			pNodeTmp = pNode->getChild(1);
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir 			// it could happen that pCondition is not more valid
1340*cdf0e10cSrcweir 			eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pNodeTmp, rLevel);
1341*cdf0e10cSrcweir 		}
1342*cdf0e10cSrcweir 		return eErrorCode;
1343*cdf0e10cSrcweir 	}
1344*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1345*cdf0e10cSrcweir 	SqlParseError GetANDCriteria(	OQueryDesignView* _pView,
1346*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
1347*cdf0e10cSrcweir 									const  ::connectivity::OSQLParseNode * pCondition,
1348*cdf0e10cSrcweir 									sal_uInt16& nLevel,
1349*cdf0e10cSrcweir 									sal_Bool bHaving,
1350*cdf0e10cSrcweir                                     bool bAddOrOnOneLine);
1351*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1352*cdf0e10cSrcweir 	SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
1353*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
1354*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode * pCondition,
1355*cdf0e10cSrcweir 							const sal_uInt16 nLevel,
1356*cdf0e10cSrcweir 							sal_Bool bHaving,
1357*cdf0e10cSrcweir                             bool bAddOrOnOneLine);
1358*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1359*cdf0e10cSrcweir 	SqlParseError GetORCriteria(OQueryDesignView* _pView,
1360*cdf0e10cSrcweir 								OSelectionBrowseBox* _pSelectionBrw,
1361*cdf0e10cSrcweir 								const ::connectivity::OSQLParseNode * pCondition,
1362*cdf0e10cSrcweir 								sal_uInt16& nLevel ,
1363*cdf0e10cSrcweir 								sal_Bool bHaving,
1364*cdf0e10cSrcweir                                 bool bAddOrOnOneLine)
1365*cdf0e10cSrcweir 	{
1366*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
1367*cdf0e10cSrcweir 
1368*cdf0e10cSrcweir 		// Runde Klammern um den Ausdruck
1369*cdf0e10cSrcweir 		if (pCondition->count() == 3 &&
1370*cdf0e10cSrcweir 			SQL_ISPUNCTUATION(pCondition->getChild(0),"(") &&
1371*cdf0e10cSrcweir 			SQL_ISPUNCTUATION(pCondition->getChild(2),")"))
1372*cdf0e10cSrcweir 		{
1373*cdf0e10cSrcweir 			eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(1),nLevel,bHaving,bAddOrOnOneLine);
1374*cdf0e10cSrcweir 		}
1375*cdf0e10cSrcweir 		// oder Verknuepfung
1376*cdf0e10cSrcweir 		// a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term
1377*cdf0e10cSrcweir 		else if (SQL_ISRULE(pCondition,search_condition))
1378*cdf0e10cSrcweir 		{
1379*cdf0e10cSrcweir 			for (int i = 0; i < 3 && eErrorCode == eOk ; i+=2)
1380*cdf0e10cSrcweir 			{
1381*cdf0e10cSrcweir                 const  ::connectivity::OSQLParseNode* pChild = pCondition->getChild(i);
1382*cdf0e10cSrcweir 				if ( SQL_ISRULE(pChild,search_condition) )
1383*cdf0e10cSrcweir 					eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pChild,nLevel,bHaving,bAddOrOnOneLine);
1384*cdf0e10cSrcweir 				else
1385*cdf0e10cSrcweir 				{
1386*cdf0e10cSrcweir                     eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pChild, nLevel,bHaving, i == 0 ? false : bAddOrOnOneLine);
1387*cdf0e10cSrcweir 					if ( !bAddOrOnOneLine)
1388*cdf0e10cSrcweir 						nLevel++;
1389*cdf0e10cSrcweir 				}
1390*cdf0e10cSrcweir 			}
1391*cdf0e10cSrcweir 		}
1392*cdf0e10cSrcweir 		else
1393*cdf0e10cSrcweir 			eErrorCode = GetANDCriteria( _pView,_pSelectionBrw,pCondition, nLevel, bHaving,bAddOrOnOneLine );
1394*cdf0e10cSrcweir 
1395*cdf0e10cSrcweir 		return eErrorCode;
1396*cdf0e10cSrcweir 	}
1397*cdf0e10cSrcweir     //--------------------------------------------------------------------------------------------------
1398*cdf0e10cSrcweir     bool CheckOrCriteria(const ::connectivity::OSQLParseNode* _pCondition,::connectivity::OSQLParseNode* _pFirstColumnRef)
1399*cdf0e10cSrcweir     {
1400*cdf0e10cSrcweir         bool bRet = true;
1401*cdf0e10cSrcweir         ::connectivity::OSQLParseNode* pFirstColumnRef = _pFirstColumnRef;
1402*cdf0e10cSrcweir         for (int i = 0; i < 3 && bRet; i+=2)
1403*cdf0e10cSrcweir 		{
1404*cdf0e10cSrcweir             const  ::connectivity::OSQLParseNode* pChild = _pCondition->getChild(i);
1405*cdf0e10cSrcweir             if ( SQL_ISRULE(pChild,search_condition) )
1406*cdf0e10cSrcweir                 bRet = CheckOrCriteria(pChild,pFirstColumnRef);
1407*cdf0e10cSrcweir             else
1408*cdf0e10cSrcweir             {
1409*cdf0e10cSrcweir                 // this is a simple way to test columns are the same, may be we have to adjust this algo a little bit in future. :-)
1410*cdf0e10cSrcweir                 ::connectivity::OSQLParseNode* pSecondColumnRef = pChild->getByRule(::connectivity::OSQLParseNode::column_ref);
1411*cdf0e10cSrcweir                 if ( pFirstColumnRef && pSecondColumnRef )
1412*cdf0e10cSrcweir                     bRet = *pFirstColumnRef == *pSecondColumnRef;
1413*cdf0e10cSrcweir                 else if ( !pFirstColumnRef )
1414*cdf0e10cSrcweir                     pFirstColumnRef = pSecondColumnRef;
1415*cdf0e10cSrcweir             }
1416*cdf0e10cSrcweir         }
1417*cdf0e10cSrcweir         return bRet;
1418*cdf0e10cSrcweir     }
1419*cdf0e10cSrcweir 	//--------------------------------------------------------------------------------------------------
1420*cdf0e10cSrcweir 	SqlParseError GetANDCriteria(	OQueryDesignView* _pView,
1421*cdf0e10cSrcweir 									OSelectionBrowseBox* _pSelectionBrw,
1422*cdf0e10cSrcweir 									const  ::connectivity::OSQLParseNode * pCondition,
1423*cdf0e10cSrcweir 									sal_uInt16& nLevel,
1424*cdf0e10cSrcweir 									sal_Bool bHaving,
1425*cdf0e10cSrcweir                                     bool bAddOrOnOneLine)
1426*cdf0e10cSrcweir 	{
1427*cdf0e10cSrcweir 		const ::com::sun::star::lang::Locale	aLocale = _pView->getLocale();
1428*cdf0e10cSrcweir 		const ::rtl::OUString sDecimal = _pView->getDecimalSeparator();
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 		// ich werde ein paar Mal einen gecasteten Pointer auf meinen ::com::sun::star::sdbcx::Container brauchen
1431*cdf0e10cSrcweir 		OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
1432*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir 		// Runde Klammern
1435*cdf0e10cSrcweir 		if (SQL_ISRULE(pCondition,boolean_primary))
1436*cdf0e10cSrcweir 		{
1437*cdf0e10cSrcweir             // check if we have to put the or criteria on one line.
1438*cdf0e10cSrcweir 			const  ::connectivity::OSQLParseNode* pSearchCondition = pCondition->getChild(1);
1439*cdf0e10cSrcweir             bool bMustAddOrOnOneLine = CheckOrCriteria(pSearchCondition,NULL);
1440*cdf0e10cSrcweir 			if ( SQL_ISRULE( pSearchCondition, search_condition) ) // we have a or
1441*cdf0e10cSrcweir 			{
1442*cdf0e10cSrcweir 				_pSelectionBrw->DuplicateConditionLevel( nLevel);
1443*cdf0e10cSrcweir 				eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(0), nLevel,bHaving,bMustAddOrOnOneLine );
1444*cdf0e10cSrcweir 				++nLevel;
1445*cdf0e10cSrcweir 				eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(2), nLevel,bHaving,bMustAddOrOnOneLine );
1446*cdf0e10cSrcweir 			}
1447*cdf0e10cSrcweir 			else
1448*cdf0e10cSrcweir 				eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition, nLevel,bHaving,bMustAddOrOnOneLine );
1449*cdf0e10cSrcweir 		}
1450*cdf0e10cSrcweir 		// Das erste Element ist (wieder) eine AND-Verknuepfung
1451*cdf0e10cSrcweir 		else if ( SQL_ISRULE(pCondition,boolean_term) )
1452*cdf0e10cSrcweir 		{
1453*cdf0e10cSrcweir             OSL_ENSURE(pCondition->count() == 3,"Illegal definifiton of boolean_term");
1454*cdf0e10cSrcweir 			eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(0), nLevel,bHaving,bAddOrOnOneLine );
1455*cdf0e10cSrcweir 			if ( eErrorCode == eOk )
1456*cdf0e10cSrcweir 				eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(2), nLevel,bHaving,bAddOrOnOneLine );
1457*cdf0e10cSrcweir 		}
1458*cdf0e10cSrcweir 		else if (SQL_ISRULE( pCondition, comparison_predicate))
1459*cdf0e10cSrcweir 		{
1460*cdf0e10cSrcweir 			eErrorCode = ComparisonPredicate(_pView,_pSelectionBrw,pCondition,nLevel,bHaving,bAddOrOnOneLine);
1461*cdf0e10cSrcweir 		}
1462*cdf0e10cSrcweir 		else if( SQL_ISRULE(pCondition,like_predicate) )
1463*cdf0e10cSrcweir 		{
1464*cdf0e10cSrcweir             const  ::connectivity::OSQLParseNode* pValueExp = pCondition->getChild(0);
1465*cdf0e10cSrcweir 			if (SQL_ISRULE(pValueExp, column_ref ) )
1466*cdf0e10cSrcweir 			{
1467*cdf0e10cSrcweir 				::rtl::OUString aColumnName;
1468*cdf0e10cSrcweir 				::rtl::OUString	aCondition;
1469*cdf0e10cSrcweir 				Reference< XConnection> xConnection = rController.getConnection();
1470*cdf0e10cSrcweir 				if ( xConnection.is() )
1471*cdf0e10cSrcweir 				{
1472*cdf0e10cSrcweir 					Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
1473*cdf0e10cSrcweir 					// the international doesn't matter I have a string
1474*cdf0e10cSrcweir 					pCondition->parseNodeToPredicateStr(aCondition,
1475*cdf0e10cSrcweir 														xConnection,
1476*cdf0e10cSrcweir 														rController.getNumberFormatter(),
1477*cdf0e10cSrcweir 														aLocale,
1478*cdf0e10cSrcweir 														static_cast<sal_Char>(sDecimal.toChar()),
1479*cdf0e10cSrcweir 														&rController.getParser().getContext());
1480*cdf0e10cSrcweir 
1481*cdf0e10cSrcweir 					pValueExp->parseNodeToPredicateStr(	aColumnName,
1482*cdf0e10cSrcweir 														xConnection,
1483*cdf0e10cSrcweir 														rController.getNumberFormatter(),
1484*cdf0e10cSrcweir 														aLocale,
1485*cdf0e10cSrcweir 														static_cast<sal_Char>(sDecimal.toChar()),
1486*cdf0e10cSrcweir 														&rController.getParser().getContext());
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir 					// don't display the column name
1489*cdf0e10cSrcweir 					aCondition = aCondition.copy(aColumnName.getLength());
1490*cdf0e10cSrcweir 					aCondition = aCondition.trim();
1491*cdf0e10cSrcweir 				}
1492*cdf0e10cSrcweir 
1493*cdf0e10cSrcweir 				OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1494*cdf0e10cSrcweir 				if ( eOk == ( eErrorCode = FillDragInfo(_pView,pValueExp,aDragLeft) ))
1495*cdf0e10cSrcweir                 {
1496*cdf0e10cSrcweir                     if ( bHaving )
1497*cdf0e10cSrcweir 					    aDragLeft->SetGroupBy(sal_True);
1498*cdf0e10cSrcweir 					_pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
1499*cdf0e10cSrcweir                 }
1500*cdf0e10cSrcweir 			}
1501*cdf0e10cSrcweir             else if(SQL_ISRULEOR2(pValueExp,general_set_fct ,set_fct_spec)	        ||
1502*cdf0e10cSrcweir 							SQL_ISRULEOR2(pValueExp,position_exp,extract_exp)	||
1503*cdf0e10cSrcweir 							SQL_ISRULEOR2(pValueExp,fold,char_substring_fct)	||
1504*cdf0e10cSrcweir 							SQL_ISRULEOR2(pValueExp,length_exp,char_value_fct))
1505*cdf0e10cSrcweir 		    {
1506*cdf0e10cSrcweir 			    AddFunctionCondition(	_pView,
1507*cdf0e10cSrcweir 									    _pSelectionBrw,
1508*cdf0e10cSrcweir 									    pCondition,
1509*cdf0e10cSrcweir 									    nLevel,
1510*cdf0e10cSrcweir 									    bHaving,
1511*cdf0e10cSrcweir                                         bAddOrOnOneLine);
1512*cdf0e10cSrcweir 		    }
1513*cdf0e10cSrcweir 			else
1514*cdf0e10cSrcweir 			{
1515*cdf0e10cSrcweir 				eErrorCode = eNoColumnInLike;
1516*cdf0e10cSrcweir 				String sError(ModuleRes(STR_QRY_LIKE_LEFT_NO_COLUMN));
1517*cdf0e10cSrcweir 				_pView->getController().appendError( sError );
1518*cdf0e10cSrcweir 			}
1519*cdf0e10cSrcweir 		}
1520*cdf0e10cSrcweir 		else if(	SQL_ISRULEOR2(pCondition,test_for_null,in_predicate)
1521*cdf0e10cSrcweir 				||	SQL_ISRULEOR2(pCondition,all_or_any_predicate,between_predicate))
1522*cdf0e10cSrcweir 		{
1523*cdf0e10cSrcweir 			if ( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
1524*cdf0e10cSrcweir 			{
1525*cdf0e10cSrcweir 				AddFunctionCondition(	_pView,
1526*cdf0e10cSrcweir 										_pSelectionBrw,
1527*cdf0e10cSrcweir 										pCondition,
1528*cdf0e10cSrcweir 										nLevel,
1529*cdf0e10cSrcweir 										bHaving,
1530*cdf0e10cSrcweir                                         bAddOrOnOneLine);
1531*cdf0e10cSrcweir 			}
1532*cdf0e10cSrcweir 			else if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) )
1533*cdf0e10cSrcweir 			{
1534*cdf0e10cSrcweir 				// parse condition
1535*cdf0e10cSrcweir 				::rtl::OUString sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
1536*cdf0e10cSrcweir 				OTableFieldDescRef	aDragLeft = new OTableFieldDesc();
1537*cdf0e10cSrcweir 				if ( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) )
1538*cdf0e10cSrcweir                 {
1539*cdf0e10cSrcweir                     if ( bHaving )
1540*cdf0e10cSrcweir 					    aDragLeft->SetGroupBy(sal_True);
1541*cdf0e10cSrcweir 					_pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
1542*cdf0e10cSrcweir                 }
1543*cdf0e10cSrcweir 			}
1544*cdf0e10cSrcweir 			else
1545*cdf0e10cSrcweir 			{
1546*cdf0e10cSrcweir 				// Funktions-Bedingung parsen
1547*cdf0e10cSrcweir 				::rtl::OUString	sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
1548*cdf0e10cSrcweir 				Reference< XConnection> xConnection = rController.getConnection();
1549*cdf0e10cSrcweir 				Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
1550*cdf0e10cSrcweir 					// the international doesn't matter I have a string
1551*cdf0e10cSrcweir 				::rtl::OUString sName;
1552*cdf0e10cSrcweir 				pCondition->getChild(0)->parseNodeToPredicateStr(sName,
1553*cdf0e10cSrcweir 													xConnection,
1554*cdf0e10cSrcweir 													rController.getNumberFormatter(),
1555*cdf0e10cSrcweir 													aLocale,
1556*cdf0e10cSrcweir 													static_cast<sal_Char>(sDecimal.toChar()),
1557*cdf0e10cSrcweir 													&rController.getParser().getContext());
1558*cdf0e10cSrcweir 
1559*cdf0e10cSrcweir 				OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1560*cdf0e10cSrcweir 				aDragLeft->SetField(sName);
1561*cdf0e10cSrcweir 				aDragLeft->SetFunctionType(FKT_OTHER);
1562*cdf0e10cSrcweir 
1563*cdf0e10cSrcweir 				if ( bHaving )
1564*cdf0e10cSrcweir 					aDragLeft->SetGroupBy(sal_True);
1565*cdf0e10cSrcweir 				_pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
1566*cdf0e10cSrcweir 			}
1567*cdf0e10cSrcweir 		}
1568*cdf0e10cSrcweir 		else if( SQL_ISRULEOR2(pCondition,existence_test,unique_test) )
1569*cdf0e10cSrcweir 		{
1570*cdf0e10cSrcweir 			// Funktions-Bedingung parsen
1571*cdf0e10cSrcweir 			::rtl::OUString	aCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,0);
1572*cdf0e10cSrcweir 
1573*cdf0e10cSrcweir 			OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1574*cdf0e10cSrcweir 			aDragLeft->SetField(aCondition);
1575*cdf0e10cSrcweir 			aDragLeft->SetFunctionType(FKT_CONDITION);
1576*cdf0e10cSrcweir 
1577*cdf0e10cSrcweir 			eErrorCode = _pSelectionBrw->InsertField(aDragLeft,BROWSER_INVALIDID,sal_False,sal_True).isValid() ? eOk : eTooManyColumns;
1578*cdf0e10cSrcweir 		}
1579*cdf0e10cSrcweir 		else //! TODO not supported yet
1580*cdf0e10cSrcweir 			eErrorCode = eStatementTooComplex;
1581*cdf0e10cSrcweir 		// Fehler einfach weiterreichen.
1582*cdf0e10cSrcweir 		return eErrorCode;
1583*cdf0e10cSrcweir 	}
1584*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1585*cdf0e10cSrcweir 	SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
1586*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
1587*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode * pCondition,
1588*cdf0e10cSrcweir 							const sal_uInt16 nLevel,
1589*cdf0e10cSrcweir 							sal_Bool bHaving,
1590*cdf0e10cSrcweir                             bool bAddOrOnOneLine)
1591*cdf0e10cSrcweir 	{
1592*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
1593*cdf0e10cSrcweir 		OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
1594*cdf0e10cSrcweir 
1595*cdf0e10cSrcweir         OSQLParseNode* pFunction = pCondition->getChild(0);
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir         OSL_ENSURE(SQL_ISRULEOR2(pFunction,general_set_fct ,set_fct_spec)	        ||
1598*cdf0e10cSrcweir 							SQL_ISRULEOR2(pFunction,position_exp,extract_exp)	||
1599*cdf0e10cSrcweir 							SQL_ISRULEOR2(pFunction,fold,char_substring_fct)	||
1600*cdf0e10cSrcweir 							SQL_ISRULEOR2(pFunction,length_exp,char_value_fct),"Illegal call!");
1601*cdf0e10cSrcweir 		::rtl::OUString	aCondition;
1602*cdf0e10cSrcweir 		OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1603*cdf0e10cSrcweir 
1604*cdf0e10cSrcweir 		::rtl::OUString aColumnName;
1605*cdf0e10cSrcweir 		Reference< XConnection> xConnection = rController.getConnection();
1606*cdf0e10cSrcweir 		if(xConnection.is())
1607*cdf0e10cSrcweir 		{
1608*cdf0e10cSrcweir 			Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
1609*cdf0e10cSrcweir 			pCondition->parseNodeToPredicateStr(aCondition,
1610*cdf0e10cSrcweir 												xConnection,
1611*cdf0e10cSrcweir 												rController.getNumberFormatter(),
1612*cdf0e10cSrcweir 												_pView->getLocale(),
1613*cdf0e10cSrcweir 												static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
1614*cdf0e10cSrcweir 												&rController.getParser().getContext());
1615*cdf0e10cSrcweir 
1616*cdf0e10cSrcweir             pFunction->parseNodeToStr(	aColumnName,
1617*cdf0e10cSrcweir 										xConnection,
1618*cdf0e10cSrcweir 										&rController.getParser().getContext(),
1619*cdf0e10cSrcweir 										sal_True,
1620*cdf0e10cSrcweir 										sal_True); // quote is to true because we need quoted elements inside the function
1621*cdf0e10cSrcweir             // i75557
1622*cdf0e10cSrcweir 			//pFunction->parseNodeToPredicateStr(aColumnName,
1623*cdf0e10cSrcweir 			//									xConnection,
1624*cdf0e10cSrcweir 			//									rController.getNumberFormatter(),
1625*cdf0e10cSrcweir 			//									_pView->getLocale(),
1626*cdf0e10cSrcweir 			//									static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
1627*cdf0e10cSrcweir 			//									&rController.getParser().getContext());
1628*cdf0e10cSrcweir 			// don't display the column name
1629*cdf0e10cSrcweir 			aCondition = aCondition.copy(aColumnName.getLength());
1630*cdf0e10cSrcweir 			aCondition = aCondition.trim();
1631*cdf0e10cSrcweir 			if ( aCondition.indexOf('=',0) == 0 ) // ignore the equal sign
1632*cdf0e10cSrcweir 				aCondition = aCondition.copy(1);
1633*cdf0e10cSrcweir 
1634*cdf0e10cSrcweir 
1635*cdf0e10cSrcweir 			if ( SQL_ISRULE(pFunction, general_set_fct ) )
1636*cdf0e10cSrcweir 			{
1637*cdf0e10cSrcweir 				sal_Int32 nFunctionType = FKT_AGGREGATE;
1638*cdf0e10cSrcweir 				OSQLParseNode* pParamNode = pFunction->getChild(pFunction->count()-2);
1639*cdf0e10cSrcweir 				if ( pParamNode && pParamNode->getTokenValue().toChar() == '*' )
1640*cdf0e10cSrcweir 				{
1641*cdf0e10cSrcweir 					OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
1642*cdf0e10cSrcweir 					OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin();
1643*cdf0e10cSrcweir                     OJoinTableView::OTableWindowMap::iterator aTabEnd = pTabList->end();
1644*cdf0e10cSrcweir 					for(;aIter != aTabEnd;++aIter)
1645*cdf0e10cSrcweir 					{
1646*cdf0e10cSrcweir 						OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
1647*cdf0e10cSrcweir 						if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aDragLeft ))
1648*cdf0e10cSrcweir 						{
1649*cdf0e10cSrcweir 							aDragLeft->SetAlias(String());
1650*cdf0e10cSrcweir 							aDragLeft->SetTable(String());
1651*cdf0e10cSrcweir 							break;
1652*cdf0e10cSrcweir 						}
1653*cdf0e10cSrcweir 					}
1654*cdf0e10cSrcweir 				}
1655*cdf0e10cSrcweir 				else if( eOk != ( eErrorCode = FillDragInfo(_pView,pParamNode,aDragLeft))
1656*cdf0e10cSrcweir 						&& SQL_ISRULE(pParamNode,num_value_exp) )
1657*cdf0e10cSrcweir 				{
1658*cdf0e10cSrcweir 					::rtl::OUString sParameterValue;
1659*cdf0e10cSrcweir 					pParamNode->parseNodeToStr(	sParameterValue,
1660*cdf0e10cSrcweir 												xConnection,
1661*cdf0e10cSrcweir 												&rController.getParser().getContext());
1662*cdf0e10cSrcweir 					nFunctionType |= FKT_NUMERIC;
1663*cdf0e10cSrcweir 					aDragLeft->SetField(sParameterValue);
1664*cdf0e10cSrcweir 					eErrorCode = eOk;
1665*cdf0e10cSrcweir 				}
1666*cdf0e10cSrcweir 				aDragLeft->SetFunctionType(nFunctionType);
1667*cdf0e10cSrcweir 				if ( bHaving )
1668*cdf0e10cSrcweir 					aDragLeft->SetGroupBy(sal_True);
1669*cdf0e10cSrcweir 				sal_Int32 nIndex = 0;
1670*cdf0e10cSrcweir 				aDragLeft->SetFunction(aColumnName.getToken(0,'(',nIndex));
1671*cdf0e10cSrcweir 			}
1672*cdf0e10cSrcweir 			else
1673*cdf0e10cSrcweir 			{
1674*cdf0e10cSrcweir 				// bei unbekannten Funktionen wird der gesamte Text in das Field gechrieben
1675*cdf0e10cSrcweir 				aDragLeft->SetField(aColumnName);
1676*cdf0e10cSrcweir 				if(bHaving)
1677*cdf0e10cSrcweir 					aDragLeft->SetGroupBy(sal_True);
1678*cdf0e10cSrcweir 				aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
1679*cdf0e10cSrcweir 			}
1680*cdf0e10cSrcweir 			_pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
1681*cdf0e10cSrcweir 		}
1682*cdf0e10cSrcweir 
1683*cdf0e10cSrcweir 		return eErrorCode;
1684*cdf0e10cSrcweir 	}
1685*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
1686*cdf0e10cSrcweir 	SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
1687*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
1688*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode * pCondition,
1689*cdf0e10cSrcweir 							const sal_uInt16 nLevel,
1690*cdf0e10cSrcweir 							sal_Bool bHaving
1691*cdf0e10cSrcweir                             ,bool bAddOrOnOneLine)
1692*cdf0e10cSrcweir 	{
1693*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
1694*cdf0e10cSrcweir 		OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
1695*cdf0e10cSrcweir 
1696*cdf0e10cSrcweir 		DBG_ASSERT(SQL_ISRULE( pCondition, comparison_predicate),"ComparisonPredicate: pCondition ist kein ComparisonPredicate");
1697*cdf0e10cSrcweir 		if ( SQL_ISRULE(pCondition->getChild(0), column_ref )
1698*cdf0e10cSrcweir 			|| SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref) )
1699*cdf0e10cSrcweir 		{
1700*cdf0e10cSrcweir 			::rtl::OUString	aCondition;
1701*cdf0e10cSrcweir 			OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir 			if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) && SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
1704*cdf0e10cSrcweir 			{
1705*cdf0e10cSrcweir 				OTableFieldDescRef aDragRight = new OTableFieldDesc();
1706*cdf0e10cSrcweir 				if (eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) ||
1707*cdf0e10cSrcweir 					eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(2),aDragRight)))
1708*cdf0e10cSrcweir 					return eErrorCode;
1709*cdf0e10cSrcweir 
1710*cdf0e10cSrcweir                 OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>(
1711*cdf0e10cSrcweir                                                     _pView->getTableView()->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()),
1712*cdf0e10cSrcweir 																					   static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()),
1713*cdf0e10cSrcweir                                                                                        true));
1714*cdf0e10cSrcweir 				if ( pConn )
1715*cdf0e10cSrcweir 				{
1716*cdf0e10cSrcweir 					OConnectionLineDataVec* pLineDataList = pConn->GetData()->GetConnLineDataList();
1717*cdf0e10cSrcweir 					OConnectionLineDataVec::iterator aIter = pLineDataList->begin();
1718*cdf0e10cSrcweir                     OConnectionLineDataVec::iterator aEnd = pLineDataList->end();
1719*cdf0e10cSrcweir 					for(;aIter != aEnd;++aIter)
1720*cdf0e10cSrcweir 					{
1721*cdf0e10cSrcweir 						if((*aIter)->GetSourceFieldName() == aDragLeft->GetField() ||
1722*cdf0e10cSrcweir 						   (*aIter)->GetDestFieldName() == aDragLeft->GetField() )
1723*cdf0e10cSrcweir 							break;
1724*cdf0e10cSrcweir 					}
1725*cdf0e10cSrcweir 					if(aIter != aEnd)
1726*cdf0e10cSrcweir 						return eOk;
1727*cdf0e10cSrcweir 				}
1728*cdf0e10cSrcweir 			}
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir 			sal_uInt32 nPos = 0;
1731*cdf0e10cSrcweir 			if(SQL_ISRULE(pCondition->getChild(0), column_ref ))
1732*cdf0e10cSrcweir 			{
1733*cdf0e10cSrcweir 				nPos = 0;
1734*cdf0e10cSrcweir 				sal_uInt32 i=1;
1735*cdf0e10cSrcweir 
1736*cdf0e10cSrcweir 				// don't display the equal
1737*cdf0e10cSrcweir 				if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL)
1738*cdf0e10cSrcweir 					i++;
1739*cdf0e10cSrcweir 
1740*cdf0e10cSrcweir 				// Bedingung parsen
1741*cdf0e10cSrcweir 				aCondition = ParseCondition(rController
1742*cdf0e10cSrcweir 											,pCondition
1743*cdf0e10cSrcweir 											,_pView->getDecimalSeparator()
1744*cdf0e10cSrcweir 											,_pView->getLocale()
1745*cdf0e10cSrcweir 											,i);
1746*cdf0e10cSrcweir 			}
1747*cdf0e10cSrcweir 			else if( SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
1748*cdf0e10cSrcweir 			{
1749*cdf0e10cSrcweir 				nPos = pCondition->count()-1;
1750*cdf0e10cSrcweir 
1751*cdf0e10cSrcweir 				sal_Int32 i = static_cast<sal_Int32>(pCondition->count() - 2);
1752*cdf0e10cSrcweir 				switch (pCondition->getChild(i)->getNodeType())
1753*cdf0e10cSrcweir 				{
1754*cdf0e10cSrcweir 					case SQL_NODE_EQUAL:
1755*cdf0e10cSrcweir 						// don't display the equal
1756*cdf0e10cSrcweir 						i--;
1757*cdf0e10cSrcweir 						break;
1758*cdf0e10cSrcweir 					case SQL_NODE_LESS:
1759*cdf0e10cSrcweir 						// take the opposite as we change the order
1760*cdf0e10cSrcweir 						i--;
1761*cdf0e10cSrcweir 						aCondition = aCondition + ::rtl::OUString::createFromAscii(">");
1762*cdf0e10cSrcweir 						break;
1763*cdf0e10cSrcweir 					case SQL_NODE_LESSEQ:
1764*cdf0e10cSrcweir 						// take the opposite as we change the order
1765*cdf0e10cSrcweir 						i--;
1766*cdf0e10cSrcweir 						aCondition = aCondition + ::rtl::OUString::createFromAscii(">=");
1767*cdf0e10cSrcweir 						break;
1768*cdf0e10cSrcweir 					case SQL_NODE_GREAT:
1769*cdf0e10cSrcweir 						// take the opposite as we change the order
1770*cdf0e10cSrcweir 						i--;
1771*cdf0e10cSrcweir 						aCondition = aCondition + ::rtl::OUString::createFromAscii("<");
1772*cdf0e10cSrcweir 						break;
1773*cdf0e10cSrcweir 					case SQL_NODE_GREATEQ:
1774*cdf0e10cSrcweir 						// take the opposite as we change the order
1775*cdf0e10cSrcweir 						i--;
1776*cdf0e10cSrcweir 						aCondition = aCondition + ::rtl::OUString::createFromAscii("<=");
1777*cdf0e10cSrcweir 						break;
1778*cdf0e10cSrcweir                     default:
1779*cdf0e10cSrcweir                         break;
1780*cdf0e10cSrcweir 				}
1781*cdf0e10cSrcweir 
1782*cdf0e10cSrcweir 				// go backward
1783*cdf0e10cSrcweir 				Reference< XConnection> xConnection = rController.getConnection();
1784*cdf0e10cSrcweir 				if(xConnection.is())
1785*cdf0e10cSrcweir 				{
1786*cdf0e10cSrcweir 					Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
1787*cdf0e10cSrcweir 					for (; i >= 0; i--)
1788*cdf0e10cSrcweir 						pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
1789*cdf0e10cSrcweir 												xConnection,
1790*cdf0e10cSrcweir 												rController.getNumberFormatter(),
1791*cdf0e10cSrcweir 												_pView->getLocale(),
1792*cdf0e10cSrcweir 												static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
1793*cdf0e10cSrcweir 												&rController.getParser().getContext());
1794*cdf0e10cSrcweir 				}
1795*cdf0e10cSrcweir 			}
1796*cdf0e10cSrcweir 			// else ???
1797*cdf0e10cSrcweir 
1798*cdf0e10cSrcweir 
1799*cdf0e10cSrcweir 			if( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(nPos),aDragLeft)))
1800*cdf0e10cSrcweir 			{
1801*cdf0e10cSrcweir 				if(bHaving)
1802*cdf0e10cSrcweir 					aDragLeft->SetGroupBy(sal_True);
1803*cdf0e10cSrcweir 				_pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
1804*cdf0e10cSrcweir 			}
1805*cdf0e10cSrcweir 		}
1806*cdf0e10cSrcweir 		else if( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
1807*cdf0e10cSrcweir 		{
1808*cdf0e10cSrcweir 			AddFunctionCondition(	_pView,
1809*cdf0e10cSrcweir 									_pSelectionBrw,
1810*cdf0e10cSrcweir 									pCondition,
1811*cdf0e10cSrcweir 									nLevel,
1812*cdf0e10cSrcweir 									bHaving,
1813*cdf0e10cSrcweir                                     bAddOrOnOneLine);
1814*cdf0e10cSrcweir 		}
1815*cdf0e10cSrcweir 		else // kann sich nur um einen Expr. Ausdruck handeln
1816*cdf0e10cSrcweir 		{
1817*cdf0e10cSrcweir 			::rtl::OUString aName,aCondition;
1818*cdf0e10cSrcweir 
1819*cdf0e10cSrcweir 			::connectivity::OSQLParseNode *pLhs = pCondition->getChild(0);
1820*cdf0e10cSrcweir 			::connectivity::OSQLParseNode *pRhs = pCondition->getChild(2);
1821*cdf0e10cSrcweir 			// Feldnamen
1822*cdf0e10cSrcweir 			Reference< XConnection> xConnection = rController.getConnection();
1823*cdf0e10cSrcweir 			if(xConnection.is())
1824*cdf0e10cSrcweir 			{
1825*cdf0e10cSrcweir 				pLhs->parseNodeToStr(aName,
1826*cdf0e10cSrcweir 									 xConnection,
1827*cdf0e10cSrcweir 									 &rController.getParser().getContext(),
1828*cdf0e10cSrcweir 									 sal_True);
1829*cdf0e10cSrcweir 				// Kriterium
1830*cdf0e10cSrcweir 				aCondition = pCondition->getChild(1)->getTokenValue();
1831*cdf0e10cSrcweir 				pRhs->parseNodeToPredicateStr(aCondition,
1832*cdf0e10cSrcweir 															xConnection,
1833*cdf0e10cSrcweir 															rController.getNumberFormatter(),
1834*cdf0e10cSrcweir 															_pView->getLocale(),
1835*cdf0e10cSrcweir 															static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
1836*cdf0e10cSrcweir 															&rController.getParser().getContext());
1837*cdf0e10cSrcweir 			}
1838*cdf0e10cSrcweir 
1839*cdf0e10cSrcweir 			OTableFieldDescRef aDragLeft = new OTableFieldDesc();
1840*cdf0e10cSrcweir 			aDragLeft->SetField(aName);
1841*cdf0e10cSrcweir 			aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
1842*cdf0e10cSrcweir 			// und anh"angen
1843*cdf0e10cSrcweir 			_pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
1844*cdf0e10cSrcweir 		}
1845*cdf0e10cSrcweir 		return eErrorCode;
1846*cdf0e10cSrcweir 	}
1847*cdf0e10cSrcweir 
1848*cdf0e10cSrcweir     //------------------------------------------------------------------------------
1849*cdf0e10cSrcweir     namespace
1850*cdf0e10cSrcweir     {
1851*cdf0e10cSrcweir         OQueryTableWindow* lcl_findColumnInTables( const ::rtl::OUString& _rColumName, const OJoinTableView::OTableWindowMap& _rTabList, OTableFieldDescRef& _rInfo )
1852*cdf0e10cSrcweir         {
1853*cdf0e10cSrcweir 			OJoinTableView::OTableWindowMap::const_iterator aIter = _rTabList.begin();
1854*cdf0e10cSrcweir             OJoinTableView::OTableWindowMap::const_iterator aEnd = _rTabList.end();
1855*cdf0e10cSrcweir 			for ( ; aIter != aEnd; ++aIter )
1856*cdf0e10cSrcweir 			{
1857*cdf0e10cSrcweir 				OQueryTableWindow* pTabWin = static_cast< OQueryTableWindow* >( aIter->second );
1858*cdf0e10cSrcweir 				if ( pTabWin && pTabWin->ExistsField( _rColumName, _rInfo ) )
1859*cdf0e10cSrcweir 					return pTabWin;
1860*cdf0e10cSrcweir 			}
1861*cdf0e10cSrcweir             return NULL;
1862*cdf0e10cSrcweir         }
1863*cdf0e10cSrcweir     }
1864*cdf0e10cSrcweir 
1865*cdf0e10cSrcweir     //------------------------------------------------------------------------------
1866*cdf0e10cSrcweir 	void InsertColumnRef(const OQueryDesignView* _pView,
1867*cdf0e10cSrcweir 						const ::connectivity::OSQLParseNode * pColumnRef,
1868*cdf0e10cSrcweir 						::rtl::OUString& aColumnName,
1869*cdf0e10cSrcweir 						const ::rtl::OUString& aColumnAlias,
1870*cdf0e10cSrcweir 						::rtl::OUString& aTableRange,
1871*cdf0e10cSrcweir 						OTableFieldDescRef& _raInfo,
1872*cdf0e10cSrcweir 						OJoinTableView::OTableWindowMap* pTabList)
1873*cdf0e10cSrcweir 	{
1874*cdf0e10cSrcweir 
1875*cdf0e10cSrcweir 		// Tabellennamen zusammen setzen
1876*cdf0e10cSrcweir 		::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
1877*cdf0e10cSrcweir 		rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
1878*cdf0e10cSrcweir 
1879*cdf0e10cSrcweir 		sal_Bool bFound(sal_False);
1880*cdf0e10cSrcweir 		DBG_ASSERT(aColumnName.getLength(),"Columnname darf nicht leer sein");
1881*cdf0e10cSrcweir 		if (!aTableRange.getLength())
1882*cdf0e10cSrcweir 		{
1883*cdf0e10cSrcweir 			// SELECT column, ...
1884*cdf0e10cSrcweir             bFound = NULL != lcl_findColumnInTables( aColumnName, *pTabList, _raInfo );
1885*cdf0e10cSrcweir 			if ( bFound && ( aColumnName.toChar() != '*' ) )
1886*cdf0e10cSrcweir 				_raInfo->SetFieldAlias(aColumnAlias);
1887*cdf0e10cSrcweir 		}
1888*cdf0e10cSrcweir 		else
1889*cdf0e10cSrcweir 		{
1890*cdf0e10cSrcweir 			// SELECT range.column, ...
1891*cdf0e10cSrcweir 			OQueryTableWindow* pTabWin = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable(aTableRange);
1892*cdf0e10cSrcweir 
1893*cdf0e10cSrcweir 			if (pTabWin && pTabWin->ExistsField(aColumnName, _raInfo))
1894*cdf0e10cSrcweir 			{
1895*cdf0e10cSrcweir 				if(aColumnName.toChar() != '*')
1896*cdf0e10cSrcweir 					_raInfo->SetFieldAlias(aColumnAlias);
1897*cdf0e10cSrcweir 				bFound = sal_True;
1898*cdf0e10cSrcweir 			}
1899*cdf0e10cSrcweir 		}
1900*cdf0e10cSrcweir 		if (!bFound)
1901*cdf0e10cSrcweir 		{
1902*cdf0e10cSrcweir 			_raInfo->SetTable(::rtl::OUString());
1903*cdf0e10cSrcweir 			_raInfo->SetAlias(::rtl::OUString());
1904*cdf0e10cSrcweir 			_raInfo->SetField(aColumnName);
1905*cdf0e10cSrcweir 			_raInfo->SetFieldAlias(aColumnAlias);	// nyi : hier ein fortlaufendes Expr_1, Expr_2 ...
1906*cdf0e10cSrcweir 			_raInfo->SetFunctionType(FKT_OTHER);
1907*cdf0e10cSrcweir 		}
1908*cdf0e10cSrcweir 	}
1909*cdf0e10cSrcweir 	//-----------------------------------------------------------------------------
1910*cdf0e10cSrcweir 	sal_Bool checkJoinConditions(	const OQueryDesignView* _pView,
1911*cdf0e10cSrcweir 									const ::connectivity::OSQLParseNode* _pNode )
1912*cdf0e10cSrcweir 	{
1913*cdf0e10cSrcweir 		const ::connectivity::OSQLParseNode* pJoinNode = NULL;
1914*cdf0e10cSrcweir 		sal_Bool bRet = sal_True;
1915*cdf0e10cSrcweir 		if (SQL_ISRULE(_pNode,qualified_join))
1916*cdf0e10cSrcweir 			pJoinNode = _pNode;
1917*cdf0e10cSrcweir         else if (SQL_ISRULE(_pNode,table_ref)
1918*cdf0e10cSrcweir                 &&  _pNode->count() == 3
1919*cdf0e10cSrcweir                 &&  SQL_ISPUNCTUATION(_pNode->getChild(0),"(")
1920*cdf0e10cSrcweir                 &&  SQL_ISPUNCTUATION(_pNode->getChild(2),")") ) // '(' joined_table ')'
1921*cdf0e10cSrcweir 			pJoinNode = _pNode->getChild(1);
1922*cdf0e10cSrcweir 		else if (! ( SQL_ISRULE(_pNode, table_ref) && _pNode->count() == 2) ) // table_node table_primary_as_range_column
1923*cdf0e10cSrcweir 			bRet = sal_False;
1924*cdf0e10cSrcweir 
1925*cdf0e10cSrcweir 		if (pJoinNode && !InsertJoin(_pView,pJoinNode))
1926*cdf0e10cSrcweir 			bRet = sal_False;
1927*cdf0e10cSrcweir 		return bRet;
1928*cdf0e10cSrcweir 	}
1929*cdf0e10cSrcweir 	//-----------------------------------------------------------------------------
1930*cdf0e10cSrcweir 	sal_Bool InsertJoin(const OQueryDesignView* _pView,
1931*cdf0e10cSrcweir 						const ::connectivity::OSQLParseNode *pNode)
1932*cdf0e10cSrcweir 	{
1933*cdf0e10cSrcweir 		DBG_ASSERT( SQL_ISRULE( pNode, qualified_join ) || SQL_ISRULE( pNode, joined_table ) || SQL_ISRULE( pNode, cross_union ),
1934*cdf0e10cSrcweir 			"OQueryDesignView::InsertJoin: Fehler im Parse Tree");
1935*cdf0e10cSrcweir 
1936*cdf0e10cSrcweir         if (SQL_ISRULE(pNode,joined_table))
1937*cdf0e10cSrcweir             return InsertJoin(_pView,pNode->getChild(1));
1938*cdf0e10cSrcweir 
1939*cdf0e10cSrcweir 		// first check the left and right side
1940*cdf0e10cSrcweir         const ::connectivity::OSQLParseNode* pRightTableRef = pNode->getChild(3); // table_ref
1941*cdf0e10cSrcweir         if ( SQL_ISRULE(pNode, qualified_join) && SQL_ISTOKEN(pNode->getChild(1),NATURAL) )
1942*cdf0e10cSrcweir             pRightTableRef = pNode->getChild(4); // table_ref
1943*cdf0e10cSrcweir 
1944*cdf0e10cSrcweir 		if ( !checkJoinConditions(_pView,pNode->getChild(0)) || !checkJoinConditions(_pView,pRightTableRef))
1945*cdf0e10cSrcweir 			return sal_False;
1946*cdf0e10cSrcweir 
1947*cdf0e10cSrcweir 		// named column join wird sp�ter vieleicht noch implementiert
1948*cdf0e10cSrcweir 		// SQL_ISRULE(pNode->getChild(4),named_columns_join)
1949*cdf0e10cSrcweir         EJoinType eJoinType = INNER_JOIN;
1950*cdf0e10cSrcweir         bool bNatural = false;
1951*cdf0e10cSrcweir 		if ( SQL_ISRULE(pNode, qualified_join) )
1952*cdf0e10cSrcweir 		{
1953*cdf0e10cSrcweir 			::connectivity::OSQLParseNode* pJoinType = pNode->getChild(1); // join_type
1954*cdf0e10cSrcweir             if ( SQL_ISTOKEN(pJoinType,NATURAL) )
1955*cdf0e10cSrcweir             {
1956*cdf0e10cSrcweir                 bNatural = true;
1957*cdf0e10cSrcweir                 pJoinType = pNode->getChild(2);
1958*cdf0e10cSrcweir             }
1959*cdf0e10cSrcweir 
1960*cdf0e10cSrcweir 			if (SQL_ISRULE(pJoinType,join_type) && (!pJoinType->count() || SQL_ISTOKEN(pJoinType->getChild(0),INNER)))
1961*cdf0e10cSrcweir 			{
1962*cdf0e10cSrcweir 				eJoinType = INNER_JOIN;
1963*cdf0e10cSrcweir 			}
1964*cdf0e10cSrcweir 			else
1965*cdf0e10cSrcweir 			{
1966*cdf0e10cSrcweir 				if (SQL_ISRULE(pJoinType,join_type))	   // eine Ebene tiefer
1967*cdf0e10cSrcweir 					pJoinType = pJoinType->getChild(0);
1968*cdf0e10cSrcweir 
1969*cdf0e10cSrcweir 				if (SQL_ISTOKEN(pJoinType->getChild(0),LEFT))
1970*cdf0e10cSrcweir 					eJoinType = LEFT_JOIN;
1971*cdf0e10cSrcweir 				else if(SQL_ISTOKEN(pJoinType->getChild(0),RIGHT))
1972*cdf0e10cSrcweir 					eJoinType = RIGHT_JOIN;
1973*cdf0e10cSrcweir 				else
1974*cdf0e10cSrcweir 					eJoinType = FULL_JOIN;
1975*cdf0e10cSrcweir 			}
1976*cdf0e10cSrcweir             if ( SQL_ISRULE(pNode->getChild(4),join_condition) )
1977*cdf0e10cSrcweir             {
1978*cdf0e10cSrcweir 			    if ( InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType,pNode->getChild(0),pRightTableRef) != eOk )
1979*cdf0e10cSrcweir 				    return sal_False;
1980*cdf0e10cSrcweir             }
1981*cdf0e10cSrcweir 		}
1982*cdf0e10cSrcweir         else if ( SQL_ISRULE(pNode, cross_union) )
1983*cdf0e10cSrcweir         {
1984*cdf0e10cSrcweir             eJoinType = CROSS_JOIN;
1985*cdf0e10cSrcweir             pRightTableRef = pNode->getChild(pNode->count() - 1);
1986*cdf0e10cSrcweir         }
1987*cdf0e10cSrcweir         else
1988*cdf0e10cSrcweir 			return sal_False;
1989*cdf0e10cSrcweir 
1990*cdf0e10cSrcweir         if ( eJoinType == CROSS_JOIN || bNatural )
1991*cdf0e10cSrcweir         {
1992*cdf0e10cSrcweir 
1993*cdf0e10cSrcweir             OQueryTableWindow*	pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pNode->getChild(0)) );
1994*cdf0e10cSrcweir             OQueryTableWindow*	pRightWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pRightTableRef) );
1995*cdf0e10cSrcweir             OSL_ENSURE(pLeftWindow && pRightWindow,"Table Windows could not be found!");
1996*cdf0e10cSrcweir             if ( !pLeftWindow || !pRightWindow )
1997*cdf0e10cSrcweir                 return sal_False;
1998*cdf0e10cSrcweir 
1999*cdf0e10cSrcweir             OTableFieldDescRef aDragLeft  = new OTableFieldDesc();
2000*cdf0e10cSrcweir             aDragLeft->SetTabWindow(pLeftWindow);
2001*cdf0e10cSrcweir             aDragLeft->SetTable(pLeftWindow->GetTableName());
2002*cdf0e10cSrcweir             aDragLeft->SetAlias(pLeftWindow->GetAliasName());
2003*cdf0e10cSrcweir 
2004*cdf0e10cSrcweir 			OTableFieldDescRef aDragRight = new OTableFieldDesc();
2005*cdf0e10cSrcweir             aDragRight->SetTabWindow(pRightWindow);
2006*cdf0e10cSrcweir             aDragRight->SetTable(pRightWindow->GetTableName());
2007*cdf0e10cSrcweir             aDragRight->SetAlias(pRightWindow->GetAliasName());
2008*cdf0e10cSrcweir 
2009*cdf0e10cSrcweir             insertConnection(_pView,eJoinType,aDragLeft,aDragRight,bNatural);
2010*cdf0e10cSrcweir         }
2011*cdf0e10cSrcweir 
2012*cdf0e10cSrcweir 
2013*cdf0e10cSrcweir 		return sal_True;
2014*cdf0e10cSrcweir 	}
2015*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2016*cdf0e10cSrcweir 	void insertUnUsedFields(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
2017*cdf0e10cSrcweir 	{
2018*cdf0e10cSrcweir 		// now we have to insert the fields which aren't in the statement
2019*cdf0e10cSrcweir 		OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
2020*cdf0e10cSrcweir 		OTableFields& rUnUsedFields = rController.getUnUsedFields();
2021*cdf0e10cSrcweir         OTableFields::iterator aEnd = rUnUsedFields.end();
2022*cdf0e10cSrcweir 		for(OTableFields::iterator aIter = rUnUsedFields.begin();aIter != aEnd;++aIter)
2023*cdf0e10cSrcweir 			if(_pSelectionBrw->InsertField(*aIter,BROWSER_INVALIDID,sal_False,sal_False).isValid())
2024*cdf0e10cSrcweir 				(*aIter) = NULL;
2025*cdf0e10cSrcweir 		OTableFields().swap( rUnUsedFields );
2026*cdf0e10cSrcweir 	}
2027*cdf0e10cSrcweir 
2028*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2029*cdf0e10cSrcweir 	SqlParseError InitFromParseNodeImpl(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
2030*cdf0e10cSrcweir 	{
2031*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2032*cdf0e10cSrcweir 
2033*cdf0e10cSrcweir 		OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
2034*cdf0e10cSrcweir 
2035*cdf0e10cSrcweir 		_pSelectionBrw->PreFill();
2036*cdf0e10cSrcweir 		_pSelectionBrw->SetReadOnly(rController.isReadOnly());
2037*cdf0e10cSrcweir 		_pSelectionBrw->Fill();
2038*cdf0e10cSrcweir 
2039*cdf0e10cSrcweir 
2040*cdf0e10cSrcweir 		::connectivity::OSQLParseTreeIterator& aIterator = rController.getParseIterator();
2041*cdf0e10cSrcweir 		const ::connectivity::OSQLParseNode* pParseTree = aIterator.getParseTree();
2042*cdf0e10cSrcweir 
2043*cdf0e10cSrcweir         do
2044*cdf0e10cSrcweir         {
2045*cdf0e10cSrcweir             if ( !pParseTree )
2046*cdf0e10cSrcweir             {
2047*cdf0e10cSrcweir 			    // now we have to insert the fields which aren't in the statement
2048*cdf0e10cSrcweir 			    insertUnUsedFields(_pView,_pSelectionBrw);
2049*cdf0e10cSrcweir                 break;
2050*cdf0e10cSrcweir             }
2051*cdf0e10cSrcweir 
2052*cdf0e10cSrcweir             if ( !rController.isEsacpeProcessing() ) // not allowed in this mode
2053*cdf0e10cSrcweir             {
2054*cdf0e10cSrcweir 			    eErrorCode = eNativeMode;
2055*cdf0e10cSrcweir                 break;
2056*cdf0e10cSrcweir             }
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir 			if ( !( SQL_ISRULE( pParseTree, select_statement ) ) )
2059*cdf0e10cSrcweir             {
2060*cdf0e10cSrcweir 				eErrorCode = eNoSelectStatement;
2061*cdf0e10cSrcweir                 break;
2062*cdf0e10cSrcweir             }
2063*cdf0e10cSrcweir 
2064*cdf0e10cSrcweir             const OSQLParseNode* pTableExp = pParseTree->getChild(3);
2065*cdf0e10cSrcweir             if ( pTableExp->getChild(6)->count() > 0 || pTableExp->getChild(7)->count() > 0 || pTableExp->getChild(8)->count() > 0)
2066*cdf0e10cSrcweir             {
2067*cdf0e10cSrcweir 				eErrorCode = eStatementTooComplex;
2068*cdf0e10cSrcweir                 break;
2069*cdf0e10cSrcweir             }
2070*cdf0e10cSrcweir 
2071*cdf0e10cSrcweir 			Reference< XConnection> xConnection = rController.getConnection();
2072*cdf0e10cSrcweir 			if ( !xConnection.is() )
2073*cdf0e10cSrcweir             {
2074*cdf0e10cSrcweir                 DBG_ERROR( "InitFromParseNodeImpl: no connection? no connection!" );
2075*cdf0e10cSrcweir                 break;
2076*cdf0e10cSrcweir             }
2077*cdf0e10cSrcweir 
2078*cdf0e10cSrcweir 			const OSQLTables& aMap = aIterator.getTables();
2079*cdf0e10cSrcweir 			::comphelper::UStringMixLess aTmp(aMap.key_comp());
2080*cdf0e10cSrcweir 			::comphelper::UStringMixEqual aKeyComp( aTmp.isCaseSensitive() );
2081*cdf0e10cSrcweir 
2082*cdf0e10cSrcweir 			Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
2083*cdf0e10cSrcweir 			try
2084*cdf0e10cSrcweir 			{
2085*cdf0e10cSrcweir 			    sal_Int32 nMax = xMetaData->getMaxTablesInSelect();
2086*cdf0e10cSrcweir                 if ( nMax && nMax < (sal_Int32)aMap.size() )
2087*cdf0e10cSrcweir                 {
2088*cdf0e10cSrcweir 					eErrorCode = eTooManyTables;
2089*cdf0e10cSrcweir                     break;
2090*cdf0e10cSrcweir                 }
2091*cdf0e10cSrcweir 
2092*cdf0e10cSrcweir 				::rtl::OUString sComposedName;
2093*cdf0e10cSrcweir 				::rtl::OUString aQualifierName;
2094*cdf0e10cSrcweir 				::rtl::OUString sAlias;
2095*cdf0e10cSrcweir 
2096*cdf0e10cSrcweir 				OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
2097*cdf0e10cSrcweir                 pTableView->clearLayoutInformation();
2098*cdf0e10cSrcweir 				OSQLTables::const_iterator aIter = aMap.begin();
2099*cdf0e10cSrcweir                 OSQLTables::const_iterator aEnd = aMap.end();
2100*cdf0e10cSrcweir 				for(;aIter != aEnd;++aIter)
2101*cdf0e10cSrcweir 				{
2102*cdf0e10cSrcweir 					OSQLTable xTable = aIter->second;
2103*cdf0e10cSrcweir                     Reference< XPropertySet > xTableProps( xTable, UNO_QUERY_THROW );
2104*cdf0e10cSrcweir 
2105*cdf0e10cSrcweir 					sAlias = aIter->first;
2106*cdf0e10cSrcweir 
2107*cdf0e10cSrcweir                     // check whether this is a query
2108*cdf0e10cSrcweir                     Reference< XPropertySetInfo > xPSI = xTableProps->getPropertySetInfo();
2109*cdf0e10cSrcweir                     bool bIsQuery = xPSI.is() && xPSI->hasPropertyByName( PROPERTY_COMMAND );
2110*cdf0e10cSrcweir 
2111*cdf0e10cSrcweir                     if ( bIsQuery )
2112*cdf0e10cSrcweir                         OSL_VERIFY( xTableProps->getPropertyValue( PROPERTY_NAME ) >>= sComposedName );
2113*cdf0e10cSrcweir                     else
2114*cdf0e10cSrcweir                     {
2115*cdf0e10cSrcweir                         sComposedName = ::dbtools::composeTableName( xMetaData, xTableProps, ::dbtools::eInDataManipulation, false, false, false );
2116*cdf0e10cSrcweir 
2117*cdf0e10cSrcweir                         // if the alias is the complete (composed) table, then shorten it
2118*cdf0e10cSrcweir                         if ( aKeyComp( sComposedName, aIter->first ) )
2119*cdf0e10cSrcweir 					    {
2120*cdf0e10cSrcweir 						    ::rtl::OUString sCatalog, sSchema, sTable;
2121*cdf0e10cSrcweir 						    ::dbtools::qualifiedNameComponents( xMetaData, sComposedName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
2122*cdf0e10cSrcweir 						    sAlias = sTable;
2123*cdf0e10cSrcweir 					    }
2124*cdf0e10cSrcweir                     }
2125*cdf0e10cSrcweir 
2126*cdf0e10cSrcweir                     // find the existent window for this alias
2127*cdf0e10cSrcweir 					OQueryTableWindow* pExistentWin	= pTableView->FindTable( sAlias );
2128*cdf0e10cSrcweir 					if ( !pExistentWin )
2129*cdf0e10cSrcweir 					{
2130*cdf0e10cSrcweir 						pTableView->AddTabWin( sComposedName, sAlias, sal_False );  // don't create data here
2131*cdf0e10cSrcweir 					}
2132*cdf0e10cSrcweir 					else
2133*cdf0e10cSrcweir 					{
2134*cdf0e10cSrcweir 						// there already exists a window for this alias ....
2135*cdf0e10cSrcweir 						if ( !aKeyComp( pExistentWin->GetData()->GetComposedName(), sComposedName ) )
2136*cdf0e10cSrcweir 							// ... but for another complete table name -> new window
2137*cdf0e10cSrcweir 							pTableView->AddTabWin(sComposedName, sAlias);
2138*cdf0e10cSrcweir 					}
2139*cdf0e10cSrcweir 				}
2140*cdf0e10cSrcweir 
2141*cdf0e10cSrcweir 				// now delete the data for which we haven't any tablewindow
2142*cdf0e10cSrcweir 				OJoinTableView::OTableWindowMap aTableMap(*pTableView->GetTabWinMap());
2143*cdf0e10cSrcweir 				OJoinTableView::OTableWindowMap::iterator aIterTableMap = aTableMap.begin();
2144*cdf0e10cSrcweir                 OJoinTableView::OTableWindowMap::iterator aIterTableEnd = aTableMap.end();
2145*cdf0e10cSrcweir 				for(;aIterTableMap != aIterTableEnd;++aIterTableMap)
2146*cdf0e10cSrcweir 				{
2147*cdf0e10cSrcweir 					if(aMap.find(aIterTableMap->second->GetComposedName())	== aMap.end() &&
2148*cdf0e10cSrcweir 						aMap.find(aIterTableMap->first)						== aMap.end())
2149*cdf0e10cSrcweir 						pTableView->RemoveTabWin(aIterTableMap->second);
2150*cdf0e10cSrcweir 				}
2151*cdf0e10cSrcweir 
2152*cdf0e10cSrcweir 				if ( eOk == (eErrorCode = FillOuterJoins(_pView,pTableExp->getChild(0)->getChild(1))) )
2153*cdf0e10cSrcweir 				{
2154*cdf0e10cSrcweir 					// check if we have a distinct statement
2155*cdf0e10cSrcweir 					if(SQL_ISTOKEN(pParseTree->getChild(1),DISTINCT))
2156*cdf0e10cSrcweir 					{
2157*cdf0e10cSrcweir 						rController.setDistinct(sal_True);
2158*cdf0e10cSrcweir 						rController.InvalidateFeature(SID_QUERY_DISTINCT_VALUES);
2159*cdf0e10cSrcweir 					}
2160*cdf0e10cSrcweir 					if ( (eErrorCode = InstallFields(_pView,pParseTree, pTableView->GetTabWinMap())) == eOk )
2161*cdf0e10cSrcweir 					{
2162*cdf0e10cSrcweir 						// GetSelectionCriteria must be called before GetHavingCriteria
2163*cdf0e10cSrcweir 						sal_uInt16 nLevel=0;
2164*cdf0e10cSrcweir 
2165*cdf0e10cSrcweir 						if ( eOk == (eErrorCode = GetSelectionCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
2166*cdf0e10cSrcweir 						{
2167*cdf0e10cSrcweir 							if ( eOk == (eErrorCode = GetGroupCriteria(_pView,_pSelectionBrw,pParseTree)) )
2168*cdf0e10cSrcweir 							{
2169*cdf0e10cSrcweir 								if ( eOk == (eErrorCode = GetHavingCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
2170*cdf0e10cSrcweir 								{
2171*cdf0e10cSrcweir 									if ( eOk == (eErrorCode = GetOrderCriteria(_pView,_pSelectionBrw,pParseTree)) )
2172*cdf0e10cSrcweir 										insertUnUsedFields(_pView,_pSelectionBrw);
2173*cdf0e10cSrcweir 								}
2174*cdf0e10cSrcweir 							}
2175*cdf0e10cSrcweir 						}
2176*cdf0e10cSrcweir 					}
2177*cdf0e10cSrcweir 				}
2178*cdf0e10cSrcweir 			}
2179*cdf0e10cSrcweir 			catch(SQLException&)
2180*cdf0e10cSrcweir 			{
2181*cdf0e10cSrcweir 				OSL_ASSERT(!"getMaxTablesInSelect!");
2182*cdf0e10cSrcweir 			}
2183*cdf0e10cSrcweir 		}
2184*cdf0e10cSrcweir         while ( false );
2185*cdf0e10cSrcweir 
2186*cdf0e10cSrcweir 		// Durch das Neuerzeugen wurden wieder Undo-Actions in den Manager gestellt
2187*cdf0e10cSrcweir 		rController.ClearUndoManager();
2188*cdf0e10cSrcweir 		_pSelectionBrw->Invalidate();
2189*cdf0e10cSrcweir 		return eErrorCode;
2190*cdf0e10cSrcweir 	}
2191*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2192*cdf0e10cSrcweir 	/** fillSelectSubList
2193*cdf0e10cSrcweir 		@return
2194*cdf0e10cSrcweir 			<TRUE/> when columns could be inserted otherwise <FALSE/>
2195*cdf0e10cSrcweir 	*/
2196*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2197*cdf0e10cSrcweir 	SqlParseError fillSelectSubList(	OQueryDesignView* _pView,
2198*cdf0e10cSrcweir 								OJoinTableView::OTableWindowMap* _pTabList)
2199*cdf0e10cSrcweir 	{
2200*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2201*cdf0e10cSrcweir 		sal_Bool bFirstField = sal_True;
2202*cdf0e10cSrcweir 		::rtl::OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*"));
2203*cdf0e10cSrcweir 		OJoinTableView::OTableWindowMap::iterator aIter = _pTabList->begin();
2204*cdf0e10cSrcweir         OJoinTableView::OTableWindowMap::iterator aEnd = _pTabList->end();
2205*cdf0e10cSrcweir 		for(;aIter != aEnd && eOk == eErrorCode ;++aIter)
2206*cdf0e10cSrcweir 		{
2207*cdf0e10cSrcweir 			OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
2208*cdf0e10cSrcweir             OTableFieldDescRef	aInfo = new OTableFieldDesc();
2209*cdf0e10cSrcweir 			if (pTabWin->ExistsField( sAsterix, aInfo ))
2210*cdf0e10cSrcweir 			{
2211*cdf0e10cSrcweir 				eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
2212*cdf0e10cSrcweir 				bFirstField = sal_False;
2213*cdf0e10cSrcweir 			}
2214*cdf0e10cSrcweir 		}
2215*cdf0e10cSrcweir 		return eErrorCode;
2216*cdf0e10cSrcweir 	}
2217*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2218*cdf0e10cSrcweir 	SqlParseError InstallFields(OQueryDesignView* _pView,
2219*cdf0e10cSrcweir 								const ::connectivity::OSQLParseNode* pNode,
2220*cdf0e10cSrcweir 								OJoinTableView::OTableWindowMap* pTabList )
2221*cdf0e10cSrcweir 	{
2222*cdf0e10cSrcweir 		if( pNode==0 || !SQL_ISRULE(pNode,select_statement))
2223*cdf0e10cSrcweir 			return eNoSelectStatement;
2224*cdf0e10cSrcweir 
2225*cdf0e10cSrcweir 		::connectivity::OSQLParseNode* pParseTree = pNode->getChild(2); // selection
2226*cdf0e10cSrcweir 		sal_Bool bFirstField = sal_True;	// bei der Initialisierung mu� auf alle Faelle das erste Feld neu aktiviert werden
2227*cdf0e10cSrcweir 
2228*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2229*cdf0e10cSrcweir 
2230*cdf0e10cSrcweir 		if ( pParseTree->isRule() && SQL_ISPUNCTUATION(pParseTree->getChild(0),"*") )
2231*cdf0e10cSrcweir 		{
2232*cdf0e10cSrcweir 			// SELECT * ...
2233*cdf0e10cSrcweir 			eErrorCode = fillSelectSubList(_pView,pTabList);
2234*cdf0e10cSrcweir 		}
2235*cdf0e10cSrcweir 		else if (SQL_ISRULE(pParseTree,scalar_exp_commalist) )
2236*cdf0e10cSrcweir 		{
2237*cdf0e10cSrcweir 			// SELECT column, ...
2238*cdf0e10cSrcweir 			OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
2239*cdf0e10cSrcweir 			Reference< XConnection> xConnection = rController.getConnection();
2240*cdf0e10cSrcweir 
2241*cdf0e10cSrcweir 			::rtl::OUString aColumnName,aTableRange;
2242*cdf0e10cSrcweir 			for (sal_uInt32 i = 0; i < pParseTree->count() && eOk == eErrorCode ; ++i)
2243*cdf0e10cSrcweir 			{
2244*cdf0e10cSrcweir 				::connectivity::OSQLParseNode * pColumnRef = pParseTree->getChild(i);
2245*cdf0e10cSrcweir 
2246*cdf0e10cSrcweir                 do {
2247*cdf0e10cSrcweir 
2248*cdf0e10cSrcweir                 if ( SQL_ISRULE(pColumnRef,select_sublist) )
2249*cdf0e10cSrcweir 				{
2250*cdf0e10cSrcweir 					 eErrorCode = fillSelectSubList(_pView,pTabList);
2251*cdf0e10cSrcweir                      break;
2252*cdf0e10cSrcweir 				}
2253*cdf0e10cSrcweir 
2254*cdf0e10cSrcweir                 if ( SQL_ISRULE(pColumnRef,derived_column) )
2255*cdf0e10cSrcweir 				{
2256*cdf0e10cSrcweir 					::rtl::OUString aColumnAlias(rController.getParseIterator().getColumnAlias(pColumnRef)); // kann leer sein
2257*cdf0e10cSrcweir 					pColumnRef = pColumnRef->getChild(0);
2258*cdf0e10cSrcweir 					OTableFieldDescRef aInfo = new OTableFieldDesc();
2259*cdf0e10cSrcweir 
2260*cdf0e10cSrcweir 					if (	pColumnRef->count() == 3 &&
2261*cdf0e10cSrcweir 							SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
2262*cdf0e10cSrcweir 							SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
2263*cdf0e10cSrcweir 						)
2264*cdf0e10cSrcweir 						pColumnRef = pColumnRef->getChild(1);
2265*cdf0e10cSrcweir 
2266*cdf0e10cSrcweir 					if (SQL_ISRULE(pColumnRef,column_ref))
2267*cdf0e10cSrcweir 					{
2268*cdf0e10cSrcweir 						InsertColumnRef(_pView,pColumnRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
2269*cdf0e10cSrcweir 						eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
2270*cdf0e10cSrcweir 						bFirstField = sal_False;
2271*cdf0e10cSrcweir 					}
2272*cdf0e10cSrcweir 					else if(SQL_ISRULEOR2(pColumnRef,general_set_fct ,set_fct_spec)	||
2273*cdf0e10cSrcweir 							SQL_ISRULEOR2(pColumnRef,position_exp,extract_exp)		||
2274*cdf0e10cSrcweir 							SQL_ISRULEOR2(pColumnRef,fold,char_substring_fct)		||
2275*cdf0e10cSrcweir 							SQL_ISRULEOR2(pColumnRef,length_exp,char_value_fct))
2276*cdf0e10cSrcweir 					{
2277*cdf0e10cSrcweir 						::rtl::OUString aColumns;
2278*cdf0e10cSrcweir                         pColumnRef->parseNodeToPredicateStr(aColumns,
2279*cdf0e10cSrcweir 												            xConnection,
2280*cdf0e10cSrcweir 												            rController.getNumberFormatter(),
2281*cdf0e10cSrcweir 												            _pView->getLocale(),
2282*cdf0e10cSrcweir 												            static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
2283*cdf0e10cSrcweir 												            &rController.getParser().getContext());
2284*cdf0e10cSrcweir 						//pColumnRef->parseNodeToStr(	aColumns,
2285*cdf0e10cSrcweir 						//							xConnection,
2286*cdf0e10cSrcweir 						//							&rController.getParser().getContext(),
2287*cdf0e10cSrcweir 						//							sal_True,
2288*cdf0e10cSrcweir 						//							sal_True); // quote is to true because we need quoted elements inside the function
2289*cdf0e10cSrcweir 
2290*cdf0e10cSrcweir 						sal_Int32 nFunctionType = FKT_NONE;
2291*cdf0e10cSrcweir 						::connectivity::OSQLParseNode* pParamRef = NULL;
2292*cdf0e10cSrcweir 						sal_Int32 nColumnRefPos = pColumnRef->count() - 2;
2293*cdf0e10cSrcweir 						if ( nColumnRefPos >= 0 && static_cast<sal_uInt32>(nColumnRefPos) < pColumnRef->count() )
2294*cdf0e10cSrcweir 							pParamRef = pColumnRef->getChild(nColumnRefPos);
2295*cdf0e10cSrcweir 
2296*cdf0e10cSrcweir 						if (	SQL_ISRULE(pColumnRef,general_set_fct)
2297*cdf0e10cSrcweir 							&&	SQL_ISRULE(pParamRef,column_ref) )
2298*cdf0e10cSrcweir 						{
2299*cdf0e10cSrcweir 							// Parameter auf Columnref pr"ufen
2300*cdf0e10cSrcweir 							InsertColumnRef(_pView,pParamRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
2301*cdf0e10cSrcweir 						}
2302*cdf0e10cSrcweir 						else if ( SQL_ISRULE(pColumnRef,general_set_fct) )
2303*cdf0e10cSrcweir 						{
2304*cdf0e10cSrcweir 							if ( pParamRef && pParamRef->getTokenValue().toChar() == '*' )
2305*cdf0e10cSrcweir 							{
2306*cdf0e10cSrcweir 								OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin();
2307*cdf0e10cSrcweir                                 OJoinTableView::OTableWindowMap::iterator aEnd  = pTabList->end();
2308*cdf0e10cSrcweir 								for(;aIter != aEnd;++aIter)
2309*cdf0e10cSrcweir 								{
2310*cdf0e10cSrcweir 									OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
2311*cdf0e10cSrcweir 									if (pTabWin->ExistsField( ::rtl::OUString::createFromAscii("*"), aInfo ))
2312*cdf0e10cSrcweir 									{
2313*cdf0e10cSrcweir 										aInfo->SetAlias(String());
2314*cdf0e10cSrcweir 										aInfo->SetTable(String());
2315*cdf0e10cSrcweir 										break;
2316*cdf0e10cSrcweir 									}
2317*cdf0e10cSrcweir 								}
2318*cdf0e10cSrcweir 							}
2319*cdf0e10cSrcweir 							else
2320*cdf0e10cSrcweir 							{
2321*cdf0e10cSrcweir 								::rtl::OUString sFieldName = aColumns;
2322*cdf0e10cSrcweir 								if ( pParamRef )
2323*cdf0e10cSrcweir 								{	// we got an aggregate function but without column name inside
2324*cdf0e10cSrcweir 									// so we set the whole argument of the function as field name
2325*cdf0e10cSrcweir 									nFunctionType |= FKT_NUMERIC;
2326*cdf0e10cSrcweir 									sFieldName = ::rtl::OUString();
2327*cdf0e10cSrcweir 									pParamRef->parseNodeToStr(	sFieldName,
2328*cdf0e10cSrcweir 														xConnection,
2329*cdf0e10cSrcweir 														&rController.getParser().getContext(),
2330*cdf0e10cSrcweir 														sal_True,
2331*cdf0e10cSrcweir 														sal_True); // quote is to true because we need quoted elements inside the function
2332*cdf0e10cSrcweir 								}
2333*cdf0e10cSrcweir 								aInfo->SetDataType(DataType::DOUBLE);
2334*cdf0e10cSrcweir 								aInfo->SetFieldType(TAB_NORMAL_FIELD);
2335*cdf0e10cSrcweir 								aInfo->SetField(sFieldName);
2336*cdf0e10cSrcweir 							}
2337*cdf0e10cSrcweir 							aInfo->SetTabWindow(NULL);
2338*cdf0e10cSrcweir 							aInfo->SetFieldAlias(aColumnAlias);
2339*cdf0e10cSrcweir 						}
2340*cdf0e10cSrcweir 						else
2341*cdf0e10cSrcweir 						{
2342*cdf0e10cSrcweir                             _pView->fillFunctionInfo(pColumnRef,aColumns,aInfo);
2343*cdf0e10cSrcweir 							aInfo->SetFieldAlias(aColumnAlias);
2344*cdf0e10cSrcweir 						}
2345*cdf0e10cSrcweir 
2346*cdf0e10cSrcweir 						if ( SQL_ISRULE(pColumnRef,general_set_fct) )
2347*cdf0e10cSrcweir 						{
2348*cdf0e10cSrcweir 							aInfo->SetFunctionType(nFunctionType|FKT_AGGREGATE);
2349*cdf0e10cSrcweir 							String aCol(aColumns);
2350*cdf0e10cSrcweir 							aInfo->SetFunction(aCol.GetToken(0,'(').EraseTrailingChars(' '));
2351*cdf0e10cSrcweir 						}
2352*cdf0e10cSrcweir 						else
2353*cdf0e10cSrcweir 							aInfo->SetFunctionType(nFunctionType|FKT_OTHER);
2354*cdf0e10cSrcweir 
2355*cdf0e10cSrcweir 						eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
2356*cdf0e10cSrcweir 						bFirstField = sal_False;
2357*cdf0e10cSrcweir 					}
2358*cdf0e10cSrcweir 					else //if(SQL_ISRULE(pColumnRef,num_value_exp)	|| SQL_ISRULE(pColumnRef,term))
2359*cdf0e10cSrcweir 					{
2360*cdf0e10cSrcweir 						::rtl::OUString aColumns;
2361*cdf0e10cSrcweir 						pColumnRef->parseNodeToStr(	aColumns,
2362*cdf0e10cSrcweir 													xConnection,
2363*cdf0e10cSrcweir 													&rController.getParser().getContext(),
2364*cdf0e10cSrcweir 													sal_True,
2365*cdf0e10cSrcweir 													sal_True); // quote is to true because we need quoted elements inside the function
2366*cdf0e10cSrcweir 
2367*cdf0e10cSrcweir                         aInfo->SetTabWindow( NULL );
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir                         // since we support queries in queries, the thingie might belong to an existing "table"
2370*cdf0e10cSrcweir                         OQueryTableWindow* pExistingTable = lcl_findColumnInTables( aColumns, *pTabList, aInfo );
2371*cdf0e10cSrcweir                         if ( pExistingTable )
2372*cdf0e10cSrcweir                         {
2373*cdf0e10cSrcweir                             aInfo->SetTabWindow( pExistingTable );
2374*cdf0e10cSrcweir 					        aInfo->SetTable( pExistingTable->GetTableName() );
2375*cdf0e10cSrcweir 					        aInfo->SetAlias( pExistingTable->GetAliasName() );
2376*cdf0e10cSrcweir                         }
2377*cdf0e10cSrcweir 
2378*cdf0e10cSrcweir                         aInfo->SetDataType(DataType::DOUBLE);
2379*cdf0e10cSrcweir 						aInfo->SetFieldType(TAB_NORMAL_FIELD);
2380*cdf0e10cSrcweir 						aInfo->SetField(aColumns);
2381*cdf0e10cSrcweir 						aInfo->SetFieldAlias(aColumnAlias);
2382*cdf0e10cSrcweir 						aInfo->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
2383*cdf0e10cSrcweir 
2384*cdf0e10cSrcweir 						eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
2385*cdf0e10cSrcweir 						bFirstField = sal_False;
2386*cdf0e10cSrcweir 					}
2387*cdf0e10cSrcweir 
2388*cdf0e10cSrcweir                     break;
2389*cdf0e10cSrcweir 				}
2390*cdf0e10cSrcweir 
2391*cdf0e10cSrcweir                 DBG_ERROR( "InstallFields: don't know how to interpret this parse node!" );
2392*cdf0e10cSrcweir 
2393*cdf0e10cSrcweir                 } while ( false );
2394*cdf0e10cSrcweir 			}
2395*cdf0e10cSrcweir 		}
2396*cdf0e10cSrcweir 		else
2397*cdf0e10cSrcweir 			eErrorCode = eStatementTooComplex;
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir 		return eErrorCode;
2400*cdf0e10cSrcweir 	}
2401*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2402*cdf0e10cSrcweir 	SqlParseError GetOrderCriteria(	OQueryDesignView* _pView,
2403*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
2404*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode* pParseRoot )
2405*cdf0e10cSrcweir 	{
2406*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2407*cdf0e10cSrcweir 		if (!pParseRoot->getChild(3)->getChild(4)->isLeaf())
2408*cdf0e10cSrcweir 		{
2409*cdf0e10cSrcweir 			::connectivity::OSQLParseNode* pNode = pParseRoot->getChild(3)->getChild(4)->getChild(2);
2410*cdf0e10cSrcweir 			::connectivity::OSQLParseNode* pParamRef = NULL;
2411*cdf0e10cSrcweir 
2412*cdf0e10cSrcweir             OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
2413*cdf0e10cSrcweir 			EOrderDir eOrderDir;
2414*cdf0e10cSrcweir 			OTableFieldDescRef aDragLeft = new OTableFieldDesc();
2415*cdf0e10cSrcweir 			for( sal_uInt32 i=0 ; i<pNode->count() ; i++ )
2416*cdf0e10cSrcweir 			{
2417*cdf0e10cSrcweir 				eOrderDir = ORDER_ASC;
2418*cdf0e10cSrcweir 				::connectivity::OSQLParseNode*	pChild = pNode->getChild( i );
2419*cdf0e10cSrcweir 
2420*cdf0e10cSrcweir 				if (SQL_ISTOKEN( pChild->getChild(1), DESC ) )
2421*cdf0e10cSrcweir 					eOrderDir = ORDER_DESC;
2422*cdf0e10cSrcweir 
2423*cdf0e10cSrcweir                 ::connectivity::OSQLParseNode* pArgument = pChild->getChild(0);
2424*cdf0e10cSrcweir 
2425*cdf0e10cSrcweir 				if(SQL_ISRULE(pArgument,column_ref))
2426*cdf0e10cSrcweir 				{
2427*cdf0e10cSrcweir 					if( eOk == FillDragInfo(_pView,pArgument,aDragLeft))
2428*cdf0e10cSrcweir 						_pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i);
2429*cdf0e10cSrcweir 					else // it could be a alias name for a field
2430*cdf0e10cSrcweir 					{
2431*cdf0e10cSrcweir 						::rtl::OUString aTableRange,aColumnName;
2432*cdf0e10cSrcweir 						::connectivity::OSQLParseTreeIterator& rParseIter = rController.getParseIterator();
2433*cdf0e10cSrcweir 						rParseIter.getColumnRange( pArgument, aColumnName, aTableRange );
2434*cdf0e10cSrcweir 
2435*cdf0e10cSrcweir 						OTableFields& aList = rController.getTableFieldDesc();
2436*cdf0e10cSrcweir 						OTableFields::iterator aIter = aList.begin();
2437*cdf0e10cSrcweir                         OTableFields::iterator aEnd = aList.end();
2438*cdf0e10cSrcweir 						for(;aIter != aEnd;++aIter)
2439*cdf0e10cSrcweir 						{
2440*cdf0e10cSrcweir 							OTableFieldDescRef pEntry = *aIter;
2441*cdf0e10cSrcweir 							if(pEntry.isValid() && pEntry->GetFieldAlias() == aColumnName)
2442*cdf0e10cSrcweir 								pEntry->SetOrderDir( eOrderDir );
2443*cdf0e10cSrcweir 						}
2444*cdf0e10cSrcweir 					}
2445*cdf0e10cSrcweir 				}
2446*cdf0e10cSrcweir 				else if(SQL_ISRULE(pArgument, general_set_fct ) &&
2447*cdf0e10cSrcweir 						SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
2448*cdf0e10cSrcweir 						eOk == FillDragInfo(_pView,pParamRef,aDragLeft))
2449*cdf0e10cSrcweir 					_pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
2450*cdf0e10cSrcweir                 else if( SQL_ISRULE(pArgument, set_fct_spec ) )
2451*cdf0e10cSrcweir                 {
2452*cdf0e10cSrcweir 
2453*cdf0e10cSrcweir 		            Reference< XConnection> xConnection = rController.getConnection();
2454*cdf0e10cSrcweir 		            if(xConnection.is())
2455*cdf0e10cSrcweir 		            {
2456*cdf0e10cSrcweir                         ::rtl::OUString sCondition;
2457*cdf0e10cSrcweir 			            pArgument->parseNodeToPredicateStr(sCondition,
2458*cdf0e10cSrcweir 												            xConnection,
2459*cdf0e10cSrcweir 												            rController.getNumberFormatter(),
2460*cdf0e10cSrcweir 												            _pView->getLocale(),
2461*cdf0e10cSrcweir 												            static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
2462*cdf0e10cSrcweir 												            &rController.getParser().getContext());
2463*cdf0e10cSrcweir                         _pView->fillFunctionInfo(pArgument,sCondition,aDragLeft);
2464*cdf0e10cSrcweir                         aDragLeft->SetFunctionType(FKT_OTHER);
2465*cdf0e10cSrcweir                         aDragLeft->SetOrderDir(eOrderDir);
2466*cdf0e10cSrcweir                         aDragLeft->SetVisible(sal_False);
2467*cdf0e10cSrcweir                         _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
2468*cdf0e10cSrcweir                     }
2469*cdf0e10cSrcweir                     else
2470*cdf0e10cSrcweir                         eErrorCode = eColumnNotFound;
2471*cdf0e10cSrcweir                 }
2472*cdf0e10cSrcweir 				else
2473*cdf0e10cSrcweir 					eErrorCode = eColumnNotFound;
2474*cdf0e10cSrcweir 			}
2475*cdf0e10cSrcweir 		}
2476*cdf0e10cSrcweir 		return eErrorCode;
2477*cdf0e10cSrcweir 	}
2478*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2479*cdf0e10cSrcweir 	SqlParseError GetHavingCriteria(	OQueryDesignView* _pView,
2480*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
2481*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode* pSelectRoot,
2482*cdf0e10cSrcweir 							sal_uInt16& rLevel )
2483*cdf0e10cSrcweir 	{
2484*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2485*cdf0e10cSrcweir 		if (!pSelectRoot->getChild(3)->getChild(3)->isLeaf())
2486*cdf0e10cSrcweir 			eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSelectRoot->getChild(3)->getChild(3)->getChild(1),rLevel, sal_True);
2487*cdf0e10cSrcweir 		return eErrorCode;
2488*cdf0e10cSrcweir 	}
2489*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2490*cdf0e10cSrcweir 	SqlParseError GetGroupCriteria(	OQueryDesignView* _pView,
2491*cdf0e10cSrcweir 							OSelectionBrowseBox* _pSelectionBrw,
2492*cdf0e10cSrcweir 							const ::connectivity::OSQLParseNode* pSelectRoot )
2493*cdf0e10cSrcweir 	{
2494*cdf0e10cSrcweir 		SqlParseError eErrorCode = eOk;
2495*cdf0e10cSrcweir 		if (!pSelectRoot->getChild(3)->getChild(2)->isLeaf()) // opt_group_by_clause
2496*cdf0e10cSrcweir 		{
2497*cdf0e10cSrcweir             OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
2498*cdf0e10cSrcweir 			::connectivity::OSQLParseNode* pGroupBy = pSelectRoot->getChild(3)->getChild(2)->getChild(2);
2499*cdf0e10cSrcweir 
2500*cdf0e10cSrcweir 			for( sal_uInt32 i=0 ; i < pGroupBy->count() && eOk == eErrorCode; ++i )
2501*cdf0e10cSrcweir 			{
2502*cdf0e10cSrcweir                 OTableFieldDescRef aDragInfo = new OTableFieldDesc();
2503*cdf0e10cSrcweir                 ::connectivity::OSQLParseNode* pParamRef = NULL;
2504*cdf0e10cSrcweir 				::connectivity::OSQLParseNode* pArgument = pGroupBy->getChild( i );
2505*cdf0e10cSrcweir 				if(SQL_ISRULE(pArgument,column_ref))
2506*cdf0e10cSrcweir 				{
2507*cdf0e10cSrcweir 					if ( eOk == (eErrorCode = FillDragInfo(_pView,pArgument,aDragInfo)) )
2508*cdf0e10cSrcweir 					{
2509*cdf0e10cSrcweir 						aDragInfo->SetGroupBy(sal_True);
2510*cdf0e10cSrcweir 						_pSelectionBrw->AddGroupBy(aDragInfo,i);
2511*cdf0e10cSrcweir 					}
2512*cdf0e10cSrcweir 				}
2513*cdf0e10cSrcweir                 else if(SQL_ISRULE(pArgument, general_set_fct ) &&
2514*cdf0e10cSrcweir 						SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
2515*cdf0e10cSrcweir 						eOk == FillDragInfo(_pView,pParamRef,aDragInfo))
2516*cdf0e10cSrcweir                 {
2517*cdf0e10cSrcweir                     aDragInfo->SetGroupBy(sal_True);
2518*cdf0e10cSrcweir 					_pSelectionBrw->AddGroupBy( aDragInfo, i );
2519*cdf0e10cSrcweir                 }
2520*cdf0e10cSrcweir                 else if( SQL_ISRULE(pArgument, set_fct_spec ) )
2521*cdf0e10cSrcweir                 {
2522*cdf0e10cSrcweir 		            Reference< XConnection> xConnection = rController.getConnection();
2523*cdf0e10cSrcweir 		            if(xConnection.is())
2524*cdf0e10cSrcweir 		            {
2525*cdf0e10cSrcweir                         ::rtl::OUString sGroupByExpression;
2526*cdf0e10cSrcweir 			            pArgument->parseNodeToStr(	sGroupByExpression,
2527*cdf0e10cSrcweir 													xConnection,
2528*cdf0e10cSrcweir 													&rController.getParser().getContext(),
2529*cdf0e10cSrcweir 													sal_True,
2530*cdf0e10cSrcweir 													sal_True); // quote is to true because we need quoted elements inside the function
2531*cdf0e10cSrcweir                         _pView->fillFunctionInfo(pArgument,sGroupByExpression,aDragInfo);
2532*cdf0e10cSrcweir                         aDragInfo->SetFunctionType(FKT_OTHER);
2533*cdf0e10cSrcweir                         aDragInfo->SetGroupBy(sal_True);
2534*cdf0e10cSrcweir                         aDragInfo->SetVisible(sal_False);
2535*cdf0e10cSrcweir                         _pSelectionBrw->AddGroupBy( aDragInfo, i );
2536*cdf0e10cSrcweir                     }
2537*cdf0e10cSrcweir                     else
2538*cdf0e10cSrcweir                         eErrorCode = eColumnNotFound;
2539*cdf0e10cSrcweir                 }
2540*cdf0e10cSrcweir 			}
2541*cdf0e10cSrcweir 		}
2542*cdf0e10cSrcweir 		return eErrorCode;
2543*cdf0e10cSrcweir 	}
2544*cdf0e10cSrcweir 
2545*cdf0e10cSrcweir     //------------------------------------------------------------------------------
2546*cdf0e10cSrcweir 	String getParseErrorMessage( SqlParseError _eErrorCode )
2547*cdf0e10cSrcweir 	{
2548*cdf0e10cSrcweir 		sal_uInt16 nResId;
2549*cdf0e10cSrcweir 		switch(_eErrorCode)
2550*cdf0e10cSrcweir 		{
2551*cdf0e10cSrcweir 			case eIllegalJoin:
2552*cdf0e10cSrcweir 				nResId = STR_QRY_ILLEGAL_JOIN;
2553*cdf0e10cSrcweir 				break;
2554*cdf0e10cSrcweir 			case eStatementTooLong:
2555*cdf0e10cSrcweir 				nResId = STR_QRY_TOO_LONG_STATEMENT;
2556*cdf0e10cSrcweir 				break;
2557*cdf0e10cSrcweir 			case eNoConnection:
2558*cdf0e10cSrcweir 				nResId = STR_QRY_SYNTAX;
2559*cdf0e10cSrcweir 				break;
2560*cdf0e10cSrcweir 			case eNoSelectStatement:
2561*cdf0e10cSrcweir 				nResId = STR_QRY_NOSELECT;
2562*cdf0e10cSrcweir 				break;
2563*cdf0e10cSrcweir 			case eColumnInLikeNotFound:
2564*cdf0e10cSrcweir 				nResId = STR_QRY_SYNTAX;
2565*cdf0e10cSrcweir 				break;
2566*cdf0e10cSrcweir 			case eNoColumnInLike:
2567*cdf0e10cSrcweir 				nResId = STR_QRY_SYNTAX;
2568*cdf0e10cSrcweir 				break;
2569*cdf0e10cSrcweir 			case eColumnNotFound:
2570*cdf0e10cSrcweir 				nResId = STR_QRY_SYNTAX;
2571*cdf0e10cSrcweir 				break;
2572*cdf0e10cSrcweir 			case eNativeMode:
2573*cdf0e10cSrcweir 				nResId = STR_QRY_NATIVE;
2574*cdf0e10cSrcweir 				break;
2575*cdf0e10cSrcweir 			case eTooManyTables:
2576*cdf0e10cSrcweir 				nResId = STR_QRY_TOO_MANY_TABLES;
2577*cdf0e10cSrcweir 				break;
2578*cdf0e10cSrcweir 			case eTooManyConditions:
2579*cdf0e10cSrcweir 				nResId = STR_QRY_TOOMANYCOND;
2580*cdf0e10cSrcweir 				break;
2581*cdf0e10cSrcweir 			case eTooManyColumns:
2582*cdf0e10cSrcweir 				nResId = STR_QRY_TOO_MANY_COLUMNS;
2583*cdf0e10cSrcweir 				break;
2584*cdf0e10cSrcweir 			case eStatementTooComplex:
2585*cdf0e10cSrcweir 				nResId = STR_QRY_TOOCOMPLEX;
2586*cdf0e10cSrcweir 				break;
2587*cdf0e10cSrcweir 			default:
2588*cdf0e10cSrcweir 				nResId = STR_QRY_SYNTAX;
2589*cdf0e10cSrcweir 				break;
2590*cdf0e10cSrcweir 		}
2591*cdf0e10cSrcweir 		;
2592*cdf0e10cSrcweir         return String( ModuleRes( nResId ) );
2593*cdf0e10cSrcweir 	}
2594*cdf0e10cSrcweir 
2595*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2596*cdf0e10cSrcweir 	//------------------------------------------------------------------------------
2597*cdf0e10cSrcweir }
2598*cdf0e10cSrcweir // end of anonymouse namespace
2599*cdf0e10cSrcweir DBG_NAME(OQueryDesignView)
2600*cdf0e10cSrcweir 
2601*cdf0e10cSrcweir OQueryDesignView::OQueryDesignView(	OQueryContainerWindow* _pParent,
2602*cdf0e10cSrcweir 									OQueryController& _rController,
2603*cdf0e10cSrcweir 									const Reference< XMultiServiceFactory >& _rFactory)
2604*cdf0e10cSrcweir 	:OQueryView( _pParent, _rController, _rFactory )
2605*cdf0e10cSrcweir 	,m_aSplitter( this )
2606*cdf0e10cSrcweir 	,m_eChildFocus(NONE)
2607*cdf0e10cSrcweir 	,m_bInKeyEvent(sal_False)
2608*cdf0e10cSrcweir 	,m_bInSplitHandler( sal_False )
2609*cdf0e10cSrcweir {
2610*cdf0e10cSrcweir     DBG_CTOR(OQueryDesignView,NULL);
2611*cdf0e10cSrcweir 
2612*cdf0e10cSrcweir 	try
2613*cdf0e10cSrcweir 	{
2614*cdf0e10cSrcweir 		SvtSysLocale aSysLocale;
2615*cdf0e10cSrcweir 		m_aLocale = aSysLocale.GetLocaleData().getLocale();
2616*cdf0e10cSrcweir 		m_sDecimalSep = aSysLocale.GetLocaleData().getNumDecimalSep();
2617*cdf0e10cSrcweir 	}
2618*cdf0e10cSrcweir 	catch(Exception&)
2619*cdf0e10cSrcweir 	{
2620*cdf0e10cSrcweir 	}
2621*cdf0e10cSrcweir 
2622*cdf0e10cSrcweir 	m_pSelectionBox = new OSelectionBrowseBox(this);
2623*cdf0e10cSrcweir 
2624*cdf0e10cSrcweir 	setNoneVisbleRow(static_cast<OQueryController&>(getController()).getVisibleRows());
2625*cdf0e10cSrcweir 	m_pSelectionBox->Show();
2626*cdf0e10cSrcweir 	// Splitter einrichten
2627*cdf0e10cSrcweir 	m_aSplitter.SetSplitHdl(LINK(this, OQueryDesignView,SplitHdl));
2628*cdf0e10cSrcweir 	m_aSplitter.Show();
2629*cdf0e10cSrcweir 
2630*cdf0e10cSrcweir }
2631*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2632*cdf0e10cSrcweir OQueryDesignView::~OQueryDesignView()
2633*cdf0e10cSrcweir {
2634*cdf0e10cSrcweir 	if ( m_pTableView )
2635*cdf0e10cSrcweir 		::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
2636*cdf0e10cSrcweir 	::std::auto_ptr<Window> aTemp(m_pSelectionBox);
2637*cdf0e10cSrcweir 	m_pSelectionBox = NULL;
2638*cdf0e10cSrcweir 
2639*cdf0e10cSrcweir     DBG_DTOR(OQueryDesignView,NULL);
2640*cdf0e10cSrcweir }
2641*cdf0e10cSrcweir //------------------------------------------------------------------------------
2642*cdf0e10cSrcweir IMPL_LINK( OQueryDesignView, SplitHdl, void*, /*p*/ )
2643*cdf0e10cSrcweir {
2644*cdf0e10cSrcweir 	if (!getController().isReadOnly())
2645*cdf0e10cSrcweir 	{
2646*cdf0e10cSrcweir 		m_bInSplitHandler = sal_True;
2647*cdf0e10cSrcweir 		m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),m_aSplitter.GetSplitPosPixel() ) );
2648*cdf0e10cSrcweir 		static_cast<OQueryController&>(getController()).setSplitPos(m_aSplitter.GetSplitPosPixel());
2649*cdf0e10cSrcweir 		static_cast<OQueryController&>(getController()).setModified( sal_True );
2650*cdf0e10cSrcweir 		Resize();
2651*cdf0e10cSrcweir 		m_bInSplitHandler = sal_True;
2652*cdf0e10cSrcweir 	}
2653*cdf0e10cSrcweir 	return 0L;
2654*cdf0e10cSrcweir }
2655*cdf0e10cSrcweir // -------------------------------------------------------------------------
2656*cdf0e10cSrcweir void OQueryDesignView::Construct()
2657*cdf0e10cSrcweir {
2658*cdf0e10cSrcweir 	m_pTableView = new OQueryTableView(m_pScrollWindow,this);
2659*cdf0e10cSrcweir 	::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::AddWindow));
2660*cdf0e10cSrcweir 	OQueryView::Construct();
2661*cdf0e10cSrcweir }
2662*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2663*cdf0e10cSrcweir void OQueryDesignView::initialize()
2664*cdf0e10cSrcweir {
2665*cdf0e10cSrcweir 	if(static_cast<OQueryController&>(getController()).getSplitPos() != -1)
2666*cdf0e10cSrcweir 	{
2667*cdf0e10cSrcweir 		m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),static_cast<OQueryController&>(getController()).getSplitPos() ) );
2668*cdf0e10cSrcweir 		m_aSplitter.SetSplitPosPixel(static_cast<OQueryController&>(getController()).getSplitPos());
2669*cdf0e10cSrcweir 	}
2670*cdf0e10cSrcweir 	m_pSelectionBox->initialize();
2671*cdf0e10cSrcweir 	reset();
2672*cdf0e10cSrcweir }
2673*cdf0e10cSrcweir // -------------------------------------------------------------------------
2674*cdf0e10cSrcweir void OQueryDesignView::resizeDocumentView(Rectangle& _rPlayground)
2675*cdf0e10cSrcweir {
2676*cdf0e10cSrcweir 	Point aPlaygroundPos( _rPlayground.TopLeft() );
2677*cdf0e10cSrcweir 	Size aPlaygroundSize( _rPlayground.GetSize() );
2678*cdf0e10cSrcweir 
2679*cdf0e10cSrcweir 	// calc the split pos, and forward it to the controller
2680*cdf0e10cSrcweir 	sal_Int32 nSplitPos = static_cast<OQueryController&>(getController()).getSplitPos();
2681*cdf0e10cSrcweir 	if ( 0 != aPlaygroundSize.Height() )
2682*cdf0e10cSrcweir 	{
2683*cdf0e10cSrcweir 		if	(	( -1 == nSplitPos )
2684*cdf0e10cSrcweir 			||	( nSplitPos >= aPlaygroundSize.Height() )
2685*cdf0e10cSrcweir 			)
2686*cdf0e10cSrcweir 		{
2687*cdf0e10cSrcweir 			// let the selection browse box determine an optimal size
2688*cdf0e10cSrcweir 			Size aSelectionBoxSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
2689*cdf0e10cSrcweir 			nSplitPos = aPlaygroundSize.Height() - aSelectionBoxSize.Height() - m_aSplitter.GetSizePixel().Height();
2690*cdf0e10cSrcweir 			// still an invalid size?
2691*cdf0e10cSrcweir 			if ( nSplitPos == -1 || nSplitPos >= aPlaygroundSize.Height() )
2692*cdf0e10cSrcweir 				nSplitPos = sal_Int32(aPlaygroundSize.Height()*0.6);
2693*cdf0e10cSrcweir 
2694*cdf0e10cSrcweir 			static_cast<OQueryController&>(getController()).setSplitPos(nSplitPos);
2695*cdf0e10cSrcweir 		}
2696*cdf0e10cSrcweir 
2697*cdf0e10cSrcweir 		if ( !m_bInSplitHandler )
2698*cdf0e10cSrcweir 		{	// the resize is triggered by something else than the split handler
2699*cdf0e10cSrcweir 			// our main focus is to try to preserve the size of the selectionbrowse box
2700*cdf0e10cSrcweir 			Size aSelBoxSize = m_pSelectionBox->GetSizePixel();
2701*cdf0e10cSrcweir 			if ( aSelBoxSize.Height() )
2702*cdf0e10cSrcweir 			{
2703*cdf0e10cSrcweir 				// keep the size of the sel box constant
2704*cdf0e10cSrcweir 				nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxSize.Height();
2705*cdf0e10cSrcweir 
2706*cdf0e10cSrcweir 				// and if the box is smaller than the optimal size, try to do something about it
2707*cdf0e10cSrcweir 				Size aSelBoxOptSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
2708*cdf0e10cSrcweir 				if ( aSelBoxOptSize.Height() > aSelBoxSize.Height() )
2709*cdf0e10cSrcweir 				{
2710*cdf0e10cSrcweir 					nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxOptSize.Height();
2711*cdf0e10cSrcweir 				}
2712*cdf0e10cSrcweir 
2713*cdf0e10cSrcweir 				static_cast< OQueryController& >(getController()).setSplitPos( nSplitPos );
2714*cdf0e10cSrcweir 			}
2715*cdf0e10cSrcweir 		}
2716*cdf0e10cSrcweir 	}
2717*cdf0e10cSrcweir 
2718*cdf0e10cSrcweir 	// normalize the split pos
2719*cdf0e10cSrcweir 	Point	aSplitPos		= Point( _rPlayground.Left(), nSplitPos );
2720*cdf0e10cSrcweir 	Size	aSplitSize		= Size( _rPlayground.GetSize().Width(), m_aSplitter.GetSizePixel().Height() );
2721*cdf0e10cSrcweir 
2722*cdf0e10cSrcweir 	if( ( aSplitPos.Y() + aSplitSize.Height() ) > ( aPlaygroundSize.Height() ))
2723*cdf0e10cSrcweir 		aSplitPos.Y() = aPlaygroundSize.Height() - aSplitSize.Height();
2724*cdf0e10cSrcweir 
2725*cdf0e10cSrcweir 	if( aSplitPos.Y() <= aPlaygroundPos.Y() )
2726*cdf0e10cSrcweir 		aSplitPos.Y() = aPlaygroundPos.Y() + sal_Int32(aPlaygroundSize.Height() * 0.2);
2727*cdf0e10cSrcweir 
2728*cdf0e10cSrcweir 	// position the table
2729*cdf0e10cSrcweir 	Size aTableViewSize(aPlaygroundSize.Width(), aSplitPos.Y() - aPlaygroundPos.Y());
2730*cdf0e10cSrcweir 	m_pScrollWindow->SetPosSizePixel(aPlaygroundPos, aTableViewSize);
2731*cdf0e10cSrcweir 
2732*cdf0e10cSrcweir 	// position the selection browse box
2733*cdf0e10cSrcweir 	Point aPos( aPlaygroundPos.X(), aSplitPos.Y() + aSplitSize.Height() );
2734*cdf0e10cSrcweir 	m_pSelectionBox->SetPosSizePixel( aPos, Size( aPlaygroundSize.Width(), aPlaygroundSize.Height() - aSplitSize.Height() - aTableViewSize.Height() ));
2735*cdf0e10cSrcweir 
2736*cdf0e10cSrcweir 	// set the size of the splitter
2737*cdf0e10cSrcweir 	m_aSplitter.SetPosSizePixel( aSplitPos, aSplitSize );
2738*cdf0e10cSrcweir 	m_aSplitter.SetDragRectPixel( _rPlayground );
2739*cdf0e10cSrcweir 
2740*cdf0e10cSrcweir 	// just for completeness: there is no space left, we occupied it all ...
2741*cdf0e10cSrcweir 	_rPlayground.SetPos( _rPlayground.BottomRight() );
2742*cdf0e10cSrcweir 	_rPlayground.SetSize( Size( 0, 0 ) );
2743*cdf0e10cSrcweir }
2744*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2745*cdf0e10cSrcweir void OQueryDesignView::setReadOnly(sal_Bool _bReadOnly)
2746*cdf0e10cSrcweir {
2747*cdf0e10cSrcweir 	m_pSelectionBox->SetReadOnly(_bReadOnly);
2748*cdf0e10cSrcweir }
2749*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2750*cdf0e10cSrcweir void OQueryDesignView::clear()
2751*cdf0e10cSrcweir {
2752*cdf0e10cSrcweir 	m_pSelectionBox->ClearAll(); // clear the whole selection
2753*cdf0e10cSrcweir 	m_pTableView->ClearAll();
2754*cdf0e10cSrcweir }
2755*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2756*cdf0e10cSrcweir void OQueryDesignView::setStatement(const ::rtl::OUString& /*_rsStatement*/)
2757*cdf0e10cSrcweir {
2758*cdf0e10cSrcweir }
2759*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2760*cdf0e10cSrcweir void OQueryDesignView::copy()
2761*cdf0e10cSrcweir {
2762*cdf0e10cSrcweir 	if( m_eChildFocus == SELECTION)
2763*cdf0e10cSrcweir 		m_pSelectionBox->copy();
2764*cdf0e10cSrcweir }
2765*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2766*cdf0e10cSrcweir sal_Bool OQueryDesignView::isCutAllowed()
2767*cdf0e10cSrcweir {
2768*cdf0e10cSrcweir 	sal_Bool bAllowed = sal_False;
2769*cdf0e10cSrcweir 	if ( SELECTION == m_eChildFocus )
2770*cdf0e10cSrcweir 		bAllowed = m_pSelectionBox->isCutAllowed();
2771*cdf0e10cSrcweir 	return bAllowed;
2772*cdf0e10cSrcweir }
2773*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2774*cdf0e10cSrcweir sal_Bool OQueryDesignView::isPasteAllowed()
2775*cdf0e10cSrcweir {
2776*cdf0e10cSrcweir 	sal_Bool bAllowed = sal_False;
2777*cdf0e10cSrcweir 	if ( SELECTION == m_eChildFocus )
2778*cdf0e10cSrcweir 		bAllowed = m_pSelectionBox->isPasteAllowed();
2779*cdf0e10cSrcweir 	return bAllowed;
2780*cdf0e10cSrcweir }
2781*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2782*cdf0e10cSrcweir sal_Bool OQueryDesignView::isCopyAllowed()
2783*cdf0e10cSrcweir {
2784*cdf0e10cSrcweir 	sal_Bool bAllowed = sal_False;
2785*cdf0e10cSrcweir 	if ( SELECTION == m_eChildFocus )
2786*cdf0e10cSrcweir 		bAllowed = m_pSelectionBox->isCopyAllowed();
2787*cdf0e10cSrcweir 	return bAllowed;
2788*cdf0e10cSrcweir }
2789*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2790*cdf0e10cSrcweir void OQueryDesignView::stopTimer()
2791*cdf0e10cSrcweir {
2792*cdf0e10cSrcweir 	m_pSelectionBox->stopTimer();
2793*cdf0e10cSrcweir }
2794*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2795*cdf0e10cSrcweir void OQueryDesignView::startTimer()
2796*cdf0e10cSrcweir {
2797*cdf0e10cSrcweir 	m_pSelectionBox->startTimer();
2798*cdf0e10cSrcweir }
2799*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2800*cdf0e10cSrcweir void OQueryDesignView::cut()
2801*cdf0e10cSrcweir {
2802*cdf0e10cSrcweir 	if( m_eChildFocus == SELECTION)
2803*cdf0e10cSrcweir 	{
2804*cdf0e10cSrcweir 		m_pSelectionBox->cut();
2805*cdf0e10cSrcweir 		static_cast<OQueryController&>(getController()).setModified(sal_True);
2806*cdf0e10cSrcweir 	}
2807*cdf0e10cSrcweir }
2808*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2809*cdf0e10cSrcweir void OQueryDesignView::paste()
2810*cdf0e10cSrcweir {
2811*cdf0e10cSrcweir 	if( m_eChildFocus == SELECTION)
2812*cdf0e10cSrcweir 	{
2813*cdf0e10cSrcweir 		m_pSelectionBox->paste();
2814*cdf0e10cSrcweir 		static_cast<OQueryController&>(getController()).setModified(sal_True);
2815*cdf0e10cSrcweir 	}
2816*cdf0e10cSrcweir }
2817*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2818*cdf0e10cSrcweir void OQueryDesignView::TableDeleted(const ::rtl::OUString& rAliasName)
2819*cdf0e10cSrcweir {
2820*cdf0e10cSrcweir 	// Nachricht, dass Tabelle aus dem Fenster gel"oscht wurde
2821*cdf0e10cSrcweir 	DeleteFields(rAliasName);
2822*cdf0e10cSrcweir 	static_cast<OQueryController&>(getController()).InvalidateFeature(ID_BROWSER_ADDTABLE);	// view nochmal bescheid sagen
2823*cdf0e10cSrcweir }
2824*cdf0e10cSrcweir //------------------------------------------------------------------------------
2825*cdf0e10cSrcweir void OQueryDesignView::DeleteFields( const ::rtl::OUString& rAliasName )
2826*cdf0e10cSrcweir {
2827*cdf0e10cSrcweir 	m_pSelectionBox->DeleteFields( rAliasName );
2828*cdf0e10cSrcweir }
2829*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2830*cdf0e10cSrcweir bool OQueryDesignView::HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo)  const
2831*cdf0e10cSrcweir {
2832*cdf0e10cSrcweir     return m_pSelectionBox->HasFieldByAliasName( rFieldName, rInfo);
2833*cdf0e10cSrcweir }
2834*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2835*cdf0e10cSrcweir SqlParseError OQueryDesignView::InsertField( const OTableFieldDescRef& rInfo, sal_Bool bVis, sal_Bool bActivate)
2836*cdf0e10cSrcweir {
2837*cdf0e10cSrcweir 	return m_pSelectionBox->InsertField( rInfo, BROWSER_INVALIDID,bVis, bActivate ).isValid() ? eOk : eTooManyColumns;
2838*cdf0e10cSrcweir }
2839*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2840*cdf0e10cSrcweir sal_Int32 OQueryDesignView::getColWidth(sal_uInt16 _nColPos) const
2841*cdf0e10cSrcweir {
2842*cdf0e10cSrcweir     static sal_Int32 s_nDefaultWidth = GetTextWidth(String(RTL_CONSTASCII_USTRINGPARAM("0"))) * 15;
2843*cdf0e10cSrcweir     sal_Int32 nWidth = static_cast<OQueryController&>(getController()).getColWidth(_nColPos);
2844*cdf0e10cSrcweir     if ( !nWidth )
2845*cdf0e10cSrcweir         nWidth = s_nDefaultWidth;
2846*cdf0e10cSrcweir 	return nWidth;
2847*cdf0e10cSrcweir }
2848*cdf0e10cSrcweir //------------------------------------------------------------------------------
2849*cdf0e10cSrcweir void OQueryDesignView::fillValidFields(const ::rtl::OUString& sAliasName, ComboBox* pFieldList)
2850*cdf0e10cSrcweir {
2851*cdf0e10cSrcweir 	DBG_ASSERT(pFieldList != NULL, "OQueryDesignView::FillValidFields : What the hell do you think I can do with a NULL-ptr ? This will crash !");
2852*cdf0e10cSrcweir 	pFieldList->Clear();
2853*cdf0e10cSrcweir 
2854*cdf0e10cSrcweir 	sal_Bool bAllTables = sAliasName.getLength() == 0;
2855*cdf0e10cSrcweir 
2856*cdf0e10cSrcweir 	OJoinTableView::OTableWindowMap* pTabWins = m_pTableView->GetTabWinMap();
2857*cdf0e10cSrcweir 	::rtl::OUString strCurrentPrefix;
2858*cdf0e10cSrcweir 	::std::vector< ::rtl::OUString> aFields;
2859*cdf0e10cSrcweir 	OJoinTableView::OTableWindowMap::iterator aIter = pTabWins->begin();
2860*cdf0e10cSrcweir     OJoinTableView::OTableWindowMap::iterator aEnd  = pTabWins->end();
2861*cdf0e10cSrcweir     for(;aIter != aEnd;++aIter)
2862*cdf0e10cSrcweir 	{
2863*cdf0e10cSrcweir 		OQueryTableWindow* pCurrentWin = static_cast<OQueryTableWindow*>(aIter->second);
2864*cdf0e10cSrcweir 		if (bAllTables || (pCurrentWin->GetAliasName() == sAliasName))
2865*cdf0e10cSrcweir 		{
2866*cdf0e10cSrcweir 			strCurrentPrefix = pCurrentWin->GetAliasName();
2867*cdf0e10cSrcweir 			strCurrentPrefix += ::rtl::OUString('.');
2868*cdf0e10cSrcweir 
2869*cdf0e10cSrcweir 			pCurrentWin->EnumValidFields(aFields);
2870*cdf0e10cSrcweir 
2871*cdf0e10cSrcweir 			::std::vector< ::rtl::OUString>::iterator aStrIter = aFields.begin();
2872*cdf0e10cSrcweir             ::std::vector< ::rtl::OUString>::iterator aStrEnd = aFields.end();
2873*cdf0e10cSrcweir 			for(;aStrIter != aStrEnd;++aStrIter)
2874*cdf0e10cSrcweir 			{
2875*cdf0e10cSrcweir 				if (bAllTables || aStrIter->toChar() == '*')
2876*cdf0e10cSrcweir 					pFieldList->InsertEntry(::rtl::OUString(strCurrentPrefix) += *aStrIter);
2877*cdf0e10cSrcweir 				else
2878*cdf0e10cSrcweir 					pFieldList->InsertEntry(*aStrIter);
2879*cdf0e10cSrcweir 			}
2880*cdf0e10cSrcweir 
2881*cdf0e10cSrcweir 			if (!bAllTables)
2882*cdf0e10cSrcweir 				// das heisst, dass ich in diesen Block kam, weil der Tabellenname genau der gesuchte war, also bin ich fertig
2883*cdf0e10cSrcweir 				// (dadurch verhindere ich auch das doppelte Einfuegen von Feldern, wenn eine Tabelle mehrmals als TabWin vorkommt)
2884*cdf0e10cSrcweir 				break;
2885*cdf0e10cSrcweir 		}
2886*cdf0e10cSrcweir 	}
2887*cdf0e10cSrcweir }
2888*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2889*cdf0e10cSrcweir long OQueryDesignView::PreNotify(NotifyEvent& rNEvt)
2890*cdf0e10cSrcweir {
2891*cdf0e10cSrcweir 	switch (rNEvt.GetType())
2892*cdf0e10cSrcweir 	{
2893*cdf0e10cSrcweir 		case EVENT_GETFOCUS:
2894*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
2895*cdf0e10cSrcweir 			{
2896*cdf0e10cSrcweir 				Window* pFocus = Application::GetFocusWindow();
2897*cdf0e10cSrcweir                 (void)pFocus;
2898*cdf0e10cSrcweir 			}
2899*cdf0e10cSrcweir #endif
2900*cdf0e10cSrcweir 
2901*cdf0e10cSrcweir 			if ( m_pSelectionBox && m_pSelectionBox->HasChildPathFocus() )
2902*cdf0e10cSrcweir 				m_eChildFocus = SELECTION;
2903*cdf0e10cSrcweir 			else
2904*cdf0e10cSrcweir 				m_eChildFocus = TABLEVIEW;
2905*cdf0e10cSrcweir 			break;
2906*cdf0e10cSrcweir 	}
2907*cdf0e10cSrcweir 
2908*cdf0e10cSrcweir 	return OQueryView::PreNotify(rNEvt);
2909*cdf0e10cSrcweir }
2910*cdf0e10cSrcweir //------------------------------------------------------------------------------
2911*cdf0e10cSrcweir 
2912*cdf0e10cSrcweir 
2913*cdf0e10cSrcweir // -----------------------------------------------------------------------------
2914*cdf0e10cSrcweir // check if the statement is correct when not returning false
2915*cdf0e10cSrcweir sal_Bool OQueryDesignView::checkStatement()
2916*cdf0e10cSrcweir {
2917*cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
2918*cdf0e10cSrcweir 	if ( m_pSelectionBox )
2919*cdf0e10cSrcweir 		bRet = m_pSelectionBox->Save(); // a error occured so we return no
2920*cdf0e10cSrcweir 	return bRet;
2921*cdf0e10cSrcweir }
2922*cdf0e10cSrcweir //-------------------------------------------------------------------------------
2923*cdf0e10cSrcweir ::rtl::OUString OQueryDesignView::getStatement()
2924*cdf0e10cSrcweir {
2925*cdf0e10cSrcweir 	OQueryController& rController = static_cast<OQueryController&>(getController());
2926*cdf0e10cSrcweir 	m_rController.clearError();
2927*cdf0e10cSrcweir 	// used for fields which aren't any longer in the statement
2928*cdf0e10cSrcweir 	OTableFields& rUnUsedFields = rController.getUnUsedFields();
2929*cdf0e10cSrcweir 	OTableFields().swap( rUnUsedFields );
2930*cdf0e10cSrcweir 
2931*cdf0e10cSrcweir 	// create the select columns
2932*cdf0e10cSrcweir 	sal_uInt32 nFieldcount = 0;
2933*cdf0e10cSrcweir 	OTableFields& rFieldList = rController.getTableFieldDesc();
2934*cdf0e10cSrcweir 	OTableFields::iterator aIter = rFieldList.begin();
2935*cdf0e10cSrcweir     OTableFields::iterator aEnd = rFieldList.end();
2936*cdf0e10cSrcweir 	for(;aIter != aEnd;++aIter)
2937*cdf0e10cSrcweir 	{
2938*cdf0e10cSrcweir 		OTableFieldDescRef pEntryField = *aIter;
2939*cdf0e10cSrcweir 		if ( pEntryField->GetField().getLength() && pEntryField->IsVisible() )
2940*cdf0e10cSrcweir 			++nFieldcount;
2941*cdf0e10cSrcweir 		else if (pEntryField->GetField().getLength()			&&
2942*cdf0e10cSrcweir 				!pEntryField->HasCriteria()					&&
2943*cdf0e10cSrcweir 				pEntryField->isNoneFunction()				&&
2944*cdf0e10cSrcweir 				pEntryField->GetOrderDir() == ORDER_NONE	&&
2945*cdf0e10cSrcweir                 !pEntryField->IsGroupBy()                   &&
2946*cdf0e10cSrcweir 				!pEntryField->GetFunction().getLength() )
2947*cdf0e10cSrcweir 			rUnUsedFields.push_back(pEntryField);
2948*cdf0e10cSrcweir 	}
2949*cdf0e10cSrcweir 	if ( !nFieldcount )	// keine Felder sichtbar also zur"uck
2950*cdf0e10cSrcweir 	{
2951*cdf0e10cSrcweir 		rUnUsedFields = rFieldList;
2952*cdf0e10cSrcweir 		return ::rtl::OUString();
2953*cdf0e10cSrcweir 	}
2954*cdf0e10cSrcweir 
2955*cdf0e10cSrcweir 	OQueryTableView::OTableWindowMap* pTabList   = m_pTableView->GetTabWinMap();
2956*cdf0e10cSrcweir 	sal_uInt32 nTabcount		= pTabList->size();
2957*cdf0e10cSrcweir 
2958*cdf0e10cSrcweir 	::rtl::OUString	aFieldListStr(GenerateSelectList(this,rFieldList,nTabcount>1));
2959*cdf0e10cSrcweir 	if( !aFieldListStr.getLength() )
2960*cdf0e10cSrcweir 		return ::rtl::OUString();
2961*cdf0e10cSrcweir 	// Ausnahmebehandlung, wenn keine Felder angegeben worden sind
2962*cdf0e10cSrcweir 	// Dann darf die Tabpage nicht gewechselt werden
2963*cdf0e10cSrcweir 	// Im TabBarSelectHdl wird der SQL-::rtl::OUString auf STATEMENT_NOFIELDS abgefragt
2964*cdf0e10cSrcweir 	// und eine Errormeldung erzeugt
2965*cdf0e10cSrcweir 	// ----------------- Tabellenliste aufbauen ----------------------
2966*cdf0e10cSrcweir 
2967*cdf0e10cSrcweir 	const ::std::vector<OTableConnection*>*	pConnList = m_pTableView->getTableConnections();
2968*cdf0e10cSrcweir 	Reference< XConnection> xConnection = rController.getConnection();
2969*cdf0e10cSrcweir 	::rtl::OUString aTableListStr(GenerateFromClause(xConnection,pTabList,pConnList));
2970*cdf0e10cSrcweir 	DBG_ASSERT(aTableListStr.getLength(), "OQueryDesignView::getStatement() : unerwartet : habe Felder, aber keine Tabellen !");
2971*cdf0e10cSrcweir 	// wenn es Felder gibt, koennen die nur durch Einfuegen aus einer schon existenten Tabelle entstanden sein; wenn andererseits
2972*cdf0e10cSrcweir 	// eine Tabelle geloescht wird, verschwinden auch die zugehoerigen Felder -> ergo KANN es das nicht geben, dass Felder
2973*cdf0e10cSrcweir 	// existieren, aber keine Tabellen (und aFieldListStr hat schon eine Laenge, das stelle ich oben sicher)
2974*cdf0e10cSrcweir 	::rtl::OUStringBuffer aHavingStr,aCriteriaListStr;
2975*cdf0e10cSrcweir 	// ----------------- Kriterien aufbauen ----------------------
2976*cdf0e10cSrcweir 	if (!GenerateCriterias(this,aCriteriaListStr,aHavingStr,rFieldList, nTabcount > 1))
2977*cdf0e10cSrcweir 		return ::rtl::OUString();
2978*cdf0e10cSrcweir 
2979*cdf0e10cSrcweir 	::rtl::OUString aJoinCrit;
2980*cdf0e10cSrcweir 	GenerateInnerJoinCriterias(xConnection,aJoinCrit,pConnList);
2981*cdf0e10cSrcweir 	if(aJoinCrit.getLength())
2982*cdf0e10cSrcweir 	{
2983*cdf0e10cSrcweir 		::rtl::OUString aTmp = ::rtl::OUString::createFromAscii("( ");
2984*cdf0e10cSrcweir 		aTmp += aJoinCrit;
2985*cdf0e10cSrcweir 		aTmp += ::rtl::OUString::createFromAscii(" )");
2986*cdf0e10cSrcweir 		if(aCriteriaListStr.getLength())
2987*cdf0e10cSrcweir 		{
2988*cdf0e10cSrcweir 			aTmp += C_AND;
2989*cdf0e10cSrcweir 			aTmp += aCriteriaListStr.makeStringAndClear();
2990*cdf0e10cSrcweir 		}
2991*cdf0e10cSrcweir 		aCriteriaListStr = aTmp;
2992*cdf0e10cSrcweir 	}
2993*cdf0e10cSrcweir 	// ----------------- Statement aufbauen ----------------------
2994*cdf0e10cSrcweir 	::rtl::OUStringBuffer aSqlCmd(::rtl::OUString::createFromAscii("SELECT "));
2995*cdf0e10cSrcweir 	if(static_cast<OQueryController&>(getController()).isDistinct())
2996*cdf0e10cSrcweir 		aSqlCmd.append(::rtl::OUString::createFromAscii(" DISTINCT "));
2997*cdf0e10cSrcweir 	aSqlCmd.append(aFieldListStr);
2998*cdf0e10cSrcweir 	aSqlCmd.append(::rtl::OUString::createFromAscii(" FROM "));
2999*cdf0e10cSrcweir 	aSqlCmd.append(aTableListStr);
3000*cdf0e10cSrcweir 
3001*cdf0e10cSrcweir 	if (aCriteriaListStr.getLength())
3002*cdf0e10cSrcweir 	{
3003*cdf0e10cSrcweir 		aSqlCmd.append(::rtl::OUString::createFromAscii(" WHERE "));
3004*cdf0e10cSrcweir 		aSqlCmd.append(aCriteriaListStr.makeStringAndClear());
3005*cdf0e10cSrcweir 	}
3006*cdf0e10cSrcweir 	// ----------------- GroupBy aufbauen und Anh"angen ------------
3007*cdf0e10cSrcweir 	Reference<XDatabaseMetaData> xMeta;
3008*cdf0e10cSrcweir 	if ( xConnection.is() )
3009*cdf0e10cSrcweir 		xMeta = xConnection->getMetaData();
3010*cdf0e10cSrcweir 	sal_Bool bUseAlias = nTabcount > 1;
3011*cdf0e10cSrcweir 	if ( xMeta.is() )
3012*cdf0e10cSrcweir 		bUseAlias = bUseAlias || !xMeta->supportsGroupByUnrelated();
3013*cdf0e10cSrcweir 
3014*cdf0e10cSrcweir 	aSqlCmd.append(GenerateGroupBy(this,rFieldList,bUseAlias));
3015*cdf0e10cSrcweir 	// ----------------- having Anh"angen ------------
3016*cdf0e10cSrcweir 	if(aHavingStr.getLength())
3017*cdf0e10cSrcweir 	{
3018*cdf0e10cSrcweir 		aSqlCmd.append(::rtl::OUString::createFromAscii(" HAVING "));
3019*cdf0e10cSrcweir 		aSqlCmd.append(aHavingStr.makeStringAndClear());
3020*cdf0e10cSrcweir 	}
3021*cdf0e10cSrcweir 	// ----------------- Sortierung aufbauen und Anh"angen ------------
3022*cdf0e10cSrcweir 	::rtl::OUString sOrder;
3023*cdf0e10cSrcweir 	SqlParseError eErrorCode = eOk;
3024*cdf0e10cSrcweir 	if ( (eErrorCode = GenerateOrder(this,rFieldList,nTabcount > 1,sOrder)) == eOk)
3025*cdf0e10cSrcweir 		aSqlCmd.append(sOrder);
3026*cdf0e10cSrcweir 	else
3027*cdf0e10cSrcweir 	{
3028*cdf0e10cSrcweir 		if ( !m_rController.hasError() )
3029*cdf0e10cSrcweir             m_rController.appendError( getParseErrorMessage( eErrorCode ) );
3030*cdf0e10cSrcweir 
3031*cdf0e10cSrcweir         m_rController.displayError();
3032*cdf0e10cSrcweir 	}
3033*cdf0e10cSrcweir 
3034*cdf0e10cSrcweir     ::rtl::OUString sSQL = aSqlCmd.makeStringAndClear();
3035*cdf0e10cSrcweir     if ( xConnection.is() )
3036*cdf0e10cSrcweir     {
3037*cdf0e10cSrcweir         ::connectivity::OSQLParser& rParser( rController.getParser() );
3038*cdf0e10cSrcweir         ::rtl::OUString sErrorMessage;
3039*cdf0e10cSrcweir         ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( sErrorMessage, sSQL, sal_True ) );
3040*cdf0e10cSrcweir         if ( pParseNode.get() )
3041*cdf0e10cSrcweir         {
3042*cdf0e10cSrcweir             OSQLParseNode* pNode = pParseNode->getChild(3)->getChild(1);
3043*cdf0e10cSrcweir             if ( pNode->count() > 1 )
3044*cdf0e10cSrcweir             {
3045*cdf0e10cSrcweir 		        ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
3046*cdf0e10cSrcweir 		        if ( pCondition ) // no where clause
3047*cdf0e10cSrcweir                 {
3048*cdf0e10cSrcweir                     OSQLParseNode::compress(pCondition);
3049*cdf0e10cSrcweir                     ::rtl::OUString sTemp;
3050*cdf0e10cSrcweir                     pParseNode->parseNodeToStr(sTemp,xConnection);
3051*cdf0e10cSrcweir                     sSQL = sTemp;
3052*cdf0e10cSrcweir                 }
3053*cdf0e10cSrcweir             }
3054*cdf0e10cSrcweir         }
3055*cdf0e10cSrcweir     }
3056*cdf0e10cSrcweir 	return sSQL;
3057*cdf0e10cSrcweir }
3058*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3059*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3060*cdf0e10cSrcweir void OQueryDesignView::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable)
3061*cdf0e10cSrcweir {
3062*cdf0e10cSrcweir 	sal_uInt16 nRow;
3063*cdf0e10cSrcweir 	switch (_nSlotId)
3064*cdf0e10cSrcweir 	{
3065*cdf0e10cSrcweir 		case SID_QUERY_VIEW_FUNCTIONS:
3066*cdf0e10cSrcweir 			nRow = BROW_FUNCTION_ROW;
3067*cdf0e10cSrcweir 			break;
3068*cdf0e10cSrcweir 		case SID_QUERY_VIEW_TABLES:
3069*cdf0e10cSrcweir 			nRow = BROW_TABLE_ROW;
3070*cdf0e10cSrcweir 			break;
3071*cdf0e10cSrcweir 		case SID_QUERY_VIEW_ALIASES:
3072*cdf0e10cSrcweir 			nRow = BROW_COLUMNALIAS_ROW;
3073*cdf0e10cSrcweir 			break;
3074*cdf0e10cSrcweir 		default:
3075*cdf0e10cSrcweir 			// ????????????
3076*cdf0e10cSrcweir 			nRow = 0;
3077*cdf0e10cSrcweir 			break;
3078*cdf0e10cSrcweir 	}
3079*cdf0e10cSrcweir 	m_pSelectionBox->SetRowVisible(nRow,_bEnable);
3080*cdf0e10cSrcweir 	m_pSelectionBox->Invalidate();
3081*cdf0e10cSrcweir }
3082*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3083*cdf0e10cSrcweir sal_Bool OQueryDesignView::isSlotEnabled(sal_Int32 _nSlotId)
3084*cdf0e10cSrcweir {
3085*cdf0e10cSrcweir 	sal_uInt16 nRow;
3086*cdf0e10cSrcweir 	switch (_nSlotId)
3087*cdf0e10cSrcweir 	{
3088*cdf0e10cSrcweir 		case SID_QUERY_VIEW_FUNCTIONS:
3089*cdf0e10cSrcweir 			nRow = BROW_FUNCTION_ROW;
3090*cdf0e10cSrcweir 			break;
3091*cdf0e10cSrcweir 		case SID_QUERY_VIEW_TABLES:
3092*cdf0e10cSrcweir 			nRow = BROW_TABLE_ROW;
3093*cdf0e10cSrcweir 			break;
3094*cdf0e10cSrcweir 		case SID_QUERY_VIEW_ALIASES:
3095*cdf0e10cSrcweir 			nRow = BROW_COLUMNALIAS_ROW;
3096*cdf0e10cSrcweir 			break;
3097*cdf0e10cSrcweir 		default:
3098*cdf0e10cSrcweir 			// ?????????
3099*cdf0e10cSrcweir 			nRow = 0;
3100*cdf0e10cSrcweir 			break;
3101*cdf0e10cSrcweir 	}
3102*cdf0e10cSrcweir 	return m_pSelectionBox->IsRowVisible(nRow);
3103*cdf0e10cSrcweir }
3104*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3105*cdf0e10cSrcweir void OQueryDesignView::SaveUIConfig()
3106*cdf0e10cSrcweir {
3107*cdf0e10cSrcweir 	OQueryController& rCtrl = static_cast<OQueryController&>(getController());
3108*cdf0e10cSrcweir 	rCtrl.SaveTabWinsPosSize( m_pTableView->GetTabWinMap(), m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos() );
3109*cdf0e10cSrcweir 	//	rCtrl.SaveTabFieldsWidth( m_pSelectionBox );
3110*cdf0e10cSrcweir 	rCtrl.setVisibleRows( m_pSelectionBox->GetNoneVisibleRows() );
3111*cdf0e10cSrcweir     if ( m_aSplitter.GetSplitPosPixel() != 0 )
3112*cdf0e10cSrcweir 	    rCtrl.setSplitPos( m_aSplitter.GetSplitPosPixel() );
3113*cdf0e10cSrcweir }
3114*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3115*cdf0e10cSrcweir OSQLParseNode* OQueryDesignView::getPredicateTreeFromEntry(OTableFieldDescRef pEntry,
3116*cdf0e10cSrcweir 														   const String& _sCriteria,
3117*cdf0e10cSrcweir 														   ::rtl::OUString& _rsErrorMessage,
3118*cdf0e10cSrcweir 														   Reference<XPropertySet>& _rxColumn) const
3119*cdf0e10cSrcweir {
3120*cdf0e10cSrcweir 	OSL_ENSURE(pEntry.isValid(),"Entry is null!");
3121*cdf0e10cSrcweir 	if(!pEntry.isValid())
3122*cdf0e10cSrcweir 		return NULL;
3123*cdf0e10cSrcweir 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getController()).getConnection();
3124*cdf0e10cSrcweir 	if(!xConnection.is())
3125*cdf0e10cSrcweir 		return NULL;
3126*cdf0e10cSrcweir 
3127*cdf0e10cSrcweir 	::connectivity::OSQLParser& rParser( static_cast<OQueryController&>(getController()).getParser() );
3128*cdf0e10cSrcweir 	OQueryTableWindow* pWin = static_cast<OQueryTableWindow*>(pEntry->GetTabWindow());
3129*cdf0e10cSrcweir 
3130*cdf0e10cSrcweir 	String sTest(_sCriteria);
3131*cdf0e10cSrcweir 	// special handling for functions
3132*cdf0e10cSrcweir 	if ( pEntry->GetFunctionType() & (FKT_OTHER | FKT_AGGREGATE | FKT_NUMERIC) )
3133*cdf0e10cSrcweir 	{
3134*cdf0e10cSrcweir 		// we have a function here so we have to distinguish the type of return value
3135*cdf0e10cSrcweir 		String sFunction;
3136*cdf0e10cSrcweir 		if ( pEntry->isNumericOrAggreateFunction() )
3137*cdf0e10cSrcweir 			sFunction = pEntry->GetFunction();
3138*cdf0e10cSrcweir 
3139*cdf0e10cSrcweir         if ( !sFunction.Len() )
3140*cdf0e10cSrcweir 			sFunction = pEntry->GetField();
3141*cdf0e10cSrcweir 
3142*cdf0e10cSrcweir 		if(sFunction.GetTokenCount('(') > 1)
3143*cdf0e10cSrcweir 			sFunction = sFunction.GetToken(0,'('); // this should be the name of the function
3144*cdf0e10cSrcweir 
3145*cdf0e10cSrcweir 		sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType(sFunction,&rParser.getContext());
3146*cdf0e10cSrcweir 		if ( nType == DataType::OTHER || (!sFunction.Len() && pEntry->isNumericOrAggreateFunction()) )
3147*cdf0e10cSrcweir 		{
3148*cdf0e10cSrcweir 			// first try the international version
3149*cdf0e10cSrcweir 			::rtl::OUString sSql;
3150*cdf0e10cSrcweir 			sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * "));
3151*cdf0e10cSrcweir 			sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x WHERE "));
3152*cdf0e10cSrcweir 			sSql += pEntry->GetField();
3153*cdf0e10cSrcweir 			sSql += _sCriteria;
3154*cdf0e10cSrcweir             ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( _rsErrorMessage, sSql, sal_True ) );
3155*cdf0e10cSrcweir 			nType = DataType::DOUBLE;
3156*cdf0e10cSrcweir 			if ( pParseNode.get() )
3157*cdf0e10cSrcweir 			{
3158*cdf0e10cSrcweir 				OSQLParseNode* pColumnRef = pParseNode->getByRule(OSQLParseNode::column_ref);
3159*cdf0e10cSrcweir 				if ( pColumnRef )
3160*cdf0e10cSrcweir 				{
3161*cdf0e10cSrcweir 					OTableFieldDescRef aField = new OTableFieldDesc();
3162*cdf0e10cSrcweir 					if ( eOk == FillDragInfo(this,pColumnRef,aField) )
3163*cdf0e10cSrcweir 					{
3164*cdf0e10cSrcweir 						nType = aField->GetDataType();
3165*cdf0e10cSrcweir 					}
3166*cdf0e10cSrcweir 				}
3167*cdf0e10cSrcweir 			}
3168*cdf0e10cSrcweir 		}
3169*cdf0e10cSrcweir 
3170*cdf0e10cSrcweir 		Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
3171*cdf0e10cSrcweir 		parse::OParseColumn* pColumn = new parse::OParseColumn(	pEntry->GetField(),
3172*cdf0e10cSrcweir 																::rtl::OUString(),
3173*cdf0e10cSrcweir 																::rtl::OUString(),
3174*cdf0e10cSrcweir                                                                 ::rtl::OUString(),
3175*cdf0e10cSrcweir 																ColumnValue::NULLABLE_UNKNOWN,
3176*cdf0e10cSrcweir 																0,
3177*cdf0e10cSrcweir 																0,
3178*cdf0e10cSrcweir 																nType,
3179*cdf0e10cSrcweir 																sal_False,
3180*cdf0e10cSrcweir 																sal_False,
3181*cdf0e10cSrcweir 																xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
3182*cdf0e10cSrcweir 		_rxColumn = pColumn;
3183*cdf0e10cSrcweir 		pColumn->setFunction(sal_True);
3184*cdf0e10cSrcweir 		pColumn->setRealName(pEntry->GetField());
3185*cdf0e10cSrcweir 	}
3186*cdf0e10cSrcweir 	else
3187*cdf0e10cSrcweir 	{
3188*cdf0e10cSrcweir 		if (pWin)
3189*cdf0e10cSrcweir 		{
3190*cdf0e10cSrcweir 			Reference<XNameAccess> xColumns = pWin->GetOriginalColumns();
3191*cdf0e10cSrcweir 			if (xColumns.is() && xColumns->hasByName(pEntry->GetField()))
3192*cdf0e10cSrcweir 				xColumns->getByName(pEntry->GetField()) >>= _rxColumn;
3193*cdf0e10cSrcweir 		}
3194*cdf0e10cSrcweir 	}
3195*cdf0e10cSrcweir 
3196*cdf0e10cSrcweir 	OSQLParseNode* pParseNode = rParser.predicateTree(	_rsErrorMessage,
3197*cdf0e10cSrcweir 														sTest,
3198*cdf0e10cSrcweir 														static_cast<OQueryController&>(getController()).getNumberFormatter(),
3199*cdf0e10cSrcweir 														_rxColumn);
3200*cdf0e10cSrcweir 	return pParseNode;
3201*cdf0e10cSrcweir }
3202*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3203*cdf0e10cSrcweir void OQueryDesignView::GetFocus()
3204*cdf0e10cSrcweir {
3205*cdf0e10cSrcweir 	OQueryView::GetFocus();
3206*cdf0e10cSrcweir 	if ( m_pSelectionBox && !m_pSelectionBox->HasChildPathFocus() )
3207*cdf0e10cSrcweir 	{
3208*cdf0e10cSrcweir 		// first we have to deactivate the current cell to refill when nescessary
3209*cdf0e10cSrcweir 		m_pSelectionBox->DeactivateCell();
3210*cdf0e10cSrcweir 		m_pSelectionBox->ActivateCell(m_pSelectionBox->GetCurRow(), m_pSelectionBox->GetCurColumnId());
3211*cdf0e10cSrcweir 		m_pSelectionBox->GrabFocus();
3212*cdf0e10cSrcweir 	}
3213*cdf0e10cSrcweir }
3214*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3215*cdf0e10cSrcweir void OQueryDesignView::reset()
3216*cdf0e10cSrcweir {
3217*cdf0e10cSrcweir 	m_pTableView->ClearAll();
3218*cdf0e10cSrcweir 	m_pTableView->ReSync();
3219*cdf0e10cSrcweir }
3220*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3221*cdf0e10cSrcweir void OQueryDesignView::setNoneVisbleRow(sal_Int32 _nRows)
3222*cdf0e10cSrcweir {
3223*cdf0e10cSrcweir 	m_pSelectionBox->SetNoneVisbleRow(_nRows);
3224*cdf0e10cSrcweir }
3225*cdf0e10cSrcweir 
3226*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3227*cdf0e10cSrcweir void OQueryDesignView::initByFieldDescriptions( const Sequence< PropertyValue >& i_rFieldDescriptions )
3228*cdf0e10cSrcweir {
3229*cdf0e10cSrcweir 	OQueryController& rController = static_cast< OQueryController& >( getController() );
3230*cdf0e10cSrcweir 
3231*cdf0e10cSrcweir 	m_pSelectionBox->PreFill();
3232*cdf0e10cSrcweir 	m_pSelectionBox->SetReadOnly( rController.isReadOnly() );
3233*cdf0e10cSrcweir 	m_pSelectionBox->Fill();
3234*cdf0e10cSrcweir 
3235*cdf0e10cSrcweir     for (   const PropertyValue* field = i_rFieldDescriptions.getConstArray();
3236*cdf0e10cSrcweir             field != i_rFieldDescriptions.getConstArray() + i_rFieldDescriptions.getLength();
3237*cdf0e10cSrcweir             ++field
3238*cdf0e10cSrcweir         )
3239*cdf0e10cSrcweir     {
3240*cdf0e10cSrcweir         ::vos::ORef< OTableFieldDesc > pField( new OTableFieldDesc() );
3241*cdf0e10cSrcweir         pField->Load( *field, true );
3242*cdf0e10cSrcweir         InsertField( pField, sal_True, sal_False );
3243*cdf0e10cSrcweir     }
3244*cdf0e10cSrcweir 
3245*cdf0e10cSrcweir     rController.ClearUndoManager();
3246*cdf0e10cSrcweir 	m_pSelectionBox->Invalidate();
3247*cdf0e10cSrcweir }
3248*cdf0e10cSrcweir 
3249*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3250*cdf0e10cSrcweir bool OQueryDesignView::initByParseIterator( ::dbtools::SQLExceptionInfo* _pErrorInfo )
3251*cdf0e10cSrcweir {
3252*cdf0e10cSrcweir 	SqlParseError eErrorCode = eNativeMode;
3253*cdf0e10cSrcweir 	m_rController.clearError();
3254*cdf0e10cSrcweir 
3255*cdf0e10cSrcweir     try
3256*cdf0e10cSrcweir     {
3257*cdf0e10cSrcweir         eErrorCode = InitFromParseNodeImpl( this, m_pSelectionBox );
3258*cdf0e10cSrcweir 
3259*cdf0e10cSrcweir         if ( eErrorCode != eOk )
3260*cdf0e10cSrcweir 	    {
3261*cdf0e10cSrcweir 	        if ( !m_rController.hasError() )
3262*cdf0e10cSrcweir                 m_rController.appendError( getParseErrorMessage( eErrorCode ) );
3263*cdf0e10cSrcweir 
3264*cdf0e10cSrcweir             if ( _pErrorInfo )
3265*cdf0e10cSrcweir             {
3266*cdf0e10cSrcweir                 *_pErrorInfo = m_rController.getError();
3267*cdf0e10cSrcweir             }
3268*cdf0e10cSrcweir             else
3269*cdf0e10cSrcweir             {
3270*cdf0e10cSrcweir                 m_rController.displayError();
3271*cdf0e10cSrcweir             }
3272*cdf0e10cSrcweir 	    }
3273*cdf0e10cSrcweir     }
3274*cdf0e10cSrcweir     catch ( const Exception& )
3275*cdf0e10cSrcweir     {
3276*cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
3277*cdf0e10cSrcweir     }
3278*cdf0e10cSrcweir 	return eErrorCode == eOk;
3279*cdf0e10cSrcweir }
3280*cdf0e10cSrcweir //------------------------------------------------------------------------------
3281*cdf0e10cSrcweir void OQueryDesignView::fillFunctionInfo(  const ::connectivity::OSQLParseNode* pNode
3282*cdf0e10cSrcweir                                         ,const ::rtl::OUString& sFunctionTerm
3283*cdf0e10cSrcweir                                         ,OTableFieldDescRef& aInfo)
3284*cdf0e10cSrcweir {
3285*cdf0e10cSrcweir     // get the type out of the funtion name
3286*cdf0e10cSrcweir     OQueryController& rController = static_cast<OQueryController&>(getController());
3287*cdf0e10cSrcweir 	sal_Int32 nDataType = DataType::DOUBLE;
3288*cdf0e10cSrcweir 	::rtl::OUString sFieldName = sFunctionTerm;
3289*cdf0e10cSrcweir 	OSQLParseNode* pFunctionName = pNode->getChild(0);
3290*cdf0e10cSrcweir 	if ( !SQL_ISPUNCTUATION(pFunctionName,"{") )
3291*cdf0e10cSrcweir 	{
3292*cdf0e10cSrcweir 		if ( SQL_ISRULEOR2(pNode,length_exp,char_value_fct) )
3293*cdf0e10cSrcweir 			pFunctionName = pFunctionName->getChild(0);
3294*cdf0e10cSrcweir 
3295*cdf0e10cSrcweir 		::rtl::OUString sFunctionName = pFunctionName->getTokenValue();
3296*cdf0e10cSrcweir 		if ( !sFunctionName.getLength() )
3297*cdf0e10cSrcweir 			sFunctionName = ::rtl::OStringToOUString(OSQLParser::TokenIDToStr(pFunctionName->getTokenID()),RTL_TEXTENCODING_UTF8);
3298*cdf0e10cSrcweir 
3299*cdf0e10cSrcweir 		nDataType = OSQLParser::getFunctionReturnType(
3300*cdf0e10cSrcweir 							sFunctionName
3301*cdf0e10cSrcweir 							,&rController.getParser().getContext());
3302*cdf0e10cSrcweir 	}
3303*cdf0e10cSrcweir 	aInfo->SetDataType(nDataType);
3304*cdf0e10cSrcweir 	aInfo->SetFieldType(TAB_NORMAL_FIELD);
3305*cdf0e10cSrcweir 	aInfo->SetField(sFieldName);
3306*cdf0e10cSrcweir 	aInfo->SetTabWindow(NULL);
3307*cdf0e10cSrcweir }
3308*cdf0e10cSrcweir // -----------------------------------------------------------------------------
3309