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