postgresql/contrib/array/array_iterator.c

405 lines
8.5 KiB
C
Raw Normal View History

1996-08-19 00:14:33 +02:00
/*
* array_iterator.c --
*
1997-11-05 22:38:25 +01:00
* This file defines a new class of operators which take an
1996-08-19 00:14:33 +02:00
* array and a scalar value, iterate a scalar operator over the
* elements of the array and the value and compute a result as
1997-11-05 22:38:25 +01:00
* the logical OR or AND of the iteration results.
1996-08-19 00:14:33 +02:00
*
1999-09-27 22:04:14 +02:00
* Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
* ported to postgreSQL 6.3.2,added oid_functions, 18.1.1999,
* Tobias Gabele <gabele@wiz.uni-kassel.de>
1999-09-27 22:04:14 +02:00
*
* This software is distributed under the GNU General Public License
* either version 2, or (at your option) any later version.
1996-08-19 00:14:33 +02:00
*/
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "postgres.h"
#include "miscadmin.h"
#include "access/xact.h"
#include "fmgr.h"
1997-11-05 22:38:25 +01:00
#include "catalog/pg_type.h"
#include "utils/array.h"
1996-08-19 00:14:33 +02:00
#include "utils/builtins.h"
1997-11-05 22:38:25 +01:00
#include "utils/memutils.h"
#include "utils/syscache.h"
#include "array_iterator.h"
1996-08-19 00:14:33 +02:00
static int32
1997-09-08 22:59:27 +02:00
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
1996-08-19 00:14:33 +02:00
{
HeapTuple typ_tuple;
Form_pg_type typ_struct;
bool typbyval;
int typlen;
int nitems,
i;
Datum result;
int ndim,
*dim;
char *p;
FmgrInfo finfo;
/* Sanity checks */
if (array == (ArrayType *) NULL)
{
/* elog(NOTICE, "array_iterator: array is null"); */
return (0);
}
/* detoast input if necessary */
array = DatumGetArrayTypeP(PointerGetDatum(array));
ndim = ARR_NDIM(array);
dim = ARR_DIMS(array);
nitems = ArrayGetNItems(ndim, dim);
if (nitems == 0)
{
/* elog(NOTICE, "array_iterator: nitems = 0"); */
return (0);
}
/* Lookup element type information */
typ_tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(elemtype),
0, 0, 0);
if (!HeapTupleIsValid(typ_tuple))
{
2000-04-16 06:14:49 +02:00
elog(ERROR, "array_iterator: cache lookup failed for type %u", elemtype);
return 0;
}
typ_struct = (Form_pg_type) GETSTRUCT(typ_tuple);
typlen = typ_struct->typlen;
typbyval = typ_struct->typbyval;
/* Lookup the function entry point */
fmgr_info(proc, &finfo);
if (finfo.fn_nargs != 2)
{
elog(ERROR, "array_iterator: proc %u does not take 2 args", proc);
return (0);
}
1997-11-05 22:38:25 +01:00
/* Scan the array and apply the operator to each element */
result = BoolGetDatum(false);
p = ARR_DATA_PTR(array);
for (i = 0; i < nitems; i++)
{
if (typbyval)
{
switch (typlen)
{
case 1:
result = FunctionCall2(&finfo,
CharGetDatum(*p),
value);
break;
case 2:
result = FunctionCall2(&finfo,
Int16GetDatum(*(int16 *) p),
value);
break;
case 3:
case 4:
result = FunctionCall2(&finfo,
Int32GetDatum(*(int32 *) p),
value);
break;
}
p += typlen;
}
else
{
result = FunctionCall2(&finfo, PointerGetDatum(p), value);
if (typlen > 0)
p += typlen;
else
p += INTALIGN(*(int32 *) p);
}
if (DatumGetBool(result))
{
if (!and)
return (1);
}
else
{
if (and)
return (0);
}
}
if (and && DatumGetBool(result))
return (1);
else
return (0);
1996-08-19 00:14:33 +02:00
}
/*
1997-11-05 22:38:25 +01:00
* Iterator functions for type _text
1996-08-19 00:14:33 +02:00
*/
int32
array_texteq(ArrayType *array, char *value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
0, /* logical or */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
array_all_texteq(ArrayType *array, char *value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
1, /* logical and */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
array_textregexeq(ArrayType *array, char *value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
array_all_textregexeq(ArrayType *array, char *value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
/*
* Iterator functions for type _varchar. Note that the regexp
* operators take the second argument of type text.
*/
int32
array_varchareq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varchareq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
1, /* logical and */
array, (Datum) value);
}
int32
array_varcharregexeq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varcharregexeq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
}
/*
* Iterator functions for type _bpchar. Note that the regexp
* operators take the second argument of type text.
*/
int32
array_bpchareq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpchareq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
1, /* logical and */
array, (Datum) value);
}
int32
array_bpcharregexeq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpcharregexeq(ArrayType *array, char *value)
{
contrib-array.patch this is an old patch which I have already submitted and never seen in the sources. It corrects the datatype oids used in some iterator functions. This bug has been reported to me by many other people. contrib-datetime.patch some code contributed by Reiner Dassing <dassing@wettzell.ifag.de> contrib-makefiles.patch fixes all my contrib makefiles which don't work with some compilers, as reported to me by another user. contrib-miscutil.patch an old patch for one of my old contribs. contrib-string.patch a small change to the c-like text output functions. Now the '{' is escaped only at the beginning of the string to distinguish it from arrays, and the '}' is no more escaped. elog-lineno.patch adds the current lineno of CopyFrom to elog messages. This is very useful when you load a 1 million tuples table from an external file and there is a bad value somehere. Currently you get an error message but you can't know where is the bad data. The patch uses a variable which was declared static in copy.c. The variable is now exported and initialized to 0. It is always cleared at the end of the copy or at the first elog message or when the copy is canceled. I know this is very ugly but I can't find any better way of knowing where the copy fails and I have this problem quite often. plperl-makefile.patch fixes a typo in a makefile, but the error must be elsewhere because it is a file generated automatically. Please have a look. tprintf-timestamp.patch restores the original 2-digit year format, assuming that the two century digits don't carry much information and that '000202' is easier to read than 20000202. Being only a log file it shouldn't break anything. Please apply the patches before the next scheduled code freeze. I also noticed that some of the contribs don't compile correcly. Should we ask people to fix their code or rename their makefiles so that they are ignored by the top makefile? -- Massimo Dal Zotto
2000-02-13 19:59:53 +01:00
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
}
1996-08-19 00:14:33 +02:00
/*
1997-11-05 22:38:25 +01:00
* Iterator functions for type _int4
1996-08-19 00:14:33 +02:00
*/
int32
1997-09-08 22:59:27 +02:00
array_int4eq(ArrayType *array, int4 value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
0, /* logical or */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
1997-09-08 22:59:27 +02:00
array_all_int4eq(ArrayType *array, int4 value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
1, /* logical and */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
0, /* logical or */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_all_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
1, /* logical and */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
1997-09-08 22:59:27 +02:00
array_int4gt(ArrayType *array, int4 value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
0, /* logical or */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
int32
1997-09-08 22:59:27 +02:00
array_all_int4gt(ArrayType *array, int4 value)
1996-08-19 00:14:33 +02:00
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
1, /* logical and */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
0, /* logical or */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_all_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
1, /* logical and */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
0, /* logical or */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_all_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
1, /* logical and */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
0, /* logical or */
array, (Datum) value);
1997-11-05 22:38:25 +01:00
}
int32
array_all_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
1, /* logical and */
array, (Datum) value);
1996-08-19 00:14:33 +02:00
}
1997-11-05 22:38:25 +01:00
/* new tobias gabele 1999 */
int32
array_oideq(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* oid */
1999-05-25 18:15:34 +02:00
(Oid) 184, /* oideq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_oidne(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* int4 */
(Oid) 185, /* oidne */
1, /* logical and */
array, (Datum) value);
}
/* end of file */
/*
* Local Variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/