提交 5cabcfcc 编写于 作者: T Tom Lane

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.
上级 8009c275
......@@ -41,9 +41,9 @@ attribute equal to a given value or matching a regular expression:
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 operators requires writing a different C function.
Furthermore in each function there are two hardcoded OIDs which reference
a base type and a procedure. Not very portable. Can anyone suggest a
better and more portable way to do it ?
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 also array_iterator.sql for an example on how to use this module.
......@@ -27,6 +27,7 @@
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/lsyscache.h"
......@@ -34,10 +35,12 @@
static int32
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
array_iterator(Oid proc, int and, ArrayType *array, Datum value)
{
Oid elemtype;
int16 typlen;
bool typbyval;
char typalign;
int nitems,
i;
Datum result;
......@@ -63,7 +66,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
return (0);
/* Lookup element type information */
get_typlenbyval(elemtype, &typlen, &typbyval);
elemtype = ARR_ELEMTYPE(array);
get_typlenbyvalalign(elemtype, &typlen, &typbyval, &typalign);
/* Lookup the function entry point */
fmgr_info(proc, &finfo);
......@@ -82,10 +86,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
itemvalue = fetch_att(p, typbyval, typlen);
if (typlen > 0)
p += typlen;
else
p += INTALIGN(*(int32 *) p);
p = att_addlength(p, typlen, PointerGetDatum(p));
p = (char *) att_align(p, typalign);
result = FunctionCall2(&finfo, itemvalue, value);
......@@ -112,37 +114,33 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
*/
int32
array_texteq(ArrayType *array, char *value)
array_texteq(ArrayType *array, void *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
return array_iterator(F_TEXTEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_texteq(ArrayType *array, char *value)
array_all_texteq(ArrayType *array, void *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
return array_iterator(F_TEXTEQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_textregexeq(ArrayType *array, char *value)
array_textregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_textregexeq(ArrayType *array, char *value)
array_all_textregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
1, /* logical and */
array, (Datum) value);
}
......@@ -153,37 +151,33 @@ array_all_textregexeq(ArrayType *array, char *value)
*/
int32
array_varchareq(ArrayType *array, char *value)
array_varchareq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
return array_iterator(F_VARCHAREQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varchareq(ArrayType *array, char *value)
array_all_varchareq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
return array_iterator(F_VARCHAREQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_varcharregexeq(ArrayType *array, char *value)
array_varcharregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varcharregexeq(ArrayType *array, char *value)
array_all_varcharregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
1, /* logical and */
array, (Datum) value);
}
......@@ -194,37 +188,33 @@ array_all_varcharregexeq(ArrayType *array, char *value)
*/
int32
array_bpchareq(ArrayType *array, char *value)
array_bpchareq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
return array_iterator(F_BPCHAREQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpchareq(ArrayType *array, char *value)
array_all_bpchareq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
return array_iterator(F_BPCHAREQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_bpcharregexeq(ArrayType *array, char *value)
array_bpcharregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpcharregexeq(ArrayType *array, char *value)
array_all_bpcharregexeq(ArrayType *array, void *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
return array_iterator(F_TEXTREGEXEQ,
1, /* logical and */
array, (Datum) value);
}
......@@ -236,8 +226,7 @@ array_all_bpcharregexeq(ArrayType *array, char *value)
int32
array_int4eq(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
return array_iterator(F_INT4EQ,
0, /* logical or */
array, (Datum) value);
}
......@@ -245,8 +234,7 @@ array_int4eq(ArrayType *array, int4 value)
int32
array_all_int4eq(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
return array_iterator(F_INT4EQ,
1, /* logical and */
array, (Datum) value);
}
......@@ -254,8 +242,7 @@ array_all_int4eq(ArrayType *array, int4 value)
int32
array_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
return array_iterator(F_INT4NE,
0, /* logical or */
array, (Datum) value);
}
......@@ -263,8 +250,7 @@ array_int4ne(ArrayType *array, int4 value)
int32
array_all_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
return array_iterator(F_INT4NE,
1, /* logical and */
array, (Datum) value);
}
......@@ -272,8 +258,7 @@ array_all_int4ne(ArrayType *array, int4 value)
int32
array_int4gt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
return array_iterator(F_INT4GT,
0, /* logical or */
array, (Datum) value);
}
......@@ -281,8 +266,7 @@ array_int4gt(ArrayType *array, int4 value)
int32
array_all_int4gt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
return array_iterator(F_INT4GT,
1, /* logical and */
array, (Datum) value);
}
......@@ -290,8 +274,7 @@ array_all_int4gt(ArrayType *array, int4 value)
int32
array_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
return array_iterator(F_INT4GE,
0, /* logical or */
array, (Datum) value);
}
......@@ -299,8 +282,7 @@ array_int4ge(ArrayType *array, int4 value)
int32
array_all_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
return array_iterator(F_INT4GE,
1, /* logical and */
array, (Datum) value);
}
......@@ -308,8 +290,7 @@ array_all_int4ge(ArrayType *array, int4 value)
int32
array_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
return array_iterator(F_INT4LT,
0, /* logical or */
array, (Datum) value);
}
......@@ -317,8 +298,7 @@ array_int4lt(ArrayType *array, int4 value)
int32
array_all_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
return array_iterator(F_INT4LT,
1, /* logical and */
array, (Datum) value);
}
......@@ -326,8 +306,7 @@ array_all_int4lt(ArrayType *array, int4 value)
int32
array_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
return array_iterator(F_INT4LE,
0, /* logical or */
array, (Datum) value);
}
......@@ -335,8 +314,7 @@ array_int4le(ArrayType *array, int4 value)
int32
array_all_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
return array_iterator(F_INT4LE,
1, /* logical and */
array, (Datum) value);
}
......@@ -346,8 +324,7 @@ array_all_int4le(ArrayType *array, int4 value)
int32
array_oideq(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* oid */
(Oid) 184, /* oideq */
return array_iterator(F_OIDEQ,
0, /* logical or */
array, (Datum) value);
}
......@@ -355,52 +332,39 @@ array_oideq(ArrayType *array, Oid value)
int32
array_all_oidne(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* int4 */
(Oid) 185, /* oidne */
return array_iterator(F_OIDNE,
1, /* logical and */
array, (Datum) value);
}
int32
array_ineteq(ArrayType *array, Oid value)
array_ineteq(ArrayType *array, void *value)
{
return array_iterator((Oid) 869, /* inet */
(Oid) 920, /* network_eq */
return array_iterator(F_NETWORK_EQ,
0, /* logical or */
array, (Datum) value);
}
int32
array_all_ineteq(ArrayType *array, Oid value)
array_all_ineteq(ArrayType *array, void *value)
{
return array_iterator((Oid) 869, /* inet */
(Oid) 920, /* network_eq */
return array_iterator(F_NETWORK_EQ,
1, /* logical and */
array, (Datum) value);
}
int32
array_inetne(ArrayType *array, Oid value)
array_inetne(ArrayType *array, void *value)
{
return array_iterator((Oid) 869, /* inet */
(Oid) 925, /* network_ne */
return array_iterator(F_NETWORK_NE,
0, /* logical and */
array, (Datum) value);
}
int32
array_all_inetne(ArrayType *array, Oid value)
array_all_inetne(ArrayType *array, void *value)
{
return array_iterator((Oid) 869, /* inet */
(Oid) 925, /* network_ne */
return array_iterator(F_NETWORK_NE,
1, /* logical and */
array, (Datum) value);
}
/*
* Local Variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/
#ifndef ARRAY_ITERATOR_H
#define ARRAY_ITERATOR_H
static int32 array_iterator(Oid elemtype, Oid proc, int and,
static int32 array_iterator(Oid proc, int and,
ArrayType *array, Datum value);
int32 array_texteq(ArrayType *array, char *value);
int32 array_all_texteq(ArrayType *array, char *value);
int32 array_textregexeq(ArrayType *array, char *value);
int32 array_all_textregexeq(ArrayType *array, char *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_varchareq(ArrayType *array, char *value);
int32 array_all_varchareq(ArrayType *array, char *value);
int32 array_varcharregexeq(ArrayType *array, char *value);
int32 array_all_varcharregexeq(ArrayType *array, char *value);
int32 array_varchareq(ArrayType *array, void *value);
int32 array_all_varchareq(ArrayType *array, void *value);
int32 array_varcharregexeq(ArrayType *array, void *value);
int32 array_all_varcharregexeq(ArrayType *array, void *value);
int32 array_bpchareq(ArrayType *array, char *value);
int32 array_all_bpchareq(ArrayType *array, char *value);
int32 array_bpcharregexeq(ArrayType *array, char *value);
int32 array_all_bpcharregexeq(ArrayType *array, char *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);
......@@ -35,16 +35,9 @@ 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, Oid value);
int32 array_all_ineteq(ArrayType *array, Oid value);
int32 array_inetne(ArrayType *array, Oid value);
int32 array_all_inetne(ArrayType *array, Oid value);
#endif
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);
/*
* Local Variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/
#endif
......@@ -4,19 +4,19 @@
--
create or replace function array_texteq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_texteq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_textregexeq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_textregexeq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_text,
......@@ -45,19 +45,19 @@ create operator **~ (
--
create or replace function array_varchareq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_varchareq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_varcharregexeq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_varcharregexeq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_varchar,
......@@ -84,19 +84,19 @@ create operator **~ (
--
create or replace function array_bpchareq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_bpchareq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_bpcharregexeq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_bpcharregexeq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_bpchar,
......@@ -123,51 +123,51 @@ create operator **~ (
--
create or replace function array_int4eq(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4eq(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_int4ne(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4ne(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_int4gt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4gt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_int4ge(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4ge(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_int4lt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4lt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_int4le(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_int4le(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_int4,
......@@ -233,11 +233,11 @@ create operator **<= (
--
create or replace function array_oideq(_oid, oid) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_oidne(_oid, oid) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_oid,
......@@ -253,19 +253,19 @@ create operator **<> (
create or replace function array_ineteq(_inet, inet) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_ineteq(_inet, inet) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_inetne(_inet, inet) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create or replace function array_all_inetne(_inet, inet) returns bool
as 'MODULE_PATHNAME'
language 'c';
language C with (isStrict);
create operator *= (
leftarg=_inet,
......
......@@ -502,6 +502,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
/*
* get array of pointers to c-strings from the input source array
*/
Assert(ARR_ELEMTYPE(src_pkattvals_arry) == TEXTOID);
src_pkattvals = (char **) palloc(src_nitems * sizeof(char *));
ptr = ARR_DATA_PTR(src_pkattvals_arry);
for (i = 0; i < src_nitems; i++)
......@@ -527,6 +528,7 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
/*
* get array of pointers to c-strings from the input target array
*/
Assert(ARR_ELEMTYPE(tgt_pkattvals_arry) == TEXTOID);
tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *));
ptr = ARR_DATA_PTR(tgt_pkattvals_arry);
for (i = 0; i < tgt_nitems; i++)
......@@ -621,6 +623,7 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
/*
* get array of pointers to c-strings from the input target array
*/
Assert(ARR_ELEMTYPE(tgt_pkattvals_arry) == TEXTOID);
tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *));
ptr = ARR_DATA_PTR(tgt_pkattvals_arry);
for (i = 0; i < tgt_nitems; i++)
......@@ -725,6 +728,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
/*
* get array of pointers to c-strings from the input source array
*/
Assert(ARR_ELEMTYPE(src_pkattvals_arry) == TEXTOID);
src_pkattvals = (char **) palloc(src_nitems * sizeof(char *));
ptr = ARR_DATA_PTR(src_pkattvals_arry);
for (i = 0; i < src_nitems; i++)
......@@ -750,6 +754,7 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
/*
* get array of pointers to c-strings from the input target array
*/
Assert(ARR_ELEMTYPE(tgt_pkattvals_arry) == TEXTOID);
tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *));
ptr = ARR_DATA_PTR(tgt_pkattvals_arry);
for (i = 0; i < tgt_nitems; i++)
......
......@@ -38,9 +38,9 @@
#include "utils/lsyscache.h"
/* This is actually a postgres version of a one dimentional array */
/* This is actually a postgres version of a one dimensional array */
typedef struct agg
typedef struct
{
ArrayType a;
int items;
......@@ -95,8 +95,9 @@ static PGARRAY * GetPGArray(int4 state, int fAdd)
}
p->a.size = cb;
p->a.ndim= 0;
p->a.ndim = 0;
p->a.flags = 0;
p->a.elmtype = INT4OID;
p->items = 0;
p->lower= START_NUM;
}
......@@ -149,6 +150,7 @@ static PGARRAY *ShrinkPGArray(PGARRAY *p)
pnew->a.size = cb;
pnew->a.ndim=1;
pnew->a.flags = 0;
pnew->a.elmtype = INT4OID;
pnew->lower = 0;
}
else
......
......@@ -59,7 +59,7 @@ _ltree_compress(PG_FUNCTION_ARGS) {
if ( entry->leafkey ) { /* ltree */
ltree_gist *key;
ArrayType *val = (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(entry->key));
ArrayType *val = DatumGetArrayTypeP(entry->key);
int4 len = LTG_HDRSIZE + ASIGLEN;
int num=ArrayGetNItems( ARR_NDIM(val), ARR_DIMS(val) );
ltree *item = (ltree*)ARR_DATA_PTR(val);
......
......@@ -61,7 +61,7 @@ array_iterator( ArrayType *la, PGCALL2 callback, void* param, ltree ** found) {
Datum
_ltree_isparent(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltree *query = PG_GETARG_LTREE(1);
bool res = array_iterator( la, ltree_isparent, (void*)query, NULL );
PG_FREE_IF_COPY(la,0);
......@@ -79,7 +79,7 @@ _ltree_r_isparent(PG_FUNCTION_ARGS) {
Datum
_ltree_risparent(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltree *query = PG_GETARG_LTREE(1);
bool res = array_iterator( la, ltree_risparent, (void*)query, NULL );
PG_FREE_IF_COPY(la,0);
......@@ -97,7 +97,7 @@ _ltree_r_risparent(PG_FUNCTION_ARGS) {
Datum
_ltq_regex(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
lquery *query = PG_GETARG_LQUERY(1);
bool res = array_iterator( la, ltq_regex, (void*)query, NULL );
PG_FREE_IF_COPY(la,0);
......@@ -115,7 +115,7 @@ _ltq_rregex(PG_FUNCTION_ARGS) {
Datum
_ltxtq_exec(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltxtquery *query = PG_GETARG_LTXTQUERY(1);
bool res = array_iterator( la, ltxtq_exec, (void*)query, NULL );
PG_FREE_IF_COPY(la,0);
......@@ -134,7 +134,7 @@ _ltxtq_rexec(PG_FUNCTION_ARGS) {
Datum
_ltree_extract_isparent(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltree *query = PG_GETARG_LTREE(1);
ltree *found,*item;
......@@ -154,7 +154,7 @@ _ltree_extract_isparent(PG_FUNCTION_ARGS) {
Datum
_ltree_extract_risparent(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltree *query = PG_GETARG_LTREE(1);
ltree *found,*item;
......@@ -174,7 +174,7 @@ _ltree_extract_risparent(PG_FUNCTION_ARGS) {
Datum
_ltq_extract_regex(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
lquery *query = PG_GETARG_LQUERY(1);
ltree *found,*item;
......@@ -194,7 +194,7 @@ _ltq_extract_regex(PG_FUNCTION_ARGS) {
Datum
_ltxtq_extract_exec(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
ltxtquery *query = PG_GETARG_LTXTQUERY(1);
ltree *found,*item;
......@@ -214,7 +214,7 @@ _ltxtq_extract_exec(PG_FUNCTION_ARGS) {
Datum
_lca(PG_FUNCTION_ARGS) {
ArrayType *la = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
ArrayType *la = PG_GETARG_ARRAYTYPE_P(0);
int num=ArrayGetNItems( ARR_NDIM(la), ARR_DIMS(la));
ltree *item = (ltree*)ARR_DATA_PTR(la);
ltree **a,*res;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.4 2002/08/05 03:29:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.5 2002/08/26 17:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -21,6 +21,7 @@
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
......@@ -83,7 +84,7 @@ CreateConstraintEntry(const char *constraintName,
for (i = 0; i < constraintNKeys; i++)
conkey[i] = Int16GetDatum(constraintKey[i]);
conkeyArray = construct_array(conkey, constraintNKeys,
true, 2, 's');
INT2OID, 2, true, 's');
}
else
conkeyArray = NULL;
......@@ -96,7 +97,7 @@ CreateConstraintEntry(const char *constraintName,
for (i = 0; i < foreignNKeys; i++)
confkey[i] = Int16GetDatum(foreignKey[i]);
confkeyArray = construct_array(confkey, foreignNKeys,
true, 2, 's');
INT2OID, 2, true, 's');
}
else
confkeyArray = NULL;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.43 2002/08/24 15:00:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.44 2002/08/26 17:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1731,7 +1731,8 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
numdatums[n] = Float4GetDatum(stats->stanumbers[k][n]);
/* XXX knows more than it should about type float4: */
arry = construct_array(numdatums, nnum,
false, sizeof(float4), 'i');
FLOAT4OID,
sizeof(float4), false, 'i');
values[i++] = PointerGetDatum(arry); /* stanumbersN */
}
else
......@@ -1767,7 +1768,8 @@ update_attstats(Oid relid, int natts, VacAttrStats **vacattrstats)
}
/* XXX knows more than it should about type text: */
arry = construct_array(txtdatums, ntxt,
false, -1, 'i');
TEXTOID,
-1, false, 'i');
values[i++] = PointerGetDatum(arry); /* stavaluesN */
}
else
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.100 2002/07/20 05:16:57 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.101 2002/08/26 17:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -219,35 +219,38 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
resultArray = array_set(array_source, i,
upper.indx,
sourceData,
arrayRef->refelembyval,
arrayRef->refelemlength,
arrayRef->refattrlength,
arrayRef->refelemlength,
arrayRef->refelembyval,
arrayRef->refelemalign,
isNull);
else
resultArray = array_set_slice(array_source, i,
upper.indx, lower.indx,
(ArrayType *) DatumGetPointer(sourceData),
arrayRef->refelembyval,
arrayRef->refelemlength,
arrayRef->refattrlength,
arrayRef->refelemlength,
arrayRef->refelembyval,
arrayRef->refelemalign,
isNull);
return PointerGetDatum(resultArray);
}
if (lIndex == NULL)
return array_ref(array_source, i,
upper.indx,
arrayRef->refelembyval,
arrayRef->refelemlength,
return array_ref(array_source, i, upper.indx,
arrayRef->refattrlength,
arrayRef->refelemlength,
arrayRef->refelembyval,
arrayRef->refelemalign,
isNull);
else
{
resultArray = array_get_slice(array_source, i,
upper.indx, lower.indx,
arrayRef->refelembyval,
arrayRef->refelemlength,
arrayRef->refattrlength,
arrayRef->refelemlength,
arrayRef->refelembyval,
arrayRef->refelemalign,
isNull);
return PointerGetDatum(resultArray);
}
......
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.205 2002/08/24 15:00:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.206 2002/08/26 17:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1056,10 +1056,11 @@ _copyArrayRef(ArrayRef *from)
/*
* copy remainder of node
*/
newnode->refrestype = from->refrestype;
newnode->refattrlength = from->refattrlength;
newnode->refelemlength = from->refelemlength;
newnode->refelemtype = from->refelemtype;
newnode->refelembyval = from->refelembyval;
newnode->refelemalign = from->refelemalign;
Node_Copy(from, newnode, refupperindexpr);
Node_Copy(from, newnode, reflowerindexpr);
......
......@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.153 2002/08/19 15:08:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.154 2002/08/26 17:53:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -258,7 +258,7 @@ _equalSubLink(SubLink *a, SubLink *b)
static bool
_equalArrayRef(ArrayRef *a, ArrayRef *b)
{
if (a->refelemtype != b->refelemtype)
if (a->refrestype != b->refrestype)
return false;
if (a->refattrlength != b->refattrlength)
return false;
......@@ -266,13 +266,17 @@ _equalArrayRef(ArrayRef *a, ArrayRef *b)
return false;
if (a->refelembyval != b->refelembyval)
return false;
if (a->refelemalign != b->refelemalign)
return false;
if (!equal(a->refupperindexpr, b->refupperindexpr))
return false;
if (!equal(a->reflowerindexpr, b->reflowerindexpr))
return false;
if (!equal(a->refexpr, b->refexpr))
return false;
return equal(a->refassgnexpr, b->refassgnexpr);
if (!equal(a->refassgnexpr, b->refassgnexpr))
return false;
return true;
}
static bool
......
......@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.168 2002/08/19 15:08:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.169 2002/08/26 17:53:58 tgl Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
......@@ -831,16 +831,18 @@ static void
_outArrayRef(StringInfo str, ArrayRef *node)
{
appendStringInfo(str,
" ARRAYREF :refelemtype %u :refattrlength %d :refelemlength %d ",
node->refelemtype,
" ARRAYREF :refrestype %u :refattrlength %d :refelemlength %d ",
node->refrestype,
node->refattrlength,
node->refelemlength);
appendStringInfo(str, " :refelembyval %c :refupperindex ",
node->refelembyval ? 't' : 'f');
appendStringInfo(str,
":refelembyval %s :refelemalign %c :refupperindexpr ",
booltostr(node->refelembyval),
node->refelemalign);
_outNode(str, node->refupperindexpr);
appendStringInfo(str, " :reflowerindex ");
appendStringInfo(str, " :reflowerindexpr ");
_outNode(str, node->reflowerindexpr);
appendStringInfo(str, " :refexpr ");
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.128 2002/08/10 20:44:48 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.129 2002/08/26 17:53:58 tgl Exp $
*
* NOTES
* Most of the read functions for plan nodes are tested. (In fact, they
......@@ -992,9 +992,9 @@ _readArrayRef(void)
local_node = makeNode(ArrayRef);
token = pg_strtok(&length); /* eat :refelemtype */
token = pg_strtok(&length); /* get refelemtype */
local_node->refelemtype = atooid(token);
token = pg_strtok(&length); /* eat :refrestype */
token = pg_strtok(&length); /* get refrestype */
local_node->refrestype = atooid(token);
token = pg_strtok(&length); /* eat :refattrlength */
token = pg_strtok(&length); /* get refattrlength */
......@@ -1008,10 +1008,14 @@ _readArrayRef(void)
token = pg_strtok(&length); /* get refelembyval */
local_node->refelembyval = strtobool(token);
token = pg_strtok(&length); /* eat :refupperindex */
token = pg_strtok(&length); /* eat :refelemalign */
token = pg_strtok(&length); /* get refelemalign */
local_node->refelemalign = token[0];
token = pg_strtok(&length); /* eat :refupperindexpr */
local_node->refupperindexpr = nodeRead(true);
token = pg_strtok(&length); /* eat :reflowerindex */
token = pg_strtok(&length); /* eat :reflowerindexpr */
local_node->reflowerindexpr = nodeRead(true);
token = pg_strtok(&length); /* eat :refexpr */
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.125 2002/08/08 01:44:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.126 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -877,7 +877,7 @@ exprType(Node *expr)
type = ((Const *) expr)->consttype;
break;
case T_ArrayRef:
type = ((ArrayRef *) expr)->refelemtype;
type = ((ArrayRef *) expr)->refrestype;
break;
case T_Aggref:
type = ((Aggref *) expr)->aggtype;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.66 2002/06/20 20:29:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.67 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -343,11 +343,12 @@ transformArraySubscripts(ParseState *pstate,
* Ready to build the ArrayRef node.
*/
aref = makeNode(ArrayRef);
aref->refrestype = resultType; /* XXX should save element type
* too */
aref->refattrlength = type_struct_array->typlen;
aref->refelemlength = type_struct_element->typlen;
aref->refelemtype = resultType; /* XXX should save element type
* too */
aref->refelembyval = type_struct_element->typbyval;
aref->refelemalign = type_struct_element->typalign;
aref->refupperindexpr = upperIndexpr;
aref->reflowerindexpr = lowerIndexpr;
aref->refexpr = arrayBase;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.105 2002/08/02 18:15:07 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.106 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -381,8 +381,8 @@ process_matched_tle(TargetEntry *src_tle,
((ArrayRef *) src_tle->expr)->refassgnexpr == NULL ||
prior_tle->expr == NULL || !IsA(prior_tle->expr, ArrayRef) ||
((ArrayRef *) prior_tle->expr)->refassgnexpr == NULL ||
((ArrayRef *) src_tle->expr)->refelemtype !=
((ArrayRef *) prior_tle->expr)->refelemtype)
((ArrayRef *) src_tle->expr)->refrestype !=
((ArrayRef *) prior_tle->expr)->refrestype)
elog(ERROR, "Multiple assignments to same attribute \"%s\"",
resdom->resname);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.75 2002/08/09 16:45:14 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.76 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -18,6 +18,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "utils/acl.h"
......@@ -252,6 +253,7 @@ makeacl(int n)
new_acl->size = size;
new_acl->ndim = 1;
new_acl->flags = 0;
new_acl->elemtype = ACLITEMOID;
ARR_LBOUND(new_acl)[0] = 0;
ARR_DIMS(new_acl)[0] = n;
return new_acl;
......
此差异已折叠。
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.79 2002/06/20 20:29:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.80 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -61,6 +61,7 @@
#include <ieeefp.h>
#endif
#include "catalog/pg_type.h"
#include "fmgr.h"
#include "utils/array.h"
#include "utils/builtins.h"
......@@ -1480,9 +1481,9 @@ check_float8_array(ArrayType *transarray, const char *caller)
* don't need to use deconstruct_array() since the array data is just
* going to look like a C array of 3 float8 values.
*/
if (ARR_SIZE(transarray) != (ARR_OVERHEAD(1) + 3 * sizeof(float8)) ||
ARR_NDIM(transarray) != 1 ||
ARR_DIMS(transarray)[0] != 3)
if (ARR_NDIM(transarray) != 1 ||
ARR_DIMS(transarray)[0] != 3 ||
ARR_ELEMTYPE(transarray) != FLOAT8OID)
elog(ERROR, "%s: expected 3-element float8 array", caller);
return (float8 *) ARR_DATA_PTR(transarray);
}
......@@ -1513,7 +1514,8 @@ float8_accum(PG_FUNCTION_ARGS)
transdatums[2] = Float8GetDatumFast(sumX2);
result = construct_array(transdatums, 3,
false /* float8 byval */ , sizeof(float8), 'd');
FLOAT8OID,
sizeof(float8), false /*float8 byval*/, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
......@@ -1548,7 +1550,8 @@ float4_accum(PG_FUNCTION_ARGS)
transdatums[2] = Float8GetDatumFast(sumX2);
result = construct_array(transdatums, 3,
false /* float8 byval */ , sizeof(float8), 'd');
FLOAT8OID,
sizeof(float8), false /*float8 byval*/, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
......
......@@ -12,13 +12,14 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.39 2002/06/20 20:29:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.40 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
......@@ -271,8 +272,9 @@ current_schemas(PG_FUNCTION_ARGS)
}
array = construct_array(names, nnames,
false, /* Name is not by-val */
NAMEOID,
NAMEDATALEN, /* sizeof(Name) */
false, /* Name is not by-val */
'i'); /* alignment of Name */
PG_RETURN_POINTER(array);
......
......@@ -5,7 +5,7 @@
*
* 1998 Jan Wieck
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.50 2002/02/18 14:25:40 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.51 2002/08/26 17:53:58 tgl Exp $
*
* ----------
*/
......@@ -18,6 +18,7 @@
#include <errno.h>
#include <sys/types.h>
#include "catalog/pg_type.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/int8.h"
......@@ -1734,7 +1735,7 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
false, -1, 'i',
NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "do_numeric_accum: expected 3-element numeric array");
......@@ -1755,7 +1756,7 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
transdatums[2] = sumX2;
result = construct_array(transdatums, 3,
false, -1, 'i');
NUMERICOID, -1, false, 'i');
return result;
}
......@@ -1825,7 +1826,7 @@ numeric_avg(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
false, -1, 'i',
NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_avg: expected 3-element numeric array");
......@@ -1861,7 +1862,7 @@ numeric_variance(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
false, -1, 'i',
NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_variance: expected 3-element numeric array");
......@@ -1940,7 +1941,7 @@ numeric_stddev(PG_FUNCTION_ARGS)
/* We assume the input is array of numeric */
deconstruct_array(transarray,
false, -1, 'i',
NUMERICOID, -1, false, 'i',
&transdatums, &ndatums);
if (ndatums != 3)
elog(ERROR, "numeric_stddev: expected 3-element numeric array");
......
......@@ -16,12 +16,13 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.2 2002/08/24 15:00:46 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pseudotypes.c,v 1.3 2002/08/26 17:53:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "utils/array.h"
#include "utils/builtins.h"
......@@ -112,13 +113,13 @@ anyarray_in(PG_FUNCTION_ARGS)
/*
* anyarray_out - output routine for pseudo-type ANYARRAY.
*
* We may as well allow this, since array_out will in fact work.
*/
Datum
anyarray_out(PG_FUNCTION_ARGS)
{
elog(ERROR, "Cannot display a value of type %s", "ANYARRAY");
PG_RETURN_VOID(); /* keep compiler quiet */
return array_out(fcinfo);
}
......
......@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.117 2002/08/18 09:36:25 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.118 2002/08/26 17:53:58 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
......@@ -725,7 +725,7 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
/* Extract data from array of int16 */
deconstruct_array(DatumGetArrayTypeP(column_index_array),
true, 2, 's',
INT2OID, 2, true, 's',
&keys, &nKeys);
for (j = 0; j < nKeys; j++)
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.69 2002/08/04 06:44:47 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.70 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -24,6 +24,7 @@
#include "access/hash.h"
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
......@@ -1917,7 +1918,7 @@ interval_accum(PG_FUNCTION_ARGS)
/* We assume the input is array of interval */
deconstruct_array(transarray,
false, 12, 'd',
INTERVALOID, 12, false, 'd',
&transdatums, &ndatums);
if (ndatums != 2)
elog(ERROR, "interval_accum: expected 2-element interval array");
......@@ -1943,7 +1944,7 @@ interval_accum(PG_FUNCTION_ARGS)
transdatums[1] = IntervalPGetDatum(&N);
result = construct_array(transdatums, 2,
false, 12, 'd');
INTERVALOID, 12, false, 'd');
PG_RETURN_ARRAYTYPE_P(result);
}
......@@ -1959,7 +1960,7 @@ interval_avg(PG_FUNCTION_ARGS)
/* We assume the input is array of interval */
deconstruct_array(transarray,
false, 12, 'd',
INTERVALOID, 12, false, 'd',
&transdatums, &ndatums);
if (ndatums != 2)
elog(ERROR, "interval_avg: expected 2-element interval array");
......
......@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.23 2002/08/04 06:33:48 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.24 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -226,7 +226,7 @@ bit(PG_FUNCTION_ARGS)
Datum
_bit(PG_FUNCTION_ARGS)
{
ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
......@@ -439,7 +439,7 @@ varbit(PG_FUNCTION_ARGS)
Datum
_varbit(PG_FUNCTION_ARGS)
{
ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.90 2002/06/20 20:29:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.91 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -283,7 +283,7 @@ bpchar(PG_FUNCTION_ARGS)
Datum
_bpchar(PG_FUNCTION_ARGS)
{
ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
......@@ -533,7 +533,7 @@ varchar(PG_FUNCTION_ARGS)
Datum
_varchar(PG_FUNCTION_ARGS)
{
ArrayType *v = (ArrayType *) PG_GETARG_VARLENA_P(0);
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int32 len = PG_GETARG_INT32(1);
FunctionCallInfoData locfcinfo;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.79 2002/08/22 00:01:44 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.80 2002/08/26 17:53:59 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
......@@ -885,6 +885,30 @@ get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
ReleaseSysCache(tp);
}
/*
* get_typlenbyvalalign
*
* A three-fer: given the type OID, return typlen, typbyval, typalign.
*/
void
get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
char *typalign)
{
HeapTuple tp;
Form_pg_type typtup;
tp = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typid),
0, 0, 0);
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for type %u", typid);
typtup = (Form_pg_type) GETSTRUCT(tp);
*typlen = typtup->typlen;
*typbyval = typtup->typbyval;
*typalign = typtup->typalign;
ReleaseSysCache(tp);
}
#ifdef NOT_USED
char
get_typalign(Oid typid)
......@@ -1287,7 +1311,9 @@ get_attstatsslot(HeapTuple statstuple,
* Do initial examination of the array. This produces a list of
* text Datums --- ie, pointers into the text array value.
*/
deconstruct_array(statarray, false, -1, 'i', values, nvalues);
deconstruct_array(statarray,
TEXTOID, -1, false, 'i',
values, nvalues);
narrayelem = *nvalues;
/*
......@@ -1346,8 +1372,8 @@ get_attstatsslot(HeapTuple statstuple,
*/
narrayelem = ARR_DIMS(statarray)[0];
if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
ARR_SIZE(statarray) != (ARR_OVERHEAD(1) + narrayelem * sizeof(float4)))
elog(ERROR, "get_attstatsslot: stanumbers is bogus");
ARR_ELEMTYPE(statarray) != FLOAT4OID)
elog(ERROR, "get_attstatsslot: stanumbers is not a 1-D float4 array");
*numbers = (float4 *) palloc(narrayelem * sizeof(float4));
memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
*nnumbers = narrayelem;
......
......@@ -5,7 +5,7 @@
* command, configuration file, and command line options.
* See src/backend/utils/misc/README for more information.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.83 2002/08/18 03:03:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.84 2002/08/26 17:53:59 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
......@@ -2680,6 +2680,7 @@ assign_defaultxactisolevel(const char *newval, bool doit, bool interactive)
/*
* Handle options fetched from pg_database.datconfig or pg_shadow.useconfig.
* The array parameter must be an array of TEXT.
*/
void
ProcessGUCArray(ArrayType *array, GucSource source)
......@@ -2687,6 +2688,9 @@ ProcessGUCArray(ArrayType *array, GucSource source)
int i;
Assert(array != NULL);
Assert(ARR_ELEMTYPE(array) == TEXTOID);
Assert(ARR_NDIM(array) == 1);
Assert(ARR_LBOUND(array)[0] == 1);
Assert(source == PGC_S_DATABASE || source == PGC_S_USER);
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
......@@ -2698,9 +2702,10 @@ ProcessGUCArray(ArrayType *array, GucSource source)
char *value;
d = array_ref(array, 1, &i,
false /*notbyvalue*/,
-1 /*varlenelem*/,
-1 /*varlenarray*/,
-1 /*TEXT's typlen*/,
false /*TEXT's typbyval*/,
'i' /*TEXT's typalign*/,
&isnull);
if (isnull)
......@@ -2756,6 +2761,10 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
bool isnull;
int i;
Assert(ARR_ELEMTYPE(array) == TEXTOID);
Assert(ARR_NDIM(array) == 1);
Assert(ARR_LBOUND(array)[0] == 1);
index = ARR_DIMS(array)[0] + 1; /* add after end */
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
......@@ -2764,10 +2773,13 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
char *current;
d = array_ref(array, 1, &i,
false /*notbyvalue*/,
-1 /*varlenelem*/,
-1 /*varlenarray*/,
-1 /*TEXT's typlen*/,
false /*TEXT's typbyval*/,
'i' /*TEXT's typalign*/,
&isnull);
if (isnull)
continue;
current = DatumGetCString(DirectFunctionCall1(textout, d));
if (strncmp(current, newval, strlen(name) + 1)==0)
{
......@@ -2777,10 +2789,18 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
}
isnull = false;
a = array_set(array, 1, &index, datum, false/*notbyval*/, -1, -1, &isnull);
a = array_set(array, 1, &index,
datum,
-1 /*varlenarray*/,
-1 /*TEXT's typlen*/,
false /*TEXT's typbyval*/,
'i' /*TEXT's typalign*/,
&isnull);
}
else
a = construct_array(&datum, 1, false, -1, 'i');
a = construct_array(&datum, 1,
TEXTOID,
-1, false, 'i');
return a;
}
......@@ -2802,7 +2822,9 @@ GUCArrayDelete(ArrayType *array, const char *name)
superuser() ? PGC_SUSET : PGC_USERSET,
PGC_S_SESSION, false, false);
newarray = construct_array(NULL, 0, false, -1, 'i');
newarray = construct_array(NULL, 0,
TEXTOID,
-1, false, 'i');
index = 1;
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
......@@ -2812,10 +2834,13 @@ GUCArrayDelete(ArrayType *array, const char *name)
bool isnull;
d = array_ref(array, 1, &i,
false /*notbyvalue*/,
-1 /*varlenelem*/,
-1 /*varlenarray*/,
-1 /*TEXT's typlen*/,
false /*TEXT's typbyval*/,
'i' /*TEXT's typalign*/,
&isnull);
if (isnull)
continue;
val = DatumGetCString(DirectFunctionCall1(textout, d));
if (strncmp(val, name, strlen(name))==0
......@@ -2823,7 +2848,13 @@ GUCArrayDelete(ArrayType *array, const char *name)
continue;
isnull = false;
newarray = array_set(newarray, 1, &index, d, false/*notbyval*/, -1, -1, &isnull);
newarray = array_set(newarray, 1, &index,
d,
-1 /*varlenarray*/,
-1 /*TEXT's typlen*/,
false /*TEXT's typbyval*/,
'i' /*TEXT's typalign*/,
&isnull);
index++;
}
......
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.152 2002/08/24 15:00:46 tgl Exp $
* $Id: catversion.h,v 1.153 2002/08/26 17:53:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200208231
#define CATALOG_VERSION_NO 200208251
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.264 2002/08/23 16:41:37 tgl Exp $
* $Id: pg_proc.h,v 1.265 2002/08/26 17:53:59 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -985,9 +985,9 @@ DESCR("session user name");
DATA(insert OID = 747 ( array_dims PGNSP PGUID 12 f f t f i 1 25 "2277" array_dims - _null_ ));
DESCR("array dimensions");
DATA(insert OID = 750 ( array_in PGNSP PGUID 12 f f t f i 3 2277 "2275 26 23" array_in - _null_ ));
DATA(insert OID = 750 ( array_in PGNSP PGUID 12 f f t f s 3 2277 "2275 26 23" array_in - _null_ ));
DESCR("array");
DATA(insert OID = 751 ( array_out PGNSP PGUID 12 f f t f i 2 2275 "2281 26" array_out - _null_ ));
DATA(insert OID = 751 ( array_out PGNSP PGUID 12 f f t f s 1 2275 "2277" array_out - _null_ ));
DESCR("array");
DATA(insert OID = 760 ( smgrin PGNSP PGUID 12 f f t f s 1 210 "2275" smgrin - _null_ ));
......@@ -3083,7 +3083,7 @@ DATA(insert OID = 2295 ( any_out PGNSP PGUID 12 f f t f i 1 2275 "2276" any_o
DESCR("(internal)");
DATA(insert OID = 2296 ( anyarray_in PGNSP PGUID 12 f f t f i 1 2277 "2275" anyarray_in - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2297 ( anyarray_out PGNSP PGUID 12 f f t f i 1 2275 "2277" anyarray_out - _null_ ));
DATA(insert OID = 2297 ( anyarray_out PGNSP PGUID 12 f f t f s 1 2275 "2277" anyarray_out - _null_ ));
DESCR("(internal)");
DATA(insert OID = 2298 ( void_in PGNSP PGUID 12 f f t f i 1 2278 "2275" void_in - _null_ ));
DESCR("(internal)");
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_type.h,v 1.129 2002/08/24 15:00:46 tgl Exp $
* $Id: pg_type.h,v 1.130 2002/08/26 17:54:01 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
......@@ -413,6 +413,7 @@ DATA(insert OID = 1025 ( _tinterval PGNSP PGUID -1 f b t \054 0 704 array_in ar
DATA(insert OID = 1027 ( _polygon PGNSP PGUID -1 f b t \054 0 604 array_in array_out d x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1033 ( aclitem PGNSP PGUID 8 f b t \054 0 0 aclitemin aclitemout i p f 0 -1 0 _null_ _null_ ));
DESCR("access control list");
#define ACLITEMOID 1033
DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b t \054 0 1033 array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b t \054 0 829 array_in array_out i x f 0 -1 0 _null_ _null_ ));
DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b t \054 0 869 array_in array_out i x f 0 -1 0 _null_ _null_ ));
......
......@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: primnodes.h,v 1.65 2002/07/04 15:24:11 thomas Exp $
* $Id: primnodes.h,v 1.66 2002/08/26 17:54:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -397,20 +397,20 @@ typedef struct SubLink
* varlena structures and have refattrlength = -1. In any case,
* an array type is never pass-by-value.
*
* Note: currently, refelemtype is NOT the element type, but the array type,
* when doing subarray fetch or either type of store. It would be cleaner
* to add more fields so we can distinguish the array element type from the
* result type of the ArrayRef operator...
* Note: refrestype is NOT the element type, but the array type,
* when doing subarray fetch or either type of store. It might be a good
* idea to include a refelemtype field as well.
* ----------------
*/
typedef struct ArrayRef
{
NodeTag type;
Oid refrestype; /* type of the result of the ArrayRef
* operation */
int refattrlength; /* typlen of array type */
int refelemlength; /* typlen of the array element type */
Oid refelemtype; /* type of the result of the ArrayRef
* operation */
bool refelembyval; /* is the element type pass-by-value? */
char refelemalign; /* typalign of the element type */
List *refupperindexpr;/* expressions that evaluate to upper
* array indexes */
List *reflowerindexpr;/* expressions that evaluate to lower
......
......@@ -10,13 +10,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: array.h,v 1.32 2002/06/20 20:29:52 momjian Exp $
*
* NOTES
* XXX the data array should be MAXALIGN'd -- currently we only INTALIGN
* which is NOT good enough for, eg, arrays of Interval. Changing this
* will break existing user tables so hold off until we have some other
* reason to break user tables (like WAL).
* $Id: array.h,v 1.33 2002/08/26 17:54:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -35,6 +29,7 @@ typedef struct
int ndim; /* # of dimensions */
int flags; /* implementation flags */
/* flags field is currently unused, always zero. */
Oid elemtype; /* element type OID */
} ArrayType;
/*
......@@ -61,6 +56,7 @@ typedef struct
*/
#define ARR_SIZE(a) (((ArrayType *) (a))->size)
#define ARR_NDIM(a) (((ArrayType *) (a))->ndim)
#define ARR_ELEMTYPE(a) (((ArrayType *) (a))->elemtype)
#define ARR_DIMS(a) \
((int *) (((char *) (a)) + sizeof(ArrayType)))
......@@ -90,29 +86,31 @@ extern Datum array_eq(PG_FUNCTION_ARGS);
extern Datum array_dims(PG_FUNCTION_ARGS);
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
bool elmbyval, int elmlen,
int arraylen, bool *isNull);
int arraylen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
Datum dataValue,
bool elmbyval, int elmlen,
int arraylen, bool *isNull);
int arraylen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern ArrayType *array_get_slice(ArrayType *array, int nSubscripts,
int *upperIndx, int *lowerIndx,
bool elmbyval, int elmlen,
int arraylen, bool *isNull);
int arraylen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern ArrayType *array_set_slice(ArrayType *array, int nSubscripts,
int *upperIndx, int *lowerIndx,
ArrayType *srcArray,
bool elmbyval, int elmlen,
int arraylen, bool *isNull);
int arraylen, int elmlen, bool elmbyval, char elmalign,
bool *isNull);
extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType);
extern ArrayType *construct_array(Datum *elems, int nelems,
bool elmbyval, int elmlen, char elmalign);
Oid elmtype,
int elmlen, bool elmbyval, char elmalign);
extern void deconstruct_array(ArrayType *array,
bool elmbyval, int elmlen, char elmalign,
Datum **elemsp, int *nelemsp);
Oid elmtype,
int elmlen, bool elmbyval, char elmalign,
Datum **elemsp, int *nelemsp);
/*
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lsyscache.h,v 1.58 2002/08/22 00:01:49 tgl Exp $
* $Id: lsyscache.h,v 1.59 2002/08/26 17:54:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -49,6 +49,8 @@ extern bool get_typisdefined(Oid typid);
extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
char *typalign);
extern char get_typstorage(Oid typid);
extern Node *get_typdefault(Oid typid);
extern char get_typtype(Oid typid);
......
......@@ -132,7 +132,7 @@ FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
(p2.oid = 'array_out'::regproc AND
p1.typelem != 0));
p1.typelem != 0 AND p1.typlen = -1));
oid | typname | oid | proname
------+-----------+-----+------------
32 | SET | 110 | unknownout
......
......@@ -108,7 +108,7 @@ FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
(p2.oid = 'array_out'::regproc AND
p1.typelem != 0));
p1.typelem != 0 AND p1.typlen = -1));
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册