]> granicus.if.org Git - postgresql/commitdiff
Modify array operations to include array's element type OID in the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Aug 2002 17:54:02 +0000 (17:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Aug 2002 17:54:02 +0000 (17:54 +0000)
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.

38 files changed:
contrib/array/README.array_iterator
contrib/array/array_iterator.c
contrib/array/array_iterator.h
contrib/array/array_iterator.sql.in
contrib/dblink/dblink.c
contrib/intagg/int_aggregate.c
contrib/ltree/_ltree_gist.c
contrib/ltree/_ltree_op.c
src/backend/catalog/pg_constraint.c
src/backend/commands/analyze.c
src/backend/executor/execQual.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_node.c
src/backend/rewrite/rewriteHandler.c
src/backend/utils/adt/acl.c
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/float.c
src/backend/utils/adt/name.c
src/backend/utils/adt/numeric.c
src/backend/utils/adt/pseudotypes.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/timestamp.c
src/backend/utils/adt/varbit.c
src/backend/utils/adt/varchar.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/misc/guc.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/catalog/pg_type.h
src/include/nodes/primnodes.h
src/include/utils/array.h
src/include/utils/lsyscache.h
src/test/regress/expected/type_sanity.out
src/test/regress/sql/type_sanity.sql

index b072ebe397005dbf6882808827784df836423862..b9e037ed85ac5b82f518672c27c92cdf33dd070a 100644 (file)
@@ -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.
index 5616350b3a5626f736623b6323d025845ce40818..d2a9a3271e632232c4e1e3c650b603248461100d 100644 (file)
@@ -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"
 
 
 
 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:
- */
index f959f09c7c7a430f4958e1ea40fefcac84a1aa72..c85d68f27ac60463a97b155520ef0b6a6d0cd453 100644 (file)
@@ -1,23 +1,23 @@
 #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
index 806d010e7240d9d357a19ce90d455aa32b8c0675..342d728f9a27433dec3690a0f718284f83910691 100644 (file)
@@ -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,
index d396f070ddda0e380498238e04f5b0f41f084486..0401e06f4f123e75ca29b3aa5704e5cd67108ed3 100644 (file)
@@ -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++)
index 6e8d17b7472e2c5800b0a60b6d6b5073c7d420d5..3801a3d91a48a32f36374ed9930a9b980039a3ac 100644 (file)
@@ -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
index 8b7420e6d9eeba8676013e3fa9bc841ae76e79ba..27bd057a567103f87815464d4ae8f73aaa30158c 100644 (file)
@@ -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);
index cc7a16c27e664dda776f2ed7f635940cae015a93..336b83820cf0351476e2fa78f8037364f62c6496 100644 (file)
@@ -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;
index 1ac4edbf0b377db94bf30fb94f7ad850649f6b51..85ca6eab648c9660a413fae72e79ed6364286499 100644 (file)
@@ -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;
index c7dbe44f7804e331e420d578fadb3845d55f2309..0d3173e9b3e9dd9a087a3184245864c7f958b3a9 100644 (file)
@@ -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
index f74f8f1b41bd97bca49cbb717b70fa0138e390da..e481ea115969c4be53e6d0b1999096d5f7ec2246 100644 (file)
@@ -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);
        }
index 49af1f90c8e5c0c85b7f9da449a8fc188b6e3160..4de9ba5b8dec55d6b7e9f9cbf060c1786afebb38 100644 (file)
@@ -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);
index 9990a04622980f845cf210be68ca6f59c4a31a50..c96389f1e8b28e67324350d9d63eb8d53b7352b6 100644 (file)
@@ -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
index 1a610b7c7c0a04e7bc97381b11fccc845ade0770..3a407753392029a5091eb679fe1ea3adcfb38af1 100644 (file)
@@ -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 ");
index fbf959931e37471e00e014a1e3f07749141dc122..b54a70159c83ce68c414e4226997d1f65c014253 100644 (file)
@@ -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 */
index 85cdc431a0e5bda98e1bfe2f2164904d91001ff6..1a7acd22527a5c7f014ba8e045a3d353ad7b946a 100644 (file)
@@ -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;
index 652ab54d2a9c7c8f2c887446618dfc12320c4323..33ee300fb2a1b32697131149b1e7b5db6efd6ec8 100644 (file)
@@ -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;
index 95ab639d0a7ff6d43e355877c8c1e059329ee29c..e526ffefd6b1485b6f5bbe4705820426f7963094 100644 (file)
@@ -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);
 
