@@ -31,11 +31,12 @@ class FunctionsBuilder
31
31
* @param string $name the name of the SQL function to constructed
32
32
* @param array $params list of params to be passed to the function
33
33
* @param array $types list of types for each function param
34
+ * @param string $return The return type of the function expression
34
35
* @return FunctionExpression
35
36
*/
36
- protected function _build ($ name , $ params = [], $ types = [])
37
+ protected function _build ($ name , $ params = [], $ types = [], $ return = ' string ' )
37
38
{
38
- return new FunctionExpression ($ name , $ params , $ types );
39
+ return new FunctionExpression ($ name , $ params , $ types, $ return );
39
40
}
40
41
41
42
/**
@@ -45,16 +46,17 @@ protected function _build($name, $params = [], $types = [])
45
46
* @param string $name name of the function to build
46
47
* @param mixed $expression the function argument
47
48
* @param array $types list of types to bind to the arguments
49
+ * @param string $return The return type for the function
48
50
* @return FunctionExpression
49
51
*/
50
- protected function _literalArgumentFunction ($ name , $ expression , $ types = [])
52
+ protected function _literalArgumentFunction ($ name , $ expression , $ types = [], $ return = ' string ' )
51
53
{
52
54
if (!is_string ($ expression )) {
53
55
$ expression = [$ expression ];
54
56
} else {
55
57
$ expression = [$ expression => 'literal ' ];
56
58
}
57
- return $ this ->_build ($ name , $ expression , $ types );
59
+ return $ this ->_build ($ name , $ expression , $ types, $ return );
58
60
}
59
61
60
62
/**
@@ -66,7 +68,7 @@ protected function _literalArgumentFunction($name, $expression, $types = [])
66
68
*/
67
69
public function sum ($ expression , $ types = [])
68
70
{
69
- return $ this ->_literalArgumentFunction ('SUM ' , $ expression , $ types );
71
+ return $ this ->_literalArgumentFunction ('SUM ' , $ expression , $ types, ' float ' );
70
72
}
71
73
72
74
/**
@@ -78,7 +80,7 @@ public function sum($expression, $types = [])
78
80
*/
79
81
public function avg ($ expression , $ types = [])
80
82
{
81
- return $ this ->_literalArgumentFunction ('AVG ' , $ expression , $ types );
83
+ return $ this ->_literalArgumentFunction ('AVG ' , $ expression , $ types, ' float ' );
82
84
}
83
85
84
86
/**
@@ -90,7 +92,7 @@ public function avg($expression, $types = [])
90
92
*/
91
93
public function max ($ expression , $ types = [])
92
94
{
93
- return $ this ->_literalArgumentFunction ('MAX ' , $ expression , $ types );
95
+ return $ this ->_literalArgumentFunction ('MAX ' , $ expression , $ types, current ( $ types ) ?: ' string ' );
94
96
}
95
97
96
98
/**
@@ -102,7 +104,7 @@ public function max($expression, $types = [])
102
104
*/
103
105
public function min ($ expression , $ types = [])
104
106
{
105
- return $ this ->_literalArgumentFunction ('MIN ' , $ expression , $ types );
107
+ return $ this ->_literalArgumentFunction ('MIN ' , $ expression , $ types, current ( $ types ) ?: ' string ' );
106
108
}
107
109
108
110
/**
@@ -114,7 +116,7 @@ public function min($expression, $types = [])
114
116
*/
115
117
public function count ($ expression , $ types = [])
116
118
{
117
- return $ this ->_literalArgumentFunction ('COUNT ' , $ expression , $ types );
119
+ return $ this ->_literalArgumentFunction ('COUNT ' , $ expression , $ types, ' integer ' );
118
120
}
119
121
120
122
/**
@@ -126,7 +128,7 @@ public function count($expression, $types = [])
126
128
*/
127
129
public function concat ($ args , $ types = [])
128
130
{
129
- return $ this ->_build ('CONCAT ' , $ args , $ types );
131
+ return $ this ->_build ('CONCAT ' , $ args , $ types, ' string ' );
130
132
}
131
133
132
134
/**
@@ -138,7 +140,7 @@ public function concat($args, $types = [])
138
140
*/
139
141
public function coalesce ($ args , $ types = [])
140
142
{
141
- return $ this ->_build ('COALESCE ' , $ args , $ types );
143
+ return $ this ->_build ('COALESCE ' , $ args , $ types, current ( $ types ) ?: ' string ' );
142
144
}
143
145
144
146
/**
@@ -151,7 +153,7 @@ public function coalesce($args, $types = [])
151
153
*/
152
154
public function dateDiff ($ args , $ types = [])
153
155
{
154
- return $ this ->_build ('DATEDIFF ' , $ args , $ types );
156
+ return $ this ->_build ('DATEDIFF ' , $ args , $ types, ' integer ' );
155
157
}
156
158
157
159
/**
@@ -177,7 +179,7 @@ public function datePart($part, $expression, $types = [])
177
179
*/
178
180
public function extract ($ part , $ expression , $ types = [])
179
181
{
180
- $ expression = $ this ->_literalArgumentFunction ('EXTRACT ' , $ expression , $ types );
182
+ $ expression = $ this ->_literalArgumentFunction ('EXTRACT ' , $ expression , $ types, ' integer ' );
181
183
$ expression ->tieWith (' FROM ' )->add ([$ part => 'literal ' ], [], true );
182
184
return $ expression ;
183
185
}
@@ -197,7 +199,7 @@ public function dateAdd($expression, $value, $unit, $types = [])
197
199
$ value = 0 ;
198
200
}
199
201
$ interval = $ value . ' ' . $ unit ;
200
- $ expression = $ this ->_literalArgumentFunction ('DATE_ADD ' , $ expression , $ types );
202
+ $ expression = $ this ->_literalArgumentFunction ('DATE_ADD ' , $ expression , $ types, ' datetime ' );
201
203
$ expression ->tieWith (', INTERVAL ' )->add ([$ interval => 'literal ' ]);
202
204
return $ expression ;
203
205
}
@@ -212,7 +214,7 @@ public function dateAdd($expression, $value, $unit, $types = [])
212
214
*/
213
215
public function dayOfWeek ($ expression , $ types = [])
214
216
{
215
- return $ this ->_literalArgumentFunction ('DAYOFWEEK ' , $ expression , $ types );
217
+ return $ this ->_literalArgumentFunction ('DAYOFWEEK ' , $ expression , $ types, ' integer ' );
216
218
}
217
219
218
220
/**
@@ -239,23 +241,23 @@ public function weekday($expression, $types = [])
239
241
public function now ($ type = 'datetime ' )
240
242
{
241
243
if ($ type === 'datetime ' ) {
242
- return $ this ->_build ('NOW ' );
244
+ return $ this ->_build ('NOW ' )-> returnType ( ' datetime ' ) ;
243
245
}
244
246
if ($ type === 'date ' ) {
245
- return $ this ->_build ('CURRENT_DATE ' );
247
+ return $ this ->_build ('CURRENT_DATE ' )-> returnType ( ' date ' ) ;
246
248
}
247
249
if ($ type === 'time ' ) {
248
- return $ this ->_build ('CURRENT_TIME ' );
250
+ return $ this ->_build ('CURRENT_TIME ' )-> returnType ( ' time ' ) ;
249
251
}
250
252
}
251
253
252
254
/**
253
255
* Magic method dispatcher to create custom SQL function calls
254
256
*
255
257
* @param string $name the SQL function name to construct
256
- * @param array $args list with up to 2 arguments, first one being an array with
257
- * parameters for the SQL function and second one a list of types to bind to those
258
- * params
258
+ * @param array $args list with up to 3 arguments, first one being an array with
259
+ * parameters for the SQL function, the second one a list of types to bind to those
260
+ * params, and the third one the return type of the function
259
261
* @return \Cake\Database\Expression\FunctionExpression
260
262
*/
261
263
public function __call ($ name , $ args )
@@ -265,8 +267,10 @@ public function __call($name, $args)
265
267
return $ this ->_build ($ name );
266
268
case 1 :
267
269
return $ this ->_build ($ name , $ args [0 ]);
268
- default :
270
+ case 2 :
269
271
return $ this ->_build ($ name , $ args [0 ], $ args [1 ]);
272
+ default :
273
+ return $ this ->_build ($ name , $ args [0 ], $ args [1 ], $ args [2 ]);
270
274
}
271
275
}
272
276
}
0 commit comments