Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit668aa24

Browse files
committed
More merge's from Dr. George's sourec tree
1 parent772ae26 commit668aa24

16 files changed

+1615
-0
lines changed

‎src/extend/array/array_iterator.c

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/*
2+
* array_iterator.c --
3+
*
4+
* This file defines a new group 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 results.
8+
* For example array_int4eq returns true if some of the elements
9+
* of an array of int4 is equal to the given value:
10+
*
11+
*array_int4eq({1,2,3}, 1) --> true
12+
*array_int4eq({1,2,3}, 4) --> false
13+
*
14+
* If we have defined T array types and O scalar operators
15+
* we can define T x O array operators, each of them has a name
16+
* like "array_<basetype><operation>" and takes an array of type T
17+
* iterating the operator O over all the elements. Note however
18+
* that some of the possible combination are invalid, for example
19+
* the array_int4_like because there is no like operator for int4.
20+
* It is now possible to write queries which look inside the arrays:
21+
*
22+
* create table t(id int4[], txt text[]);
23+
*select * from t where t.id *= 123;
24+
*select * from t where t.txt *~ '[a-z]';
25+
*select * from t where t.txt[1:3] **~ '[a-z]';
26+
*
27+
* Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
28+
*/
29+
30+
#include<ctype.h>
31+
#include<stdio.h>
32+
#include<sys/types.h>
33+
#include<string.h>
34+
35+
#include"postgres.h"
36+
#include"pg_type.h"
37+
#include"miscadmin.h"
38+
#include"syscache.h"
39+
#include"access/xact.h"
40+
#include"utils/builtins.h"
41+
#include"utils/elog.h"
42+
43+
staticint32
44+
array_iterator(Oidelemtype,Oidproc,intand,ArrayType*array,Datumvalue)
45+
{
46+
HeapTupletyp_tuple;
47+
TypeTupleFormtyp_struct;
48+
booltypbyval;
49+
inttyplen;
50+
func_ptrproc_fn;
51+
intpronargs;
52+
intnitems,i,result;
53+
intndim,*dim;
54+
char*p;
55+
56+
/* Sanity checks */
57+
if ((array== (ArrayType*)NULL)
58+
|| (ARR_IS_LO(array)== true)) {
59+
/* elog(NOTICE, "array_iterator: array is null"); */
60+
return (0);
61+
}
62+
ndim=ARR_NDIM(array);
63+
dim=ARR_DIMS(array);
64+
nitems=getNitems(ndim,dim);
65+
if (nitems==0) {
66+
/* elog(NOTICE, "array_iterator: nitems = 0"); */
67+
return (0);
68+
}
69+
70+
/* Lookup element type information */
71+
typ_tuple=SearchSysCacheTuple(TYPOID,ObjectIdGetDatum(elemtype),0,0,0);
72+
if (!HeapTupleIsValid(typ_tuple)) {
73+
elog(WARN,"array_iterator: cache lookup failed for type %d",elemtype);
74+
return0;
75+
}
76+
typ_struct= (TypeTupleForm)GETSTRUCT(typ_tuple);
77+
typlen=typ_struct->typlen;
78+
typbyval=typ_struct->typbyval;
79+
80+
/* Lookup the function entry point */
81+
proc_fn== (func_ptr)NULL;
82+
fmgr_info(proc,&proc_fn,&pronargs);
83+
if ((proc_fn==NULL)|| (pronargs!=2)) {
84+
elog(WARN,"array_iterator: fmgr_info lookup failed for oid %d",proc);
85+
return (0);
86+
}
87+
88+
/* Scan the array and apply the operator to each element */
89+
result=0;
90+
p=ARR_DATA_PTR(array);
91+
for (i=0;i<nitems;i++) {
92+
if (typbyval) {
93+
switch(typlen) {
94+
case1:
95+
result= (int) (*proc_fn)(*p,value);
96+
break;
97+
case2:
98+
result= (int) (*proc_fn)(* (int16*)p,value);
99+
break;
100+
case3:
101+
case4:
102+
result= (int) (*proc_fn)(* (int32*)p,value);
103+
break;
104+
}
105+
p+=typlen;
106+
}else {
107+
result= (int) (*proc_fn)(p,value);
108+
if (typlen>0) {
109+
p+=typlen;
110+
}else {
111+
p+=INTALIGN(* (int32*)p);
112+
}
113+
}
114+
if (result) {
115+
if (!and) {
116+
return (1);
117+
}
118+
}else {
119+
if (and) {
120+
return (0);
121+
}
122+
}
123+
}
124+
125+
if (and&&result) {
126+
return (1);
127+
}else {
128+
return (0);
129+
}
130+
}
131+
132+
/*
133+
* Iterators for type _text
134+
*/
135+
136+
int32
137+
array_texteq(ArrayType*array,char*value)
138+
{
139+
returnarray_iterator((Oid)25,/* text */
140+
(Oid)67,/* texteq */
141+
0,/* logical or */
142+
array, (Datum)value);
143+
}
144+
145+
int32
146+
array_all_texteq(ArrayType*array,char*value)
147+
{
148+
returnarray_iterator((Oid)25,/* text */
149+
(Oid)67,/* texteq */
150+
1,/* logical and */
151+
array, (Datum)value);
152+
}
153+
154+
int32
155+
array_textregexeq(ArrayType*array,char*value)
156+
{
157+
returnarray_iterator((Oid)25,/* text */
158+
(Oid)81,/* textregexeq */
159+
0,/* logical or */
160+
array, (Datum)value);
161+
}
162+
163+
int32
164+
array_all_textregexeq(ArrayType*array,char*value)
165+
{
166+
returnarray_iterator((Oid)25,/* text */
167+
(Oid)81,/* textregexeq */
168+
1,/* logical and */
169+
array, (Datum)value);
170+
}
171+
172+
/*
173+
* Iterators for type _char16. Note that the regexp operators
174+
* take the second argument of type text.
175+
*/
176+
177+
int32
178+
array_char16eq(ArrayType*array,char*value)
179+
{
180+
returnarray_iterator((Oid)20,/* char16 */
181+
(Oid)490,/* char16eq */
182+
0,/* logical or */
183+
array, (Datum)value);
184+
}
185+
186+
int32
187+
array_all_char16eq(ArrayType*array,char*value)
188+
{
189+
returnarray_iterator((Oid)20,/* char16 */
190+
(Oid)490,/* char16eq */
191+
1,/* logical and */
192+
array, (Datum)value);
193+
}
194+
195+
int32
196+
array_char16regexeq(ArrayType*array,char*value)
197+
{
198+
returnarray_iterator((Oid)20,/* char16 */
199+
(Oid)700,/* char16regexeq */
200+
0,/* logical or */
201+
array, (Datum)value);
202+
}
203+
204+
int32
205+
array_all_char16regexeq(ArrayType*array,char*value)
206+
{
207+
returnarray_iterator((Oid)20,/* char16 */
208+
(Oid)700,/* char16regexeq */
209+
1,/* logical and */
210+
array, (Datum)value);
211+
}
212+
213+
/*
214+
* Iterators for type _int4
215+
*/
216+
217+
int32
218+
array_int4eq(ArrayType*array,int4value)
219+
{
220+
returnarray_iterator((Oid)23,/* int4 */
221+
(Oid)65,/* int4eq */
222+
0,/* logical or */
223+
array, (Datum)value);
224+
}
225+
226+
int32
227+
array_all_int4eq(ArrayType*array,int4value)
228+
{
229+
returnarray_iterator((Oid)23,/* int4 */
230+
(Oid)65,/* int4eq */
231+
1,/* logical and */
232+
array, (Datum)value);
233+
}
234+
235+
int32
236+
array_int4gt(ArrayType*array,int4value)
237+
{
238+
returnarray_iterator((Oid)23,/* int4 */
239+
(Oid)147,/* int4gt */
240+
0,/* logical or */
241+
array, (Datum)value);
242+
}
243+
244+
int32
245+
array_all_int4gt(ArrayType*array,int4value)
246+
{
247+
returnarray_iterator((Oid)23,/* int4 */
248+
(Oid)147,/* int4gt */
249+
1,/* logical and */
250+
array, (Datum)value);
251+
}

