Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
2c773296
Commit
2c773296
authored
Jul 16, 2008
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add array_fill() to create arrays initialized with a value.
Pavel Stehule
parent
2fa42cc9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
371 additions
and
8 deletions
+371
-8
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+14
-1
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/arrayfuncs.c
+275
-1
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+5
-3
src/include/utils/array.h
src/include/utils/array.h
+3
-1
src/test/regress/expected/arrays.out
src/test/regress/expected/arrays.out
+58
-0
src/test/regress/sql/arrays.sql
src/test/regress/sql/arrays.sql
+14
-0
No files found.
doc/src/sgml/func.sgml
View file @
2c773296
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.44
0 2008/07/15 18:24:59
momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.44
1 2008/07/16 00:48:53
momjian Exp $ -->
<chapter
id=
"functions"
>
<title>
Functions and Operators
</title>
...
...
@@ -9371,6 +9371,19 @@ SELECT NULLIF(value, '(none)') ...
<entry><literal>
array_dims(ARRAY[[1,2,3], [4,5,6]])
</literal></entry>
<entry><literal>
[1:2][1:3]
</literal></entry>
</row>
<row>
<entry>
<literal>
<function>
array_fill
</function>
(
<type>
anyelement
</type>
,
<type>
anyarray
</type>
,
<optional>
,
<type>
anyarray
</type></optional>
)
</literal>
</entry>
<entry><type>
anyarray
</type></entry>
<entry>
returns an array initialized with supplied value,
dimensions, and lower bounds
</entry>
<entry><literal>
array_fill(7, ARRAY[3], ARRAY[2])
</literal></entry>
<entry><literal>
[2:4]={7,7,7}
</literal></entry>
</row>
<row>
<entry>
<literal>
...
...
src/backend/utils/adt/arrayfuncs.c
View file @
2c773296
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.14
5 2008/05/12 00:00:51 alvherre
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.14
6 2008/07/16 00:48:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -95,6 +95,11 @@ static void array_insert_slice(ArrayType *destArray, ArrayType *origArray,
int
*
st
,
int
*
endp
,
int
typlen
,
bool
typbyval
,
char
typalign
);
static
int
array_cmp
(
FunctionCallInfo
fcinfo
);
static
ArrayType
*
create_array_envelope
(
int
ndims
,
int
*
dimv
,
int
*
lbv
,
int
nbytes
,
Oid
elmtype
,
int
dataoffset
);
static
ArrayType
*
array_fill_internal
(
ArrayType
*
dims
,
ArrayType
*
lbs
,
Datum
value
,
Oid
elmtype
,
bool
isnull
,
FunctionCallInfo
fcinfo
);
/*
...
...
@@ -4314,3 +4319,272 @@ generate_subscripts_nodir(PG_FUNCTION_ARGS)
/* just call the other one -- it can handle both cases */
return
generate_subscripts
(
fcinfo
);
}
/*
* array_fill_with_lower_bounds
* Create and fill array with defined lower bounds.
*/
Datum
array_fill_with_lower_bounds
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
dims
;
ArrayType
*
lbs
;
ArrayType
*
result
;
Oid
elmtype
;
Datum
value
;
bool
isnull
;
if
(
PG_ARGISNULL
(
1
)
||
PG_ARGISNULL
(
2
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension array or low bound array cannot be NULL"
)));
dims
=
PG_GETARG_ARRAYTYPE_P
(
1
);
lbs
=
PG_GETARG_ARRAYTYPE_P
(
2
);
if
(
!
PG_ARGISNULL
(
0
))
{
value
=
PG_GETARG_DATUM
(
0
);
isnull
=
false
;
}
else
{
value
=
0
;
isnull
=
true
;
}
elmtype
=
get_fn_expr_argtype
(
fcinfo
->
flinfo
,
0
);
if
(
!
OidIsValid
(
elmtype
))
elog
(
ERROR
,
"could not determine data type of input"
);
result
=
array_fill_internal
(
dims
,
lbs
,
value
,
elmtype
,
isnull
,
fcinfo
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
/*
* array_fill
* Create and fill array with default lower bounds.
*/
Datum
array_fill
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
dims
;
ArrayType
*
result
;
Oid
elmtype
;
Datum
value
;
bool
isnull
;
if
(
PG_ARGISNULL
(
1
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension array or low bound array cannot be NULL"
)));
dims
=
PG_GETARG_ARRAYTYPE_P
(
1
);
if
(
!
PG_ARGISNULL
(
0
))
{
value
=
PG_GETARG_DATUM
(
0
);
isnull
=
false
;
}
else
{
value
=
0
;
isnull
=
true
;
}
elmtype
=
get_fn_expr_argtype
(
fcinfo
->
flinfo
,
0
);
if
(
!
OidIsValid
(
elmtype
))
elog
(
ERROR
,
"could not determine data type of input"
);
result
=
array_fill_internal
(
dims
,
NULL
,
value
,
elmtype
,
isnull
,
fcinfo
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
static
ArrayType
*
create_array_envelope
(
int
ndims
,
int
*
dimv
,
int
*
lbsv
,
int
nbytes
,
Oid
elmtype
,
int
dataoffset
)
{
ArrayType
*
result
;
result
=
(
ArrayType
*
)
palloc0
(
nbytes
);
SET_VARSIZE
(
result
,
nbytes
);
result
->
ndim
=
ndims
;
result
->
dataoffset
=
dataoffset
;
result
->
elemtype
=
elmtype
;
memcpy
(
ARR_DIMS
(
result
),
dimv
,
ndims
*
sizeof
(
int
));
memcpy
(
ARR_LBOUND
(
result
),
lbsv
,
ndims
*
sizeof
(
int
));
return
result
;
}
static
ArrayType
*
array_fill_internal
(
ArrayType
*
dims
,
ArrayType
*
lbs
,
Datum
value
,
Oid
elmtype
,
bool
isnull
,
FunctionCallInfo
fcinfo
)
{
ArrayType
*
result
;
int
*
dimv
;
int
*
lbsv
;
int
ndims
;
int
nitems
;
int
deflbs
[
MAXDIM
];
int16
elmlen
;
bool
elmbyval
;
char
elmalign
;
ArrayMetaState
*
my_extra
;
/*
* Params checks
*/
if
(
ARR_NDIM
(
dims
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array subscripts"
),
errhint
(
"Dimension array must be one dimensional."
)));
if
(
ARR_LBOUND
(
dims
)[
0
]
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong range of array_subscripts"
),
errhint
(
"Lower bound of dimension array must be one."
)));
if
(
ARR_HASNULL
(
dims
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension values cannot be null"
)));
dimv
=
(
int
*
)
ARR_DATA_PTR
(
dims
);
ndims
=
ARR_DIMS
(
dims
)[
0
];
if
(
ndims
<
0
)
/* we do allow zero-dimension arrays */
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid number of dimensions: %d"
,
ndims
)));
if
(
ndims
>
MAXDIM
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
errmsg
(
"number of array dimensions (%d) exceeds the maximum allowed (%d)"
,
ndims
,
MAXDIM
)));
if
(
lbs
!=
NULL
)
{
if
(
ARR_NDIM
(
lbs
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array subscripts"
),
errhint
(
"Dimension array must be one dimensional."
)));
if
(
ARR_LBOUND
(
lbs
)[
0
]
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong range of array_subscripts"
),
errhint
(
"Lower bound of dimension array must be one."
)));
if
(
ARR_HASNULL
(
lbs
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension values cannot be null"
)));
if
(
ARR_DIMS
(
lbs
)[
0
]
!=
ndims
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array_subscripts"
),
errhint
(
"Low bound array has different size than dimensions array."
)));
lbsv
=
(
int
*
)
ARR_DATA_PTR
(
lbs
);
}
else
{
int
i
;
for
(
i
=
0
;
i
<
MAXDIM
;
i
++
)
deflbs
[
i
]
=
1
;
lbsv
=
deflbs
;
}
/* fast track for empty array */
if
(
ndims
==
0
)
return
construct_empty_array
(
elmtype
);
nitems
=
ArrayGetNItems
(
ndims
,
dimv
);
/*
* We arrange to look up info about element type only once per series of
* calls, assuming the element type doesn't change underneath us.
*/
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
if
(
my_extra
==
NULL
)
{
fcinfo
->
flinfo
->
fn_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
}
if
(
my_extra
->
element_type
!=
elmtype
)
{
/* Get info about element type */
get_typlenbyvalalign
(
elmtype
,
&
my_extra
->
typlen
,
&
my_extra
->
typbyval
,
&
my_extra
->
typalign
);
my_extra
->
element_type
=
elmtype
;
}
elmlen
=
my_extra
->
typlen
;
elmbyval
=
my_extra
->
typbyval
;
elmalign
=
my_extra
->
typalign
;
/* compute required space */
if
(
!
isnull
)
{
int
i
;
char
*
p
;
int
nbytes
;
Datum
aux_value
=
value
;
/* make sure data is not toasted */
if
(
elmlen
==
-
1
)
value
=
PointerGetDatum
(
PG_DETOAST_DATUM
(
value
));
nbytes
=
att_addlength_datum
(
0
,
elmlen
,
value
);
nbytes
=
att_align_nominal
(
nbytes
,
elmalign
);
nbytes
*=
nitems
;
/* check for overflow of total request */
if
(
!
AllocSizeIsValid
(
nbytes
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
errmsg
(
"array size exceeds the maximum allowed (%d)"
,
(
int
)
MaxAllocSize
)));
nbytes
+=
ARR_OVERHEAD_NONULLS
(
ndims
);
result
=
create_array_envelope
(
ndims
,
dimv
,
lbsv
,
nbytes
,
elmtype
,
0
);
p
=
ARR_DATA_PTR
(
result
);
for
(
i
=
0
;
i
<
nitems
;
i
++
)
p
+=
ArrayCastAndSet
(
value
,
elmlen
,
elmbyval
,
elmalign
,
p
);
/* cleaning up detoasted copies of datum */
if
(
aux_value
!=
value
)
pfree
((
Pointer
)
value
);
}
else
{
int
nbytes
;
int
dataoffset
;
bits8
*
bitmap
;
dataoffset
=
ARR_OVERHEAD_WITHNULLS
(
ndims
,
nitems
);
nbytes
=
dataoffset
;
result
=
create_array_envelope
(
ndims
,
dimv
,
lbsv
,
nbytes
,
elmtype
,
dataoffset
);
bitmap
=
ARR_NULLBITMAP
(
result
);
MemSet
(
bitmap
,
0
,
(
nitems
+
7
)
/
8
);
}
return
result
;
}
src/include/catalog/catversion.h
View file @
2c773296
...
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.46
7 2008/07/14 00:51:45 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.46
8 2008/07/16 00:48:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 2008071
3
1
#define CATALOG_VERSION_NO 2008071
5
1
#endif
src/include/catalog/pg_proc.h
View file @
2c773296
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.50
5 2008/07/14 00:51:45 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.50
6 2008/07/16 00:48:53 momjian
Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
...
...
@@ -1010,8 +1010,10 @@ DATA(insert OID = 1191 ( generate_subscripts PGNSP PGUID 12 1 1000 f f t t i 3
DESCR
(
"array subscripts generator"
);
DATA
(
insert
OID
=
1192
(
generate_subscripts
PGNSP
PGUID
12
1
1000
f
f
t
t
i
2
23
"2277 23"
_null_
_null_
_null_
generate_subscripts_nodir
-
_null_
_null_
));
DESCR
(
"array subscripts generator"
);
DATA
(
insert
OID
=
1193
(
array_fill
PGNSP
PGUID
12
1
0
f
f
f
f
i
2
2277
"2283 1007"
_null_
_null_
_null_
array_fill
-
_null_
_null_
));
DESCR
(
"array constructor with value"
);
DATA
(
insert
OID
=
1286
(
array_fill
PGNSP
PGUID
12
1
0
f
f
f
f
i
3
2277
"2283 1007 1007"
_null_
_null_
_null_
array_fill_with_lower_bounds
-
_null_
_null_
));
DESCR
(
"array constructor with value"
);
DATA
(
insert
OID
=
760
(
smgrin
PGNSP
PGUID
12
1
0
f
f
t
f
s
1
210
"2275"
_null_
_null_
_null_
smgrin
-
_null_
_null_
));
DESCR
(
"I/O"
);
DATA
(
insert
OID
=
761
(
smgrout
PGNSP
PGUID
12
1
0
f
f
t
f
s
1
2275
"210"
_null_
_null_
_null_
smgrout
-
_null_
_null_
));
...
...
src/include/utils/array.h
View file @
2c773296
...
...
@@ -49,7 +49,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.6
7 2008/04/28 14:48:57 alvherre
Exp $
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.6
8 2008/07/16 00:48:54 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -202,6 +202,8 @@ extern Datum array_larger(PG_FUNCTION_ARGS);
extern
Datum
array_smaller
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_subscripts
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_subscripts_nodir
(
PG_FUNCTION_ARGS
);
extern
Datum
array_fill
(
PG_FUNCTION_ARGS
);
extern
Datum
array_fill_with_lower_bounds
(
PG_FUNCTION_ARGS
);
extern
Datum
array_ref
(
ArrayType
*
array
,
int
nSubscripts
,
int
*
indx
,
int
arraytyplen
,
int
elmlen
,
bool
elmbyval
,
char
elmalign
,
...
...
src/test/regress/expected/arrays.out
View file @
2c773296
...
...
@@ -933,3 +933,61 @@ select * from unnest2(array[[1,2,3],[4,5,6]]);
drop function unnest1(anyarray);
drop function unnest2(anyarray);
select array_fill(null::integer, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::integer, array[3,3]);
array_fill
------------------------------------------------------
{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::text, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::text, array[3,3]);
array_fill
------------------------------------------------------
{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(7, array[3,3],array[2,2]);
array_fill
--------------------------------------
[2:4][2:4]={{7,7,7},{7,7,7},{7,7,7}}
(1 row)
select array_fill(7, array[3,3]);
array_fill
---------------------------
{{7,7,7},{7,7,7},{7,7,7}}
(1 row)
select array_fill('juhu'::text, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
(1 row)
select array_fill('juhu'::text, array[3,3]);
array_fill
------------------------------------------------------
{{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
(1 row)
-- raise exception
select array_fill(1, null, array[2,2]);
ERROR: dimension array or low bound array cannot be NULL
select array_fill(1, array[2,2], null);
ERROR: dimension array or low bound array cannot be NULL
select array_fill(1, array[3,3], array[1,1,1]);
ERROR: wrong number of array_subscripts
HINT: Low bound array has different size than dimensions array.
select array_fill(1, array[1,2,null]);
ERROR: dimension values cannot be null
src/test/regress/sql/arrays.sql
View file @
2c773296
...
...
@@ -357,3 +357,17 @@ select * from unnest2(array[[1,2,3],[4,5,6]]);
drop
function
unnest1
(
anyarray
);
drop
function
unnest2
(
anyarray
);
select
array_fill
(
null
::
integer
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
null
::
integer
,
array
[
3
,
3
]);
select
array_fill
(
null
::
text
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
null
::
text
,
array
[
3
,
3
]);
select
array_fill
(
7
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
7
,
array
[
3
,
3
]);
select
array_fill
(
'juhu'
::
text
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
'juhu'
::
text
,
array
[
3
,
3
]);
-- raise exception
select
array_fill
(
1
,
null
,
array
[
2
,
2
]);
select
array_fill
(
1
,
array
[
2
,
2
],
null
);
select
array_fill
(
1
,
array
[
3
,
3
],
array
[
1
,
1
,
1
]);
select
array_fill
(
1
,
array
[
1
,
2
,
null
]);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment