1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #ifndef ZORBA_FUNCTIONS_FUNCTION_H
18 #define ZORBA_FUNCTIONS_FUNCTION_H
19 
20 #include <vector>
21 
22 #include "common/shared_types.h"
23 
24 #include "functions/function_consts.h"
25 #include "functions/signature.h"
26 #include "annotations/annotations.h"
27 
28 #include "compiler/parser/parse_constants.h"
29 #include "compiler/parser/query_loc.h"
30 #include "compiler/expression/expr_consts.h"
31 
32 #include "context/static_context_consts.h"
33 
34 
35 namespace zorba
36 {
37 
38 
39 class fo_expr;
40 class CompilerCB;
41 class expr;
42 class pragma;
43 
44 
45 /*******************************************************************************
46   theModuleContext:
47   -----------------
48   The root sctx of the module containing the declaration. It is NULL for
49   functions that must be executed in the static context of the caller.
50 ********************************************************************************/
51 class function : public SimpleRCObject
52 {
53 protected:
54 	signature                    theSignature;
55   FunctionConsts::FunctionKind theKind;
56   uint32_t                     theFlags;
57   AnnotationList_t             theAnnotationList;
58   static_context             * theModuleSctx;
59 
60   StaticContextConsts::xquery_version_t theXQueryVersion;
61 
62 
63 public:
64 #ifdef PRE_SERIALIZE_BUILTIN_FUNCTIONS
65   SERIALIZABLE_ABSTRACT_CLASS(function);
66 #else
67   SERIALIZABLE_CLASS(function);
68 #endif
69   SERIALIZABLE_CLASS_CONSTRUCTOR3(function, SimpleRCObject, theSignature);
70   void serialize(::zorba::serialization::Archiver& ar);
71 
72 public:
73 	function(const signature& sig, FunctionConsts::FunctionKind kind);
74 
~function()75 	virtual ~function() {}
76 
getXQueryVersion()77   StaticContextConsts::xquery_version_t getXQueryVersion() const
78   {
79     return theXQueryVersion;
80   }
81 
setXQueryVersion(StaticContextConsts::xquery_version_t version)82   void setXQueryVersion(StaticContextConsts::xquery_version_t version)
83   {
84     theXQueryVersion = version;
85   }
86 
getKind()87   FunctionConsts::FunctionKind getKind() const { return theKind; }
88 
getName()89 	store::Item* getName() const { return theSignature.getName(); }
90 
setSignature(signature & sig)91 	void setSignature(signature& sig) { theSignature = sig; }
92 
getSignature()93   const signature& getSignature() const { return theSignature; }
94 
getSignature()95   signature& getSignature() { return theSignature; }
96 
getArity()97   size_t getArity() const { return theSignature.paramCount(); }
98 
isVariadic()99   bool isVariadic() const { return theSignature.isVariadic(); }
100 
getStaticContext()101   static_context* getStaticContext() const { return theModuleSctx; }
102 
setStaticContext(static_context * sctx)103   void setStaticContext(static_context* sctx) { theModuleSctx = sctx; }
104 
setFlag(FunctionConsts::AnnotationFlags flag)105   void setFlag(FunctionConsts::AnnotationFlags flag)
106   {
107     theFlags |= flag;
108   }
109 
resetFlag(FunctionConsts::AnnotationFlags flag)110   void resetFlag(FunctionConsts::AnnotationFlags flag)
111   {
112     theFlags &= ~flag;
113   }
114 
testFlag(FunctionConsts::AnnotationFlags flag)115   bool testFlag(FunctionConsts::AnnotationFlags flag) const
116   {
117     return (theFlags & flag) != 0;
118   }
119 
isBuiltin()120   bool isBuiltin() const
121   {
122     return testFlag(FunctionConsts::isBuiltin);
123   }
124 
isUdf()125   bool isUdf() const
126   {
127     return testFlag(FunctionConsts::isUDF);
128   }
129 
isExternal()130   bool isExternal() const
131   {
132     return !isBuiltin() && !isUdf();
133   }
134 
isPrivate()135   bool isPrivate() const
136   {
137     return testFlag(FunctionConsts::isPrivate);
138   }
139 
setPrivate(bool v)140   void setPrivate(bool v)
141   {
142     if (v)
143       setFlag(FunctionConsts::isPrivate);
144     else
145       resetFlag(FunctionConsts::isPrivate);
146   }
147 
isDeterministic()148   bool isDeterministic() const
149   {
150     // Note: For udfs, the flag is set before the udf is optimized (see call
151     // to inferDeterminism in XQueryCompiler::optimize method).
152     return testFlag(FunctionConsts::isDeterministic);
153   }
154 
setDeterministic(bool v)155   void setDeterministic(bool v)
156   {
157     if (v)
158       setFlag(FunctionConsts::isDeterministic);
159     else
160       resetFlag(FunctionConsts::isDeterministic);
161   }
162 
163   void setAnnotations(AnnotationList* annotations);
164 
getAnnotationList()165   const AnnotationList* getAnnotationList() const { return theAnnotationList.getp(); }
166 
167 	bool validate_args(std::vector<PlanIter_t>& argv) const;
168 
isUpdating()169   bool isUpdating() const { return (getScriptingKind() & UPDATING_EXPR) != 0; }
170 
171   bool isSequential() const;
172 
173   virtual unsigned short getScriptingKind() const;
174 
175   virtual xqtref_t getReturnType(const fo_expr* caller) const;
176 
177   virtual bool accessesDynCtx() const;
178 
179   virtual bool isMap(csize input) const;
180 
181   virtual bool propagatesInputNodes(expr* fo, csize input) const;
182 
183   virtual bool mustCopyInputNodes(expr* fo, csize input) const;
184 
propagatesSortedNodes(csize input)185   virtual bool propagatesSortedNodes(csize input) const { return false; }
186 
propagatesDistinctNodes(csize input)187   virtual bool propagatesDistinctNodes(csize input) const { return false; }
188 
189   virtual FunctionConsts::AnnotationValue producesDistinctNodes() const;
190 
191   virtual FunctionConsts::AnnotationValue producesSortedNodes() const;
192 
193   virtual BoolAnnotationValue ignoresSortedNodes(expr* fo, csize input) const;
194 
195   virtual BoolAnnotationValue ignoresDuplicateNodes(expr* fo, csize input) const;
196 
isArithmeticFunction()197   virtual bool isArithmeticFunction() const { return false; }
198 
arithmeticKind()199   virtual ArithmeticConsts::OperationKind arithmeticKind() const
200   {
201     return ArithmeticConsts::UNKNOWN;
202   }
203 
isComparisonFunction()204   virtual bool isComparisonFunction() const { return false; }
205 
isValueComparisonFunction()206   virtual bool isValueComparisonFunction() const { return false; }
207 
isGeneralComparisonFunction()208   virtual bool isGeneralComparisonFunction() const { return false; }
209 
comparisonKind()210   virtual CompareConsts::CompareType comparisonKind() const
211   {
212     return CompareConsts::UNKNOWN;
213   }
214 
isNodeDistinctFunction()215   virtual bool isNodeDistinctFunction() const { return false; }
216 
isSource()217   virtual bool isSource() const { return false; }
218 
specializable()219   virtual bool specializable() const { return false; }
220 
specialize(static_context * sctx,const std::vector<xqtref_t> & argTypes)221   virtual function* specialize(
222       static_context* sctx,
223       const std::vector<xqtref_t>& argTypes) const
224   {
225     return NULL;
226   }
227 
processPragma(expr * expr,const std::vector<pragma * > & pragmas)228   virtual void processPragma(
229       expr* expr,
230       const std::vector<pragma*>& pragmas) const { return; }
231 
232   virtual PlanIter_t codegen(
233       CompilerCB* cb,
234       static_context* sctx,
235       const QueryLoc& loc,
236       std::vector<PlanIter_t>& argv,
237       expr& ann) const;
238 };
239 
240 
241 } /* namespace zorba */
242 #endif
243 
244 /*
245  * Local variables:
246  * mode: c++
247  * End:
248  */
249 /* vim:set et sw=2 ts=2: */
250