LCOV - code coverage report
Current view: top level - include/connectivity - sqlnode.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 15 15 100.0 %
Date: 2014-11-03 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          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             : #ifndef INCLUDED_CONNECTIVITY_SQLNODE_HXX
      20             : #define INCLUDED_CONNECTIVITY_SQLNODE_HXX
      21             : 
      22             : #include <connectivity/dbtoolsdllapi.hxx>
      23             : #include <connectivity/dbmetadata.hxx>
      24             : #include <com/sun/star/uno/Reference.hxx>
      25             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
      26             : #include <com/sun/star/beans/XPropertySet.hpp>
      27             : #include <vector>
      28             : #include <functional>
      29             : #include <set>
      30             : #include <boost/shared_ptr.hpp>
      31             : #include <rtl/ustrbuf.hxx>
      32             : 
      33             : // forward declarations
      34             : namespace com
      35             : {
      36             :     namespace sun
      37             :     {
      38             :         namespace star
      39             :         {
      40             :             namespace beans
      41             :             {
      42             :                 class XPropertySet;
      43             :             }
      44             :             namespace util
      45             :             {
      46             :                 class XNumberFormatter;
      47             :             }
      48             :             namespace container
      49             :             {
      50             :                 class XNameAccess;
      51             :             }
      52             :         }
      53             :     }
      54             : }
      55             : 
      56             : #define ORDER_BY_CHILD_POS  5
      57             : #define TABLE_EXPRESSION_CHILD_COUNT    9
      58             : 
      59             : namespace connectivity
      60             : {
      61             :     class OSQLParser;
      62             :     class OSQLParseNode;
      63             :     class IParseContext;
      64             : 
      65             :     typedef ::std::vector< OSQLParseNode* >                  OSQLParseNodes;
      66             : 
      67             :     enum SQLNodeType    {SQL_NODE_RULE, SQL_NODE_LISTRULE, SQL_NODE_COMMALISTRULE,
      68             :                          SQL_NODE_KEYWORD, SQL_NODE_COMPARISON, SQL_NODE_NAME,
      69             :                          SQL_NODE_STRING,   SQL_NODE_INTNUM, SQL_NODE_APPROXNUM,
      70             :                          SQL_NODE_EQUAL,SQL_NODE_LESS,SQL_NODE_GREAT,SQL_NODE_LESSEQ,SQL_NODE_GREATEQ,SQL_NODE_NOTEQUAL,
      71             :                          SQL_NODE_PUNCTUATION, SQL_NODE_AMMSC, SQL_NODE_ACCESS_DATE,SQL_NODE_DATE,SQL_NODE_CONCAT};
      72             : 
      73             :     typedef ::std::set< OUString >   QueryNameSet;
      74             : 
      75             :     //= SQLParseNodeParameter
      76             : 
      77       20615 :     struct OOO_DLLPUBLIC_DBTOOLS SQLParseNodeParameter
      78             :     {
      79             :         const ::com::sun::star::lang::Locale&   rLocale;
      80             :         ::dbtools::DatabaseMetaData             aMetaData;
      81             :         OSQLParser*                             pParser;
      82             :         ::boost::shared_ptr< QueryNameSet >     pSubQueryHistory;
      83             :         ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >    xFormatter;
      84             :         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >       xField;
      85             :         OUString                                                                        sPredicateTableAlias;
      86             :         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    xQueries;  // see bParseToSDBCLevel
      87             :         const IParseContext& m_rContext;
      88             :         sal_Char            cDecSep;
      89             :         bool                bQuote                      : 1;    /// should we quote identifiers?
      90             :         bool                bInternational              : 1;    /// should we internationalize keywords and placeholders?
      91             :         bool                bPredicate                  : 1;    /// are we going to parse a mere predicate?
      92             :         bool                bParseToSDBCLevel           : 1;    /// should we create an SDBC-level statement (e.g. with substituted sub queries)?
      93             : 
      94             :         SQLParseNodeParameter(
      95             :             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
      96             :             const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _xFormatter,
      97             :             const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _xField,
      98             :             const OUString &_sPredicateTableAlias,
      99             :             const ::com::sun::star::lang::Locale& _rLocale,
     100             :             const IParseContext* _pContext,
     101             :             bool _bIntl,
     102             :             bool _bQuote,
     103             :             sal_Char _cDecSep,
     104             :             bool _bPredicate,
     105             :             bool _bParseToSDBC
     106             :         );
     107             :         ~SQLParseNodeParameter();
     108             :     };
     109             : 
     110             : 
     111             :     //= OSQLParseNode
     112             : 
     113             :     class OOO_DLLPUBLIC_DBTOOLS OSQLParseNode
     114             :     {
     115             :         friend class OSQLParser;
     116             : 
     117             :         OSQLParseNodes                  m_aChildren;
     118             :         OSQLParseNode*                  m_pParent;      // pParent for reverse linkage in the tree
     119             :         OUString                 m_aNodeValue;   // token name, or empty in case of rules,
     120             :                                                         // or OUString in case of
     121             :                                                         // OUString, INT, etc.
     122             :         SQLNodeType                     m_eNodeType;    // see above
     123             :         sal_uInt32                      m_nNodeID;      // Rule ID (if IsRule())
     124             :                                                         // or Token ID (if !IsRule())
     125             :                                             // Rule IDs and Token IDs can't
     126             :                                             // be distinguished by their values,
     127             :                                             // IsRule has to be used for that!
     128             :     public:
     129             :         enum Rule
     130             :         {
     131             :             UNKNOWN_RULE = 0,  // ID indicating that a node is no rule with a matching Rule-enum value (see getKnownRuleID)
     132             :                                // we make sure it is 0 so that it is the default-constructor value of this enum
     133             :                                // and std::map<foo,Rule>::operator[](bar) default-inserts UNKNOWN_RULE rather than select_statement (!)
     134             :             select_statement,
     135             :             table_exp,
     136             :             table_ref_commalist,
     137             :             table_ref,
     138             :             catalog_name,
     139             :             schema_name,
     140             :             table_name,
     141             :             opt_column_commalist,
     142             :             column_commalist,
     143             :             column_ref_commalist,
     144             :             column_ref,
     145             :             opt_order_by_clause,
     146             :             ordering_spec_commalist,
     147             :             ordering_spec,
     148             :             opt_asc_desc,
     149             :             where_clause,
     150             :             opt_where_clause,
     151             :             search_condition,
     152             :             comparison,
     153             :             comparison_predicate,
     154             :             between_predicate,
     155             :             like_predicate,
     156             :             opt_escape,
     157             :             test_for_null,
     158             :             scalar_exp_commalist,
     159             :             scalar_exp,
     160             :             parameter_ref,
     161             :             parameter,
     162             :             general_set_fct,
     163             :             range_variable,
     164             :             column,
     165             :             delete_statement_positioned,
     166             :             delete_statement_searched,
     167             :             update_statement_positioned,
     168             :             update_statement_searched,
     169             :             assignment_commalist,
     170             :             assignment,
     171             :             values_or_query_spec,
     172             :             insert_statement,
     173             :             insert_atom_commalist,
     174             :             insert_atom,
     175             :             from_clause,
     176             :             qualified_join,
     177             :             cross_union,
     178             :             select_sublist,
     179             :             derived_column,
     180             :             column_val,
     181             :             set_fct_spec,
     182             :             boolean_term,
     183             :             boolean_primary,
     184             :             num_value_exp,
     185             :             join_type,
     186             :             position_exp,
     187             :             extract_exp,
     188             :             length_exp,
     189             :             char_value_fct,
     190             :             odbc_call_spec,
     191             :             in_predicate,
     192             :             existence_test,
     193             :             unique_test,
     194             :             all_or_any_predicate,
     195             :             named_columns_join,
     196             :             join_condition,
     197             :             joined_table,
     198             :             boolean_factor,
     199             :             sql_not,
     200             :             manipulative_statement,
     201             :             subquery,
     202             :             value_exp_commalist,
     203             :             odbc_fct_spec,
     204             :             union_statement,
     205             :             outer_join_type,
     206             :             char_value_exp,
     207             :             term,
     208             :             value_exp_primary,
     209             :             value_exp,
     210             :             selection,
     211             :             fold,
     212             :             char_substring_fct,
     213             :             factor,
     214             :             base_table_def,
     215             :             base_table_element_commalist,
     216             :             data_type,
     217             :             column_def,
     218             :             table_node,
     219             :             as_clause,
     220             :             opt_as,
     221             :             op_column_commalist,
     222             :             table_primary_as_range_column,
     223             :             datetime_primary,
     224             :             concatenation,
     225             :             char_factor,
     226             :             bit_value_fct,
     227             :             comparison_predicate_part_2,
     228             :             parenthesized_boolean_value_expression,
     229             :             character_string_type,
     230             :             other_like_predicate_part_2,
     231             :             between_predicate_part_2,
     232             :             null_predicate_part_2,
     233             :             cast_spec,
     234             :             window_function,
     235             :             rule_count             // last value
     236             :         };
     237             : 
     238             :         // must be ascii encoding for the value
     239             :         OSQLParseNode(const sal_Char* _pValueStr,
     240             :                       SQLNodeType _eNodeType,
     241             :                       sal_uInt32 _nNodeID = 0);
     242             : 
     243             :         OSQLParseNode(const OString& _rValue,
     244             :                       SQLNodeType eNewNodeType,
     245             :                       sal_uInt32 nNewNodeID=0);
     246             : 
     247             :         OSQLParseNode(const OUString& _rValue,
     248             :                       SQLNodeType _eNodeType,
     249             :                       sal_uInt32 _nNodeID = 0);
     250             : 
     251             :             // copies the respective ParseNode
     252             :         OSQLParseNode(const OSQLParseNode& rParseNode);
     253             :         OSQLParseNode& operator=(const OSQLParseNode& rParseNode);
     254             : 
     255             :         bool operator==(OSQLParseNode& rParseNode) const;
     256             : 
     257             :         // destructor destructs the tree recursively
     258             :         virtual ~OSQLParseNode();
     259             : 
     260       28339 :         OSQLParseNode* getParent() const {return m_pParent;};
     261             : 
     262       25086 :         void setParent(OSQLParseNode* pParseNode) {m_pParent = pParseNode;};
     263             : 
     264       49230 :         size_t count() const {return m_aChildren.size();};
     265             :         inline OSQLParseNode* getChild(sal_uInt32 nPos) const;
     266             : 
     267             :         void append(OSQLParseNode* pNewSubTree);
     268             :         void insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree);
     269             : 
     270             :         OSQLParseNode* replace(OSQLParseNode* pOldSubTree, OSQLParseNode* pNewSubTree);
     271             : 
     272             :         OSQLParseNode* removeAt(sal_uInt32 nPos);
     273             : 
     274             :         void replaceNodeValue(const OUString& rTableAlias,const OUString& rColumnName);
     275             : 
     276             :         /** parses the node to a string which can be passed to a driver's connection for execution
     277             : 
     278             :             Any particles of the parse tree which represent application-level features - such
     279             :             as queries appearing in the FROM part - are substituted, so that the resulting statement can
     280             :             be executed at an SDBC-level connection.
     281             : 
     282             :             @param  _out_rString
     283             :                 is an output parameter taking the resulting SQL statement
     284             : 
     285             :             @param  _rxConnection
     286             :                 the connection relative to which to parse. This must be an SDB-level connection (e.g.
     287             :                 support the XQueriesSupplier interface) for the method to be able to do all necessary
     288             :                 substitutions.
     289             : 
     290             :             @param _rParser
     291             :                 the SQLParser used to create the node. This is needed in case we need to parse
     292             :                 sub queries which are present in the SQL statement - those sub queries need to be parsed,
     293             :                 too, to check whether they contain nested sub queries.
     294             : 
     295             :             @param _pErrorHolder
     296             :                 takes the error which occurred while generating the statement, if any. Might be <NULL/>,
     297             :                 in this case the error is not reported back, and can only be recognized by examing the
     298             :                 return value.
     299             : 
     300             :             @return
     301             :                 <TRUE/> if and only if the parsing was successful.<br/>
     302             : 
     303             :                 Currently, there's only one condition how this method can fail: If it contains a nested
     304             :                 query which causes a cycle. E.g., consider a statement <code>SELECT * from "foo"</code>,
     305             :                 where <code>foo</code> is a query defined as <code>SELECT * FROM "bar"</code>, where
     306             :                 <code>bar</code> is defined as <code>SELECT * FROM "foo"</code>. This statement obviously
     307             :                 cannot be parsed to an executable statement.
     308             : 
     309             :                 If this method returns <FALSE/>, you're encouraged to check and handle the error in
     310             :                 <arg>_pErrorHolder</arg>.
     311             :         */
     312             :         bool parseNodeToExecutableStatement( OUString& _out_rString,
     313             :             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
     314             :             OSQLParser& _rParser,
     315             :             ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const;
     316             : 
     317             :         void parseNodeToStr(OUString& rString,
     318             :                             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
     319             :                             const IParseContext* pContext = NULL,
     320             :                             bool _bIntl = false,
     321             :                             bool _bQuote= true) const;
     322             : 
     323             :         // quoted and internationalised
     324             :         void parseNodeToPredicateStr(OUString& rString,
     325             :                                      const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
     326             :                                      const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
     327             :                                      const ::com::sun::star::lang::Locale& rIntl,
     328             :                                      sal_Char _cDec,
     329             :                                      const IParseContext* pContext = NULL ) const;
     330             : 
     331             :         void parseNodeToPredicateStr(OUString& rString,
     332             :                                      const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
     333             :                                      const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
     334             :                                      const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & _xField,
     335             :                                      const OUString &_sTableAlias,
     336             :                                      const ::com::sun::star::lang::Locale& rIntl,
     337             :                                      sal_Char _cDec,
     338             :                                      const IParseContext* pContext = NULL ) const;
     339             : 
     340             :         OSQLParseNode* getByRule(OSQLParseNode::Rule eRule) const;
     341             : 
     342             : #if OSL_DEBUG_LEVEL > 1
     343             :         // shows the ParseTree with tabs and linefeeds
     344             :         void showParseTree( OUString& rString ) const;
     345             :         void showParseTree( OUStringBuffer& _inout_rBuf, sal_uInt32 nLevel ) const;
     346             : #endif
     347             : 
     348       20948 :         SQLNodeType getNodeType() const {return m_eNodeType;};
     349             : 
     350             :         // RuleId returns the RuleID of the node's rule (only if IsRule())
     351      136089 :         sal_uInt32 getRuleID() const {return m_nNodeID;}
     352             : 
     353             :         /** returns the ID of the rule represented by the node
     354             :             If the node does not represent a rule, UNKNOWN_RULE is returned
     355             :         */
     356             :         Rule getKnownRuleID() const;
     357             : 
     358             :             // returns the TokenId of the node's token (only if !isRule())
     359         350 :         sal_uInt32 getTokenID() const {return m_nNodeID;}
     360             : 
     361             :             // IsRule tests whether a node is a rule (NonTerminal)
     362             :             // ATTENTION: rules can be leaves, for example empty lists
     363      181853 :         bool isRule() const
     364      221025 :             { return (m_eNodeType == SQL_NODE_RULE) || (m_eNodeType == SQL_NODE_LISTRULE)
     365      221025 :                 || (m_eNodeType == SQL_NODE_COMMALISTRULE);}
     366             : 
     367             :             // IsToken tests whether a Node is a Token (Terminal but not a rule)
     368       25406 :         bool isToken() const {return !isRule();}
     369             : 
     370        5776 :         const OUString& getTokenValue() const {return m_aNodeValue;}
     371             : 
     372             :         void setTokenValue(const OUString& rString) {    if (isToken()) m_aNodeValue = rString;}
     373             : 
     374         428 :         bool isLeaf() const {return m_aChildren.empty();}
     375             : 
     376             :         // negate only a searchcondition, any other rule could cause a gpf
     377             :         static void negateSearchCondition(OSQLParseNode*& pSearchCondition, bool bNegate=false);
     378             : 
     379             :         // normalize a logic form
     380             :         // e.q. (a or b) and (c or d) <=> a and c or a and d or b and c or b and d
     381             :         static void disjunctiveNormalForm(OSQLParseNode*& pSearchCondition);
     382             : 
     383             :         //   Simplifies logic expressions
     384             :         // a and a        = a
     385             :         // a or a         = a
     386             :         // a and ( a + b) = a
     387             :         // a or a and b   = a
     388             :         static void absorptions(OSQLParseNode*& pSearchCondition);
     389             : 
     390             :         // erase unnecessary braces
     391             :         static void eraseBraces(OSQLParseNode*& pSearchCondition);
     392             : 
     393             :         // makes the logic formula a little smaller
     394             :         static void compress(OSQLParseNode*& pSearchCondition);
     395             :         // return the catalog, schema and tablename form this node
     396             :         // _pTableNode must be a rule of that above or a SQL_TOKEN_NAME
     397             :         static bool getTableComponents(const OSQLParseNode* _pTableNode,
     398             :                                             ::com::sun::star::uno::Any &_rCatalog,
     399             :                                             OUString &_rSchema,
     400             :                                             OUString &_rTable
     401             :                                             ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _xMetaData);
     402             : 
     403             :         // substitute all occurrences of :var or [name] into the dynamic parameter ?
     404             :         // _pNode will be modified if parameters exists
     405             :         static void substituteParameterNames(OSQLParseNode* _pNode);
     406             : 
     407             :         /** return a table range when it exists.
     408             :         */
     409             :         static OUString getTableRange(const OSQLParseNode* _pTableRef);
     410             : 
     411             :     protected:
     412             :         // ParseNodeToStr concatenates all Tokens (leaves) of the ParseNodes.
     413             :         void parseNodeToStr(OUString& rString,
     414             :                             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
     415             :                             const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
     416             :                             const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & _xField,
     417             :                             const OUString &_sPredicateTableAlias,
     418             :                             const ::com::sun::star::lang::Locale& rIntl,
     419             :                             const IParseContext* pContext,
     420             :                             bool _bIntl,
     421             :                             bool _bQuote,
     422             :                             sal_Char _cDecSep,
     423             :                             bool _bPredicate,
     424             :                             bool _bSubstitute) const;
     425             : 
     426             :     private:
     427             :         void impl_parseNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple=true ) const;
     428             :         void impl_parseLikeNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam, bool bSimple=true ) const;
     429             :         void impl_parseTableRangeNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const;
     430             : 
     431             :         /** parses a table_name node into a SQL statement particle.
     432             :             @return
     433             :                 <TRUE/> if and only if parsing was successful, <FALSE/> if default handling should
     434             :                 be applied.
     435             :         */
     436             :         bool impl_parseTableNameNodeToString_throw( OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const;
     437             : 
     438             :         bool addDateValue(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const;
     439             :         OUString convertDateTimeString(const SQLParseNodeParameter& rParam, const OUString& rString) const;
     440             :         OUString convertDateString(const SQLParseNodeParameter& rParam, const OUString& rString) const;
     441             :         OUString convertTimeString(const SQLParseNodeParameter& rParam, const OUString& rString) const;
     442             :         void parseLeaf(OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const;
     443             :     };
     444             : 
     445             : 
     446       65683 :     inline OSQLParseNode* OSQLParseNode::getChild(sal_uInt32 nPos) const
     447             :     {
     448             :         OSL_ENSURE(nPos < m_aChildren.size(), "Invalid Position");
     449             : 
     450             :         //  return m_aChildren[nPos];
     451       65683 :         return m_aChildren.at(nPos);
     452             :     }
     453             : 
     454             :     // utilities to query for a specific rule, token or punctuation
     455             :     #define SQL_ISRULE(pParseNode, eRule)   ((pParseNode)->isRule() && (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::eRule))
     456             :     #define SQL_ISRULEOR2(pParseNode, e1, e2)  ((pParseNode)->isRule() && ( \
     457             :                                                   (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
     458             :                                                   (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
     459             :     #define SQL_ISRULEOR3(pParseNode, e1, e2, e3)  ((pParseNode)->isRule() && ( \
     460             :                                                       (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
     461             :                                                       (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2) || \
     462             :                                                       (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e3)))
     463             :     #define SQL_ISTOKEN(pParseNode, token) ((pParseNode)->isToken() && (pParseNode)->getTokenID() == SQL_TOKEN_##token)
     464             :     #define SQL_ISTOKENOR2(pParseNode, tok0, tok1) ((pParseNode)->isToken() &&  ( (pParseNode)->getTokenID() == SQL_TOKEN_##tok0 || (pParseNode)->getTokenID() == SQL_TOKEN_##tok1 ))
     465             :     #define SQL_ISTOKENOR3(pParseNode, tok0, tok1, tok2) ((pParseNode)->isToken() && ( (pParseNode)->getTokenID() == SQL_TOKEN_##tok0 || (pParseNode)->getTokenID() == SQL_TOKEN_##tok1 || (pParseNode)->getTokenID() == SQL_TOKEN_##tok2 ))
     466             :     #define SQL_ISPUNCTUATION(pParseNode, aString) ((pParseNode)->getNodeType() == SQL_NODE_PUNCTUATION && (pParseNode)->getTokenValue().equalsAscii(aString))
     467             : }
     468             : 
     469             : #endif // INCLUDED_CONNECTIVITY_SQLNODE_HXX
     470             : 
     471             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10