Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5cabcfc

Browse files
committed
Modify array operations to include array's element type OID in the
array header, and to compute sizing and alignment of array elements the same way normal tuple access operations do --- viz, using the tupmacs.h macros att_addlength and att_align. This makes the world safe for arrays of cstrings or intervals, and should make it much easier to write array-type-polymorphic functions; as examples see the cleanups of array_out and contrib/array_iterator. By Joe Conway and Tom Lane.
1 parent 8009c27 commit 5cabcfc

38 files changed

+558
-434
lines changed

contrib/array/README.array_iterator

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ attribute equal to a given value or matching a regular expression:
4141

4242
The scheme is quite general, each operator which operates on a base type
4343
can be iterated over the elements of an array. It seem to work well but
44-
defining each new operators requires writing a different C function.
45-
Furthermore in each function there are two hardcoded OIDs which reference
46-
a base type and a procedure. Not very portable. Can anyone suggest a
47-
better and more portable way to do it ?
44+
defining each new operator requires writing a different C function.
45+
This is tedious, and error-prone since one must take care that the correct
46+
datatypes are associated with the selected underlying function.
47+
Can anyone suggest a better and more portable way to do it ?
4848

4949
See also array_iterator.sql for an example on how to use this module.

contrib/array/array_iterator.c

Lines changed: 54 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@
2727
#include "miscadmin.h"
2828
#include "utils/array.h"
2929
#include "utils/builtins.h"
30+
#include "utils/fmgroids.h"
3031
#include "utils/memutils.h"
3132
#include "utils/lsyscache.h"
3233

3334
#include "array_iterator.h"
3435

3536

