summaryrefslogtreecommitdiff
path: root/connectivity/source/parse
diff options
context:
space:
mode:
authorOcke Janssen [oj] <Ocke.Janssen@sun.com>2010-02-08 14:05:16 +0100
committerOcke Janssen [oj] <Ocke.Janssen@sun.com>2010-02-08 14:05:16 +0100
commit5f71d659243796e2fea2514860ed7d020a3d6d5b (patch)
tree7b4baaf96a621404fb19f2d28e8d47a1fb4605bf /connectivity/source/parse
parent1e76109004db25f8d4906852124252738e54403a (diff)
dba33f: #i108730# impl case case and rank functions
Diffstat (limited to 'connectivity/source/parse')
-rw-r--r--connectivity/source/parse/sqliterator.cxx103
-rw-r--r--connectivity/source/parse/sqlnode.cxx52
2 files changed, 113 insertions, 42 deletions
diff --git a/connectivity/source/parse/sqliterator.cxx b/connectivity/source/parse/sqliterator.cxx
index 42486ed73ab5..18d3ce25ad98 100644
--- a/connectivity/source/parse/sqliterator.cxx
+++ b/connectivity/source/parse/sqliterator.cxx
@@ -53,6 +53,10 @@
#include "diagnose_ex.h"
#include <rtl/logfile.hxx>
+#define SQL_ISRULEOR2(pParseNode, e1,e2) ((pParseNode)->isRule() && (\
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
+ (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
+
using namespace ::comphelper;
using namespace ::connectivity;
using namespace ::connectivity::sdbcx;
@@ -70,6 +74,7 @@ namespace connectivity
{
struct OSQLParseTreeIteratorImpl
{
+ ::std::vector< TNodePair > m_aJoinConditions;
Reference< XConnection > m_xConnection;
Reference< XDatabaseMetaData > m_xDatabaseMetaData;
Reference< XNameAccess > m_xTableContainer;
@@ -479,7 +484,42 @@ void OSQLParseTreeIterator::traverseOneTableName( OSQLTables& _rTables,const OSQ
if ( aTable.is() )
_rTables[ aTableRange ] = aTable;
}
-
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition)
+{
+ if (i_pJoinCondition->count() == 3 && // Ausdruck is geklammert
+ SQL_ISPUNCTUATION(i_pJoinCondition->getChild(0),"(") &&
+ SQL_ISPUNCTUATION(i_pJoinCondition->getChild(2),")"))
+ {
+ impl_fillJoinConditions(i_pJoinCondition->getChild(1));
+ }
+ else if (SQL_ISRULEOR2(i_pJoinCondition,search_condition,boolean_term) && // AND/OR-Verknuepfung:
+ i_pJoinCondition->count() == 3)
+ {
+ // nur AND Verknpfung zulassen
+ if ( SQL_ISTOKEN(i_pJoinCondition->getChild(1),AND) )
+ {
+ impl_fillJoinConditions(i_pJoinCondition->getChild(0));
+ impl_fillJoinConditions(i_pJoinCondition->getChild(1));
+ }
+ }
+ else if (SQL_ISRULE(i_pJoinCondition,comparison_predicate))
+ {
+ // only the comparison of columns is allowed
+ OSL_ENSURE(i_pJoinCondition->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree");
+ if (SQL_ISRULE(i_pJoinCondition->getChild(0),column_ref) &&
+ SQL_ISRULE(i_pJoinCondition->getChild(2),column_ref) &&
+ i_pJoinCondition->getChild(1)->getNodeType() == SQL_NODE_EQUAL)
+ {
+ m_pImpl->m_aJoinConditions.push_back( TNodePair(i_pJoinCondition->getChild(0),i_pJoinCondition->getChild(2)) );
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+::std::vector< TNodePair >& OSQLParseTreeIterator::getJoinConditions() const
+{
+ return m_pImpl->m_aJoinConditions;
+}
//-----------------------------------------------------------------------------
void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, ::rtl::OUString& aTableRange )
{
@@ -494,8 +534,30 @@ void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLP
traverseOneTableName( _rTables, pNode, aTableRange );
sal_uInt32 nPos = 4;
- if(SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
+ if( SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
+ {
nPos = 3;
+ // join_condition,named_columns_join
+ if ( SQL_ISRULE( pTableRef, qualified_join ) )
+ {
+ const OSQLParseNode* pJoin_spec = pTableRef->getChild(4);
+ if ( SQL_ISRULE( pJoin_spec, join_condition ) )
+ {
+ impl_fillJoinConditions(pJoin_spec->getChild(1));
+ }
+ else
+ {
+ const OSQLParseNode* pColumnCommalist = pJoin_spec->getChild(2);
+ // Alle Columns in der column_commalist ...
+ for (sal_uInt32 i = 0; i < pColumnCommalist->count(); i++)
+ {
+ const OSQLParseNode * pCol = pColumnCommalist->getChild(i);
+ // add twice because the column must exists in both tables
+ m_pImpl->m_aJoinConditions.push_back( TNodePair(pCol,pCol) );
+ }
+ }
+ }
+ }
pNode = getTableNode(_rTables,pTableRef->getChild(nPos),aTableRange);
if ( isTableNode( pNode ) )
@@ -1118,17 +1180,17 @@ void OSQLParseTreeIterator::traverseParameters(const OSQLParseNode* _pNode)
else
pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
} // if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X
- else if ( SQL_ISRULE(pParent,like_predicate) )
+ else if ( SQL_ISRULE(pParent,other_like_predicate_part_2) )
{
- const OSQLParseNode* pOther = pParent->getChild(0);
+ const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
if ( SQL_ISRULE( pOther, column_ref ) )
getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
else
pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
}
- else if ( SQL_ISRULE(pParent,between_predicate) )
+ else if ( SQL_ISRULE(pParent,between_predicate_part_2) )
{
- const OSQLParseNode* pOther = pParent->getChild(0);
+ const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
if ( SQL_ISRULE( pOther, column_ref ) )
getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
else
@@ -1307,17 +1369,19 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
::rtl::OUString aValue;
pSearchCondition->getChild(2)->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
traverseOnePredicate(pSearchCondition->getChild(0),aValue,pSearchCondition->getChild(2));
+ impl_fillJoinConditions(pSearchCondition);
// if (! aIteratorStatus.IsSuccessful())
// return;
}
else if (SQL_ISRULE(pSearchCondition,like_predicate) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
{
- OSL_ENSURE(pSearchCondition->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
+ OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
+ const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
- sal_Int32 nCurentPos = pSearchCondition->count()-2;
+ sal_Int32 nCurentPos = pPart2->count()-2;
- OSQLParseNode * pNum_value_exp = pSearchCondition->getChild(nCurentPos);
- OSQLParseNode * pOptEscape = pSearchCondition->getChild(nCurentPos+1);
+ OSQLParseNode * pNum_value_exp = pPart2->getChild(nCurentPos);
+ OSQLParseNode * pOptEscape = pPart2->getChild(nCurentPos+1);
OSL_ENSURE(pNum_value_exp != NULL,"OSQLParseTreeIterator: error in parse tree!");
OSL_ENSURE(pOptEscape != NULL,"OSQLParseTreeIterator: error in parse tree!");
@@ -1347,12 +1411,13 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
}
else if (SQL_ISRULE(pSearchCondition,in_predicate))
{
- OSL_ENSURE(pSearchCondition->count() == 4,"OSQLParseTreeIterator: error in parse tree!");
+ OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
+ const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
traverseORCriteria(pSearchCondition->getChild(0));
// if (! aIteratorStatus.IsSuccessful()) return;
- OSQLParseNode* pChild = pSearchCondition->getChild(3);
+ OSQLParseNode* pChild = pPart2->getChild(2);
if ( SQL_ISRULE(pChild->getChild(0),subquery) )
{
traverseTableNames( *m_pImpl->m_pSubTables );
@@ -1370,8 +1435,9 @@ void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition
}
else if (SQL_ISRULE(pSearchCondition,test_for_null) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
{
- OSL_ENSURE(pSearchCondition->count() >= 3,"OSQLParseTreeIterator: error in parse tree!");
- OSL_ENSURE(SQL_ISTOKEN(pSearchCondition->getChild(1),IS),"OSQLParseTreeIterator: error in parse tree!");
+ OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
+ const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
+ OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"OSQLParseTreeIterator: error in parse tree!");
::rtl::OUString aString;
traverseOnePredicate(pSearchCondition->getChild(0),aString,NULL);
@@ -1430,7 +1496,14 @@ void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode
{// found a function as column_ref
::rtl::OUString sFunctionName;
_pColumnRef->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
- sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() );
+ const sal_uInt32 nCount = _pColumnRef->count();
+ sal_uInt32 i = 0;
+ for(; i < nCount;++i)
+ {
+ if ( _pColumnRef->getChild(i) == _pParseNode )
+ break;
+ }
+ sal_Int32 nType = ::connectivity::OSQLParser::getFunctionParameterType( _pColumnRef->getParent()->getChild(0)->getTokenID(), i+1);
OParseColumn* pColumn = new OParseColumn( sParameterName,
::rtl::OUString(),
diff --git a/connectivity/source/parse/sqlnode.cxx b/connectivity/source/parse/sqlnode.cxx
index 12f608c68d47..f2a9085ae800 100644
--- a/connectivity/source/parse/sqlnode.cxx
+++ b/connectivity/source/parse/sqlnode.cxx
@@ -680,7 +680,7 @@ void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUStringBuffer
void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseLikeNodeToString_throw" );
- OSL_ENSURE(count() >= 4,"count != 5: Prepare for GPF");
+ OSL_ENSURE(count() == 2,"count != 2: Prepare for GPF");
const OSQLParseNode* pEscNode = NULL;
const OSQLParseNode* pParaNode = NULL;
@@ -717,13 +717,14 @@ void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rSt
if (bAddName)
m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam );
- m_aChildren[1]->impl_parseNodeToString_throw( rString, aNewParam );
- if(count() == 5)
- m_aChildren[2]->impl_parseNodeToString_throw( rString, aNewParam );
+ const OSQLParseNode* pPart2 = m_aChildren[1];
+ pPart2->getChild(1)->impl_parseNodeToString_throw( rString, aNewParam );
+ if (SQL_ISTOKEN(pPart2->getChild(0), NOT))
+ pPart2->getChild(2)->impl_parseNodeToString_throw( rString, aNewParam );
- sal_Int32 nCurentPos = m_aChildren.size()-2;
- pParaNode = m_aChildren[nCurentPos];
- pEscNode = m_aChildren[nCurentPos+1];
+ sal_Int32 nCurentPos = pPart2->count() - 2;
+ pParaNode = pPart2->getChild(nCurentPos);
+ pEscNode = pPart2->getChild(nCurentPos+1);
if (pParaNode->isToken())
{
@@ -1428,7 +1429,9 @@ OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star:
{ OSQLParseNode::bit_value_fct, "bit_value_fct" },
{ OSQLParseNode::comparison_predicate_part_2, "comparison_predicate_part_2" },
{ OSQLParseNode::parenthesized_boolean_value_expression, "parenthesized_boolean_value_expression" },
- { OSQLParseNode::character_string_type, "character_string_type" }
+ { OSQLParseNode::character_string_type, "character_string_type" },
+ { OSQLParseNode::other_like_predicate_part_2, "other_like_predicate_part_2" },
+ { OSQLParseNode::between_predicate_part_2, "between_predicate_part_2" }
};
size_t nRuleMapCount = sizeof( aRuleDescriptions ) / sizeof( aRuleDescriptions[0] );
OSL_ENSURE( nRuleMapCount == size_t( OSQLParseNode::rule_count ), "OSQLParser::OSQLParser: added a new rule? Adjust this map!" );
@@ -1990,39 +1993,34 @@ void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_B
else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) ||
SQL_ISRULE(pSearchCondition,between_predicate) || SQL_ISRULE(pSearchCondition,boolean_test) ))
{
+ OSQLParseNode* pPart2 = pSearchCondition;
+ if ( !SQL_ISRULE(pSearchCondition,boolean_test) )
+ pPart2 = pSearchCondition->getChild(1);
sal_uInt32 nNotPos = 0;
- // row_value_constructor not SQL_TOKEN_IN in_predicate_value
- // row_value_constructor not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor
- if ( SQL_ISRULE( pSearchCondition, in_predicate )
- || SQL_ISRULE( pSearchCondition, between_predicate )
- )
+ if ( SQL_ISRULE( pSearchCondition, test_for_null ) )
nNotPos = 1;
- // row_value_constructor SQL_TOKEN_IS not SQL_TOKEN_NULL
- // boolean_primary SQL_TOKEN_IS not truth_value
- else if ( SQL_ISRULE( pSearchCondition, test_for_null )
- || SQL_ISRULE( pSearchCondition, boolean_test )
- )
+ else if ( SQL_ISRULE( pSearchCondition, boolean_test ) )
nNotPos = 2;
- OSQLParseNode* pNot = pSearchCondition->getChild(nNotPos);
+ OSQLParseNode* pNot = pPart2->getChild(nNotPos);
OSQLParseNode* pNotNot = NULL;
if(pNot->isRule())
pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
else
pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
- pSearchCondition->replace(pNot, pNotNot);
+ pPart2->replace(pNot, pNotNot);
delete pNot;
}
else if(bNegate && (SQL_ISRULE(pSearchCondition,like_predicate)))
{
- OSQLParseNode* pCheckForNOT = pSearchCondition->getChild( 1 );
- if ( SQL_ISTOKEN(pCheckForNOT,NOT) )
- delete pSearchCondition->removeAt( 1 );
+ OSQLParseNode* pNot = pSearchCondition->getChild( 1 )->getChild( 0 );
+ OSQLParseNode* pNotNot = NULL;
+ if(pNot->isRule())
+ pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT);
else
- {
- OSQLParseNode* pNot = new OSQLParseNode( ::rtl::OUString::createFromAscii( "NOT" ), SQL_NODE_KEYWORD, SQL_TOKEN_NOT );
- pSearchCondition->insert( 1, pNot );
- }
+ pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not));
+ pSearchCondition->getChild( 1 )->replace(pNot, pNotNot);
+ delete pNot;
}
}
//-----------------------------------------------------------------------------