Kaydet (Commit) f1bde8cb authored tarafından Lionel Elie Mamane's avatar Lionel Elie Mamane

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
üst 5214bda6
...@@ -2202,7 +2202,8 @@ namespace ...@@ -2202,7 +2202,8 @@ namespace
pColumnRef = pColumnRef->getChild(0); pColumnRef = pColumnRef->getChild(0);
OTableFieldDescRef aInfo = new OTableFieldDesc(); 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(0),"(") &&
SQL_ISPUNCTUATION(pColumnRef->getChild(2),")") SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
) )
......
...@@ -649,7 +649,7 @@ sal_Bool OSelectionBrowseBox::fillColumnRef(const ::rtl::OUString& _sColumnName, ...@@ -649,7 +649,7 @@ sal_Bool OSelectionBrowseBox::fillColumnRef(const ::rtl::OUString& _sColumnName,
return bError; 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; sal_Bool bError = sal_False;
...@@ -680,50 +680,63 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes ...@@ -680,50 +680,63 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes
// we have to look which entries we should quote // we have to look which entries we should quote
const ::rtl::OUString sFieldAlias = _pEntry->GetFieldAlias(); const ::rtl::OUString sFieldAlias = _pEntry->GetFieldAlias();
size_t nPass = 4;
::connectivity::OSQLParser& rParser( rController.getParser() ); ::connectivity::OSQLParser& rParser( rController.getParser() );
{
// 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 + ")";
}
OSQLParseNode* pParseNode = NULL; OSQLParseNode* pParseNode = NULL;
// 4 passes in trying to interprete the field name {
// - don't quote the field name, parse internationally // 4 passes in trying to interprete the field name
// - don't quote the field name, parse en-US // - don't quote the field name, parse internationally
// - quote the field name, parse internationally // - don't quote the field name, parse en-US
// - quote the field name, parse en-US // - quote the field name, parse internationally
do // - quote the field name, parse en-US
{ size_t nPass = 4;
bool bQuote = ( nPass <= 2 ); ::rtl::OUString sQuotedFullFieldName(::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName ));
bool bInternational = ( nPass % 2 ) == 0; ::rtl::OUString sFullFieldName(_sFieldName);
::rtl::OUString sSql;
if ( bQuote )
sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName );
else
sSql += _sFieldName;
if ( _pEntry->isAggreateFunction() ) if ( _pEntry->isAggreateFunction() )
{ {
OSL_ENSURE(!_pEntry->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-("); OSL_ENSURE(!_pEntry->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-(");
::rtl::OUStringBuffer aTmpStr2( _pEntry->GetFunction()); sQuotedFullFieldName = _pEntry->GetFunction() + "(" + sQuotedFullFieldName + ")";
aTmpStr2.appendAscii("("); sFullFieldName = _pEntry->GetFunction() + "(" + sFullFieldName + ")";
aTmpStr2.append(sSql);
aTmpStr2.appendAscii(")");
sSql = aTmpStr2.makeStringAndClear();
} }
sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) + sSql; do
if ( !sFieldAlias.isEmpty() ) {
{ // always quote the alias name there canbe no function in it bool bQuote = ( nPass <= 2 );
sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ")); bool bInternational = ( nPass % 2 ) == 0;
sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
}
sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x"));
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 ) 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 ) ); String sErrorMessage( ModuleRes( STR_QRY_COLUMN_NOT_FOUND ) );
sErrorMessage.SearchAndReplaceAscii("$name$",_sFieldName); sErrorMessage.SearchAndReplaceAscii("$name$",_sFieldName);
OSQLWarningBox( this, sErrorMessage ).Execute(); OSQLWarningBox( this, sErrorMessage ).Execute();
...@@ -737,8 +750,8 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes ...@@ -737,8 +750,8 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes
{ {
_pEntry->SetField(_sFieldName); _pEntry->SetField(_sFieldName);
clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId()); 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()); ::comphelper::UStringMixEqual bCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
...@@ -777,6 +790,7 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes ...@@ -777,6 +790,7 @@ sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDes
::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0); ::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0);
if ( if (
pColumnRef->getKnownRuleID() != OSQLParseNode::subquery &&
pColumnRef->count() == 3 && pColumnRef->count() == 3 &&
SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") && SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
SQL_ISPUNCTUATION(pColumnRef->getChild(2),")") SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
......
...@@ -246,7 +246,7 @@ namespace dbaui ...@@ -246,7 +246,7 @@ namespace dbaui
@return @return
<TRUE/> if an error occurred otherwise <FALSE/> <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 /** sets the table window at the _pEntry
@param _pEntry @param _pEntry
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment