[PATCH] Change in core[libreoffice-4-0]: fix handling of subqueries in query design

Lionel Elie Mamane (via Code Review) gerrit at gerrit.libreoffice.org
Wed Jan 23 07:36:35 PST 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/1827

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/27/1827/1

fix handling of subqueries in query design

 - don't remove parentheses around subqueries
   (without the parentheses, it is not valid SQL)
   * when saving a Field (name value) typed by the user interactively
   * when parsing SQL and constructing the initial Query Design view

 - automatically add the necessary parentheses
   when a SELECT statement is entered as column name

Also:

In code saving a Field (name value) typed by the user interactively,
factorise some common code

Assorted minor fixes (typos in comments, etc)

Change-Id: I3843258323c903cba23238b0730ec4eb5875f792
---
M dbaccess/source/ui/querydesign/QueryDesignView.cxx
M dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
M dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
3 files changed, 50 insertions(+), 35 deletions(-)



diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
index 3c386db..8264152 100644
--- a/dbaccess/source/ui/querydesign/QueryDesignView.cxx
+++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
@@ -2198,7 +2198,8 @@
                     pColumnRef = pColumnRef->getChild(0);
                     OTableFieldDescRef aInfo = new OTableFieldDesc();
 
-                    if (    pColumnRef->count() == 3 &&
+                    if (    pColumnRef->getKnownRuleID() != OSQLParseNode::subquery &&
+                            pColumnRef->count() == 3 &&
                             SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
                             SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
                         )
diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
index 5544549..e85cb29 100644
--- a/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx
@@ -649,7 +649,7 @@
     return bError;
 }
 // -----------------------------------------------------------------------------
-sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction)
+sal_Bool OSelectionBrowseBox::saveField(String& _sFieldName ,OTableFieldDescRef& _pEntry, sal_Bool& _bListAction)
 {
     sal_Bool bError = sal_False;
 
@@ -680,50 +680,63 @@
     // we have to look which entries  we should quote
 
     const ::rtl::OUString sFieldAlias = _pEntry->GetFieldAlias();
-    size_t nPass = 4;
     ::connectivity::OSQLParser& rParser( rController.getParser() );
-    OSQLParseNode* pParseNode = NULL;
-    // 4 passes in trying to interprete the field name
-    // - don't quote the field name, parse internationally
-    // - don't quote the field name, parse en-US
-    // - quote the field name, parse internationally
-    // - quote the field name, parse en-US
-    do
     {
-        bool bQuote = ( nPass <= 2 );
-        bool bInternational = ( nPass % 2 ) == 0;
+        // automatically add parentheses around subqueries
+        OSQLParseNode *pParseNode = NULL;
+        OUString devnull;
+        pParseNode = rParser.parseTree( devnull, _sFieldName, true );
+        if (pParseNode == NULL)
+            pParseNode = rParser.parseTree( devnull, _sFieldName, false );
+        if (pParseNode != NULL && SQL_ISRULE(pParseNode, select_statement))
+            _sFieldName = ::rtl::OUString("(") + _sFieldName + ")";
+    }
 
-        ::rtl::OUString sSql;
-        if ( bQuote )
-            sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName );
-        else
-            sSql += _sFieldName;
+    OSQLParseNode* pParseNode = NULL;
+    {
+        // 4 passes in trying to interprete the field name
+        // - don't quote the field name, parse internationally
+        // - don't quote the field name, parse en-US
+        // - quote the field name, parse internationally
+        // - quote the field name, parse en-US
+        size_t nPass = 4;
+        ::rtl::OUString sQuotedFullFieldName(::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName ));
+        ::rtl::OUString sFullFieldName(_sFieldName);
 
         if  ( _pEntry->isAggreateFunction() )
         {
             OSL_ENSURE(!_pEntry->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-(");
-            ::rtl::OUStringBuffer aTmpStr2( _pEntry->GetFunction());
-            aTmpStr2.appendAscii("(");
-            aTmpStr2.append(sSql);
-            aTmpStr2.appendAscii(")");
-            sSql = aTmpStr2.makeStringAndClear();
+            sQuotedFullFieldName = _pEntry->GetFunction() + "(" + sQuotedFullFieldName + ")";
+            sFullFieldName = _pEntry->GetFunction() + "(" + sFullFieldName + ")";
         }
 
-        sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) + sSql;
-        if ( !sFieldAlias.isEmpty() )
-        { // always quote the alias name there canbe no function in it
-            sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
-            sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
-        }
-        sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x"));
+        do
+        {
+            bool bQuote = ( nPass <= 2 );
+            bool bInternational = ( nPass % 2 ) == 0;
 
-        pParseNode = rParser.parseTree( sErrorMsg, sSql, bInternational );
+            ::rtl::OUString sSql;
+            if ( bQuote )
+                sSql += sQuotedFullFieldName;
+            else
+                sSql += sFullFieldName;
+
+            sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) + sSql;
+            if ( !sFieldAlias.isEmpty() )
+            { // always quote the alias name: there cannot be a function in it
+                sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
+                sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
+            }
+            sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x"));
+
+            pParseNode = rParser.parseTree( sErrorMsg, sSql, bInternational );
+        }
+        while ( ( pParseNode == NULL ) && ( --nPass > 0 ) );
     }
-    while ( ( pParseNode == NULL ) && ( --nPass > 0 ) );
 
     if ( pParseNode == NULL )
     {
-        // something different which we have to check (may be a select statement)
+        // something different which we have to check
         String sErrorMessage( ModuleRes( STR_QRY_COLUMN_NOT_FOUND ) );
         sErrorMessage.SearchAndReplaceAscii("$name$",_sFieldName);
         OSQLWarningBox( this, sErrorMessage ).Execute();
@@ -737,8 +750,8 @@
     {
         _pEntry->SetField(_sFieldName);
         clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
-    } // travel through the select column parse node
-    else
+    }
+    else // travel through the select column parse node
     {
         ::comphelper::UStringMixEqual bCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
 
@@ -777,6 +790,7 @@
 
             ::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0);
             if (
+                    pColumnRef->getKnownRuleID() != OSQLParseNode::subquery &&
                     pColumnRef->count() == 3 &&
                     SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
                     SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
diff --git a/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx b/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
index b3b2c98..55bf270 100644
--- a/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
+++ b/dbaccess/source/ui/querydesign/SelectionBrowseBox.hxx
@@ -246,7 +246,7 @@
             @return
                 <TRUE/> if an error occurred otherwise <FALSE/>
         */
-        sal_Bool        saveField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction);
+        sal_Bool        saveField(String& _sFieldName, OTableFieldDescRef& _pEntry, sal_Bool& _bListAction);
 
         /** sets the table window at the _pEntry
             @param  _pEntry

-- 
To view, visit https://gerrit.libreoffice.org/1827
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3843258323c903cba23238b0730ec4eb5875f792
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Lionel Elie Mamane <lionel at mamane.lu>



More information about the LibreOffice mailing list