diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 29ac5d5..c7bbe22 100644
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
*************** ObjectAddress
*** 729,734 ****
--- 729,735 ----
  DefineDomain(CreateDomainStmt *stmt)
  {
  	char	   *domainName;
+ 	char	   *domainArrayName;
  	Oid			domainNamespace;
  	AclResult	aclresult;
  	int16		internalLength;
*************** DefineDomain(CreateDomainStmt *stmt)
*** 757,762 ****
--- 758,764 ----
  	Oid			basetypeoid;
  	Oid			old_type_oid;
  	Oid			domaincoll;
+ 	Oid			domainArrayOid;
  	Form_pg_type baseType;
  	int32		basetypeMod;
  	Oid			baseColl;
*************** DefineDomain(CreateDomainStmt *stmt)
*** 1027,1032 ****
--- 1029,1037 ----
  		}
  	}
  
+ 	/* Allocate OID for array type */
+ 	domainArrayOid = AssignTypeArrayOid();
+ 
  	/*
  	 * Have TypeCreate do all the real work.
  	 */
*************** DefineDomain(CreateDomainStmt *stmt)
*** 1051,1057 ****
  				   analyzeProcedure,	/* analyze procedure */
  				   InvalidOid,	/* no array element type */
  				   false,		/* this isn't an array */
! 				   InvalidOid,	/* no arrays for domains (yet) */
  				   basetypeoid, /* base type ID */
  				   defaultValue,	/* default type value (text) */
  				   defaultValueBin, /* default type value (binary) */
--- 1056,1062 ----
  				   analyzeProcedure,	/* analyze procedure */
  				   InvalidOid,	/* no array element type */
  				   false,		/* this isn't an array */
! 				   domainArrayOid,	/* array type we are about to create */
  				   basetypeoid, /* base type ID */
  				   defaultValue,	/* default type value (text) */
  				   defaultValueBin, /* default type value (binary) */
*************** DefineDomain(CreateDomainStmt *stmt)
*** 1064,1069 ****
--- 1069,1116 ----
  				   domaincoll); /* type's collation */
  
  	/*
+ 	 * Create the array type that goes with it.
+ 	 */
+ 	domainArrayName = makeArrayTypeName(domainName, domainNamespace);
+ 
+ 	/* alignment must be 'i' or 'd' for arrays */
+ 	alignment = (alignment == 'd') ? 'd' : 'i';
+ 
+ 	TypeCreate(domainArrayOid,	/* force assignment of this type OID */
+ 			   domainArrayName, /* type name */
+ 			   domainNamespace, /* namespace */
+ 			   InvalidOid,		/* relation oid (n/a here) */
+ 			   0,				/* relation kind (ditto) */
+ 			   GetUserId(),		/* owner's ID */
+ 			   -1,				/* internal size (always varlena) */
+ 			   TYPTYPE_BASE,	/* type-type (base type) */
+ 			   TYPCATEGORY_ARRAY,	/* type-category (array) */
+ 			   false,			/* array types are never preferred */
+ 			   delimiter,		/* array element delimiter */
+ 			   F_ARRAY_IN,		/* input procedure */
+ 			   F_ARRAY_OUT,		/* output procedure */
+ 			   F_ARRAY_RECV,	/* receive procedure */
+ 			   F_ARRAY_SEND,	/* send procedure */
+ 			   InvalidOid,		/* typmodin procedure - none */
+ 			   InvalidOid,		/* typmodout procedure - none */
+ 			   F_ARRAY_TYPANALYZE,	/* analyze procedure */
+ 			   address.objectId,	/* element type ID */
+ 			   true,			/* yes this is an array type */
+ 			   InvalidOid,		/* no further array type */
+ 			   InvalidOid,		/* base type ID */
+ 			   NULL,			/* never a default type value */
+ 			   NULL,			/* binary default isn't sent either */
+ 			   false,			/* never passed by value */
+ 			   alignment,		/* see above */
+ 			   'x',				/* ARRAY is always toastable */
+ 			   -1,				/* typMod (Domains only) */
+ 			   0,				/* Array dimensions of typbasetype */
+ 			   false,			/* Type NOT NULL */
+ 			   domaincoll);		/* type's collation */
+ 
+ 	pfree(domainArrayName);
+ 
+ 	/*
  	 * Process constraints which refer to the domain ID returned by TypeCreate
  	 */
  	foreach(listptr, schema)
*************** DefineEnum(CreateEnumStmt *stmt)
*** 1139,1144 ****
--- 1186,1192 ----
  					 errmsg("type \"%s\" already exists", enumName)));
  	}
  
+ 	/* Allocate OID for array type */
  	enumArrayOid = AssignTypeArrayOid();
  
  	/* Create the pg_type entry */
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 3acc696..1e62c57 100644
*** a/src/test/regress/expected/domain.out
--- b/src/test/regress/expected/domain.out
*************** Rules:
*** 310,315 ****
--- 310,410 ----
  drop table dcomptable;
  drop type comptype cascade;
  NOTICE:  drop cascades to type dcomptypea