index 494a262f0bdbea68d61bc129dfde6707d1794221..05493033d325209e630648c708c52cc3faa18fe5 100644 (file)
@@ -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;
index 30c279319230f9764ffeae42c51b40dd706b31f5..53a4c83d6395e066a7dcd8f34086ed12c95883f2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.78 2002/06/20 20:29:36 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.79 2002/08/26 17:53:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "utils/syscache.h"
 
 
-/*
- * An array has the following internal structure:
- *       <nbytes>              - total number of bytes
+/*----------
+ * A standard varlena array has the following internal structure:
+ *       <size>                - total number of bytes (also, TOAST info flags)
  *       <ndim>                - number of dimensions of the array
  *       <flags>               - bit mask of flags
- *       <dim>                 - size of each array axis
- *       <dim_lower>   - lower boundary of each dimension
+ *       <elemtype>    - element type OID
+ *       <dim>                 - size of each array axis (C array of int)
+ *       <dim_lower>   - lower boundary of each dimension (C array of int)
  *       <actual data> - whatever is the stored data
- * The actual data starts on a MAXALIGN boundary.
+ * The actual data starts on a MAXALIGN boundary.  Individual items in the
+ * array are aligned as specified by the array element type.
  *
  * NOTE: it is important that array elements of toastable datatypes NOT be
  * toasted, since the tupletoaster won't know they are there.  (We could
  * support compressed toasted items; only out-of-line items are dangerous.
  * However, it seems preferable to store such items uncompressed and allow
  * the toaster to compress the whole array as one input.)
+ *
+ * There is currently no support for NULL elements in arrays, either.
+ * A reasonable (and backwards-compatible) way to add support would be to
+ * add a nulls bitmap following the <dim_lower> array, which would be present
+ * if needed; and its presence would be signaled by a bit in the flags word.
+ *
+ *
+ * There are also some "fixed-length array" datatypes, such as NAME and
+ * OIDVECTOR.  These are simply a sequence of a fixed number of items each
+ * of a fixed-length datatype, with no overhead; the item size must be
+ * a multiple of its alignment requirement, because we do no padding.
+ * We support subscripting on these types, but array_in() and array_out()
+ * only work with varlena arrays.
+ *----------
  */
 
 
 static int     ArrayCount(char *str, int *dim, char typdelim);
 static Datum *ReadArrayStr(char *arrayStr, int nitems, int ndim, int *dim,
                         FmgrInfo *inputproc, Oid typelem, int32 typmod,
-                        char typdelim, int typlen, bool typbyval,
-                        char typalign, int *nbytes);
+                        char typdelim,
+                        int typlen, bool typbyval, char typalign,
+                        int *nbytes);
 static void CopyArrayEls(char *p, Datum *values, int nitems,
-                        bool typbyval, int typlen, char typalign,
+                        int typlen, bool typbyval, char typalign,
                         bool freedata);
 static void system_cache_lookup(Oid element_type, bool input, int *typlen,
                                        bool *typbyval, char *typdelim, Oid *typelem,
                                        Oid *proc, char *typalign);
 static Datum ArrayCast(char *value, bool byval, int len);
-static int     ArrayCastAndSet(Datum src, bool typbyval, int typlen, char *dest);
-static int     array_nelems_size(char *ptr, int eltsize, int nitems);
-static char *array_seek(char *ptr, int eltsize, int nitems);
-static int     array_copy(char *destptr, int eltsize, int nitems, char *srcptr);
+static int     ArrayCastAndSet(Datum src,
+                                                       int typlen, bool typbyval, char typalign,
+                                                       char *dest);
+static int     array_nelems_size(char *ptr, int nitems,
+                                                         int typlen, bool typbyval, char typalign);
+static char *array_seek(char *ptr, int nitems,
+                                               int typlen, bool typbyval, char typalign);
+static int     array_copy(char *destptr, int nitems, char *srcptr,
+                                          int typlen, bool typbyval, char typalign);
 static int array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
