func.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. ** Copyright (c) 2011 D. Richard Hipp
  3. **
  4. ** This program is free software; you can redistribute it and/or
  5. ** modify it under the terms of the Simplified BSD License (also
  6. ** known as the "2-Clause License" or "FreeBSD License".)
  7. **
  8. ** This program is distributed in the hope that it will be useful,
  9. ** but without any warranty; without even the implied warranty of
  10. ** merchantability or fitness for a particular purpose.
  11. **
  12. ** Author contact information:
  13. ** [email protected]
  14. ** http://www.hwaci.com/drh/
  15. **
  16. *************************************************************************
  17. */
  18. #include "xjd1Int.h"
  19. /*
  20. ** A structure used to store the definition of a query language function
  21. ** or aggregate.
  22. */
  23. struct Function {
  24. int nMinArg;
  25. int nMaxArg;
  26. const char *zName;
  27. JsonNode *(*xFunc)(int nArg, JsonNode **apArg);
  28. int (*xStep)(int nArg, JsonNode **apArg, void **, int *pbSave);
  29. JsonNode *(*xFinal)(void *);
  30. };
  31. /*************************************************************************
  32. ** Start of implementation of aggregate functions:
  33. **
  34. ** count()
  35. ** This aggregate may be invoked with zero or one argument. If no
  36. ** arguments are specified, it returns the number of rows visited. If
  37. ** one argument is supplied, it returns the number of rows visited
  38. ** for which the argument was anything other than a NULL. In all cases,
  39. ** this function returns a non-negative integer value.
  40. **
  41. ** min()
  42. ** This aggregate is invoked with exactly one argument. If no rows are
  43. ** visited, NULL is returned. Otherwise, it returns a copy of the
  44. ** smallest argument it is passed. The comparisons used to determine
  45. ** which argument is the smallest are performed using the same rules
  46. ** as for the < and > operators.
  47. **
  48. ** max()
  49. ** This aggregate is invoked with exactly one argument. If no rows are
  50. ** visited, NULL is returned. Otherwise, it returns a copy of the
  51. ** largest argument it is passed. The comparisons used to determine
  52. ** which argument is the largest are performed using the same rules
  53. ** as for the < and > operators.
  54. **
  55. ** array()
  56. ** This aggregate is invoked with exactly one argument. If no rows are
  57. ** visited, an empty array is returned. Otherwise, an array containing
  58. ** the argument passed to this aggregate for each row visited is returned.
  59. ** The order in which the values appear in the returned array is not
  60. ** defined.
  61. **
  62. ** sum()
  63. ** This aggregate is invoked with exactly one argument. If no rows are
  64. ** visited, the value 0.0 (a number) is returned. Otherwise, each argument
  65. ** is converted to a number and the sum of all converted arguments
  66. ** returned. Any value that cannot be converted to a number (i.e. a struct,
  67. ** an array or any string value that does not look like a number) is
  68. ** treated as 0.0.
  69. **
  70. ** avg()
  71. ** This aggregate is invoked with exactly one argument. If no rows are
  72. ** visited, NULL is returned. Otherwise, the expression avg(X) is
  73. ** equivalent to (sum(X)/count()).
  74. */
  75. /*
  76. ** Aggregate function count().
  77. */
  78. static int xCountStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  79. int *pnCount = (int *)*pp;
  80. if( pnCount==0 ){
  81. pnCount = xjd1MallocZero(sizeof(int));
  82. *pp = (void *)pnCount;
  83. }
  84. if( nArg==0 || apArg[0]->eJType!=XJD1_NULL ){
  85. (*pnCount)++;
  86. }
  87. return XJD1_OK;
  88. }
  89. static JsonNode *xCountFinal(void *p){
  90. JsonNode *pRet;
  91. pRet = xjd1JsonNew(0);
  92. pRet->eJType = XJD1_REAL;
  93. if( p ){
  94. pRet->u.r = (double)*(int *)p;
  95. xjd1_free(p);
  96. }
  97. return pRet;
  98. }
  99. /*
  100. ** Aggregate functions min() and max().
  101. */
  102. static int xMinStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  103. JsonNode *pArg;
  104. JsonNode *pBest = *pp;
  105. assert( nArg==1 );
  106. pArg = apArg[0];
  107. if( !pBest || xjd1JsonCompare(pArg, pBest, 0)<0 ){
  108. xjd1JsonFree(pBest);
  109. *pp = (void *)xjd1JsonRef(pArg);
  110. *pbSave = 1;
  111. }
  112. return XJD1_OK;
  113. }
  114. static int xMaxStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  115. JsonNode *pArg;
  116. JsonNode *pBest = *pp;
  117. assert( nArg==1 );
  118. pArg = apArg[0];
  119. if( !pBest || xjd1JsonCompare(pArg, pBest, 0)>0 ){
  120. xjd1JsonFree(pBest);
  121. *pp = (void *)xjd1JsonRef(pArg);
  122. *pbSave = 1;
  123. }
  124. return XJD1_OK;
  125. }
  126. static JsonNode *xMinMaxFinal(void *p){
  127. JsonNode *pRet;
  128. if( p ){
  129. pRet = (JsonNode *)p;
  130. }else{
  131. pRet = xjd1JsonNew(0);
  132. pRet->eJType = XJD1_NULL;
  133. }
  134. return pRet;
  135. }
  136. /*
  137. ** Aggregate function array().
  138. */
  139. static int xArrayStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  140. JsonNode *pArray = (JsonNode *)*pp;
  141. JsonNode *pArg = apArg[0];
  142. int nNew;
  143. if( !pArray ){
  144. pArray = xjd1JsonNew(0);
  145. pArray->eJType = XJD1_ARRAY;
  146. *pp = (void *)pArray;
  147. }
  148. nNew = pArray->u.ar.nElem+1;
  149. pArray->u.ar.apElem = (JsonNode **)xjd1_realloc(
  150. pArray->u.ar.apElem, nNew*sizeof(JsonNode *)
  151. );
  152. pArray->u.ar.nElem = nNew;
  153. pArray->u.ar.apElem[nNew-1] = xjd1JsonRef(pArg);
  154. return XJD1_OK;
  155. }
  156. static JsonNode *xArrayFinal(void *p){
  157. JsonNode *pArray = (JsonNode *)p;
  158. if( !pArray ){
  159. pArray = xjd1JsonNew(0);
  160. pArray->eJType = XJD1_ARRAY;
  161. }
  162. return pArray;
  163. }
  164. /*
  165. ** Aggregate function sum()
  166. */
  167. static int xSumStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  168. JsonNode *pVal = (JsonNode *)*pp;
  169. double rVal = 0.0;
  170. if( !pVal ){
  171. pVal = xjd1JsonNew(0);
  172. pVal->eJType = XJD1_REAL;
  173. *pp = (void *)pVal;
  174. }
  175. if( XJD1_OK==xjd1JsonToReal(apArg[0], &rVal) ){
  176. pVal->u.r += rVal;
  177. }
  178. return XJD1_OK;
  179. }
  180. static JsonNode *xSumFinal(void *p){
  181. JsonNode *pVal = (JsonNode *)p;
  182. if( !pVal ){
  183. pVal = xjd1JsonNew(0);
  184. pVal->eJType = XJD1_REAL;
  185. }
  186. return pVal;
  187. }
  188. /*
  189. ** Aggregate function avg()
  190. */
  191. typedef struct AvgCtx AvgCtx;
  192. struct AvgCtx {
  193. int nRow;
  194. double rSum;
  195. };
  196. static int xAvgStep(int nArg, JsonNode **apArg, void **pp, int *pbSave){
  197. AvgCtx *pCtx = (AvgCtx *)*pp;
  198. double rVal = 0.0;
  199. if( !pCtx ){
  200. pCtx = xjd1MallocZero(sizeof(AvgCtx));
  201. *pp = (void *)pCtx;
  202. }
  203. pCtx->nRow++;
  204. if( XJD1_OK==xjd1JsonToReal(apArg[0], &rVal) ){
  205. pCtx->rSum += rVal;
  206. }
  207. return XJD1_OK;
  208. }
  209. static JsonNode *xAvgFinal(void *p){
  210. AvgCtx *pCtx = (AvgCtx *)p;
  211. JsonNode *pRet;
  212. pRet = xjd1JsonNew(0);
  213. if( pCtx ){
  214. pRet->eJType = XJD1_REAL;
  215. pRet->u.r = pCtx->rSum/(double)pCtx->nRow;
  216. xjd1_free(pCtx);
  217. }else{
  218. pRet->eJType = XJD1_NULL;
  219. }
  220. return pRet;
  221. }
  222. /*
  223. ** End of implementation of aggregates.
  224. *************************************************************************/
  225. /*************************************************************************
  226. ** Start of implementation of scalar functions:
  227. **
  228. ** length()
  229. ** This function is called with exactly one argument. It converts
  230. ** that argument to a string, and returns the number of characters
  231. ** in that string.
  232. **
  233. */
  234. /*
  235. ** Scalar function "length(x)".
  236. */
  237. static JsonNode *xLength(int nArg, JsonNode **apArg){
  238. JsonNode *pRet;
  239. JsonNode *pStr;
  240. int nRet;
  241. assert( nArg==1 );
  242. pStr = apArg[0];
  243. if( pStr->eJType==XJD1_STRING ){
  244. nRet = xjd1Strlen30(pStr->u.z);
  245. }else{
  246. String str;
  247. xjd1StringInit(&str, 0, 0);
  248. xjd1JsonToString(pStr, &str);
  249. nRet = str.nUsed;
  250. xjd1StringClear(&str);
  251. }
  252. pRet = xjd1JsonNew(0);
  253. pRet->eJType = XJD1_REAL;
  254. pRet->u.r = (double)nRet;
  255. return pRet;
  256. }
  257. /*
  258. ** End of implementation of scalar functions.
  259. *************************************************************************/
  260. int xjd1AggregateInit(xjd1_stmt *pStmt, Query *pQuery, Expr *p){
  261. Aggregate *pAgg;
  262. assert( pQuery->eQType==TK_SELECT );
  263. pAgg = pQuery->u.simple.pAgg;
  264. if( pAgg==0 ){
  265. pAgg = (Aggregate *)xjd1PoolMallocZero(&pStmt->sPool, sizeof(Aggregate));
  266. if( pAgg==0 ) return XJD1_NOMEM;
  267. pQuery->u.simple.pAgg = pAgg;
  268. }
  269. if( p ){
  270. static const int ARRAY_ALLOC_INCR = 8;
  271. if( (pAgg->nExpr % ARRAY_ALLOC_INCR)==0 ){
  272. int nByte; /* Size of new allocation in bytes */
  273. int nCopy; /* Size of old allocation in bytes */
  274. AggExpr *aNew; /* Pointer to new allocation */
  275. nByte = (pAgg->nExpr + ARRAY_ALLOC_INCR) * sizeof(AggExpr);
  276. nCopy = pAgg->nExpr * sizeof(AggExpr);
  277. aNew = (AggExpr *)xjd1PoolMallocZero(&pStmt->sPool, nByte);
  278. if( aNew==0 ) return XJD1_NOMEM;
  279. memcpy(aNew, pAgg->aAggExpr, nCopy);
  280. pAgg->aAggExpr = aNew;
  281. }
  282. p->u.func.iAgg = pAgg->nExpr;
  283. pAgg->aAggExpr[pAgg->nExpr++].pExpr = p;
  284. }
  285. return XJD1_OK;
  286. }
  287. /*
  288. ** The expression passed as the first argument is of type TK_FUNCTION.
  289. ** This function initializes the expression object. If successful, XJD1_OK
  290. ** is returned. Otherwise, an error code is returned and an error left in
  291. ** the pStmt statement handle.
  292. */
  293. int xjd1FunctionInit(Expr *p, xjd1_stmt *pStmt, Query *pQuery, int eExpr){
  294. char *zName;
  295. int nArg;
  296. int nByte;
  297. int i;
  298. int bAggOk;
  299. int bWrongNumArgs = 0;
  300. static Function aFunc[] = {
  301. { 1,1, "length", xLength, 0, 0 },
  302. { 0,1, "count", 0, xCountStep, xCountFinal },
  303. { 1,1, "min", 0, xMinStep, xMinMaxFinal },
  304. { 1,1, "max", 0, xMaxStep, xMinMaxFinal },
  305. { 1,1, "array", 0, xArrayStep, xArrayFinal },
  306. { 1,1, "sum", 0, xSumStep, xSumFinal },
  307. { 1,1, "avg", 0, xAvgStep, xAvgFinal },
  308. };
  309. assert( p->eType==TK_FUNCTION && p->eClass==XJD1_EXPR_FUNC );
  310. assert( pQuery || eExpr==0 );
  311. /* Set bAggOk to true if aggregate functions may be used in this context. */
  312. bAggOk = (pQuery && pQuery->eQType==TK_SELECT
  313. && (eExpr==XJD1_EXPR_RESULT || eExpr==XJD1_EXPR_GROUPBY
  314. || eExpr==XJD1_EXPR_HAVING || eExpr==XJD1_EXPR_ORDERBY
  315. ));
  316. zName = p->u.func.zFName;
  317. nArg = p->u.func.args->nEItem;
  318. for(i=0; i<ArraySize(aFunc); i++){
  319. Function *pFunc = &aFunc[i];
  320. assert( (pFunc->xFunc==0)==(pFunc->xStep && pFunc->xFinal) );
  321. if( !strcmp(pFunc->zName, zName) ){
  322. if( nArg<=pFunc->nMaxArg && nArg>=pFunc->nMinArg ){
  323. if( pFunc->xStep ){
  324. int rc;
  325. if( bAggOk==0 ){
  326. const char *zErrMsg = "illegal use of aggregate function: %s";
  327. xjd1StmtError(pStmt, XJD1_ERROR, zErrMsg, zName);
  328. return XJD1_ERROR;
  329. }
  330. /* Add this aggregate function to the Query.pAgg->apExpr[] array. */
  331. rc = xjd1AggregateInit(pStmt, pQuery, p);
  332. if( rc!=XJD1_OK ) return rc;
  333. }
  334. p->u.func.pFunction = pFunc;
  335. }else{
  336. bWrongNumArgs = 1;
  337. }
  338. break;
  339. }
  340. }
  341. if( !p->u.func.pFunction ){
  342. if( bWrongNumArgs ){
  343. xjd1StmtError(pStmt, XJD1_ERROR,
  344. "wrong number of arguments to function %s()", zName);
  345. }else{
  346. xjd1StmtError(pStmt, XJD1_ERROR, "no such function: %s", zName);
  347. }
  348. return XJD1_ERROR;
  349. }
  350. nByte = sizeof(JsonNode *) * nArg;
  351. p->u.func.apArg = (JsonNode **)xjd1PoolMallocZero(&pStmt->sPool, nByte);
  352. if( !p->u.func.apArg ){
  353. return XJD1_NOMEM;
  354. }
  355. return XJD1_OK;
  356. }
  357. static int aggExprStep(AggExpr *pAggExpr, int *pbSave){
  358. Expr *p = pAggExpr->pExpr;
  359. Function *pFunc = p->u.func.pFunction;
  360. int i;
  361. int nItem = p->u.func.args->nEItem;
  362. assert( p->eType==TK_FUNCTION && p->eClass==XJD1_EXPR_FUNC );
  363. assert( pFunc->xStep && pFunc->xFinal && pFunc->xFunc==0 );
  364. for(i=0; i<nItem; i++){
  365. p->u.func.apArg[i] = xjd1ExprEval(p->u.func.args->apEItem[i].pExpr);
  366. }
  367. pFunc->xStep(nItem, p->u.func.apArg, &pAggExpr->pAggCtx, pbSave);
  368. for(i=0; i<nItem; i++){
  369. xjd1JsonFree(p->u.func.apArg[i]);
  370. }
  371. return XJD1_OK;
  372. }
  373. int xjd1AggregateStep(
  374. Aggregate *pAgg,
  375. int *pbSave /* OUT: True if this row should be saved */
  376. ){
  377. int i; /* Used to iterate through aggregate functions */
  378. for(i=0; i<pAgg->nExpr; i++){
  379. int rc = aggExprStep(&pAgg->aAggExpr[i], pbSave);
  380. if( rc!=XJD1_OK ) return rc;
  381. }
  382. return XJD1_OK;;
  383. }
  384. int xjd1AggregateFinalize(Aggregate *pAgg){
  385. int i;
  386. for(i=0; i<pAgg->nExpr; i++){
  387. AggExpr *pAggExpr = &pAgg->aAggExpr[i];
  388. Expr *p = pAggExpr->pExpr;
  389. assert( i==p->u.func.iAgg );
  390. xjd1JsonFree(pAggExpr->pValue);
  391. pAggExpr->pValue = p->u.func.pFunction->xFinal(pAggExpr->pAggCtx);
  392. pAggExpr->pAggCtx = 0;
  393. }
  394. return XJD1_OK;
  395. }
  396. /*
  397. ** Call any outstanding xFinal() functions for aggregate functions in the
  398. ** query. This is required to reset the aggregate contexts when a query is
  399. ** rewound following an error.
  400. */
  401. void xjd1AggregateClear(Query *pQuery){
  402. Aggregate *pAgg = pQuery->u.simple.pAgg;
  403. assert( pQuery->eQType==TK_SELECT );
  404. if( pAgg ){
  405. int i;
  406. for(i=0; i<pAgg->nExpr; i++){
  407. AggExpr *pAggExpr = &pAgg->aAggExpr[i];
  408. Expr *p = pAggExpr->pExpr;
  409. xjd1JsonFree( p->u.func.pFunction->xFinal(pAggExpr->pAggCtx) );
  410. xjd1JsonFree( pAggExpr->pValue );
  411. pAggExpr->pAggCtx = 0;
  412. pAggExpr->pValue = 0;
  413. }
  414. }
  415. }
  416. JsonNode *xjd1FunctionEval(Expr *p){
  417. JsonNode *pRet;
  418. Function *pFunc = p->u.func.pFunction;
  419. assert( p->eType==TK_FUNCTION && p->eClass==XJD1_EXPR_FUNC );
  420. if( pFunc->xFunc ){
  421. /* A scalar function. */
  422. int i;
  423. int nItem = p->u.func.args->nEItem;
  424. for(i=0; i<nItem; i++){
  425. p->u.func.apArg[i] = xjd1ExprEval(p->u.func.args->apEItem[i].pExpr);
  426. }
  427. pRet = pFunc->xFunc(nItem, p->u.func.apArg);
  428. for(i=0; i<nItem; i++){
  429. xjd1JsonFree(p->u.func.apArg[i]);
  430. }
  431. }else{
  432. AggExpr *pAggExpr = &p->pQuery->u.simple.pAgg->aAggExpr[p->u.func.iAgg];
  433. pRet = xjd1JsonRef(pAggExpr->pValue);
  434. }
  435. return pRet;
  436. }