+ -- Test arrays over domains
+ create domain posint as int check (value > 0);
+ create table pitable (f1 posint[]);
+ insert into pitable values(array[42]);
+ insert into pitable values(array[-1]);  -- fail
+ ERROR:  value for domain posint violates check constraint "posint_check"
+ insert into pitable values('{0}');  -- fail
+ ERROR:  value for domain posint violates check constraint "posint_check"
+ LINE 1: insert into pitable values('{0}');
+                                    ^
+ update pitable set f1[1] = f1[1] + 1;
+ update pitable set f1[1] = 0;  -- fail
+ ERROR:  value for domain posint violates check constraint "posint_check"
+ select * from pitable;
+   f1  
+ ------
+  {43}
+ (1 row)
+ 
+ drop table pitable;
+ create domain vc4 as varchar(4);
+ create table vc4table (f1 vc4[]);
+ insert into vc4table values(array['too long']);  -- fail
+ ERROR:  value too long for type character varying(4)
+ insert into vc4table values(array['too long']::vc4[]);  -- cast truncates
+ select * from vc4table;
+     f1    
+ ----------
+  {"too "}
+ (1 row)
+ 
+ drop table vc4table;
+ drop type vc4;
+ -- You can sort of fake arrays-of-arrays by putting a domain in between
+ create domain dposinta as posint[];
+ create table dposintatable (f1 dposinta[]);
+ insert into dposintatable values(array[array[42]]);  -- fail
+ ERROR:  column "f1" is of type dposinta[] but expression is of type integer[]
+ LINE 1: insert into dposintatable values(array[array[42]]);
+                                          ^
+ HINT:  You will need to rewrite or cast the expression.
+ insert into dposintatable values(array[array[42]::posint[]]); -- still fail
+ ERROR:  column "f1" is of type dposinta[] but expression is of type posint[]
+ LINE 1: insert into dposintatable values(array[array[42]::posint[]])...
+                                          ^
+ HINT:  You will need to rewrite or cast the expression.
+ insert into dposintatable values(array[array[42]::dposinta]); -- but this works
+ select f1, f1[1], (f1[1])[1] from dposintatable;
+     f1    |  f1  | f1 
+ ----------+------+----
+  {"{42}"} | {42} | 42
+ (1 row)
+ 
+ select pg_typeof(f1) from dposintatable;
+  pg_typeof  
+ ------------
+  dposinta[]
+ (1 row)
+ 
+ select pg_typeof(f1[1]) from dposintatable;
+  pg_typeof 
+ -----------
+  dposinta
+ (1 row)
+ 
+ select pg_typeof(f1[1][1]) from dposintatable;
+  pg_typeof 
+ -----------
+  dposinta
+ (1 row)
+ 
+ select pg_typeof((f1[1])[1]) from dposintatable;
+  pg_typeof 
+ -----------
+  posint
+ (1 row)
+ 
+ update dposintatable set f1[2] = array[99];
+ select f1, f1[1], (f1[2])[1] from dposintatable;
+        f1        |  f1  | f1 
+ -----------------+------+----
+  {"{42}","{99}"} | {42} | 99
+ (1 row)
+ 
+ -- it'd be nice if you could do something like this, but for now you can't:
+ update dposintatable set f1[2][1] = array[97];
+ ERROR:  wrong number of array subscripts
+ -- maybe someday we can make this syntax work:
+ update dposintatable set (f1[2])[1] = array[98];
+ ERROR:  syntax error at or near "["
+ LINE 1: update dposintatable set (f1[2])[1] = array[98];
+                                         ^
+ drop table dposintatable;
+ drop domain posint cascade;
+ NOTICE:  drop cascades to type dposinta
  -- Test not-null restrictions
  create domain dnotnull varchar(15) NOT NULL;
  create domain dnull    varchar(15);
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index 0fd383e..8fb3e20 100644
*** a/src/test/regress/sql/domain.sql
--- b/src/test/regress/sql/domain.sql
*************** drop table dcomptable;
*** 166,171 ****
--- 166,214 ----
  drop type comptype cascade;
  
  
+ -- Test arrays over domains
+ 
+ create domain posint as int check (value > 0);
+ 
+ create table pitable (f1 posint[]);
+ insert into pitable values(array[42]);
+ insert into pitable values(array[-1]);  -- fail
+ insert into pitable values('{0}');  -- fail
+ update pitable set f1[1] = f1[1] + 1;
+ update pitable set f1[1] = 0;  -- fail
+ select * from pitable;
+ drop table pitable;
+ 
+ create domain vc4 as varchar(4);
+ create table vc4table (f1 vc4[]);
+ insert into vc4table values(array['too long']);  -- fail
+ insert into vc4table values(array['too long']::vc4[]);  -- cast truncates
+ select * from vc4table;
+ drop table vc4table;
+ drop type vc4;
+ 
+ -- You can sort of fake arrays-of-arrays by putting a domain in between
+ create domain dposinta as posint[];
+ create table dposintatable (f1 dposinta[]);
+ insert into dposintatable values(array[array[42]]);  -- fail
+ insert into dposintatable values(array[array[42]::posint[]]); -- still fail
+ insert into dposintatable values(array[array[42]::dposinta]); -- but this works
+ select f1, f1[1], (f1[1])[1] from dposintatable;
+ select pg_typeof(f1) from dposintatable;
+ select pg_typeof(f1[1]) from dposintatable;
+ select pg_typeof(f1[1][1]) from dposintatable;
+ select pg_typeof((f1[1])[1]) from dposintatable;
+ update dposintatable set f1[2] = array[99];
+ select f1, f1[1], (f1[2])[1] from dposintatable;
+ -- it'd be nice if you could do something like this, but for now you can't:
+ update dposintatable set f1[2][1] = array[97];
+ -- maybe someday we can make this syntax work:
+ update dposintatable set (f1[2])[1] = array[98];
+ 
+ drop table dposintatable;
+ drop domain posint cascade;
+ 
+ 
  -- Test not-null restrictions
  
  create domain dnotnull varchar(15) NOT NULL;
