Modify array operations to include array's element type OID in the
authorTom Lane
Mon, 26 Aug 2002 17:54:02 +0000 (17:54 +0000)
committerTom Lane
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)
  *           - number of dimensions of the array
  *          - bit mask of flags
- *            - size of each array axis
- *      - lower boundary of each dimension
+ *       - element type OID
+ *            - size of each array axis (C array of int)
+ *      - lower boundary of each dimension (C array of int)
  *    - 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  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 
 #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 
 #include 
 
+#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 .
@@ -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