3637
static int32
37-
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
38+
array_iterator(Oid proc, int and, ArrayType *array, Datum value)
3839
{
40+
Oid elemtype;
3941
int16 typlen;
4042
bool typbyval;
43+
char typalign;
4144
int nitems,
4245
i;
4346
Datum result;
@@ -63,7 +66,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
6366
return (0);
6467

6568
/* Lookup element type information */
66-
get_typlenbyval(elemtype, &typlen, &typbyval);
69+
elemtype = ARR_ELEMTYPE(array);
70+
get_typlenbyvalalign(elemtype, &typlen, &typbyval, &typalign);
6771

6872
/* Lookup the function entry point */
6973
fmgr_info(proc, &finfo);
@@ -82,10 +86,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
8286

8387
itemvalue = fetch_att(p, typbyval, typlen);
8488

85-
if (typlen > 0)
86-
p += typlen;
87-
else
88-
p += INTALIGN(*(int32 *) p);
89+
p = att_addlength(p, typlen, PointerGetDatum(p));
90+
p = (char *) att_align(p, typalign);
8991

9092
result = FunctionCall2(&finfo, itemvalue, value);
9193

@@ -112,37 +114,33 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
112114
*/
113115

114116
int32
115-
array_texteq(ArrayType *array, char *value)
117+
array_texteq(ArrayType *array, void *value)
116118
{
117-
return array_iterator((Oid) 25, /* text */
118-
(Oid) 67, /* texteq */
119+
return array_iterator(F_TEXTEQ,
119120
0, /* logical or */
120121
array, (Datum) value);
121122
}
122123

123124
int32
124-
array_all_texteq(ArrayType *array, char *value)
125+
array_all_texteq(ArrayType *array, void *value)
125126
{
126-
return array_iterator((Oid) 25, /* text */
127-
(Oid) 67, /* texteq */
127+
return array_iterator(F_TEXTEQ,
128128
1, /* logical and */
129129
array, (Datum) value);
130130
}
131131

132132
int32
133-
array_textregexeq(ArrayType *array, char *value)
133+
array_textregexeq(ArrayType *array, void *value)
134134
{
135-
return array_iterator((Oid) 25, /* text */
136-
(Oid) 1254, /* textregexeq */
135+
return array_iterator(F_TEXTREGEXEQ,
137136
0, /* logical or */
138137
array, (Datum) value);
139138
}
140139

141140
int32
142-
array_all_textregexeq(ArrayType *array, char *value)
141+
array_all_textregexeq(ArrayType *array, void *value)
143142
{
144-
return array_iterator((Oid) 25, /* text */
145-
(Oid) 1254, /* textregexeq */
143+
return array_iterator(F_TEXTREGEXEQ,
146144
1, /* logical and */
147145
array, (Datum) value);
148146
}
@@ -153,37 +151,33 @@ array_all_textregexeq(ArrayType *array, char *value)
153151
*/
154152

155153
int32
156-
array_varchareq(ArrayType *array, char *value)
154+
array_varchareq(ArrayType *array, void *value)
157155
{
158-
return array_iterator((Oid) 1043, /* varchar */
159-
(Oid) 1070, /* varchareq */
156+
return array_iterator(F_VARCHAREQ,
160157
0, /* logical or */
161158
array, (Datum) value);
162159
}
163160

164161
int32
165-
array_all_varchareq(ArrayType *array, char *value)
162+
array_all_varchareq(ArrayType *array, void *value)
166163
{
167-
return array_iterator((Oid) 1043, /* varchar */
168-
(Oid) 1070, /* varchareq */
164+
return array_iterator(F_VARCHAREQ,
169165
1, /* logical and */
170166
array, (Datum) value);
171167
}
172168

173169
int32
174-
array_varcharregexeq(ArrayType *array, char *value)
170+
array_varcharregexeq(ArrayType *array, void *value)
175171
{
176-
return array_iterator((Oid) 1043, /* varchar */
177-
(Oid) 1254, /* textregexeq */
172+
return array_iterator(F_TEXTREGEXEQ,
178173
0, /* logical or */
179174
array, (Datum) value);
180175
}
181176

182177
int32
183-
array_all_varcharregexeq(ArrayType *array, char *value)
178+
array_all_varcharregexeq(ArrayType *array, void *value)
184179
{
185-
return array_iterator((Oid) 1043, /* varchar */
186-
(Oid) 1254, /* textregexeq */
180+
return array_iterator(F_TEXTREGEXEQ,
187181
1, /* logical and */
188182
array, (Datum) value);
189183
}
@@ -194,37 +188,33 @@ array_all_varcharregexeq(ArrayType *array, char *value)
194188
*/
195189

196190
int32
197-
array_bpchareq(ArrayType *array, char *value)
191+
array_bpchareq(ArrayType *array, void *value)
198192
{
199-
return array_iterator((Oid) 1042, /* bpchar */
200-
(Oid) 1048, /* bpchareq */
193+
return array_iterator(F_BPCHAREQ,
201194
0, /* logical or */
202195
array, (Datum) value);
203196
}
204197

205198
int32
206-
array_all_bpchareq(ArrayType *array, char *value)
199+
array_all_bpchareq(ArrayType *array, void *value)
207200
{
208-
return array_iterator((Oid) 1042, /* bpchar */
209-
(Oid) 1048, /* bpchareq */
201+
return array_iterator(F_BPCHAREQ,
210202
1, /* logical and */
211203
array, (Datum) value);
212204
}
213205

214206
int32
215-
array_bpcharregexeq(ArrayType *array, char *value)
207+
array_bpcharregexeq(ArrayType *array, void *value)
216208
{
217-
return array_iterator((Oid) 1042, /* bpchar */
218-
(Oid) 1254, /* textregexeq */
209+
return array_iterator(F_TEXTREGEXEQ,
219210
0, /* logical or */
220211
array, (Datum) value);
221212
}
222213

223214
int32
224-
array_all_bpcharregexeq(ArrayType *array, char *value)
215+
array_all_bpcharregexeq(ArrayType *array, void *value)
225216
{
226-
return array_iterator((Oid) 1042, /* bpchar */
227-
(Oid) 1254, /* textregexeq */
217+
return array_iterator(F_TEXTREGEXEQ,
228218
1, /* logical and */
229219
array, (Datum) value);
230220
}
@@ -236,107 +226,95 @@ array_all_bpcharregexeq(ArrayType *array, char *value)
236226
int32
237227
array_int4eq(ArrayType *array, int4 value)
238228
{
239-
return array_iterator((Oid) 23, /* int4 */
240-
(Oid) 65, /* int4eq */
229+
return array_iterator(F_INT4EQ,
241230
0, /* logical or */
242231
array, (Datum) value);
243232
}
244233

245234
int32
246235
array_all_int4eq(ArrayType *array, int4 value)
247236
{
248-
return array_iterator((Oid) 23, /* int4 */
249-
(Oid) 65, /* int4eq */
237+
return array_iterator(F_INT4EQ,
250238
1, /* logical and */
251239
array, (Datum) value);
252240
}
253241

254242
int32
255243
array_int4ne(ArrayType *array, int4 value)
256244
{
257-
return array_iterator((Oid) 23, /* int4 */
258-
(Oid) 144, /* int4ne */
245+
return array_iterator(F_INT4NE,
259246
0, /* logical or */
260247
array, (Datum) value);
261248
}
262249

263250
int32
264251
array_all_int4ne(ArrayType *array, int4 value)
265252
{
266-
return array_iterator((Oid) 23, /* int4 */
267-
(Oid) 144, /* int4ne */
253+
return array_iterator(F_INT4NE,
268254
1, /* logical and */
269255
array, (Datum) value);
270256
}
271257

272258
int32
273259
array_int4gt(ArrayType *array, int4 value)
274260
{
275-
return array_iterator((Oid) 23, /* int4 */
276-
(Oid) 147, /* int4gt */
261+
return array_iterator(F_INT4GT,
277262
0, /* logical or */
278263
array, (Datum) value);
279264
}
280265

281266
int32
282267
array_all_int4gt(ArrayType *array, int4 value)
283268
{
284-
return array_iterator((Oid) 23, /* int4 */
285-
(Oid) 147, /* int4gt */
269+
return array_iterator(F_INT4GT,
286270
1, /* logical and */
287271
array, (Datum) value);
288272
}
289273

290274
int32
291275
array_int4ge(ArrayType *array, int4 value)
292276
{
293-
return array_iterator((Oid) 23, /* int4 */
294-
(Oid) 150, /* int4ge */
277+
return array_iterator(F_INT4GE,
295278
0, /* logical or */
296279
array, (Datum) value);
297280
}
298281

299282
int32
300283
array_all_int4ge(ArrayType *array, int4 value)
301284
{
302-
return array_iterator((Oid) 23, /* int4 */
303-
(Oid) 150, /* int4ge */
285+
return array_iterator(F_INT4GE,
304286
1, /* logical and */
305287
array, (Datum) value);
306288
}
307289

308290
int32
309291
array_int4lt(ArrayType *array, int4 value)
310292
{
311-
return array_iterator((Oid) 23, /* int4 */
312-
(Oid) 66, /* int4lt */
293+
return array_iterator(F_INT4LT,
313294
0, /* logical or */
314295
array, (Datum) value);
315296
}
316297

317298
int32
318299
array_all_int4lt(ArrayType *array, int4 value)
319300
{
320-
return array_iterator((Oid) 23, /* int4 */
321-
(Oid) 66, /* int4lt */
301+
return array_iterator(F_INT4LT,
322302
1, /* logical and */
323303
array, (Datum) value);
324304
}
325305

326306
int32
327307
array_int4le(ArrayType *array, int4 value)
328308
{
329-
return array_iterator((Oid) 23, /* int4 */
330-
(Oid) 149, /* int4le */
309+
return array_iterator(F_INT4LE,
331310
0, /* logical or */
332311
array, (Datum) value);
333312
}
334313

335314
int32
336315
array_all_int4le(ArrayType *array, int4 value)
337316
{
338-
return array_iterator((Oid) 23, /* int4 */
339-
(Oid) 149, /* int4le */
317+
return array_iterator(F_INT4LE,
340318
1, /* logical and */
341319
array, (Datum) value);
342320
}
@@ -346,61 +324,47 @@ array_all_int4le(ArrayType *array, int4 value)
346324
int32
347325
array_oideq(ArrayType *array, Oid value)
348326
{
349-
return array_iterator((Oid) 26, /* oid */
350-
(Oid) 184, /* oideq */
327+
return array_iterator(F_OIDEQ,
351328
0, /* logical or */
352329
array, (Datum) value);
353330
}
354331

355332
int32
356333
array_all_oidne(ArrayType *array, Oid value)
357334
{
358-
return array_iterator((Oid) 26, /* int4 */
359-
(Oid) 185, /* oidne */
335+
return array_iterator(F_OIDNE,
360336
1, /* logical and */
361337
array, (Datum) value);
362338
}
363339

364340
int32
365-
array_ineteq(ArrayType *array, Oid value)
341+
array_ineteq(ArrayType *array, void *value)
366342
{
367-
return array_iterator((Oid) 869, /* inet */
368-
(Oid) 920, /* network_eq */
343+
return array_iterator(F_NETWORK_EQ,
369344
0, /* logical or */
370345
array, (Datum) value);
371346
}
372347

373348
int32
374-
array_all_ineteq(ArrayType *array, Oid value)
349+
array_all_ineteq(ArrayType *array, void *value)
375350
{
376-
return array_iterator((Oid) 869, /* inet */
377-
(Oid) 920, /* network_eq */
351+
return array_iterator(F_NETWORK_EQ,
378352
1, /* logical and */
379353
array, (Datum) value);
380354
}
381355

382356
int32
383-
array_inetne(ArrayType *array, Oid value)
357+
array_inetne(ArrayType *array, void *value)
384358
{
385-
return array_iterator((Oid) 869, /* inet */
386-
(Oid) 925, /* network_ne */
359+
return array_iterator(F_NETWORK_NE,
387360
0, /* logical and */
388361
array, (Datum) value);
389362
}
390363

391364
int32
392-
array_all_inetne(ArrayType *array, Oid value)
365+
array_all_inetne(ArrayType *array, void *value)
393366
{
394-
return array_iterator((Oid) 869, /* inet */
395-
(Oid) 925, /* network_ne */
367+
return array_iterator(F_NETWORK_NE,
396368
1, /* logical and */
397369
array, (Datum) value);
398370
}
399-
400-
/*
401-
* Local Variables:
402-
* tab-width: 4
403-
* c-indent-level: 4
404-
* c-basic-offset: 4
405-
* End:
406-
*/

0 commit comments

Comments
 (0)