1caf5cd79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3caf5cd79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4caf5cd79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5caf5cd79SAndrew Rist  * distributed with this work for additional information
6caf5cd79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7caf5cd79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8caf5cd79SAndrew Rist  * "License"); you may not use this file except in compliance
9caf5cd79SAndrew Rist  * with the License.  You may obtain a copy of the License at
10caf5cd79SAndrew Rist  *
11caf5cd79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12caf5cd79SAndrew Rist  *
13caf5cd79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14caf5cd79SAndrew Rist  * software distributed under the License is distributed on an
15caf5cd79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16caf5cd79SAndrew Rist  * KIND, either express or implied.  See the License for the
17caf5cd79SAndrew Rist  * specific language governing permissions and limitations
18caf5cd79SAndrew Rist  * under the License.
19caf5cd79SAndrew Rist  *
20caf5cd79SAndrew Rist  *************************************************************/
21caf5cd79SAndrew Rist 
22caf5cd79SAndrew Rist 
23cdf0e10cSrcweir #ifndef _CONNECTIVITY_SQLPARSE_HXX
24cdf0e10cSrcweir #define _CONNECTIVITY_SQLPARSE_HXX
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
27cdf0e10cSrcweir #include <osl/mutex.hxx>
28cdf0e10cSrcweir #include <connectivity/sqlnode.hxx>
29cdf0e10cSrcweir #ifndef YYBISON
30cdf0e10cSrcweir #ifndef FLEX_SCANNER
31cdf0e10cSrcweir #ifndef BISON_INCLUDED
32cdf0e10cSrcweir #define BISON_INCLUDED
33cdf0e10cSrcweir #include "sqlbison.hxx"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #include <com/sun/star/i18n/XCharacterClassification.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39cdf0e10cSrcweir #include <com/sun/star/i18n/XLocaleData.hpp>
40ba7fd2e3Sdamjan #include <com/sun/star/lang/Locale.hpp>
41cdf0e10cSrcweir #include "connectivity/IParseContext.hxx"
42cdf0e10cSrcweir #include "connectivity/dbtoolsdllapi.hxx"
43ba7fd2e3Sdamjan #include "connectivity/sqlerror.hxx"
44cdf0e10cSrcweir #include <salhelper/singletonref.hxx>
45cdf0e10cSrcweir #include <osl/mutex.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <map>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir // forward declarations
50cdf0e10cSrcweir namespace com
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 	namespace sun
53cdf0e10cSrcweir 	{
54cdf0e10cSrcweir 		namespace star
55cdf0e10cSrcweir 		{
56cdf0e10cSrcweir 			namespace beans
57cdf0e10cSrcweir 			{
58cdf0e10cSrcweir 				class XPropertySet;
59cdf0e10cSrcweir 			}
60cdf0e10cSrcweir 			namespace util
61cdf0e10cSrcweir 			{
62cdf0e10cSrcweir 				class XNumberFormatter;
63cdf0e10cSrcweir 			}
64cdf0e10cSrcweir 			namespace lang
65cdf0e10cSrcweir 			{
66cdf0e10cSrcweir 				struct Locale;
67cdf0e10cSrcweir 			}
68cdf0e10cSrcweir 		}
69cdf0e10cSrcweir 	}
70cdf0e10cSrcweir }
71cdf0e10cSrcweir namespace connectivity
72cdf0e10cSrcweir {
73cdf0e10cSrcweir 	class OSQLScanner;
74cdf0e10cSrcweir     class SQLError;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	//==========================================================================
77cdf0e10cSrcweir 	//= OParseContext
78cdf0e10cSrcweir 	//==========================================================================
79cdf0e10cSrcweir 	class OOO_DLLPUBLIC_DBTOOLS OParseContext : public IParseContext
80cdf0e10cSrcweir 	{
81cdf0e10cSrcweir 	public:
82cdf0e10cSrcweir 		OParseContext();
83cdf0e10cSrcweir 
84cdf0e10cSrcweir 		virtual ~OParseContext();
85cdf0e10cSrcweir 		// retrieves language specific error messages
86cdf0e10cSrcweir 		virtual ::rtl::OUString getErrorMessage(ErrorCode _eCodes) const;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 		// retrieves language specific keyword strings (only ASCII allowed)
89cdf0e10cSrcweir 		virtual ::rtl::OString getIntlKeywordAscii(InternationalKeyCode _eKey) const;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 		// finds out, if we have an international keyword (only ASCII allowed)
92cdf0e10cSrcweir 		virtual InternationalKeyCode getIntlKeyCode(const ::rtl::OString& rToken) const;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 		// determines the default international setting
95cdf0e10cSrcweir 		static const ::com::sun::star::lang::Locale& getDefaultLocale();
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 		/** set's the default locale which should be used when analyzing strings
98cdf0e10cSrcweir 			<p>If no locale is set, and any method which needs a locale is called, a default
99cdf0e10cSrcweir 			(en-US) is used.</p>
100cdf0e10cSrcweir 			<p>If, while parsing, the locale can be obtained from other sources (such as the number format
101cdf0e10cSrcweir 			set for a table column), the preferred locale is ignored.</p>
102cdf0e10cSrcweir 		*/
103cdf0e10cSrcweir 		static void setDefaultLocale( const ::com::sun::star::lang::Locale& _rLocale );
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 		/** get's a locale instance which should be used when parsing in the context specified by this instance
106cdf0e10cSrcweir 			<p>if this is not overridden by derived classes, it returns the static default locale.</p>
107cdf0e10cSrcweir 		*/
108cdf0e10cSrcweir 		virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const;
109cdf0e10cSrcweir 	};
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     //==========================================================================
112cdf0e10cSrcweir     // OSQLParseNodesContainer
113cdf0e10cSrcweir     // grabage collection of nodes
114cdf0e10cSrcweir     //==========================================================================
115cdf0e10cSrcweir     class OSQLParseNodesContainer
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         ::osl::Mutex m_aMutex;
118cdf0e10cSrcweir         ::std::vector< OSQLParseNode* > m_aNodes;
119cdf0e10cSrcweir     public:
120cdf0e10cSrcweir         OSQLParseNodesContainer();
121cdf0e10cSrcweir         ~OSQLParseNodesContainer();
122cdf0e10cSrcweir 
123cdf0e10cSrcweir         void push_back(OSQLParseNode* _pNode);
124cdf0e10cSrcweir         void erase(OSQLParseNode* _pNode);
125cdf0e10cSrcweir         bool empty() const;
126cdf0e10cSrcweir         void clear();
127cdf0e10cSrcweir         void clearAndDelete();
128cdf0e10cSrcweir     };
129cdf0e10cSrcweir 
130cdf0e10cSrcweir     typedef salhelper::SingletonRef<OSQLParseNodesContainer> OSQLParseNodesGarbageCollector;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	//==========================================================================
133cdf0e10cSrcweir 	//= OSQLParser
134cdf0e10cSrcweir 	//==========================================================================
135ba7fd2e3Sdamjan     struct OSQLParser_Data
136ba7fd2e3Sdamjan     {
137ba7fd2e3Sdamjan         ::com::sun::star::lang::Locale  aLocale;
138ba7fd2e3Sdamjan         ::connectivity::SQLError        aErrors;
139ba7fd2e3Sdamjan 
140*b6875243Sdamjan         OSQLParser_Data( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory );
141ba7fd2e3Sdamjan 
142ba7fd2e3Sdamjan     };
143cdf0e10cSrcweir 	/** Parser for SQL92
144cdf0e10cSrcweir 	*/
145cdf0e10cSrcweir 	class OOO_DLLPUBLIC_DBTOOLS OSQLParser
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		friend class OSQLParseNode;
148cdf0e10cSrcweir 		friend class OSQLInternalNode;
149cdf0e10cSrcweir 		friend struct SQLParseNodeParameter;
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	private:
152cdf0e10cSrcweir         typedef ::std::map< sal_uInt32, OSQLParseNode::Rule >   RuleIDMap;
153cdf0e10cSrcweir 	//	static parts for parsers
154cdf0e10cSrcweir 		static sal_uInt32			s_nRuleIDs[OSQLParseNode::rule_count + 1];
155cdf0e10cSrcweir         static RuleIDMap            s_aReverseRuleIDLookup;
156cdf0e10cSrcweir 		static OParseContext		s_aDefaultContext;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 		static OSQLScanner*			            s_pScanner;
159cdf0e10cSrcweir         static OSQLParseNodesGarbageCollector*  s_pGarbageCollector;
160cdf0e10cSrcweir 		static sal_Int32			            s_nRefCount;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 	// informations on the current parse action
163cdf0e10cSrcweir 		const IParseContext*		m_pContext;
164cdf0e10cSrcweir 		OSQLParseNode*				m_pParseTree;	// result from parsing
165cdf0e10cSrcweir         ::std::auto_ptr< OSQLParser_Data >
166cdf0e10cSrcweir                                     m_pData;
167cdf0e10cSrcweir 		::rtl::OUString						m_sFieldName;	// current field name for a predicate
168cdf0e10cSrcweir 		::rtl::OUString						m_sErrorMessage;// current error msg
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
171cdf0e10cSrcweir 									m_xField;		// current field
172cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >
173cdf0e10cSrcweir 									m_xFormatter;	// current number formatter
174cdf0e10cSrcweir 		sal_Int32					m_nFormatKey;	// numberformat, which should be used
175cdf0e10cSrcweir 		sal_Int32					m_nDateFormatKey;
176cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >	m_xServiceFactory;
177cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass;
178cdf0e10cSrcweir 		static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>		s_xLocaleData;
179cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>		xDummy; // can be deleted after 627
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 		// convert a string into double trim it to scale of _nscale and than transform it back to string
182cdf0e10cSrcweir 		::rtl::OUString stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale);
183cdf0e10cSrcweir 		OSQLParseNode*  buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral);
184cdf0e10cSrcweir         bool            extractDate(OSQLParseNode* pLiteral,double& _rfValue);
185cdf0e10cSrcweir         void            killThousandSeparator(OSQLParseNode* pLiteral);
186cdf0e10cSrcweir         OSQLParseNode*  convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral);
187cdf0e10cSrcweir         // makes a string out of a number, pLiteral will be deleted
188cdf0e10cSrcweir 		OSQLParseNode*  buildNode_STR_NUM(OSQLParseNode*& pLiteral);
189cdf0e10cSrcweir         OSQLParseNode*  buildNode_Date(const double& fValue, sal_Int32 nType);
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 		static ::osl::Mutex& getMutex();
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	public:
194cdf0e10cSrcweir 		// if NULL, a default context will be used
195cdf0e10cSrcweir 		// the context must live as long as the parser
196cdf0e10cSrcweir 		OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext = NULL);
197cdf0e10cSrcweir 		~OSQLParser();
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 		// Parsing an SQLStatement
200cdf0e10cSrcweir 		OSQLParseNode* parseTree(::rtl::OUString& rErrorMessage,
201cdf0e10cSrcweir 					   const ::rtl::OUString& rStatement,
202cdf0e10cSrcweir 					   sal_Bool bInternational = sal_False);
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 		// Check a Predicate
205cdf0e10cSrcweir 		OSQLParseNode* predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement,
206cdf0e10cSrcweir 					   const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
207cdf0e10cSrcweir 					   const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField);
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 		// Access to the context
getContext() const210cdf0e10cSrcweir 		const IParseContext& getContext() const {return *m_pContext;}
211cdf0e10cSrcweir 
212cdf0e10cSrcweir         /// access to the SQLError instance owned by this parser
213cdf0e10cSrcweir         const SQLError& getErrorHelper() const;
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 		// TokenIDToStr: Token-Name zu einer Token-Nr.
216cdf0e10cSrcweir 		static ::rtl::OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL);
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 		// StrToTokenID: Token-Nr. zu einem Token-Namen.
219cdf0e10cSrcweir 		// static sal_uInt32 StrToTokenID(const ::rtl::OString & rName);
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 		// RuleIDToStr gibt den zu einer RuleID gehoerenden ::rtl::OUString zurueck
222cdf0e10cSrcweir 		// (Leerstring, falls nicht gefunden)
223cdf0e10cSrcweir 		static ::rtl::OUString RuleIDToStr(sal_uInt32 nRuleID);
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 		// StrToRuleID berechnet zu einem ::rtl::OUString die RuleID (d.h. ::com::sun::star::sdbcx::Index in yytname)
226cdf0e10cSrcweir 		// (0, falls nicht gefunden). Die Suche nach der ID aufgrund eines Strings ist
227cdf0e10cSrcweir 		// extrem ineffizient (sequentielle Suche nach ::rtl::OUString)!
228cdf0e10cSrcweir 		static sal_uInt32 StrToRuleID(const ::rtl::OString & rValue);
229cdf0e10cSrcweir 
230cdf0e10cSrcweir         static OSQLParseNode::Rule RuleIDToRule( sal_uInt32 _nRule );
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 		// RuleId mit enum, wesentlich effizienter
233cdf0e10cSrcweir 		static sal_uInt32 RuleID(OSQLParseNode::Rule eRule);
234cdf0e10cSrcweir 		// compares the _sFunctionName with all known function names and return the DataType of the return value
235cdf0e10cSrcweir 		static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL);
236cdf0e10cSrcweir 
237cdf0e10cSrcweir         // returns the type for a parameter in a given function name
238cdf0e10cSrcweir         static sal_Int32 getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos);
239cdf0e10cSrcweir 
240b135d50bSHerbert Dürr 		void error( const sal_Char* pFormat);
241cdf0e10cSrcweir 		int SQLlex();
242cdf0e10cSrcweir #ifdef YYBISON
243cdf0e10cSrcweir 		void setParseTree(OSQLParseNode * pNewParseTree);
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 		// Is the parse in a special mode?
246cdf0e10cSrcweir 		// Predicate chack is used to check a condition for a field
inPredicateCheck() const247cdf0e10cSrcweir 		sal_Bool inPredicateCheck() const {return m_xField.is();}
getFieldName() const248cdf0e10cSrcweir 		const ::rtl::OUString& getFieldName() const {return m_sFieldName;}
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 		void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank);
251cdf0e10cSrcweir 		 // does not change the pLiteral argument
252cdf0e10cSrcweir 		sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pCompare,OSQLParseNode* pLiteral,OSQLParseNode* pLiteral2);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 		sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral);
255cdf0e10cSrcweir 		// pCompre will be deleted if it is not used
256cdf0e10cSrcweir 		sal_Int16 buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2 = NULL);
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 		sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape);
259cdf0e10cSrcweir 		sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral);
260cdf0e10cSrcweir #else
261cdf0e10cSrcweir #endif
262cdf0e10cSrcweir 	};
263cdf0e10cSrcweir }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 
266cdf0e10cSrcweir #endif //_CONNECTIVITY_SQLPARSE_HXX
267