1 | package tuffy.ra; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.HashMap; |
5 | import java.util.List; |
6 | |
7 | import tuffy.mln.Type; |
8 | |
9 | |
10 | /** |
11 | * Bool, numberic, and string functions; user-defined functions. |
12 | * |
13 | * @author Feng Niu |
14 | * |
15 | */ |
16 | |
17 | public class Function { |
18 | public static HashMap<String, Function> builtInMap = |
19 | new HashMap<String, Function>(); |
20 | |
21 | public static Function getBuiltInFunctionByName(String name){ |
22 | return builtInMap.get(name); |
23 | } |
24 | |
25 | // atomic functions |
26 | public static Function ConstantNumber = null; |
27 | public static Function ConstantString = null; |
28 | public static Function VariableBinding = null; |
29 | |
30 | static{ |
31 | ConstantNumber = new Function("_constNum", Type.Float); |
32 | ConstantNumber.isBuiltIn_ = true; |
33 | ConstantNumber.addArgument(Type.Float); |
34 | builtInMap.put("_constNum", ConstantNumber); |
35 | |
36 | ConstantString = new Function("_constStr", Type.String); |
37 | ConstantString.isBuiltIn_ = true; |
38 | ConstantString.addArgument(Type.String); |
39 | builtInMap.put("_constStr", ConstantString); |
40 | |
41 | VariableBinding = new Function("_var", Type.Generic); |
42 | VariableBinding.isBuiltIn_ = true; |
43 | VariableBinding.addArgument(Type.Generic); |
44 | builtInMap.put("_var", VariableBinding); |
45 | } |
46 | |
47 | |
48 | |
49 | // boolean functions |
50 | public static Function NOT = null; |
51 | public static Function OR = null; |
52 | public static Function AND = null; |
53 | |
54 | public static Function Eq = null; |
55 | public static Function Neq = null; |
56 | public static Function LessThan = null; |
57 | public static Function LessThanEq = null; |
58 | public static Function GreaterThan = null; |
59 | public static Function GreaterThanEq = null; |
60 | |
61 | public static Function StrContains = null; |
62 | public static Function StrStartsWith = null; |
63 | public static Function StrEndsWith = null; |
64 | |
65 | static{ |
66 | Function f = null; |
67 | |
68 | // logical operators |
69 | |
70 | f = new Function("NOT", Type.Bool); |
71 | f.isBuiltIn_ = true; |
72 | f.addArgument(Type.Bool); |
73 | builtInMap.put("NOT", f); |
74 | builtInMap.put("!", f); |
75 | NOT = f; |
76 | |
77 | f = new Function("OR", Type.Bool); |
78 | f.isBuiltIn_ = true; |
79 | f.addArgument(Type.Bool); |
80 | f.addArgument(Type.Bool); |
81 | builtInMap.put("OR", f); |
82 | f.isOperator_ = true; |
83 | OR = f; |
84 | |
85 | f = new Function("AND", Type.Bool); |
86 | f.isBuiltIn_ = true; |
87 | f.addArgument(Type.Bool); |
88 | f.addArgument(Type.Bool); |
89 | builtInMap.put("AND", f); |
90 | f.isOperator_ = true; |
91 | AND = f; |
92 | |
93 | |
94 | // numeric bool functions |
95 | |
96 | f = new Function("_eq", Type.Bool); |
97 | f.isBuiltIn_ = true; |
98 | f.addArgument(Type.Generic); |
99 | f.addArgument(Type.Generic); |
100 | builtInMap.put("_eq", f); |
101 | builtInMap.put("=", f); |
102 | f.isOperator_ = true; |
103 | Eq = f; |
104 | |
105 | f = new Function("_neq", Type.Bool); |
106 | f.isBuiltIn_ = true; |
107 | f.addArgument(Type.Generic); |
108 | f.addArgument(Type.Generic); |
109 | builtInMap.put("_neq", f); |
110 | builtInMap.put("!=", f); |
111 | builtInMap.put("<>", f); |
112 | f.isOperator_ = true; |
113 | Neq = f; |
114 | |
115 | f = new Function("_less", Type.Bool); |
116 | f.isBuiltIn_ = true; |
117 | f.addArgument(Type.Float); |
118 | f.addArgument(Type.Float); |
119 | builtInMap.put("_less", f); |
120 | builtInMap.put("<", f); |
121 | f.isOperator_ = true; |
122 | LessThan = f; |
123 | |
124 | f = new Function("_lessEq", Type.Bool); |
125 | f.isBuiltIn_ = true; |
126 | f.addArgument(Type.Float); |
127 | f.addArgument(Type.Float); |
128 | builtInMap.put("_lessEq", f); |
129 | builtInMap.put("<=", f); |
130 | f.isOperator_ = true; |
131 | LessThanEq = f; |
132 | |
133 | f = new Function("_greater", Type.Bool); |
134 | f.isBuiltIn_ = true; |
135 | f.addArgument(Type.Float); |
136 | f.addArgument(Type.Float); |
137 | builtInMap.put("_greater", f); |
138 | builtInMap.put(">", f); |
139 | f.isOperator_ = true; |
140 | GreaterThan = f; |
141 | |
142 | f = new Function("_greaterEq", Type.Bool); |
143 | f.isBuiltIn_ = true; |
144 | f.addArgument(Type.Float); |
145 | f.addArgument(Type.Float); |
146 | builtInMap.put("_greaterEq", f); |
147 | builtInMap.put(">=", f); |
148 | f.isOperator_ = true; |
149 | GreaterThanEq = f; |
150 | |
151 | // string bool functions |
152 | |
153 | f = new Function("contains", Type.Bool); |
154 | f.isBuiltIn_ = true; |
155 | f.addArgument(Type.String); |
156 | f.addArgument(Type.String); |
157 | builtInMap.put("contains", f); |
158 | StrContains = f; |
159 | |
160 | f = new Function("startsWith", Type.Bool); |
161 | f.isBuiltIn_ = true; |
162 | f.addArgument(Type.String); |
163 | f.addArgument(Type.String); |
164 | builtInMap.put("startsWith", f); |
165 | StrStartsWith = f; |
166 | |
167 | f = new Function("endsWith", Type.Bool); |
168 | f.isBuiltIn_ = true; |
169 | f.addArgument(Type.String); |
170 | f.addArgument(Type.String); |
171 | builtInMap.put("endsWith", f); |
172 | StrEndsWith = f; |
173 | } |
174 | |
175 | |
176 | // math functions, unary |
177 | public static Function Sign = null; |
178 | public static Function Abs = null; |
179 | public static Function Exp = null; |
180 | public static Function Ceil = null; |
181 | public static Function Floor = null; |
182 | public static Function Trunc = null; |
183 | public static Function Round = null; |
184 | public static Function Ln = null; // base-e |
185 | public static Function Lg = null; // base-10 |
186 | public static Function Sin = null; |
187 | public static Function Cos = null; |
188 | public static Function Tan = null; |
189 | public static Function Sqrt = null; |
190 | public static Function Factorial = null; |
191 | |
192 | static{ |
193 | Function f = null; |
194 | |
195 | f = new Function("sign", Type.Integer); |
196 | f.isBuiltIn_ = true; |
197 | f.addArgument(Type.Float); |
198 | builtInMap.put(f.name_, f); |
199 | Sign = f; |
200 | |
201 | f = new Function("abs", Type.Float); |
202 | f.isBuiltIn_ = true; |
203 | f.addArgument(Type.Float); |
204 | builtInMap.put(f.name_, f); |
205 | Abs = f; |
206 | |
207 | f = new Function("exp", Type.Float); |
208 | f.isBuiltIn_ = true; |
209 | f.addArgument(Type.Float); |
210 | builtInMap.put(f.name_, f); |
211 | Exp = f; |
212 | |
213 | f = new Function("ceil", Type.Float); |
214 | f.isBuiltIn_ = true; |
215 | f.addArgument(Type.Float); |
216 | builtInMap.put(f.name_, f); |
217 | builtInMap.put("ceiling", f); |
218 | Ceil = f; |
219 | |
220 | f = new Function("floor", Type.Float); |
221 | f.isBuiltIn_ = true; |
222 | f.addArgument(Type.Float); |
223 | builtInMap.put(f.name_, f); |
224 | Floor = f; |
225 | |
226 | f = new Function("trunc", Type.Float); |
227 | f.isBuiltIn_ = true; |
228 | f.addArgument(Type.Float); |
229 | builtInMap.put(f.name_, f); |
230 | Trunc = f; |
231 | |
232 | f = new Function("round", Type.Float); |
233 | f.isBuiltIn_ = true; |
234 | f.addArgument(Type.Float); |
235 | builtInMap.put(f.name_, f); |
236 | Round = f; |
237 | |
238 | f = new Function("ln", Type.Float); |
239 | f.isBuiltIn_ = true; |
240 | f.addArgument(Type.Float); |
241 | builtInMap.put(f.name_, f); |
242 | Ln = f; |
243 | |
244 | f = new Function("lg", Type.Float); |
245 | f.isBuiltIn_ = true; |
246 | f.addArgument(Type.Float); |
247 | builtInMap.put(f.name_, f); |
248 | f.setPgFunction("log"); |
249 | Lg = f; |
250 | |
251 | f = new Function("sin", Type.Float); |
252 | f.isBuiltIn_ = true; |
253 | f.addArgument(Type.Float); |
254 | builtInMap.put(f.name_, f); |
255 | Sin = f; |
256 | |
257 | f = new Function("cos", Type.Float); |
258 | f.isBuiltIn_ = true; |
259 | f.addArgument(Type.Float); |
260 | builtInMap.put(f.name_, f); |
261 | Cos = f; |
262 | |
263 | f = new Function("tan", Type.Float); |
264 | f.isBuiltIn_ = true; |
265 | f.addArgument(Type.Float); |
266 | builtInMap.put(f.name_, f); |
267 | Tan = f; |
268 | |
269 | f = new Function("sqrt", Type.Float); |
270 | f.isBuiltIn_ = true; |
271 | f.addArgument(Type.Float); |
272 | builtInMap.put(f.name_, f); |
273 | Sqrt = f; |
274 | |
275 | f = new Function("factorial", Type.Float); |
276 | f.isBuiltIn_ = true; |
277 | f.addArgument(Type.Float); |
278 | builtInMap.put(f.name_, f); |
279 | Factorial = f; |
280 | |
281 | } |
282 | |
283 | |
284 | // math functions, binary |
285 | public static Function Add = null; |
286 | public static Function Subtract = null; |
287 | public static Function Multiply = null; |
288 | public static Function Divide = null; |
289 | public static Function Modulo = null; |
290 | public static Function Power = null; |
291 | public static Function Log = null; |
292 | public static Function BitAnd = null; |
293 | public static Function BitOr = null; |
294 | public static Function BitXor = null; |
295 | public static Function BitNeg = null; |
296 | public static Function BitShiftLeft = null; |
297 | public static Function BitShiftRight = null; |
298 | |
299 | static{ |
300 | Function f = null; |
301 | f = new Function("add", Type.Float); |
302 | f.isBuiltIn_ = true; |
303 | f.addArgument(Type.Float); |
304 | f.addArgument(Type.Float); |
305 | builtInMap.put("add", f); |
306 | builtInMap.put("+", f); |
307 | f.isOperator_ = true; |
308 | Add = f; |
309 | |
310 | f = new Function("subtract", Type.Float); |
311 | f.isBuiltIn_ = true; |
312 | f.addArgument(Type.Float); |
313 | f.addArgument(Type.Float); |
314 | builtInMap.put("subtract", f); |
315 | builtInMap.put("-", f); |
316 | f.isOperator_ = true; |
317 | Subtract = f; |
318 | |
319 | f = new Function("multiply", Type.Float); |
320 | f.isBuiltIn_ = true; |
321 | f.addArgument(Type.Float); |
322 | f.addArgument(Type.Float); |
323 | builtInMap.put("multiply", f); |
324 | builtInMap.put("*", f); |
325 | f.isOperator_ = true; |
326 | Multiply = f; |
327 | |
328 | f = new Function("divide", Type.Float); |
329 | f.isBuiltIn_ = true; |
330 | f.addArgument(Type.Float); |
331 | f.addArgument(Type.Float); |
332 | builtInMap.put("divide", f); |
333 | builtInMap.put("/", f); |
334 | f.isOperator_ = true; |
335 | Divide = f; |
336 | |
337 | f = new Function("mod", Type.Integer); |
338 | f.isBuiltIn_ = true; |
339 | f.addArgument(Type.Integer); |
340 | f.addArgument(Type.Integer); |
341 | builtInMap.put("mod", f); |
342 | builtInMap.put("%", f); |
343 | f.isOperator_ = true; |
344 | Modulo = f; |
345 | |
346 | f = new Function("pow", Type.Float); |
347 | f.isBuiltIn_ = true; |
348 | f.addArgument(Type.Float); |
349 | f.addArgument(Type.Float); |
350 | builtInMap.put("pow", f); |
351 | f.isOperator_ = false; |
352 | Power = f; |
353 | |
354 | f = new Function("log", Type.Float); |
355 | f.isBuiltIn_ = true; |
356 | f.addArgument(Type.Float); |
357 | f.addArgument(Type.Float); |
358 | builtInMap.put("log", f); |
359 | f.isOperator_ = false; |
360 | Log = f; |
361 | |
362 | f = new Function("bitand", Type.Integer); |
363 | f.isBuiltIn_ = true; |
364 | f.addArgument(Type.Integer); |
365 | f.addArgument(Type.Integer); |
366 | builtInMap.put(f.name_, f); |
367 | builtInMap.put("&", f); |
368 | f.isOperator_ = true; |
369 | BitAnd = f; |
370 | |
371 | f = new Function("bitor", Type.Integer); |
372 | f.isBuiltIn_ = true; |
373 | f.addArgument(Type.Integer); |
374 | f.addArgument(Type.Integer); |
375 | builtInMap.put(f.name_, f); |
376 | builtInMap.put("|", f); |
377 | f.isOperator_ = true; |
378 | BitOr = f; |
379 | |
380 | f = new Function("bitxor", Type.Integer); |
381 | f.isBuiltIn_ = true; |
382 | f.addArgument(Type.Integer); |
383 | f.addArgument(Type.Integer); |
384 | builtInMap.put(f.name_, f); |
385 | builtInMap.put("^", f); |
386 | f.isOperator_ = true; |
387 | BitXor = f; |
388 | |
389 | f = new Function("bitneg", Type.Integer); |
390 | f.isBuiltIn_ = true; |
391 | f.addArgument(Type.Integer); |
392 | f.addArgument(Type.Integer); |
393 | builtInMap.put(f.name_, f); |
394 | builtInMap.put("~", f); |
395 | f.isOperator_ = true; |
396 | BitNeg = f; |
397 | |
398 | f = new Function("bitShiftLeft", Type.Integer); |
399 | f.isBuiltIn_ = true; |
400 | f.addArgument(Type.Integer); |
401 | f.addArgument(Type.Integer); |
402 | builtInMap.put(f.name_, f); |
403 | builtInMap.put("<<", f); |
404 | f.isOperator_ = true; |
405 | BitShiftLeft = f; |
406 | |
407 | f = new Function("bitShiftRight", Type.Integer); |
408 | f.isBuiltIn_ = true; |
409 | f.addArgument(Type.Integer); |
410 | f.addArgument(Type.Integer); |
411 | builtInMap.put(f.name_, f); |
412 | builtInMap.put(">>", f); |
413 | f.isOperator_ = true; |
414 | BitShiftRight = f; |
415 | |
416 | } |
417 | |
418 | |
419 | |
420 | // string functions, unary |
421 | public static Function Length = null; |
422 | public static Function UpperCase = null; |
423 | public static Function LowerCase = null; |
424 | public static Function Trim = null; |
425 | public static Function InitCap = null; |
426 | public static Function MD5 = null; |
427 | |
428 | static{ |
429 | Function f = null; |
430 | |
431 | f = new Function("length", Type.Integer); |
432 | f.isBuiltIn_ = true; |
433 | f.addArgument(Type.String); |
434 | builtInMap.put("length", f); |
435 | builtInMap.put("strlen", f); |
436 | builtInMap.put("len", f); |
437 | Length = f; |
438 | |
439 | f = new Function("upper", Type.String); |
440 | f.isBuiltIn_ = true; |
441 | f.addArgument(Type.String); |
442 | builtInMap.put(f.name_, f); |
443 | UpperCase = f; |
444 | |
445 | f = new Function("lower", Type.String); |
446 | f.isBuiltIn_ = true; |
447 | f.addArgument(Type.String); |
448 | builtInMap.put(f.name_, f); |
449 | LowerCase = f; |
450 | |
451 | f = new Function("trim", Type.String); |
452 | f.isBuiltIn_ = true; |
453 | f.addArgument(Type.String); |
454 | builtInMap.put(f.name_, f); |
455 | Trim = f; |
456 | |
457 | f = new Function("initcap", Type.String); |
458 | f.isBuiltIn_ = true; |
459 | f.addArgument(Type.String); |
460 | builtInMap.put(f.name_, f); |
461 | InitCap = f; |
462 | |
463 | f = new Function("md5", Type.String); |
464 | f.isBuiltIn_ = true; |
465 | f.addArgument(Type.String); |
466 | builtInMap.put(f.name_, f); |
467 | MD5 = f; |
468 | } |
469 | |
470 | |
471 | |
472 | // string functions, binary |
473 | public static Function Concat = null; |
474 | public static Function StrPos = null; |
475 | public static Function Repeat = null; |
476 | |
477 | static{ |
478 | Function f = null; |
479 | |
480 | f = new Function("concat", Type.String); |
481 | f.isBuiltIn_ = true; |
482 | f.addArgument(Type.String); |
483 | f.addArgument(Type.String); |
484 | builtInMap.put("concat", f); |
485 | builtInMap.put("||", f); |
486 | Concat = f; |
487 | |
488 | f = new Function("strpos", Type.Integer); |
489 | f.isBuiltIn_ = true; |
490 | f.addArgument(Type.String); |
491 | f.addArgument(Type.String); |
492 | builtInMap.put(f.name_, f); |
493 | StrPos = f; |
494 | |
495 | f = new Function("repeat", Type.String); |
496 | f.isBuiltIn_ = true; |
497 | f.addArgument(Type.String); |
498 | f.addArgument(Type.Integer); |
499 | builtInMap.put(f.name_, f); |
500 | Repeat = f; |
501 | |
502 | } |
503 | |
504 | |
505 | |
506 | // string functions, ternary |
507 | public static Function Substr = null; |
508 | public static Function Replace = null; |
509 | public static Function SplitPart = null; |
510 | public static Function RegexReplace = null; |
511 | |
512 | static{ |
513 | Function f = null; |
514 | |
515 | f = new Function("substr", Type.String); |
516 | f.isBuiltIn_ = true; |
517 | f.addArgument(Type.String); |
518 | f.addArgument(Type.Integer); |
519 | f.addArgument(Type.Integer); |
520 | builtInMap.put(f.name_, f); |
521 | Substr = f; |
522 | |
523 | f = new Function("replace", Type.String); |
524 | f.isBuiltIn_ = true; |
525 | f.addArgument(Type.String); |
526 | f.addArgument(Type.String); |
527 | f.addArgument(Type.String); |
528 | builtInMap.put(f.name_, f); |
529 | Replace = f; |
530 | |
531 | f = new Function("split_part", Type.String); |
532 | f.isBuiltIn_ = true; |
533 | f.addArgument(Type.String); |
534 | f.addArgument(Type.String); |
535 | f.addArgument(Type.Integer); |
536 | builtInMap.put(f.name_, f); |
537 | SplitPart = f; |
538 | |
539 | f = new Function("regex_replace", Type.String); |
540 | f.isBuiltIn_ = true; |
541 | f.addArgument(Type.String); |
542 | f.addArgument(Type.String); |
543 | f.addArgument(Type.String); |
544 | f.setPgFunction("regexp_replace"); |
545 | builtInMap.put(f.name_, f); |
546 | RegexReplace = f; |
547 | |
548 | } |
549 | |
550 | |
551 | |
552 | /** |
553 | * Name of this function. |
554 | */ |
555 | private String name_; |
556 | private String pgfun_ = null; |
557 | |
558 | private boolean isOperator_ = false; |
559 | public boolean isOperator(){ |
560 | return isOperator_; |
561 | } |
562 | |
563 | /** |
564 | * List of argument types and return type of this function. |
565 | */ |
566 | private ArrayList<Type> argTypes_ = new ArrayList<Type>(); |
567 | private Type retType_ = null; |
568 | |
569 | private boolean isBuiltIn_ = false; |
570 | |
571 | public boolean isBuiltIn(){ |
572 | return isBuiltIn_; |
573 | } |
574 | |
575 | /** |
576 | * Get the corresponding function name inside PgSQL. |
577 | * |
578 | */ |
579 | public String getPgFunction(){ |
580 | return pgfun_; |
581 | } |
582 | |
583 | /** |
584 | * Set the corresponding function name inside PgSQL. |
585 | * |
586 | */ |
587 | public void setPgFunction(String fun){ |
588 | pgfun_ = fun; |
589 | } |
590 | |
591 | public Function(String name, Type retType){ |
592 | name_ = name; |
593 | retType_ = retType; |
594 | pgfun_ = name_; |
595 | } |
596 | |
597 | public void addArgument(Type type){ |
598 | argTypes_.add(type); |
599 | } |
600 | |
601 | public int arity(){ |
602 | return argTypes_.size(); |
603 | } |
604 | |
605 | public String getName(){ |
606 | return name_; |
607 | } |
608 | |
609 | /** |
610 | * Get return type |
611 | * |
612 | */ |
613 | public Type getRetType(){ |
614 | return retType_; |
615 | } |
616 | |
617 | public List<Type> getArgTypes(){ |
618 | return argTypes_; |
619 | } |
620 | } |