‎src/extend/array/array_iterator.doc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
From: Massimo Dal Zotto <dz@cs.unitn.it>
2+
Date: Mon, 6 May 1996 01:03:37 +0200 (MET DST)
3+
Subject: [PG95]: new operators for arrays
4+
5+
- -----BEGIN PGP SIGNED MESSAGE-----
6+
7+
Hi,
8+
9+
I have written an extension to Postgres95 which allows to use qualification
10+
clauses based on the values of single elements of arrays.
11+
For example I can now select rows having some or all element of an array
12+
attribute equal to a given value or matching a regular expression:
13+
14+
select * from t where t.foo *= 'bar';
15+
select * from t where t.foo **~ '^ba[rz]';
16+
17+
The scheme is quite general, each operator which operates on a base type can
18+
be iterated over the elements of an array. It seem to work well but defining
19+
each new operators requires writing a different C function. Furthermore in
20+
each function there are two hardcoded OIDs which reference a base type and
21+
a procedure. Not very portable. Can anyone suggest a better and more portable
22+
way to do it ? Do you think this could be a useful feature for next release ?
23+
Here is my code, it can be compiled and loaded as a dynamic module without
24+
need to recompile the backend. I have defined only the few operators I needed,
25+
the list can be extended. Feddback is welcome.
26+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp