array_iterator.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:8k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*
  2.  * array_iterator.c --
  3.  *
  4.  * This file defines a new class of operators which take an
  5.  * array and a scalar value, iterate a scalar operator over the
  6.  * elements of the array and the value and compute a result as
  7.  * the logical OR or AND of the iteration results.
  8.  *
  9.  * Copyright (c) 1997, Massimo Dal Zotto <dz@cs.unitn.it>
  10.  * ported to postgreSQL 6.3.2,added oid_functions, 18.1.1999,
  11.  * Tobias Gabele <gabele@wiz.uni-kassel.de>
  12.  */
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <sys/types.h>
  16. #include <string.h>
  17. #include "postgres.h"
  18. #include "miscadmin.h"
  19. #include "access/xact.h"
  20. #include "fmgr.h"
  21. #include "catalog/pg_type.h"
  22. #include "utils/array.h"
  23. #include "utils/builtins.h"
  24. #include "utils/memutils.h"
  25. #include "utils/syscache.h"
  26. #include "array_iterator.h"
  27. static int32
  28. array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
  29. {
  30. HeapTuple typ_tuple;
  31. Form_pg_type typ_struct;
  32. bool typbyval;
  33. int typlen;
  34. func_ptr proc_fn;
  35. int pronargs;
  36. int nitems,
  37. i,
  38. result;
  39. int ndim,
  40.    *dim;
  41. char    *p;
  42. FmgrInfo finf; /* Tobias Gabele Jan 18 1999 */
  43. /* Sanity checks */
  44. if ((array == (ArrayType *) NULL)
  45. || (ARR_IS_LO(array) == true))
  46. {
  47. /* elog(NOTICE, "array_iterator: array is null"); */
  48. return (0);
  49. }
  50. ndim = ARR_NDIM(array);
  51. dim = ARR_DIMS(array);
  52. nitems = getNitems(ndim, dim);
  53. if (nitems == 0)
  54. {
  55. /* elog(NOTICE, "array_iterator: nitems = 0"); */
  56. return (0);
  57. }
  58. /* Lookup element type information */
  59. typ_tuple = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(elemtype), 0, 0, 0);
  60. if (!HeapTupleIsValid(typ_tuple))
  61. {
  62. elog(ERROR, "array_iterator: cache lookup failed for type %d", elemtype);
  63. return 0;
  64. }
  65. typ_struct = (Form_pg_type) GETSTRUCT(typ_tuple);
  66. typlen = typ_struct->typlen;
  67. typbyval = typ_struct->typbyval;
  68. /* Lookup the function entry point */
  69. proc_fn = (func_ptr) NULL;
  70. fmgr_info(proc, &finf); /* Tobias Gabele Jan 18 1999 */
  71. proc_fn = finf.fn_addr; /* Tobias Gabele Jan 18 1999 */
  72. pronargs = finf.fn_nargs; /* Tobias Gabele Jan 18 1999 */
  73. if ((proc_fn == NULL) || (pronargs != 2))
  74. {
  75. elog(ERROR, "array_iterator: fmgr_info lookup failed for oid %d", proc);
  76. return (0);
  77. }
  78. /* Scan the array and apply the operator to each element */
  79. result = 0;
  80. p = ARR_DATA_PTR(array);
  81. for (i = 0; i < nitems; i++)
  82. {
  83. if (typbyval)
  84. {
  85. switch (typlen)
  86. {
  87. case 1:
  88. result = (int) (*proc_fn) (*p, value);
  89. break;
  90. case 2:
  91. result = (int) (*proc_fn) (*(int16 *) p, value);
  92. break;
  93. case 3:
  94. case 4:
  95. result = (int) (*proc_fn) (*(int32 *) p, value);
  96. break;
  97. }
  98. p += typlen;
  99. }
  100. else
  101. {
  102. result = (int) (*proc_fn) (p, value);
  103. if (typlen > 0)
  104. p += typlen;
  105. else
  106. p += INTALIGN(*(int32 *) p);
  107. }
  108. if (result)
  109. {
  110. if (!and)
  111. return (1);
  112. }
  113. else
  114. {
  115. if (and)
  116. return (0);
  117. }
  118. }
  119. if (and && result)
  120. return (1);
  121. else
  122. return (0);
  123. }
  124. /*
  125.  * Iterator functions for type _text
  126.  */
  127. int32
  128. array_texteq(ArrayType *array, char *value)
  129. {
  130. return array_iterator((Oid) 25, /* text */
  131.   (Oid) 67, /* texteq */
  132.   0, /* logical or */
  133.   array, (Datum) value);
  134. }
  135. int32
  136. array_all_texteq(ArrayType *array, char *value)
  137. {
  138. return array_iterator((Oid) 25, /* text */
  139.   (Oid) 67, /* texteq */
  140.   1, /* logical and */
  141.   array, (Datum) value);
  142. }
  143. int32
  144. array_textregexeq(ArrayType *array, char *value)
  145. {
  146. return array_iterator((Oid) 25, /* text */
  147.   (Oid) 1254, /* textregexeq */
  148.   0, /* logical or */
  149.   array, (Datum) value);
  150. }
  151. int32
  152. array_all_textregexeq(ArrayType *array, char *value)
  153. {
  154. return array_iterator((Oid) 25, /* text */
  155.   (Oid) 1254, /* textregexeq */
  156.   1, /* logical and */
  157.   array, (Datum) value);
  158. }
  159. /*
  160.  * Iterator functions for type _varchar. Note that the regexp
  161.  * operators take the second argument of type text.
  162.  */
  163. int32
  164. array_varchareq(ArrayType *array, char *value)
  165. {
  166. return array_iterator((Oid) 20, /* varchar */
  167.   (Oid) 1070, /* varchareq */
  168.   0, /* logical or */
  169.   array, (Datum) value);
  170. }
  171. int32
  172. array_all_varchareq(ArrayType *array, char *value)
  173. {
  174. return array_iterator((Oid) 20, /* varchar */
  175.   (Oid) 1070, /* varchareq */
  176.   1, /* logical and */
  177.   array, (Datum) value);
  178. }
  179. int32
  180. array_varcharregexeq(ArrayType *array, char *value)
  181. {
  182. return array_iterator((Oid) 20, /* varchar */
  183.   (Oid) 1254, /* textregexeq */
  184.   0, /* logical or */
  185.   array, (Datum) value);
  186. }
  187. int32
  188. array_all_varcharregexeq(ArrayType *array, char *value)
  189. {
  190. return array_iterator((Oid) 20, /* varchar */
  191.   (Oid) 1254, /* textregexeq */
  192.   1, /* logical and */
  193.   array, (Datum) value);
  194. }
  195. /*
  196.  * Iterator functions for type _bpchar. Note that the regexp
  197.  * operators take the second argument of type text.
  198.  */
  199. int32
  200. array_bpchareq(ArrayType *array, char *value)
  201. {
  202. return array_iterator((Oid) 20, /* bpchar */
  203.   (Oid) 1048, /* bpchareq */
  204.   0, /* logical or */
  205.   array, (Datum) value);
  206. }
  207. int32
  208. array_all_bpchareq(ArrayType *array, char *value)
  209. {
  210. return array_iterator((Oid) 20, /* bpchar */
  211.   (Oid) 1048, /* bpchareq */
  212.   1, /* logical and */
  213.   array, (Datum) value);
  214. }
  215. int32
  216. array_bpcharregexeq(ArrayType *array, char *value)
  217. {
  218. return array_iterator((Oid) 20, /* bpchar */
  219.   (Oid) 1254, /* textregexeq */
  220.   0, /* logical or */
  221.   array, (Datum) value);
  222. }
  223. int32
  224. array_all_bpcharregexeq(ArrayType *array, char *value)
  225. {
  226. return array_iterator((Oid) 20, /* bpchar */
  227.   (Oid) 1254, /* textregexeq */
  228.   1, /* logical and */
  229.   array, (Datum) value);
  230. }
  231. /*
  232.  * Iterator functions for type _int4
  233.  */
  234. int32
  235. array_int4eq(ArrayType *array, int4 value)
  236. {
  237. return array_iterator((Oid) 23, /* int4 */
  238.   (Oid) 65, /* int4eq */
  239.   0, /* logical or */
  240.   array, (Datum) value);
  241. }
  242. int32
  243. array_all_int4eq(ArrayType *array, int4 value)
  244. {
  245. return array_iterator((Oid) 23, /* int4 */
  246.   (Oid) 65, /* int4eq */
  247.   1, /* logical and */
  248.   array, (Datum) value);
  249. }
  250. int32
  251. array_int4ne(ArrayType *array, int4 value)
  252. {
  253. return array_iterator((Oid) 23, /* int4 */
  254.   (Oid) 144, /* int4ne */
  255.   0, /* logical or */
  256.   array, (Datum) value);
  257. }
  258. int32
  259. array_all_int4ne(ArrayType *array, int4 value)
  260. {
  261. return array_iterator((Oid) 23, /* int4 */
  262.   (Oid) 144, /* int4ne */
  263.   1, /* logical and */
  264.   array, (Datum) value);
  265. }
  266. int32
  267. array_int4gt(ArrayType *array, int4 value)
  268. {
  269. return array_iterator((Oid) 23, /* int4 */
  270.   (Oid) 147, /* int4gt */
  271.   0, /* logical or */
  272.   array, (Datum) value);
  273. }
  274. int32
  275. array_all_int4gt(ArrayType *array, int4 value)
  276. {
  277. return array_iterator((Oid) 23, /* int4 */
  278.   (Oid) 147, /* int4gt */
  279.   1, /* logical and */
  280.   array, (Datum) value);
  281. }
  282. int32
  283. array_int4ge(ArrayType *array, int4 value)
  284. {
  285. return array_iterator((Oid) 23, /* int4 */
  286.   (Oid) 150, /* int4ge */
  287.   0, /* logical or */
  288.   array, (Datum) value);
  289. }
  290. int32
  291. array_all_int4ge(ArrayType *array, int4 value)
  292. {
  293. return array_iterator((Oid) 23, /* int4 */
  294.   (Oid) 150, /* int4ge */
  295.   1, /* logical and */
  296.   array, (Datum) value);
  297. }
  298. int32
  299. array_int4lt(ArrayType *array, int4 value)
  300. {
  301. return array_iterator((Oid) 23, /* int4 */
  302.   (Oid) 66, /* int4lt */
  303.   0, /* logical or */
  304.   array, (Datum) value);
  305. }
  306. int32
  307. array_all_int4lt(ArrayType *array, int4 value)
  308. {
  309. return array_iterator((Oid) 23, /* int4 */
  310.   (Oid) 66, /* int4lt */
  311.   1, /* logical and */
  312.   array, (Datum) value);
  313. }
  314. int32
  315. array_int4le(ArrayType *array, int4 value)
  316. {
  317. return array_iterator((Oid) 23, /* int4 */
  318.   (Oid) 149, /* int4le */
  319.   0, /* logical or */
  320.   array, (Datum) value);
  321. }
  322. int32
  323. array_all_int4le(ArrayType *array, int4 value)
  324. {
  325. return array_iterator((Oid) 23, /* int4 */
  326.   (Oid) 149, /* int4le */
  327.   1, /* logical and */
  328.   array, (Datum) value);
  329. }
  330. /* new tobias gabele 1999 */
  331. int32
  332. array_oideq(ArrayType *array, Oid value)
  333. {
  334. return array_iterator((Oid) 26, /* oid */
  335.   (Oid) 184, /* oideq */
  336.   0, /* logical or */
  337.   array, (Datum) value);
  338. }
  339. int32
  340. array_all_oidne(ArrayType *array, Oid value)
  341. {
  342. return array_iterator((Oid) 26, /* int4 */
  343.   (Oid) 185, /* oidne */
  344.   1, /* logical and */
  345.   array, (Datum) value);
  346. }
  347. /* end of file */
  348. /*
  349.  * Local Variables:
  350.  *  tab-width: 4
  351.  *  c-indent-level: 4
  352.  *  c-basic-offset: 4
  353.  * End:
  354.  */