Here is a patch that removes contrib/array, leaving only the README with

some examples of the new syntax and a reference to the documentation.

Joe Conway.
This commit is contained in:
Bruce Momjian 2003-09-11 17:15:27 +00:00
parent d768cb267b
commit 92e100dd33
6 changed files with 22 additions and 750 deletions

View File

@ -1,11 +1,10 @@
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.45 2003/07/24 16:54:58 tgl Exp $
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.46 2003/09/11 17:15:27 momjian Exp $
subdir = contrib
top_builddir = ..
include $(top_builddir)/src/Makefile.global
WANTED_DIRS = \
array \
btree_gist \
chkpass \
cube \
@ -44,6 +43,7 @@ WANTED_DIRS = \
vacuumlo
# Missing:
# array \ (removed all but the README)
# adddepend \ (does not have a makefile)
# ipc_check \ (does not have a makefile)
# mSQL-interface \ (requires msql installed)

View File

@ -1,11 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/array/Attic/Makefile,v 1.16 2001/09/06 10:49:29 petere Exp $
subdir = contrib/array
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = array_iterator
DATA_built = array_iterator.sql
DOCS = README.array_iterator
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,49 +1,32 @@
Array iterator functions, by Massimo Dal Zotto <dz@cs.unitn.it>
Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
Array iterator functions have been removed as of PostgreSQL 7.4, because
equivalent functionality is now available built in to the backend.
This software is distributed under the GNU General Public License
either version 2, or (at your option) any later version.
For example, previously, using contrib/array, you might have used the
following construct:
create table t(id int4[], txt text[]);
This loadable module defines a new class of functions 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.
For example array_int4eq returns true if some of the elements
of an array of int4 is equal to the given value:
-- select tuples with some id element equal to 123
select * from t where t.id *= 123;
array_int4eq({1,2,3}, 1) --> true
array_int4eq({1,2,3}, 4) --> false
Now you would do this instead:
If we have defined T array types and O scalar operators we can
define T x O x 2 array functions, each of them has a name like
"array_[all_]<basetype><operation>" and takes an array of type T
iterating the operator O over all the elements. Note however
that some of the possible combination are invalid, for example
the array_int4_like because there is no like operator for int4.
-- select tuples with some id element equal to 123
select * from t where 123 = any (t.id);
We can then define new operators based on these functions and use
them to write queries with qualification clauses based on the
values of some of the elements of an array.
For example to select rows having some or all element of an array
attribute equal to a given value or matching a regular expression:
-- or you could also do this
select * from t where 123 = some (t.id);
create table t(id int4[], txt text[]);
Similarly, if using contrib/array, you did the following:
-- select tuples with some id element equal to 123
select * from t where t.id *= 123;
-- select tuples with all txt elements matching '^[A-Z]'
select * from t where t.txt[1:3] **~ '^[A-Z]';
-- select tuples with some txt element matching '[a-z]'
select * from t where t.txt *~ '[a-z]';
Now do this instead:
-- select tuples with all txt elements matching '^[A-Z]'
select * from t where t.txt[1:3] **~ '^[A-Z]';
-- select tuples with all txt elements matching '^[A-Z]'
select * from t where '^[A-Z]' ~ all (t.txt[1:3]);
The scheme is quite general, each operator which operates on a base type
can be iterated over the elements of an array. It seem to work well but
defining each new operator requires writing a different C function.
This is tedious, and error-prone since one must take care that the correct
datatypes are associated with the selected underlying function.
Can anyone suggest a better and more portable way to do it ?
See the related section in the online documentation for more detail:
Table of Contents => Functions and Operators => Row and Array Comparisons
See also array_iterator.sql for an example on how to use this module.

View File