-                                int eltsize, int *st, int *endp);
+                                                       int *st, int *endp,
+                                                       int typlen, bool typbyval, char typalign);
 static void array_extract_slice(int ndim, int *dim, int *lb,
-                                       char *arraydataptr, int eltsize,
-                                       int *st, int *endp, char *destPtr);
+                                                               char *arraydataptr,
+                                                               int *st, int *endp, char *destPtr,
+                                                               int typlen, bool typbyval, char typalign);
 static void array_insert_slice(int ndim, int *dim, int *lb,
-                                  char *origPtr, int origdatasize,
-                                  char *destPtr, int eltsize,
-                                  int *st, int *endp, char *srcPtr);
+                                                          char *origPtr, int origdatasize,
+                                                          char *destPtr,
+                                                          int *st, int *endp, char *srcPtr,
+                                                          int typlen, bool typbyval, char typalign);
 
 
 /*---------------------------------------------------------------------
@@ -212,6 +237,7 @@ array_in(PG_FUNCTION_ARGS)
                retval = (ArrayType *) palloc(sizeof(ArrayType));
                MemSet(retval, 0, sizeof(ArrayType));
                retval->size = sizeof(ArrayType);
+               retval->elemtype = element_type;
                PG_RETURN_ARRAYTYPE_P(retval);
        }
 
@@ -226,13 +252,14 @@ array_in(PG_FUNCTION_ARGS)
        MemSet(retval, 0, nbytes);
        retval->size = nbytes;
        retval->ndim = ndim;
+       retval->elemtype = element_type;
        memcpy((char *) ARR_DIMS(retval), (char *) dim,
                   ndim * sizeof(int));
        memcpy((char *) ARR_LBOUND(retval), (char *) lBound,
                   ndim * sizeof(int));
 
        CopyArrayEls(ARR_DATA_PTR(retval), dataPtr, nitems,
-                                typbyval, typlen, typalign, true);
+                                typlen, typbyval, typalign, true);
        pfree(dataPtr);
        pfree(string_save);
        PG_RETURN_ARRAYTYPE_P(retval);
@@ -336,7 +363,7 @@ ArrayCount(char *str, int *dim, char typdelim)
  *      internal format. The external format expected is like C array
  *      declaration. Unspecified elements are initialized to zero for fixed length
  *      base types and to empty varlena structures for variable length base
- *      types.
+ *      types.  (This is pretty bogus; NULL would be much safer.)
  * result :
  *      returns a palloc'd array of Datum representations of the array elements.
  *      If element type is pass-by-ref, the Datums point to palloc'd values.
@@ -482,7 +509,7 @@ ReadArrayStr(char *arrayStr,
         */
        if (typlen > 0)
        {
-               *nbytes = nitems * typlen;
+               *nbytes = nitems * att_align(typlen, typalign);
                if (!typbyval)
                        for (i = 0; i < nitems; i++)
                                if (values[i] == (Datum) 0)
@@ -493,23 +520,34 @@ ReadArrayStr(char *arrayStr,
        }
        else
        {
+               Assert(!typbyval);
                *nbytes = 0;
                for (i = 0; i < nitems; i++)
                {
                        if (values[i] != (Datum) 0)
                        {
                                /* let's just make sure data is not toasted */
-                               values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
-                               if (typalign == 'd')
-                                       *nbytes += MAXALIGN(VARSIZE(DatumGetPointer(values[i])));
-                               else
-                                       *nbytes += INTALIGN(VARSIZE(DatumGetPointer(values[i])));
+                               if (typlen == -1)
+                                       values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
+                               *nbytes = att_addlength(*nbytes, typlen, values[i]);
+                               *nbytes = att_align(*nbytes, typalign);
                        }
-                       else
+                       else if (typlen == -1)
                        {
-                               *nbytes += sizeof(int32);
+                               /* dummy varlena value (XXX bogus, see notes above) */
                                values[i] = PointerGetDatum(palloc(sizeof(int32)));
                                VARATT_SIZEP(DatumGetPointer(values[i])) = sizeof(int32);
+                               *nbytes += sizeof(int32);
+                               *nbytes = att_align(*nbytes, typalign);
+                       }
+                       else
+                       {
+                               /* dummy cstring value */
+                               Assert(typlen == -2);
+                               values[i] = PointerGetDatum(palloc(1));
+                               *((char *) DatumGetPointer(values[i])) = '\0';
+                               *nbytes += 1;
+                               *nbytes = att_align(*nbytes, typalign);
                        }
                }
        }
@@ -536,21 +574,19 @@ static void
 CopyArrayEls(char *p,
                         Datum *values,
                         int nitems,
-                        bool typbyval,
                         int typlen,
+                        bool typbyval,
                         char typalign,
                         bool freedata)
 {
        int                     i;
-       int                     inc;
 
        if (typbyval)
                freedata = false;
 
        for (i = 0; i < nitems; i++)
        {
-               inc = ArrayCastAndSet(values[i], typbyval, typlen, p);
-               p += inc;
+               p += ArrayCastAndSet(values[i], typlen, typbyval, typalign, p);
                if (freedata)
                        pfree(DatumGetPointer(values[i]));
        }
@@ -566,7 +602,7 @@ Datum
 array_out(PG_FUNCTION_ARGS)
 {
        ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
-       Oid                     element_type = PG_GETARG_OID(1);
+       Oid                     element_type;
        int                     typlen;
        bool            typbyval;
        char            typdelim;
@@ -588,9 +624,11 @@ array_out(PG_FUNCTION_ARGS)
        int                     ndim,
                           *dim;
 
+       element_type = ARR_ELEMTYPE(v);
        system_cache_lookup(element_type, false, &typlen, &typbyval,
                                                &typdelim, &typelem, &typoutput, &typalign);
        fmgr_info(typoutput, &outputproc);
+
        ndim = ARR_NDIM(v);
        dim = ARR_DIMS(v);
        nitems = ArrayGetNItems(ndim, dim);
@@ -620,10 +658,8 @@ array_out(PG_FUNCTION_ARGS)
                                                                                                  itemvalue,
                                                                                           ObjectIdGetDatum(typelem),
                                                                                                  Int32GetDatum(-1)));
-               if (typlen > 0)
-                       p += typlen;
-               else
-                       p += INTALIGN(*(int32 *) p);
+               p = att_addlength(p, typlen, PointerGetDatum(p));
+               p = (char *) att_align(p, typalign);
 
                /* count data plus backslashes; detect chars needing quotes */
                nq = (values[i][0] == '\0');    /* force quotes for empty string */
@@ -774,9 +810,10 @@ Datum
 array_ref(ArrayType *array,
                  int nSubscripts,
                  int *indx,
-                 bool elmbyval,
-                 int elmlen,
                  int arraylen,
+                 int elmlen,
+                 bool elmbyval,
+                 char elmalign,
                  bool *isNull)
 {
        int                     i,
@@ -806,7 +843,7 @@ array_ref(ArrayType *array,
        }
        else
        {
-               /* detoast input if necessary */
+               /* detoast input array if necessary */
                array = DatumGetArrayTypeP(PointerGetDatum(array));
 
                ndim = ARR_NDIM(array);
@@ -829,7 +866,7 @@ array_ref(ArrayType *array,
         */
        offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
 
-       retptr = array_seek(arraydataptr, elmlen, offset);
+       retptr = array_seek(arraydataptr, offset, elmlen, elmbyval, elmalign);
 
        *isNull = false;
        return ArrayCast(retptr, elmbyval, elmlen);
@@ -850,9 +887,10 @@ array_get_slice(ArrayType *array,
                                int nSubscripts,
                                int *upperIndx,
                                int *lowerIndx,
-                               bool elmbyval,
-                               int elmlen,
                                int arraylen,
+                               int elmlen,
+                               bool elmbyval,
+                               char elmalign,
                                bool *isNull)
 {
        int                     i,
@@ -882,6 +920,7 @@ array_get_slice(ArrayType *array,
 
                /*
                 * fixed-length arrays -- these are assumed to be 1-d, 0-based
+                * XXX where would we get the correct ELEMTYPE from?
                 */
                ndim = 1;
                fixedDim[0] = arraylen / elmlen;
@@ -892,7 +931,7 @@ array_get_slice(ArrayType *array,
        }
        else
        {
-               /* detoast input if necessary */
+               /* detoast input array if necessary */
                array = DatumGetArrayTypeP(PointerGetDatum(array));
 
                ndim = ARR_NDIM(array);
@@ -931,13 +970,15 @@ array_get_slice(ArrayType *array,
        mda_get_range(ndim, span, lowerIndx, upperIndx);
 
        bytes = array_slice_size(ndim, dim, lb, arraydataptr,
-                                                        elmlen, lowerIndx, upperIndx);
+                                                        lowerIndx, upperIndx,
+                                                        elmlen, elmbyval, elmalign);
        bytes += ARR_OVERHEAD(ndim);
 
        newarray = (ArrayType *) palloc(bytes);
        newarray->size = bytes;
        newarray->ndim = ndim;
        newarray->flags = 0;
+       newarray->elemtype = ARR_ELEMTYPE(array);
        memcpy(ARR_DIMS(newarray), span, ndim * sizeof(int));
        /*
         * Lower bounds of the new array are set to 1.  Formerly (before 7.3)
@@ -947,8 +988,9 @@ array_get_slice(ArrayType *array,
        for (i = 0; i < ndim; i++)
                newlb[i] = 1;
 
-       array_extract_slice(ndim, dim, lb, arraydataptr, elmlen,
-                                               lowerIndx, upperIndx, ARR_DATA_PTR(newarray));
+       array_extract_slice(ndim, dim, lb, arraydataptr,
+                                               lowerIndx, upperIndx, ARR_DATA_PTR(newarray),
+                                               elmlen, elmbyval, elmalign);
 
        return newarray;
 }
@@ -976,9 +1018,10 @@ array_set(ArrayType *array,
                  int nSubscripts,
                  int *indx,
                  Datum dataValue,
-                 bool elmbyval,
-                 int elmlen,
                  int arraylen,
+                 int elmlen,
+                 bool elmbyval,
+                 char elmalign,
                  bool *isNull)
 {
        int                     i,
@@ -1014,15 +1057,15 @@ array_set(ArrayType *array,
                newarray = (ArrayType *) palloc(arraylen);
                memcpy(newarray, array, arraylen);
                elt_ptr = (char *) newarray + indx[0] * elmlen;
-               ArrayCastAndSet(dataValue, elmbyval, elmlen, elt_ptr);
+               ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
                return newarray;
        }
 
        /* make sure item to be inserted is not toasted */
-       if (elmlen < 0)
+       if (elmlen == -1)
                dataValue = PointerGetDatum(PG_DETOAST_DATUM(dataValue));
 
-       /* detoast input if necessary */
+       /* detoast input array if necessary */
        array = DatumGetArrayTypeP(PointerGetDatum(array));
 
        ndim = ARR_NDIM(array);
@@ -1081,19 +1124,16 @@ array_set(ArrayType *array,
        else
        {
                offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
-               elt_ptr = array_seek(ARR_DATA_PTR(array), elmlen, offset);
+               elt_ptr = array_seek(ARR_DATA_PTR(array), offset,
+                                                        elmlen, elmbyval, elmalign);
                lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
-               if (elmlen > 0)
-                       olditemlen = elmlen;
-               else
-                       olditemlen = INTALIGN(*(int32 *) elt_ptr);
+               olditemlen = att_addlength(0, elmlen, PointerGetDatum(elt_ptr));
+               olditemlen = att_align(olditemlen, elmalign);
                lenafter = (int) (olddatasize - lenbefore - olditemlen);
        }
 
-       if (elmlen > 0)
-               newitemlen = elmlen;
-       else
-               newitemlen = INTALIGN(*(int32 *) DatumGetPointer(dataValue));
+       newitemlen = att_addlength(0, elmlen, dataValue);
+       newitemlen = att_align(newitemlen, elmalign);
 
        newsize = overheadlen + lenbefore + newitemlen + lenafter;
 
@@ -1104,6 +1144,7 @@ array_set(ArrayType *array,
        newarray->size = newsize;
        newarray->ndim = ndim;
        newarray->flags = 0;
+       newarray->elemtype = ARR_ELEMTYPE(array);
        memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
        memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
        memcpy((char *) newarray + overheadlen,
@@ -1113,7 +1154,7 @@ array_set(ArrayType *array,
                   (char *) array + overheadlen + lenbefore + olditemlen,
                   lenafter);
 
-       ArrayCastAndSet(dataValue, elmbyval, elmlen,
+       ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign,
                                        (char *) newarray + overheadlen + lenbefore);
 
        return newarray;
@@ -1143,9 +1184,10 @@ array_set_slice(ArrayType *array,
                                int *upperIndx,
                                int *lowerIndx,
                                ArrayType *srcArray,
-                               bool elmbyval,
-                               int elmlen,
                                int arraylen,
+                               int elmlen,
+                               bool elmbyval,
+                               char elmalign,
                                bool *isNull)
 {
        int                     i,
@@ -1240,8 +1282,8 @@ array_set_slice(ArrayType *array,
         * Compute space occupied by new entries, space occupied by replaced
         * entries, and required space for new array.
         */
-       newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), elmlen,
-                                                                       nsrcitems);
+       newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), nsrcitems,
+                                                                       elmlen, elmbyval, elmalign);
        overheadlen = ARR_OVERHEAD(ndim);
        olddatasize = ARR_SIZE(array) - overheadlen;
        if (ndim > 1)
@@ -1251,7 +1293,8 @@ array_set_slice(ArrayType *array,
                 * would be a lot more complicated if we had to do so...
                 */
                olditemsize = array_slice_size(ndim, dim, lb, ARR_DATA_PTR(array),
-                                                                          elmlen, lowerIndx, upperIndx);
+                                                                          lowerIndx, upperIndx,
+                                                                          elmlen, elmbyval, elmalign);
                lenbefore = lenafter = 0;               /* keep compiler quiet */
        }
        else
@@ -1266,15 +1309,14 @@ array_set_slice(ArrayType *array,
                int                     sliceub = Min(oldub, upperIndx[0]);
                char       *oldarraydata = ARR_DATA_PTR(array);
 
-               lenbefore = array_nelems_size(oldarraydata,
-                                                                         elmlen,
-                                                                         slicelb - oldlb);
+               lenbefore = array_nelems_size(oldarraydata, slicelb - oldlb,
+                                                                         elmlen, elmbyval, elmalign);
                if (slicelb > sliceub)
                        olditemsize = 0;
                else
                        olditemsize = array_nelems_size(oldarraydata + lenbefore,
-                                                                                       elmlen,
-                                                                                       sliceub - slicelb + 1);
+                                                                                       sliceub - slicelb + 1,
+                                                                                       elmlen, elmbyval, elmalign);
                lenafter = olddatasize - lenbefore - olditemsize;
        }
 
@@ -1284,6 +1326,7 @@ array_set_slice(ArrayType *array,
        newarray->size = newsize;
        newarray->ndim = ndim;
        newarray->flags = 0;
+       newarray->elemtype = ARR_ELEMTYPE(array);
        memcpy(ARR_DIMS(newarray), dim, ndim * sizeof(int));
        memcpy(ARR_LBOUND(newarray), lb, ndim * sizeof(int));
 
@@ -1294,8 +1337,9 @@ array_set_slice(ArrayType *array,
                 * would be a lot more complicated if we had to do so...
                 */
                array_insert_slice(ndim, dim, lb, ARR_DATA_PTR(array), olddatasize,
-                                                  ARR_DATA_PTR(newarray), elmlen,
-                                                  lowerIndx, upperIndx, ARR_DATA_PTR(srcArray));
+                                                  ARR_DATA_PTR(newarray),
+                                                  lowerIndx, upperIndx, ARR_DATA_PTR(srcArray),
+                                                  elmlen, elmbyval, elmalign);
        }
        else
        {
@@ -1352,12 +1396,13 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
        int                     nbytes = 0;
        int                     inp_typlen;
        bool            inp_typbyval;
+       char            inp_typalign;
        int                     typlen;
        bool            typbyval;
+       char            typalign;
        char            typdelim;
        Oid                     typelem;
        Oid                     proc;
-       char            typalign;
        char       *s;
 
        /* Get input array */
@@ -1367,6 +1412,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
                elog(ERROR, "array_map: null input array");
        v = PG_GETARG_ARRAYTYPE_P(0);
 
+       Assert(ARR_ELEMTYPE(v) == inpType);
+
        ndim = ARR_NDIM(v);
        dim = ARR_DIMS(v);
        nitems = ArrayGetNItems(ndim, dim);
@@ -1377,7 +1424,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
 
        /* Lookup source and result types. Unneeded variables are reused. */
        system_cache_lookup(inpType, false, &inp_typlen, &inp_typbyval,
-                                               &typdelim, &typelem, &proc, &typalign);
+                                               &typdelim, &typelem, &proc, &inp_typalign);
        system_cache_lookup(retType, false, &typlen, &typbyval,
                                                &typdelim, &typelem, &proc, &typalign);
 
@@ -1391,10 +1438,8 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
                /* Get source element */
                elt = fetch_att(s, inp_typbyval, inp_typlen);
 
-               if (inp_typlen > 0)
-                       s += inp_typlen;
-               else
-                       s += INTALIGN(*(int32 *) s);
+               s = att_addlength(s, inp_typlen, PointerGetDatum(s));
+               s = (char *) att_align(s, inp_typalign);
 
                /*
                 * Apply the given function to source elt and extra args.
@@ -1410,14 +1455,13 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
                if (fcinfo->isnull)
                        elog(ERROR, "array_map: cannot handle NULL in array");
 
-               /* Ensure data is not toasted, and update total result size */
-               if (typbyval || typlen > 0)
-                       nbytes += typlen;
-               else
-               {
+               /* Ensure data is not toasted */
+               if (typlen == -1)
                        values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
-                       nbytes += INTALIGN(VARSIZE(DatumGetPointer(values[i])));
-               }
+
+               /* Update total result size */
+               nbytes = att_addlength(nbytes, typlen, values[i]);
+               nbytes = att_align(nbytes, typalign);
        }
 
        /* Allocate and initialize the result array */
@@ -1427,6 +1471,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
 
        result->size = nbytes;
        result->ndim = ndim;
+       result->elemtype = retType;
        memcpy(ARR_DIMS(result), ARR_DIMS(v), 2 * ndim * sizeof(int));
 
        /*
@@ -1434,7 +1479,7 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
         * function
         */
        CopyArrayEls(ARR_DATA_PTR(result), values, nitems,
-                                typbyval, typlen, typalign, false);
+                                typlen, typbyval, typalign, false);
        pfree(values);
 
        PG_RETURN_ARRAYTYPE_P(result);
@@ -1445,34 +1490,43 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
  *
  * elems: array of Datum items to become the array contents
  * nelems: number of items
- * elmbyval, elmlen, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
  *
  * A palloc'd 1-D array object is constructed and returned.  Note that
  * elem values will be copied into the object even if pass-by-ref type.
  * NULL element values are not supported.
+ *
+ * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
+ * from the system catalogs, given the elmtype.  However, in most current
+ * uses the type is hard-wired into the caller and so we can save a lookup
+ * cycle by hard-wiring the type info as well.
  *----------
  */
 ArrayType *
 construct_array(Datum *elems, int nelems,
-                               bool elmbyval, int elmlen, char elmalign)
+                               Oid elmtype,
+                               int elmlen, bool elmbyval, char elmalign)
 {
        ArrayType  *result;
        int                     nbytes;
        int                     i;
 
+       /* compute required space */
        if (elmlen > 0)
        {
-               /* XXX what about alignment? */
-               nbytes = elmlen * nelems;
+               nbytes = nelems * att_align(elmlen, elmalign);
        }
        else
        {
-               /* varlena type ... make sure it is untoasted */
+               Assert(!elmbyval);
                nbytes = 0;
                for (i = 0; i < nelems; i++)
                {
-                       elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
-                       nbytes += INTALIGN(VARSIZE(DatumGetPointer(elems[i])));
+                       /* make sure data is not toasted */
+                       if (elmlen == -1)
+                               elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
+                       nbytes = att_addlength(nbytes, elmlen, elems[i]);
+                       nbytes = att_align(nbytes, elmalign);
                }
        }
 
@@ -1483,11 +1537,12 @@ construct_array(Datum *elems, int nelems,
        result->size = nbytes;
        result->ndim = 1;
        result->flags = 0;
+       result->elemtype = elmtype;
        ARR_DIMS(result)[0] = nelems;
        ARR_LBOUND(result)[0] = 1;
 
        CopyArrayEls(ARR_DATA_PTR(result), elems, nelems,
-                                elmbyval, elmlen, elmalign, false);
+                                elmlen, elmbyval, elmalign, false);
 
        return result;
 }
@@ -1496,17 +1551,23 @@ construct_array(Datum *elems, int nelems,
  * deconstruct_array  --- simple method for extracting data from an array
  *
  * array: array object to examine (must not be NULL)
- * elmbyval, elmlen, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
  * elemsp: return value, set to point to palloc'd array of Datum values
  * nelemsp: return value, set to number of extracted values
  *
  * If array elements are pass-by-ref data type, the returned Datums will
  * be pointers into the array object.
+ *
+ * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
+ * from the system catalogs, given the elmtype.  However, in most current
+ * uses the type is hard-wired into the caller and so we can save a lookup
+ * cycle by hard-wiring the type info as well.
  *----------
  */
 void
 deconstruct_array(ArrayType *array,
-                                 bool elmbyval, int elmlen, char elmalign,
+                                 Oid elmtype,
+                                 int elmlen, bool elmbyval, char elmalign,
                                  Datum **elemsp, int *nelemsp)
 {
        Datum      *elems;
@@ -1514,6 +1575,8 @@ deconstruct_array(ArrayType *array,
        char       *p;
        int                     i;
 
+       Assert(ARR_ELEMTYPE(array) == elmtype);
+
        nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
        if (nelems <= 0)
        {
@@ -1528,10 +1591,8 @@ deconstruct_array(ArrayType *array,
        for (i = 0; i < nelems; i++)
        {
                elems[i] = fetch_att(p, elmbyval, elmlen);
-               if (elmlen > 0)
-                       p += elmlen;
-               else
-                       p += INTALIGN(VARSIZE(p));
+               p = att_addlength(p, elmlen, PointerGetDatum(p));
+               p = (char *) att_align(p, elmalign);
        }
 }
 
@@ -1586,8 +1647,7 @@ system_cache_lookup(Oid element_type,
                                                           ObjectIdGetDatum(element_type),
                                                           0, 0, 0);
        if (!HeapTupleIsValid(typeTuple))
-               elog(ERROR, "array_out: Cache lookup failed for type %u",
-                        element_type);
+               elog(ERROR, "cache lookup failed for type %u", element_type);
        typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
 
        *typlen = typeStruct->typlen;
@@ -1613,13 +1673,12 @@ ArrayCast(char *value, bool byval, int len)
 
 /*
  * Copy datum to *dest and return total space used (including align padding)
- *
- * XXX this routine needs to be told typalign too!
  */
 static int
 ArrayCastAndSet(Datum src,
-                               bool typbyval,
                                int typlen,
+                               bool typbyval,
+                               char typalign,
                                char *dest)
 {
        int                     inc;
@@ -1627,24 +1686,17 @@ ArrayCastAndSet(Datum src,
        if (typlen > 0)
        {
                if (typbyval)
-               {
                        store_att_byval(dest, src, typlen);
-                       /* For by-val types, assume no alignment padding is needed */
-                       inc = typlen;
-               }
                else
-               {
                        memmove(dest, DatumGetPointer(src), typlen);
-                       /* XXX WRONG: need to consider type's alignment requirement */
-                       inc = typlen;
-               }
+               inc = att_align(typlen, typalign);
        }
        else
        {
-               /* varlena type */
-               memmove(dest, DatumGetPointer(src), VARSIZE(DatumGetPointer(src)));
-               /* XXX WRONG: should use MAXALIGN or type's alignment requirement */
-               inc = INTALIGN(VARSIZE(DatumGetPointer(src)));
+               Assert(!typbyval);
+               inc = att_addlength(0, typlen, src);
+               memmove(dest, DatumGetPointer(src), inc);
+               inc = att_align(inc, typalign);
        }
 
        return inc;
@@ -1652,22 +1704,25 @@ ArrayCastAndSet(Datum src,
 
 /*
  * Compute total size of the nitems array elements starting at *ptr
- *
- * XXX should consider alignment spec for fixed-length types
  */
 static int
-array_nelems_size(char *ptr, int eltsize, int nitems)
+array_nelems_size(char *ptr, int nitems,
+                                 int typlen, bool typbyval, char typalign)
 {
        char       *origptr;
        int                     i;
 
        /* fixed-size elements? */
-       if (eltsize > 0)
-               return eltsize * nitems;
-       /* else assume they are varlena items */
+       if (typlen > 0)
+               return nitems * att_align(typlen, typalign);
+
+       Assert(!typbyval);
        origptr = ptr;
        for (i = 0; i < nitems; i++)
-               ptr += INTALIGN(*(int32 *) ptr);
+       {
+               ptr = att_addlength(ptr, typlen, PointerGetDatum(ptr));
+               ptr = (char *) att_align(ptr, typalign);
+       }
        return ptr - origptr;
 }
 
@@ -1675,9 +1730,11 @@ array_nelems_size(char *ptr, int eltsize, int nitems)
  * Advance ptr over nitems array elements
  */
 static char *
-array_seek(char *ptr, int eltsize, int nitems)
+array_seek(char *ptr, int nitems,
+                  int typlen, bool typbyval, char typalign)
 {
-       return ptr + array_nelems_size(ptr, eltsize, nitems);
+       return ptr + array_nelems_size(ptr, nitems,
+                                                                  typlen, typbyval, typalign);
 }
 
 /*
@@ -1686,9 +1743,11 @@ array_seek(char *ptr, int eltsize, int nitems)
  * Returns number of bytes copied
  */
 static int
-array_copy(char *destptr, int eltsize, int nitems, char *srcptr)
+array_copy(char *destptr, int nitems, char *srcptr,
+                  int typlen, bool typbyval, char typalign)
 {
-       int                     numbytes = array_nelems_size(srcptr, eltsize, nitems);
+       int                     numbytes = array_nelems_size(srcptr, nitems,
+                                                                                        typlen, typbyval, typalign);
 
        memmove(destptr, srcptr, numbytes);
        return numbytes;
@@ -1701,7 +1760,8 @@ array_copy(char *destptr, int eltsize, int nitems, char *srcptr)
  */
 static int
 array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
-                                int eltsize, int *st, int *endp)
+                                int *st, int *endp,
+                                int typlen, bool typbyval, char typalign)
 {
        int                     st_pos,
                                span[MAXDIM],
@@ -1717,12 +1777,13 @@ array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
        mda_get_range(ndim, span, st, endp);
 
        /* Pretty easy for fixed element length ... */
-       if (eltsize > 0)
-               return ArrayGetNItems(ndim, span) * eltsize;
+       if (typlen > 0)
+               return ArrayGetNItems(ndim, span) * att_align(typlen, typalign);
 
        /* Else gotta do it the hard way */
        st_pos = ArrayGetOffset(ndim, dim, lb, st);
-       ptr = array_seek(arraydataptr, eltsize, st_pos);
+       ptr = array_seek(arraydataptr, st_pos,
+                                        typlen, typbyval, typalign);
        mda_get_prod(ndim, dim, prod);
        mda_get_offset_values(ndim, dist, prod, span);
        for (i = 0; i < ndim; i++)
@@ -1730,8 +1791,10 @@ array_slice_size(int ndim, int *dim, int *lb, char *arraydataptr,
        j = ndim - 1;
        do
        {
-               ptr = array_seek(ptr, eltsize, dist[j]);
-               inc = INTALIGN(*(int32 *) ptr);
+               ptr = array_seek(ptr, dist[j],
+                                                typlen, typbyval, typalign);
+               inc = att_addlength(0, typlen, PointerGetDatum(ptr));
+               inc = att_align(inc, typalign);
                ptr += inc;
                count += inc;
        } while ((j = mda_next_tuple(ndim, indx, span)) != -1);
@@ -1749,10 +1812,12 @@ array_extract_slice(int ndim,
                                        int *dim,
                                        int *lb,
                                        char *arraydataptr,
-                                       int eltsize,
                                        int *st,
                                        int *endp,
-                                       char *destPtr)
+                                       char *destPtr,
+                                       int typlen,
+                                       bool typbyval,
+                                       char typalign)
 {
        int                     st_pos,
                                prod[MAXDIM],
@@ -1765,7 +1830,8 @@ array_extract_slice(int ndim,
                                inc;
 
        st_pos = ArrayGetOffset(ndim, dim, lb, st);
-       srcPtr = array_seek(arraydataptr, eltsize, st_pos);
+       srcPtr = array_seek(arraydataptr, st_pos,
+                                               typlen, typbyval, typalign);
        mda_get_prod(ndim, dim, prod);
        mda_get_range(ndim, span, st, endp);
        mda_get_offset_values(ndim, dist, prod, span);
@@ -1774,8 +1840,10 @@ array_extract_slice(int ndim,
        j = ndim - 1;
        do
        {
-               srcPtr = array_seek(srcPtr, eltsize, dist[j]);
-               inc = array_copy(destPtr, eltsize, 1, srcPtr);
+               srcPtr = array_seek(srcPtr, dist[j],
+                                                       typlen, typbyval, typalign);
+               inc = array_copy(destPtr, 1, srcPtr,
+                                                typlen, typbyval, typalign);
                destPtr += inc;
                srcPtr += inc;
        } while ((j = mda_next_tuple(ndim, indx, span)) != -1);
@@ -1801,10 +1869,12 @@ array_insert_slice(int ndim,
                                   char *origPtr,
                                   int origdatasize,
                                   char *destPtr,
-                                  int eltsize,
                                   int *st,
                                   int *endp,
-                                  char *srcPtr)
+                                  char *srcPtr,
+                                  int typlen,
+                                  bool typbyval,
+                                  char typalign)
 {
        int                     st_pos,
                                prod[MAXDIM],
@@ -1817,7 +1887,8 @@ array_insert_slice(int ndim,
                                inc;
 
        st_pos = ArrayGetOffset(ndim, dim, lb, st);
-       inc = array_copy(destPtr, eltsize, st_pos, origPtr);
+       inc = array_copy(destPtr, st_pos, origPtr,
+                                        typlen, typbyval, typalign);
        destPtr += inc;
        origPtr += inc;
        mda_get_prod(ndim, dim, prod);
@@ -1829,15 +1900,18 @@ array_insert_slice(int ndim,
        do
        {
                /* Copy/advance over elements between here and next part of slice */
-               inc = array_copy(destPtr, eltsize, dist[j], origPtr);
+               inc = array_copy(destPtr, dist[j], origPtr,
+                                                typlen, typbyval, typalign);
                destPtr += inc;
                origPtr += inc;
                /* Copy new element at this slice position */
-               inc = array_copy(destPtr, eltsize, 1, srcPtr);
+               inc = array_copy(destPtr, 1, srcPtr,
+                                                typlen, typbyval, typalign);
                destPtr += inc;
                srcPtr += inc;
                /* Advance over old element at this slice position */
-               origPtr = array_seek(origPtr, eltsize, 1);
+               origPtr = array_seek(origPtr, 1,
+                                                        typlen, typbyval, typalign);
        } while ((j = mda_next_tuple(ndim, indx, span)) != -1);
 
        /* don't miss any data at the end */
index 84233ebd1c4dd51a3ff8b8fb80edb268e1f37272..5edea787afae3d4fb8efa956a387a9fa752d0861 100644 (file)
@@ -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);
 }
index de3f04a7df08049a7e13ee4e9deb151277f5ea61..41eca445f63b55e06bd0466f61622d4e49abd9ee 100644 (file)
  *
  *
  * 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);
index 1af7402fb38dfffd33ca1811c294a9f0210db7c1..99ef1327e48a9afcd628bff3f2a9151accf09efc 100644 (file)
@@ -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");
index cb374e8f93c1ec25b58598353d022c11bf7f2fff..63f585fe32ecb2eec3ca1a6b629ecd73662c68f4 100644 (file)
  *
  *
  * 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);
 }
 
 
index 0f5d0fca86bcf6d1b3d410c6a1fe4895a6e4796c..10116364560acd50856cf663f444b5a5e30f24ea 100644 (file)
@@ -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++)
index 5be34e6199c1c08dfd05de58dc797517ce3d4f37..1b2553ec9478343c6626d41a67802a6e9795d572 100644 (file)
@@ -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");
index 8779acddb434f8d62b89dc433938cd6ca84bd0b7..97c3567f1ac1f0b83f0dd691ed3f493247e236f8 100644 (file)
@@ -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;
 
index 2520d415d5a1abf791e988ec0dcd71a2b0bf2439..cdf5c301d2e88a4bd2aafae3620f929ea11fd681 100644 (file)
@@ -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;
 
index a916dc94012f59d272118574ee481774440ecc57..079ba2152a7f0de1891fce09541c2afd519ee239 100644 (file)
@@ -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;
index a759b3f5271d2dc2d16d55526bca8e05ce80db0c..b73118289fce6779125de125a7792a58c8357bc1 100644 (file)
@@ -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++;
        }
 
index a45b775dc7eedb3505bdc32428d0bc38be2c23f8..4656f2ee97bb27ebf5aff3181a0212c6b93d46b9 100644 (file)
@@ -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
index 4129ea73b40ae16a3d93b6dfb95ccd82d1fe1be0..1e0c775b5373cce49c3977f512ff7621235e8d2a 100644 (file)
@@ -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)");
index e72a9c4c84ec2e2092600b5b0e171568c80bea31..8efb6c07a3d439f470cf8903824d8dd80d01ab68 100644 (file)
@@ -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_ ));
index 647ff8bb3923aa936d57569eb7035b431d430928..8fbb9442b41d197b9c160f95170fce7fcaa3cc9e 100644 (file)
@@ -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
index 459d2caaff2752ffbf7d8a249b0b2b98314fdfe1..b0920c70d9db8bd07c85e1c8399ff99792a10068 100644 (file)
  * 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);
 
 
 /*
index ccd385b7779fa65c062afeb25fdd49b023b134f5..78d099086592a3d239c4cbf52eea11994bfec67f 100644 (file)
@@ -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);
index 7f606ec976fd761f3a1f1fda8fa5eab71f803284..50000afcf90c16e039faacf2ecdb4ca733f9ac71 100644 (file)
@@ -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
index 7bea3058b4b3cf0cb748506bd58c54ddfb33572c..3b297b3694debd603382722793b96b32767b0889 100644 (file)
@@ -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