mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-29 04:17:20 +02:00
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
401 lines
8.5 KiB
C
401 lines
8.5 KiB
C
/*
|
|
* array_iterator.c --
|
|
*
|
|
* This file defines a new class of operators which take an
|
|
* array and a scalar value, iterate a scalar operator over the
|
|
* elements of the array and the value and compute a result as
|
|
* the logical OR or AND of the iteration results.
|
|
*
|
|
* 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>
|
|
*
|
|
* This software is distributed under the GNU General Public License
|
|
* either version 2, or (at your option) any later version.
|
|
*/
|
|
|
|
#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"
|
|
#include "catalog/pg_type.h"
|
|
#include "utils/array.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/memutils.h"
|
|
#include "utils/syscache.h"
|
|
|
|
#include "array_iterator.h"
|
|
|
|
static int32
|
|
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
|
|
{
|
|
HeapTuple typ_tuple;
|
|
Form_pg_type typ_struct;
|
|
bool typbyval;
|
|
int typlen;
|
|
func_ptr proc_fn;
|
|
int pronargs;
|
|
int nitems,
|
|
i,
|
|
result;
|
|
int ndim,
|
|
*dim;
|
|
char *p;
|
|
FmgrInfo finf; /* Tobias Gabele Jan 18 1999 */
|
|
|
|
|
|
/* Sanity checks */
|
|
if ((array == (ArrayType *) NULL)
|
|
|| (ARR_IS_LO(array) == true))
|
|
{
|
|
/* elog(NOTICE, "array_iterator: array is null"); */
|
|
return (0);
|
|
}
|
|
ndim = ARR_NDIM(array);
|
|
dim = ARR_DIMS(array);
|
|
nitems = getNitems(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))
|
|
{
|
|
elog(ERROR, "array_iterator: cache lookup failed for type %d", elemtype);
|
|
return 0;
|
|
}
|
|
typ_struct = (Form_pg_type) GETSTRUCT(typ_tuple);
|
|
typlen = typ_struct->typlen;
|
|
typbyval = typ_struct->typbyval;
|
|
|
|
/* Lookup the function entry point */
|
|
proc_fn = (func_ptr) NULL;
|
|
fmgr_info(proc, &finf); /* Tobias Gabele Jan 18 1999 */
|
|
proc_fn = finf.fn_addr; /* Tobias Gabele Jan 18 1999 */
|
|
pronargs = finf.fn_nargs; /* Tobias Gabele Jan 18 1999 */
|
|
if ((proc_fn == NULL) || (pronargs != 2))
|
|
{
|
|
elog(ERROR, "array_iterator: fmgr_info lookup failed for oid %d", proc);
|
|
return (0);
|
|
}
|
|
|
|
/* Scan the array and apply the operator to each element */
|
|
result = 0;
|
|
p = ARR_DATA_PTR(array);
|
|
for (i = 0; i < nitems; i++)
|
|
{
|
|
if (typbyval)
|
|
{
|
|
switch (typlen)
|
|
{
|
|
case 1:
|
|
result = (int) (*proc_fn) (*p, value);
|
|
break;
|
|
case 2:
|
|
result = (int) (*proc_fn) (*(int16 *) p, value);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
result = (int) (*proc_fn) (*(int32 *) p, value);
|
|
break;
|
|
}
|
|
p += typlen;
|
|
}
|
|
else
|
|
{
|
|
result = (int) (*proc_fn) (p, value);
|
|
if (typlen > 0)
|
|
p += typlen;
|
|
else
|
|
p += INTALIGN(*(int32 *) p);
|
|
}
|
|
if (result)
|
|
{
|
|
if (!and)
|
|
return (1);
|
|
}
|
|
else
|
|
{
|
|
if (and)
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
if (and && result)
|
|
return (1);
|
|
else
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Iterator functions for type _text
|
|
*/
|
|
|
|
int32
|
|
array_texteq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 25, /* text */
|
|
(Oid) 67, /* texteq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_texteq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 25, /* text */
|
|
(Oid) 67, /* texteq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_textregexeq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 25, /* text */
|
|
(Oid) 1254, /* textregexeq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_textregexeq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 25, /* text */
|
|
(Oid) 1254, /* textregexeq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
/*
|
|
* Iterator functions for type _varchar. Note that the regexp
|
|
* operators take the second argument of type text.
|
|
*/
|
|
|
|
int32
|
|
array_varchareq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1043, /* varchar */
|
|
(Oid) 1070, /* varchareq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_varchareq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1043, /* varchar */
|
|
(Oid) 1070, /* varchareq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_varcharregexeq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1043, /* varchar */
|
|
(Oid) 1254, /* textregexeq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_varcharregexeq(ArrayType *array, char *value)
|
|
{
|
|
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)
|
|
{
|
|
return array_iterator((Oid) 1042, /* bpchar */
|
|
(Oid) 1048, /* bpchareq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_bpchareq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1042, /* bpchar */
|
|
(Oid) 1048, /* bpchareq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_bpcharregexeq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1042, /* bpchar */
|
|
(Oid) 1254, /* textregexeq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_bpcharregexeq(ArrayType *array, char *value)
|
|
{
|
|
return array_iterator((Oid) 1042, /* bpchar */
|
|
(Oid) 1254, /* textregexeq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
/*
|
|
* Iterator functions for type _int4
|
|
*/
|
|
|
|
int32
|
|
array_int4eq(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 65, /* int4eq */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4eq(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 65, /* int4eq */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_int4ne(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 144, /* int4ne */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4ne(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 144, /* int4ne */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_int4gt(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 147, /* int4gt */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4gt(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 147, /* int4gt */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_int4ge(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 150, /* int4ge */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4ge(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 150, /* int4ge */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_int4lt(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 66, /* int4lt */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4lt(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 66, /* int4lt */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_int4le(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 149, /* int4le */
|
|
0, /* logical or */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
int32
|
|
array_all_int4le(ArrayType *array, int4 value)
|
|
{
|
|
return array_iterator((Oid) 23, /* int4 */
|
|
(Oid) 149, /* int4le */
|
|
1, /* logical and */
|
|
array, (Datum) value);
|
|
}
|
|
|
|
/* new tobias gabele 1999 */
|
|
|
|
int32
|
|
array_oideq(ArrayType *array, Oid value)
|
|
{
|
|
return array_iterator((Oid) 26, /* oid */
|
|
(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:
|
|
*/
|