@ -1,333 +0,0 @@
/*
* 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 "postgres.h"
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "access/tupmacs.h"
#include "access/xact.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/lsyscache.h"
#include "array_iterator.h"
static int32
array_iterator(Oid proc, int and, ArrayType *array, Datum value)
{
Oid elemtype;
int16 typlen;
bool typbyval;
char typalign;
int nitems,
i;
Datum result;
int ndim,
*dim;
char *p;
FmgrInfo finfo;
/* Sanity checks */
if (array == (ArrayType *) NULL)
{
/* elog(WARNING, "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)
return (0);
/* Lookup element type information */
elemtype = ARR_ELEMTYPE(array);
get_typlenbyvalalign(elemtype, &typlen, &typbyval, &typalign);
/* 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);
}
/* Scan the array and apply the operator to each element */
result = BoolGetDatum(false);
p = ARR_DATA_PTR(array);
for (i = 0; i < nitems; i++)
{
Datum itemvalue;
itemvalue = fetch_att(p, typbyval, typlen);
p = att_addlength(p, typlen, PointerGetDatum(p));
p = (char *) att_align(p, typalign);
result = FunctionCall2(&finfo, itemvalue, value);
if (DatumGetBool(result))
{
if (!and)
return (1);
}
else
{
if (and)
return (0);
}
}
if (and && DatumGetBool(result))
return (1);
else
return (0);
}
/*
* Iterator functions for type _text
*/
int32
array_texteq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_texteq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTEQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_textregexeq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_textregexeq(ArrayType *array, void *value)
{
return array_iterator(F_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, void *value)
{
return array_iterator(F_BPCHAREQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpchareq(ArrayType *array, void *value)
{
return array_iterator(F_BPCHAREQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_bpcharregexeq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpcharregexeq(ArrayType *array, void *value)
{
return array_iterator(F_TEXTREGEXEQ,
1, /* logical and */
array, (Datum) value);
}
/*
* Iterator functions for type _int4
*/
int32
array_int4eq(ArrayType *array, int4 value)
{
return array_iterator(F_INT4EQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4eq(ArrayType *array, int4 value)
{
return array_iterator(F_INT4EQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_int4ne(ArrayType *array, int4 value)
{
return array_iterator(F_INT4NE,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4ne(ArrayType *array, int4 value)
{
return array_iterator(F_INT4NE,
1, /* logical and */
array, (Datum) value);
}
int32
array_int4gt(ArrayType *array, int4 value)
{
return array_iterator(F_INT4GT,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4gt(ArrayType *array, int4 value)
{
return array_iterator(F_INT4GT,
1, /* logical and */
array, (Datum) value);
}
int32
array_int4ge(ArrayType *array, int4 value)
{
return array_iterator(F_INT4GE,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4ge(ArrayType *array, int4 value)
{
return array_iterator(F_INT4GE,
1, /* logical and */
array, (Datum) value);
}
int32
array_int4lt(ArrayType *array, int4 value)
{
return array_iterator(F_INT4LT,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4lt(ArrayType *array, int4 value)
{
return array_iterator(F_INT4LT,
1, /* logical and */
array, (Datum) value);
}
int32
array_int4le(ArrayType *array, int4 value)
{
return array_iterator(F_INT4LE,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4le(ArrayType *array, int4 value)
{
return array_iterator(F_INT4LE,
1, /* logical and */
array, (Datum) value);
}
/* new tobias gabele 1999 */
int32
array_oideq(ArrayType *array, Oid value)
{
return array_iterator(F_OIDEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_oidne(ArrayType *array, Oid value)
{
return array_iterator(F_OIDNE,
1, /* logical and */
array, (Datum) value);
}
int32
array_ineteq(ArrayType *array, void *value)
{
return array_iterator(F_NETWORK_EQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_ineteq(ArrayType *array, void *value)
{
return array_iterator(F_NETWORK_EQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_inetne(ArrayType *array, void *value)
{
return array_iterator(F_NETWORK_NE,
0, /* logical and */
array, (Datum) value);
}
int32
array_all_inetne(ArrayType *array, void *value)
{
return array_iterator(F_NETWORK_NE,
1, /* logical and */
array, (Datum) value);
}

View File

@ -1,38 +0,0 @@
#ifndef ARRAY_ITERATOR_H
#define ARRAY_ITERATOR_H
static int32 array_iterator(Oid proc, int and,
ArrayType *array, Datum value);
int32 array_texteq(ArrayType *array, void *value);
int32 array_all_texteq(ArrayType *array, void *value);
int32 array_textregexeq(ArrayType *array, void *value);
int32 array_all_textregexeq(ArrayType *array, void *value);
int32 array_bpchareq(ArrayType *array, void *value);
int32 array_all_bpchareq(ArrayType *array, void *value);
int32 array_bpcharregexeq(ArrayType *array, void *value);
int32 array_all_bpcharregexeq(ArrayType *array, void *value);
int32 array_int4eq(ArrayType *array, int4 value);
int32 array_all_int4eq(ArrayType *array, int4 value);
int32 array_int4ne(ArrayType *array, int4 value);
int32 array_all_int4ne(ArrayType *array, int4 value);
int32 array_int4gt(ArrayType *array, int4 value);
int32 array_all_int4gt(ArrayType *array, int4 value);
int32 array_int4ge(ArrayType *array, int4 value);
int32 array_all_int4ge(ArrayType *array, int4 value);
int32 array_int4lt(ArrayType *array, int4 value);
int32 array_all_int4lt(ArrayType *array, int4 value);
int32 array_int4le(ArrayType *array, int4 value);
int32 array_all_int4le(ArrayType *array, int4 value);
int32 array_oideq(ArrayType *array, Oid value);
int32 array_all_oidne(ArrayType *array, Oid value);
int32 array_ineteq(ArrayType *array, void *value);
int32 array_all_ineteq(ArrayType *array, void *value);
int32 array_inetne(ArrayType *array, void *value);
int32 array_all_inetne(ArrayType *array, void *value);
#endif

View File

@ -1,329 +0,0 @@
-- SQL code to define the new array iterator functions and operators
-- define the array operators *=, **=, *~ and **~ for type _text
--
-- Adjust this setting to control where the objects get created.
SET search_path = public;
CREATE OR REPLACE FUNCTION array_texteq(_text, text)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_texteq(_text, text)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_textregexeq(_text, text)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_textregexeq(_text, text)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_text,text);
CREATE OPERATOR *= (
LEFTARG=_text,
RIGHTARG=text,
PROCEDURE=array_texteq
);
DROP OPERATOR **=(_text,text);
CREATE OPERATOR **= (
LEFTARG=_text,
RIGHTARG=text,
PROCEDURE=array_all_texteq
);
DROP OPERATOR *~(_text,text);
CREATE OPERATOR *~ (
LEFTARG=_text,
RIGHTARG=text,
PROCEDURE=array_textregexeq
);
DROP OPERATOR **~(_text,text);
CREATE OPERATOR **~ (
LEFTARG=_text,
RIGHTARG=text,
PROCEDURE=array_all_textregexeq
);
-- define the array operators *=, **=, *~ and **~ for type _bpchar
--
CREATE OR REPLACE FUNCTION array_bpchareq(_bpchar, bpchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_bpchareq(_bpchar, bpchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_bpcharregexeq(_bpchar, bpchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_bpcharregexeq(_bpchar, bpchar)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_bpchar,bpchar);
CREATE OPERATOR *= (
LEFTARG=_bpchar,
RIGHTARG=bpchar,
PROCEDURE=array_bpchareq
);
DROP OPERATOR **=(_bpchar,bpchar);
CREATE OPERATOR **= (
LEFTARG=_bpchar,
RIGHTARG=bpchar,
PROCEDURE=array_all_bpchareq
);
DROP OPERATOR *~(_bpchar,bpchar);
CREATE OPERATOR *~ (
LEFTARG=_bpchar,
RIGHTARG=bpchar,
PROCEDURE=array_bpcharregexeq
);
DROP OPERATOR **~(_bpchar,bpchar);
CREATE OPERATOR **~ (
LEFTARG=_bpchar,
RIGHTARG=bpchar,
PROCEDURE=array_all_bpcharregexeq
);
-- define the array operators *=, **=, *> and **> for type _int4
--
CREATE OR REPLACE FUNCTION array_int4eq(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4eq(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_int4ne(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4ne(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_int4gt(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4gt(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_int4ge(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4ge(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_int4lt(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4lt(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_int4le(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_int4le(_int4, int4)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_int4,int4);
CREATE OPERATOR *= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4eq
);
DROP OPERATOR **=(_int4,int4);
CREATE OPERATOR **= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4eq
);
DROP OPERATOR *<>(_int4,int4);
CREATE OPERATOR *<> (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4ne
);
DROP OPERATOR **<>(_int4,int4);
CREATE OPERATOR **<> (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4ne
);
DROP OPERATOR *>(_int4,int4);
CREATE OPERATOR *> (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4gt
);
DROP OPERATOR **>(_int4,int4);
CREATE OPERATOR **> (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4gt
);
DROP OPERATOR *>=(_int4,int4);
CREATE OPERATOR *>= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4ge
);
DROP OPERATOR **>=(_int4,int4);
CREATE OPERATOR **>= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4ge
);
DROP OPERATOR *<(_int4,int4);
CREATE OPERATOR *< (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4lt
);
DROP OPERATOR **<(_int4,int4);
CREATE OPERATOR **< (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4lt
);
DROP OPERATOR *<=(_int4,int4);
CREATE OPERATOR *<= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_int4le
);
DROP OPERATOR **<=(_int4,int4);
CREATE OPERATOR **<= (
LEFTARG=_int4,
RIGHTARG=int4,
PROCEDURE=array_all_int4le
);
-- define the array operators *=, **<> for type _oid (added tobias 1. 1999)
--
CREATE OR REPLACE FUNCTION array_oideq(_oid, oid)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_oidne(_oid, oid)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_oid,oid);
CREATE OPERATOR *= (
LEFTARG=_oid,
RIGHTARG=oid,
PROCEDURE=array_oideq
);
DROP OPERATOR **<>(_oid,oid);
CREATE OPERATOR **<> (
LEFTARG=_oid,
RIGHTARG=oid,
PROCEDURE=array_all_oidne
);
-- define the array operators *=, **=, *<>, **<> for type _inet
CREATE OR REPLACE FUNCTION array_ineteq(_inet, inet)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_ineteq(_inet, inet)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_inetne(_inet, inet)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION array_all_inetne(_inet, inet)
RETURNS bool
AS 'MODULE_PATHNAME'
LANGUAGE 'C' IMMUTABLE STRICT;
DROP OPERATOR *=(_inet,inet);
CREATE OPERATOR *= (
LEFTARG=_inet,
RIGHTARG=inet,
PROCEDURE=array_ineteq
);
DROP OPERATOR **=(_inet,inet);
CREATE OPERATOR **= (
LEFTARG=_inet,
RIGHTARG=inet,
PROCEDURE=array_all_ineteq
);
DROP OPERATOR *<>(_inet,inet);
CREATE OPERATOR *<> (
LEFTARG=_inet,
RIGHTARG=inet,
PROCEDURE=array_inetne
);
DROP OPERATOR **<>(_inet,inet);
CREATE OPERATOR **<> (
LEFTARG=_inet,
RIGHTARG=inet,
PROCEDURE=array_all_inetne
);