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
111d8e52
Commit
111d8e52
authored
Jun 25, 2003
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Back out array mega-patch.
Joe Conway
parent
621691d8
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
676 additions
and
2615 deletions
+676
-2615
doc/src/sgml/array.sgml
doc/src/sgml/array.sgml
+9
-278
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+1
-198
src/backend/catalog/pg_aggregate.c
src/backend/catalog/pg_aggregate.c
+19
-80
src/backend/commands/aggregatecmds.c
src/backend/commands/aggregatecmds.c
+2
-4
src/backend/executor/execQual.c
src/backend/executor/execQual.c
+4
-4
src/backend/executor/nodeAgg.c
src/backend/executor/nodeAgg.c
+12
-211
src/backend/executor/nodeSubplan.c
src/backend/executor/nodeSubplan.c
+226
-272
src/backend/nodes/copyfuncs.c
src/backend/nodes/copyfuncs.c
+1
-9
src/backend/nodes/equalfuncs.c
src/backend/nodes/equalfuncs.c
+1
-9
src/backend/nodes/outfuncs.c
src/backend/nodes/outfuncs.c
+1
-9
src/backend/nodes/readfuncs.c
src/backend/nodes/readfuncs.c
+1
-3
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/plan/subselect.c
+14
-49
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/clauses.c
+1
-23
src/backend/parser/gram.y
src/backend/parser/gram.y
+1
-38
src/backend/parser/parse_coerce.c
src/backend/parser/parse_coerce.c
+3
-16
src/backend/parser/parse_expr.c
src/backend/parser/parse_expr.c
+6
-28
src/backend/parser/parse_func.c
src/backend/parser/parse_func.c
+1
-2
src/backend/parser/parse_oper.c
src/backend/parser/parse_oper.c
+1
-70
src/backend/utils/adt/acl.c
src/backend/utils/adt/acl.c
+1
-10
src/backend/utils/adt/array_userfuncs.c
src/backend/utils/adt/array_userfuncs.c
+186
-103
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/arrayfuncs.c
+94
-730
src/backend/utils/adt/varlena.c
src/backend/utils/adt/varlena.c
+5
-191
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/lsyscache.c
+1
-85
src/backend/utils/fmgr/fmgr.c
src/backend/utils/fmgr/fmgr.c
+1
-27
src/include/catalog/pg_amop.h
src/include/catalog/pg_amop.h
+1
-10
src/include/catalog/pg_amproc.h
src/include/catalog/pg_amproc.h
+1
-2
src/include/catalog/pg_opclass.h
src/include/catalog/pg_opclass.h
+1
-3
src/include/catalog/pg_operator.h
src/include/catalog/pg_operator.h
+5
-11
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+12
-21
src/include/fmgr.h
src/include/fmgr.h
+5
-6
src/include/nodes/primnodes.h
src/include/nodes/primnodes.h
+4
-20
src/include/optimizer/clauses.h
src/include/optimizer/clauses.h
+1
-4
src/include/parser/parse_oper.h
src/include/parser/parse_oper.h
+1
-2
src/include/utils/acl.h
src/include/utils/acl.h
+1
-2
src/include/utils/array.h
src/include/utils/array.h
+7
-48
src/include/utils/builtins.h
src/include/utils/builtins.h
+1
-3
src/include/utils/lsyscache.h
src/include/utils/lsyscache.h
+1
-19
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/preproc.y
+4
-4
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/type.c
+1
-1
src/interfaces/ecpg/preproc/variable.c
src/interfaces/ecpg/preproc/variable.c
+6
-6
src/test/regress/expected/arrays.out
src/test/regress/expected/arrays.out
+26
-2
src/test/regress/sql/arrays.sql
src/test/regress/sql/arrays.sql
+6
-2
No files found.
doc/src/sgml/array.sgml
View file @
111d8e52
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/array.sgml,v 1.2
6 2003/06/24 23:14:42
momjian Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/array.sgml,v 1.2
7 2003/06/25 21:30:25
momjian Exp $ -->
<sect1 id="arrays">
<sect1 id="arrays">
<title>Arrays</title>
<title>Arrays</title>
...
@@ -60,74 +60,14 @@ INSERT INTO sal_emp
...
@@ -60,74 +60,14 @@ INSERT INTO sal_emp
</programlisting>
</programlisting>
</para>
</para>
<para>
A limitation of the present array implementation is that individual
elements of an array cannot be SQL null values. The entire array can be set
to null, but you can't have an array with some elements null and some
not.
</para>
<para>
This can lead to surprising results. For example, the result of the
previous two inserts looks like this:
<programlisting>
SELECT * FROM sal_emp;
name | pay_by_quarter | schedule
-------+---------------------------+--------------------
Bill | {10000,10000,10000,10000} | {{meeting},{""}}
Carol | {20000,25000,25000,25000} | {{talk},{meeting}}
(2 rows)
</programlisting>
Because the <literal>[2][2]</literal> element of
<structfield>schedule</structfield> is missing in each of the
<command>INSERT</command> statements, the <literal>[1][2]</literal>
element is discarded.
</para>
<note>
<note>
<para>
<para>
Fixing this is on the to-do list.
A limitation of the present array implementation is that individual
elements of an array cannot be SQL null values. The entire array can be set
to null, but you can't have an array with some elements null and some
not. Fixing this is on the to-do list.
</para>
</para>
</note>
</note>
<para>
The <command>ARRAY</command> expression syntax may also be used:
<programlisting>
INSERT INTO sal_emp
VALUES ('Bill',
ARRAY[10000, 10000, 10000, 10000],
ARRAY[['meeting', 'lunch'], ['','']]);
INSERT INTO sal_emp
VALUES ('Carol',
ARRAY[20000, 25000, 25000, 25000],
ARRAY[['talk', 'consult'], ['meeting', '']]);
SELECT * FROM sal_emp;
name | pay_by_quarter | schedule
-------+---------------------------+-------------------------------
Bill | {10000,10000,10000,10000} | {{meeting,lunch},{"",""}}
Carol | {20000,25000,25000,25000} | {{talk,consult},{meeting,""}}
(2 rows)
</programlisting>
Note that with this syntax, multidimensional arrays must have matching
extents for each dimension. This eliminates the missing-array-elements
problem above. For example:
<programlisting>
INSERT INTO sal_emp
VALUES ('Carol',
ARRAY[20000, 25000, 25000, 25000],
ARRAY[['talk', 'consult'], ['meeting']]);
ERROR: Multidimensional arrays must have array expressions with matching dimensions
</programlisting>
Also notice that string literals are single quoted instead of double quoted.
</para>
<note>
<para>
The examples in the rest of this section are based on the
<command>ARRAY</command> expression syntax <command>INSERT</command>s.
</para>
</note>
</sect2>
</sect2>
<sect2>
<sect2>
...
@@ -192,30 +132,11 @@ SELECT schedule[1:2][1] FROM sal_emp WHERE name = 'Bill';
...
@@ -192,30 +132,11 @@ SELECT schedule[1:2][1] FROM sal_emp WHERE name = 'Bill';
</programlisting>
</programlisting>
with the same result. An array subscripting operation is always taken to
with the same result. An array subscripting operation is always taken to
represent an array slice if any of the subscripts are written in the form
represent an array slice if any of the subscripts are written in the
form
<literal><replaceable>lower</replaceable>:<replaceable>upper</replaceable></literal>.
<literal><replaceable>lower</replaceable>:<replaceable>upper</replaceable></literal>.
A lower bound of 1 is assumed for any subscript where only one value
A lower bound of 1 is assumed for any subscript where only one value
is specified; another example follows:
is specified.
<programlisting>
SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
schedule
---------------------------
{{meeting,lunch},{"",""}}
(1 row)
</programlisting>
</para>
<para>
Additionally, we can also access a single arbitrary array element of
a one-dimensional array with the <function>array_subscript</function>
function:
<programlisting>
SELECT array_subscript(pay_by_quarter, 2) FROM sal_emp WHERE name = 'Bill';
array_subscript
-----------------
10000
(1 row)
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -226,23 +147,7 @@ UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
...
@@ -226,23 +147,7 @@ UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Carol';
WHERE name = 'Carol';
</programlisting>
</programlisting>
or using the <command>ARRAY</command> expression syntax:
or updated at a single element:
<programlisting>
UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Carol';
</programlisting>
<note>
<para>
Anywhere you can use the <quote>curly braces</quote> array syntax,
you can also use the <command>ARRAY</command> expression syntax. The
remainder of this section will illustrate only one or the other, but
not both.
</para>
</note>
An array may also be updated at a single element:
<programlisting>
<programlisting>
UPDATE sal_emp SET pay_by_quarter[4] = 15000
UPDATE sal_emp SET pay_by_quarter[4] = 15000
...
@@ -255,14 +160,6 @@ UPDATE sal_emp SET pay_by_quarter[4] = 15000
...
@@ -255,14 +160,6 @@ UPDATE sal_emp SET pay_by_quarter[4] = 15000
UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
WHERE name = 'Carol';
WHERE name = 'Carol';
</programlisting>
</programlisting>
A one-dimensional array may also be updated with the
<function>array_assign</function> function:
<programlisting>
UPDATE sal_emp SET pay_by_quarter = array_assign(pay_by_quarter, 4, 15000)
WHERE name = 'Bill';
</programListing>
</para>
</para>
<para>
<para>
...
@@ -281,88 +178,6 @@ UPDATE sal_emp SET pay_by_quarter = array_assign(pay_by_quarter, 4, 15000)
...
@@ -281,88 +178,6 @@ UPDATE sal_emp SET pay_by_quarter = array_assign(pay_by_quarter, 4, 15000)
create an array with subscript values running from -2 to 7.
create an array with subscript values running from -2 to 7.
</para>
</para>
<para>
An array can also be enlarged by using the concatenation operator,
<command>||</command>.
<programlisting>
SELECT ARRAY[1,2] || ARRAY[3,4];
?column?
---------------
{{1,2},{3,4}}
(1 row)
SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
?column?
---------------------
{{5,6},{1,2},{3,4}}
(1 row)
</programlisting>
The concatenation operator allows a single element to be pushed on to the
beginning or end of a one-dimensional array. It also allows two
<replaceable>N</>-dimensional arrays, or an <replaceable>N</>-dimensional
and an <replaceable>N+1</>-dimensional array. In the former case, the two
<replaceable>N</>-dimension arrays become outer elements of an
<replaceable>N+1</>-dimensional array. In the latter, the
<replaceable>N</>-dimensional array is added as either the first or last
outer element of the <replaceable>N+1</>-dimensional array.
The array is extended in the direction of the push. Hence, by pushing
onto the beginning of an array with a one-based subscript, a zero-based
subscript array is created:
<programlisting>
SELECT array_dims(t.f) FROM (SELECT 1 || ARRAY[2,3] AS f) AS t;
array_dims
------------
[0:2]
(1 row)
</programlisting>
</para>
<para>
An array can also be enlarged by using the functions
<function>array_prepend</function>, <function>array_append</function>,
or <function>array_cat</function>. The first two only support one-dimensional
arrays, but <function>array_cat</function> supports multidimensional arrays.
Note that the concatenation operator discussed above is preferred over
direct use of these functions. In fact, the functions are primarily for use
in implementing the concatenation operator. However, they may be directly
useful in the creation of user-defined aggregates. Some examples:
<programlisting>
SELECT array_prepend(1, ARRAY[2,3]);
array_prepend
---------------
{1,2,3}
(1 row)
SELECT array_append(ARRAY[1,2], 3);
array_append
--------------
{1,2,3}
(1 row)
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
array_cat
---------------
{{1,2},{3,4}}
(1 row)
SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
array_cat
---------------------
{{1,2},{3,4},{5,6}}
(1 row)
SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]);
array_cat
---------------------
{{5,6},{1,2},{3,4}}
</programlisting>
</para>
<para>
<para>
The syntax for <command>CREATE TABLE</command> allows fixed-length
The syntax for <command>CREATE TABLE</command> allows fixed-length
arrays to be defined:
arrays to be defined:
...
@@ -378,16 +193,6 @@ CREATE TABLE tictactoe (
...
@@ -378,16 +193,6 @@ CREATE TABLE tictactoe (
length.
length.
</para>
</para>
<para>
An alternative syntax for one-dimensional arrays may be used.
<structfield>pay_by_quarter</structfield> could have been defined as:
<programlisting>
pay_by_quarter integer ARRAY[4],
</programlisting>
This syntax may <emphasis>only</emphasis> be used with the integer
constant to denote the array size.
</para>
<para>
<para>
Actually, the current implementation does not enforce the declared
Actually, the current implementation does not enforce the declared
number of dimensions either. Arrays of a particular element type are
number of dimensions either. Arrays of a particular element type are
...
@@ -495,72 +300,6 @@ SELECT * FROM sal_emp WHERE pay_by_quarter **= 10000;
...
@@ -495,72 +300,6 @@ SELECT * FROM sal_emp WHERE pay_by_quarter **= 10000;
is not ignored, however: after skipping leading whitespace, everything
is not ignored, however: after skipping leading whitespace, everything
up to the next right brace or delimiter is taken as the item value.
up to the next right brace or delimiter is taken as the item value.
</para>
</para>
<para>
As illustrated earlier in this chapter, arrays may also be represented
using the <command>ARRAY</command> expression syntax. This representation
of an array value consists of items that are interpreted according to the
I/O conversion rules for the array's element type, plus decoration that
indicates the array structure. The decoration consists of the keyword
<command>ARRAY</command> and square brackets (<literal>[</> and
<literal>]</>) around the array values, plus delimiter characters between
adjacent items. The delimiter character is always a comma (<literal>,</>).
When representing multidimensional arrays, the keyword
<command>ARRAY</command> is only necessary for the outer level. For example,
<literal>'{{"hello world", "happy birthday"}}'</literal> could be written as:
<programlisting>
SELECT ARRAY[['hello world', 'happy birthday']];
array
------------------------------------
{{"hello world","happy birthday"}}
(1 row)
</programlisting>
or it also could be written as:
<programlisting>
SELECT ARRAY[ARRAY['hello world', 'happy birthday']];
array
------------------------------------
{{"hello world","happy birthday"}}
(1 row)
</programlisting>
</para>
<para>
A final method to represent an array, is through an
<command>ARRAY</command> sub-select expression. For example:
<programlisting>
SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
?column?
-------------------------------------------------------------
{2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31}
(1 row)
</programlisting>
The sub-select may <emphasis>only</emphasis> return a single column. The
resulting one-dimensional array will have an element for each row in the
sub-select result, with an element type matching that of the sub-select's
target column.
</para>
<para>
Arrays may be cast from one type to another in similar fashion to other
data types:
<programlisting>
SELECT ARRAY[1,2,3]::oid[];
array
---------
{1,2,3}
(1 row)
SELECT CAST(ARRAY[1,2,3] AS float8[]);
array
---------
{1,2,3}
(1 row)
</programlisting>
</para>
</sect2>
</sect2>
<sect2>
<sect2>
...
@@ -578,14 +317,6 @@ SELECT CAST(ARRAY[1,2,3] AS float8[]);
...
@@ -578,14 +317,6 @@ SELECT CAST(ARRAY[1,2,3] AS float8[]);
that would otherwise be taken as array syntax or ignorable white space.
that would otherwise be taken as array syntax or ignorable white space.
</para>
</para>
<note>
<para>
The discussion in the preceding paragraph with respect to double quoting does
not pertain to the <command>ARRAY</command> expression syntax. In that case,
each element is quoted exactly as any other literal value of the element type.
</para>
</note>
<para>
<para>
The array output routine will put double quotes around element values
The array output routine will put double quotes around element values
if they are empty strings or contain curly braces, delimiter characters,
if they are empty strings or contain curly braces, delimiter characters,
...
...
doc/src/sgml/func.sgml
View file @
111d8e52
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.15
5 2003/06/24 23:14:42
momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.15
6 2003/06/25 21:30:25
momjian Exp $
PostgreSQL documentation
PostgreSQL documentation
-->
-->
...
@@ -6962,203 +6962,6 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
...
@@ -6962,203 +6962,6 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
</sect1>
</sect1>
<sect1 id="functions-array">
<title>Array Functions</title>
<para>
<xref linkend="array-operators-table"> shows the operators
available for the <type>array</type> types.
</para>
<table id="array-operators-table">
<title><type>array</type> Operators</title>
<tgroup cols="4">
<thead>
<row>
<entry>Operator</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
</row>
</thead>
<tbody>
<row>
<entry> <literal>=</literal> </entry>
<entry>equals</entry>
<entry><literal>ARRAY[1.1,2.1,3.1]::int[] = ARRAY[1,2,3]</literal></entry>
<entry><literal>t</literal></entry>
</row>
<row>
<entry> <literal>||</literal> </entry>
<entry>array-to-array concatenation</entry>
<entry><literal>ARRAY[1,2,3] || ARRAY[4,5,6]</literal></entry>
<entry><literal>{{1,2,3},{4,5,6}}</literal></entry>
</row>
<row>
<entry> <literal>||</literal> </entry>
<entry>array-to-array concatenation</entry>
<entry><literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9]]</literal></entry>
<entry><literal>{{1,2,3},{4,5,6},{7,8,9}}</literal></entry>
</row>
<row>
<entry> <literal>||</literal> </entry>
<entry>element-to-array concatenation</entry>
<entry><literal>3 || ARRAY[4,5,6]</literal></entry>
<entry><literal>{3,4,5,6}</literal></entry>
</row>
<row>
<entry> <literal>||</literal> </entry>
<entry>array-to-element concatenation</entry>
<entry><literal>ARRAY[4,5,6] || 7</literal></entry>
<entry><literal>{4,5,6,7}</literal></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
<xref linkend="array-functions-table"> shows the functions
available for use with array types. See <xref linkend="arrays">
for more discussion and examples for the use of these functions.
</para>
<table id="array-functions-table">
<title><type>array</type> Functions</title>
<tgroup cols="5">
<thead>
<row>
<entry>Function</entry>
<entry>Return Type</entry>
<entry>Description</entry>
<entry>Example</entry>
<entry>Result</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<literal>
<function>array_append</function>
(<type>anyarray</type>, <type>anyelement</type>)
</literal>
</entry>
<entry><type>anyarray</type></entry>
<entry>
append an element to the end of an array, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_append(ARRAY[1,2], 3)</literal></entry>
<entry><literal>{1,2,3}</literal></entry>
</row>
<row>
<entry>
<literal>
<function>array_cat</function>
(<type>anyarray</type>, <type>anyarray</type>)
</literal>
</entry>
<entry><type>anyarray</type></entry>
<entry>
concatenate two arrays, returning <literal>NULL</literal>
for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_cat(ARRAY[1,2,3], ARRAY[4,5,6])</literal></entry>
<entry><literal>{{1,2,3},{4,5,6}}</literal></entry>
</row>
<row>
<entry>
<literal>
<function>array_dims</function>
(<type>anyarray</type>)
</literal>
</entry>
<entry><type>text</type></entry>
<entry>
returns a text representation of array dimension lower and upper bounds,
generating an ERROR for <literal>NULL</literal> inputs
</entry>
<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_lower</function>
(<type>anyarray</type>, <type>integer</type>)
</literal>
</entry>
<entry><type>integer</type></entry>
<entry>
returns lower bound of the requested array dimension, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_lower(array_prepend(0, ARRAY[1,2,3]), 1)</literal></entry>
<entry><literal>0</literal></entry>
</row>
<row>
<entry>
<literal>
<function>array_prepend</function>
(<type>anyelement</type>, <type>anyarray</type>)
</literal>
</entry>
<entry><type>anyarray</type></entry>
<entry>
append an element to the beginning of an array, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
<entry><literal>{1,2,3}</literal></entry>
</row>
<row>
<entry>
<literal>
<function>array_to_string</function>
(<type>anyarray</type>, <type>text</type>)
</literal>
</entry>
<entry><type>text</type></entry>
<entry>
concatenates array elements using provided delimiter, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_to_string(array[1.1,2.2,3.3]::numeric(4,2)[],'~^~')</literal></entry>
<entry><literal>1.10~^~2.20~^~3.30</literal></entry>
</row>
<row>
<entry>
<literal>
<function>array_upper</function>
(<type>anyarray</type>, <type>integer</type>)
</literal>
</entry>
<entry><type>integer</type></entry>
<entry>
returns upper bound of the requested array dimension, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>array_upper(array_append(ARRAY[1,2,3], 4), 1)</literal></entry>
<entry><literal>4</literal></entry>
</row>
<row>
<entry>
<literal>
<function>string_to_array</function>
(<type>text</type>, <type>text</type>)
</literal>
</entry>
<entry><type>text[]</type></entry>
<entry>
splits string into array elements using provided delimiter, returning
<literal>NULL</literal> for <literal>NULL</literal> inputs
</entry>
<entry><literal>string_to_array('1.10~^~2.20~^~3.30','~^~')::float8[]</literal></entry>
<entry><literal>{1.1,2.2,3.3}</literal></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="functions-aggregate">
<sect1 id="functions-aggregate">
<title>Aggregate Functions</title>
<title>Aggregate Functions</title>
...
...
src/backend/catalog/pg_aggregate.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.5
7 2003/06/24 23:14:42
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.5
8 2003/06/25 21:30:25
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -50,16 +50,10 @@ AggregateCreate(const char *aggName,
...
@@ -50,16 +50,10 @@ AggregateCreate(const char *aggName,
Oid
finalfn
=
InvalidOid
;
/* can be omitted */
Oid
finalfn
=
InvalidOid
;
/* can be omitted */
Oid
finaltype
;
Oid
finaltype
;
Oid
fnArgs
[
FUNC_MAX_ARGS
];
Oid
fnArgs
[
FUNC_MAX_ARGS
];
int
nargs_transfn
;
int
nargs
;
int
nargs_finalfn
;
Oid
procOid
;
Oid
procOid
;
TupleDesc
tupDesc
;
TupleDesc
tupDesc
;
int
i
;
int
i
;
Oid
rettype
;
Oid
*
true_oid_array_transfn
;
Oid
*
true_oid_array_finalfn
;
bool
retset
;
FuncDetailCode
fdresult
;
ObjectAddress
myself
,
ObjectAddress
myself
,
referenced
;
referenced
;
...
@@ -74,49 +68,24 @@ AggregateCreate(const char *aggName,
...
@@ -74,49 +68,24 @@ AggregateCreate(const char *aggName,
MemSet
(
fnArgs
,
0
,
FUNC_MAX_ARGS
*
sizeof
(
Oid
));
MemSet
(
fnArgs
,
0
,
FUNC_MAX_ARGS
*
sizeof
(
Oid
));
fnArgs
[
0
]
=
aggTransType
;
fnArgs
[
0
]
=
aggTransType
;
if
(
aggBaseType
==
ANYOID
)
if
(
aggBaseType
==
ANYOID
)
nargs
_transfn
=
1
;
nargs
=
1
;
else
else
{
{
fnArgs
[
1
]
=
aggBaseType
;
fnArgs
[
1
]
=
aggBaseType
;
nargs
_transfn
=
2
;
nargs
=
2
;
}
}
transfn
=
LookupFuncName
(
aggtransfnName
,
nargs
,
fnArgs
);
/*
* func_get_detail looks up the function in the catalogs, does
* disambiguation for polymorphic functions, handles inheritance, and
* returns the funcid and type and set or singleton status of the
* function's return value. it also returns the true argument types
* to the function.
*/
fdresult
=
func_get_detail
(
aggtransfnName
,
NIL
,
nargs_transfn
,
fnArgs
,
&
transfn
,
&
rettype
,
&
retset
,
&
true_oid_array_transfn
);
/* only valid case is a normal function */
if
(
fdresult
!=
FUNCDETAIL_NORMAL
)
func_error
(
"AggregateCreate"
,
aggtransfnName
,
nargs_transfn
,
fnArgs
,
NULL
);
if
(
!
OidIsValid
(
transfn
))
if
(
!
OidIsValid
(
transfn
))
func_error
(
"AggregateCreate"
,
aggtransfnName
,
nargs_transfn
,
fnArgs
,
NULL
);
func_error
(
"AggregateCreate"
,
aggtransfnName
,
nargs
,
fnArgs
,
NULL
);
/*
* enforce consistency with ANYARRAY and ANYELEMENT argument
* and return types, possibly modifying return type along the way
*/
rettype
=
enforce_generic_type_consistency
(
fnArgs
,
true_oid_array_transfn
,
nargs_transfn
,
rettype
);
if
(
rettype
!=
aggTransType
)
elog
(
ERROR
,
"return type of transition function %s is not %s"
,
NameListToString
(
aggtransfnName
),
format_type_be
(
aggTransType
));
tup
=
SearchSysCache
(
PROCOID
,
tup
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
transfn
),
ObjectIdGetDatum
(
transfn
),
0
,
0
,
0
);
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
tup
))
if
(
!
HeapTupleIsValid
(
tup
))
func_error
(
"AggregateCreate"
,
aggtransfnName
,
func_error
(
"AggregateCreate"
,
aggtransfnName
,
nargs
,
fnArgs
,
NULL
);
nargs_transfn
,
fnArgs
,
NULL
);
proc
=
(
Form_pg_proc
)
GETSTRUCT
(
tup
);
proc
=
(
Form_pg_proc
)
GETSTRUCT
(
tup
);
if
(
proc
->
prorettype
!=
aggTransType
)
elog
(
ERROR
,
"return type of transition function %s is not %s"
,
NameListToString
(
aggtransfnName
),
format_type_be
(
aggTransType
));
/*
/*
* If the transfn is strict and the initval is NULL, make sure input
* If the transfn is strict and the initval is NULL, make sure input
...
@@ -136,26 +105,17 @@ AggregateCreate(const char *aggName,
...
@@ -136,26 +105,17 @@ AggregateCreate(const char *aggName,
{
{
MemSet
(
fnArgs
,
0
,
FUNC_MAX_ARGS
*
sizeof
(
Oid
));
MemSet
(
fnArgs
,
0
,
FUNC_MAX_ARGS
*
sizeof
(
Oid
));
fnArgs
[
0
]
=
aggTransType
;
fnArgs
[
0
]
=
aggTransType
;
nargs_finalfn
=
1
;
finalfn
=
LookupFuncName
(
aggfinalfnName
,
1
,
fnArgs
);
fdresult
=
func_get_detail
(
aggfinalfnName
,
NIL
,
1
,
fnArgs
,
&
finalfn
,
&
rettype
,
&
retset
,
&
true_oid_array_finalfn
);
/* only valid case is a normal function */
if
(
fdresult
!=
FUNCDETAIL_NORMAL
)
func_error
(
"AggregateCreate"
,
aggfinalfnName
,
1
,
fnArgs
,
NULL
);
if
(
!
OidIsValid
(
finalfn
))
if
(
!
OidIsValid
(
finalfn
))
func_error
(
"AggregateCreate"
,
aggfinalfnName
,
1
,
fnArgs
,
NULL
);
func_error
(
"AggregateCreate"
,
aggfinalfnName
,
1
,
fnArgs
,
NULL
);
tup
=
SearchSysCache
(
PROCOID
,
/*
ObjectIdGetDatum
(
finalfn
),
* enforce consistency with ANYARRAY and ANYELEMENT argument
0
,
0
,
0
);
* and return types, possibly modifying return type along the way
if
(
!
HeapTupleIsValid
(
tup
))
*/
func_error
(
"AggregateCreate"
,
aggfinalfnName
,
1
,
fnArgs
,
NULL
);
finaltype
=
enforce_generic_type_consistency
(
fnArgs
,
proc
=
(
Form_pg_proc
)
GETSTRUCT
(
tup
);
true_oid_array_finalfn
,
finaltype
=
proc
->
prorettype
;
nargs_finalfn
,
rettype
);
ReleaseSysCache
(
tup
);
}
}
else
else
{
{
...
@@ -166,27 +126,6 @@ AggregateCreate(const char *aggName,
...
@@ -166,27 +126,6 @@ AggregateCreate(const char *aggName,
}
}
Assert
(
OidIsValid
(
finaltype
));
Assert
(
OidIsValid
(
finaltype
));
/*
* special disallowed cases:
* 1) if finaltype is polymorphic, basetype cannot be ANY
* 2) if finaltype is polymorphic, both args to transfn must be
* polymorphic
*/
if
(
finaltype
==
ANYARRAYOID
||
finaltype
==
ANYELEMENTOID
)
{
if
(
aggBaseType
==
ANYOID
)
elog
(
ERROR
,
"aggregate with base type ANY must have a "
\
"non-polymorphic return type"
);
if
(
nargs_transfn
>
1
&&
(
(
true_oid_array_transfn
[
0
]
!=
ANYARRAYOID
&&
true_oid_array_transfn
[
0
]
!=
ANYELEMENTOID
)
||
(
true_oid_array_transfn
[
1
]
!=
ANYARRAYOID
&&
true_oid_array_transfn
[
1
]
!=
ANYELEMENTOID
)))
elog
(
ERROR
,
"aggregate with polymorphic return type requires "
\
"state function with both arguments polymorphic"
);
}
/*
/*
* Everything looks okay. Try to create the pg_proc entry for the
* Everything looks okay. Try to create the pg_proc entry for the
* aggregate. (This could fail if there's already a conflicting
* aggregate. (This could fail if there's already a conflicting
...
...
src/backend/commands/aggregatecmds.c
View file @
111d8e52
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.
6 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.
7 2003/06/25 21:30:26
momjian Exp $
*
*
* DESCRIPTION
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
* The "DefineFoo" routines take the parse tree and pick out the
...
@@ -119,9 +119,7 @@ DefineAggregate(List *names, List *parameters)
...
@@ -119,9 +119,7 @@ DefineAggregate(List *names, List *parameters)
baseTypeId
=
typenameTypeId
(
baseType
);
baseTypeId
=
typenameTypeId
(
baseType
);
transTypeId
=
typenameTypeId
(
transType
);
transTypeId
=
typenameTypeId
(
transType
);
if
(
get_typtype
(
transTypeId
)
==
'p'
&&
if
(
get_typtype
(
transTypeId
)
==
'p'
)
transTypeId
!=
ANYARRAYOID
&&
transTypeId
!=
ANYELEMENTOID
)
elog
(
ERROR
,
"Aggregate transition datatype cannot be %s"
,
elog
(
ERROR
,
"Aggregate transition datatype cannot be %s"
,
format_type_be
(
transTypeId
));
format_type_be
(
transTypeId
));
...
...
src/backend/executor/execQual.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.13
1 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.13
2 2003/06/25 21:30:28
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -1528,17 +1528,17 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
...
@@ -1528,17 +1528,17 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
{
{
/* Check other sub-arrays are compatible */
/* Check other sub-arrays are compatible */
if
(
elem_ndims
!=
ARR_NDIM
(
array
))
if
(
elem_ndims
!=
ARR_NDIM
(
array
))
elog
(
ERROR
,
"Multi
dimensional
arrays must have array "
elog
(
ERROR
,
"Multi
ple dimension
arrays must have array "
"expressions with matching number of dimensions"
);
"expressions with matching number of dimensions"
);
if
(
memcmp
(
elem_dims
,
ARR_DIMS
(
array
),
if
(
memcmp
(
elem_dims
,
ARR_DIMS
(
array
),
elem_ndims
*
sizeof
(
int
))
!=
0
)
elem_ndims
*
sizeof
(
int
))
!=
0
)
elog
(
ERROR
,
"Multi
dimensional
arrays must have array "
elog
(
ERROR
,
"Multi
ple dimension
arrays must have array "
"expressions with matching dimensions"
);
"expressions with matching dimensions"
);
if
(
memcmp
(
elem_lbs
,
ARR_LBOUND
(
array
),
if
(
memcmp
(
elem_lbs
,
ARR_LBOUND
(
array
),
elem_ndims
*
sizeof
(
int
))
!=
0
)
elem_ndims
*
sizeof
(
int
))
!=
0
)
elog
(
ERROR
,
"Multi
dimensional
arrays must have array "
elog
(
ERROR
,
"Multi
ple dimension
arrays must have array "
"expressions with matching dimensions"
);
"expressions with matching dimensions"
);
}
}
...
...
src/backend/executor/nodeAgg.c
View file @
111d8e52
...
@@ -45,7 +45,7 @@
...
@@ -45,7 +45,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.10
8 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.10
9 2003/06/25 21:30:28
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -58,7 +58,6 @@
...
@@ -58,7 +58,6 @@
#include "executor/executor.h"
#include "executor/executor.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAgg.h"
#include "miscadmin.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/clauses.h"
#include "parser/parse_coerce.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_expr.h"
...
@@ -213,7 +212,7 @@ static TupleTableSlot *agg_retrieve_direct(AggState *aggstate);
...
@@ -213,7 +212,7 @@ static TupleTableSlot *agg_retrieve_direct(AggState *aggstate);
static
void
agg_fill_hash_table
(
AggState
*
aggstate
);
static
void
agg_fill_hash_table
(
AggState
*
aggstate
);
static
TupleTableSlot
*
agg_retrieve_hash_table
(
AggState
*
aggstate
);
static
TupleTableSlot
*
agg_retrieve_hash_table
(
AggState
*
aggstate
);
static
Datum
GetAggInitVal
(
Datum
textInitVal
,
Oid
transtype
);
static
Datum
GetAggInitVal
(
Datum
textInitVal
,
Oid
transtype
);
static
Oid
resolve_type
(
Oid
type_to_resolve
,
Oid
context_type
);
/*
/*
* Initialize all aggregates for a new group of input values.
* Initialize all aggregates for a new group of input values.
...
@@ -352,12 +351,14 @@ advance_transition_function(AggState *aggstate,
...
@@ -352,12 +351,14 @@ advance_transition_function(AggState *aggstate,
fcinfo
.
context
=
NULL
;
fcinfo
.
context
=
NULL
;
fcinfo
.
resultinfo
=
NULL
;
fcinfo
.
resultinfo
=
NULL
;
fcinfo
.
isnull
=
false
;
fcinfo
.
isnull
=
false
;
fcinfo
.
flinfo
=
&
peraggstate
->
transfn
;
fcinfo
.
flinfo
=
&
peraggstate
->
transfn
;
fcinfo
.
nargs
=
2
;
fcinfo
.
nargs
=
2
;
fcinfo
.
arg
[
0
]
=
pergroupstate
->
transValue
;
fcinfo
.
arg
[
0
]
=
pergroupstate
->
transValue
;
fcinfo
.
argnull
[
0
]
=
pergroupstate
->
transValueIsNull
;
fcinfo
.
argnull
[
0
]
=
pergroupstate
->
transValueIsNull
;
fcinfo
.
arg
[
1
]
=
newVal
;
fcinfo
.
arg
[
1
]
=
newVal
;
fcinfo
.
argnull
[
1
]
=
isNull
;
fcinfo
.
argnull
[
1
]
=
isNull
;
newVal
=
FunctionCallInvoke
(
&
fcinfo
);
newVal
=
FunctionCallInvoke
(
&
fcinfo
);
/*
/*
...
@@ -1186,21 +1187,7 @@ ExecInitAgg(Agg *node, EState *estate)
...
@@ -1186,21 +1187,7 @@ ExecInitAgg(Agg *node, EState *estate)
AclResult
aclresult
;
AclResult
aclresult
;
Oid
transfn_oid
,
Oid
transfn_oid
,
finalfn_oid
;
finalfn_oid
;
FuncExpr
*
transfnexpr
,
*
finalfnexpr
;
Datum
textInitVal
;
Datum
textInitVal
;
List
*
fargs
;
Oid
agg_rt_type
;
Oid
*
transfn_arg_types
;
List
*
transfn_args
=
NIL
;
int
transfn_nargs
;
Oid
transfn_ret_type
;
Oid
*
finalfn_arg_types
=
NULL
;
List
*
finalfn_args
=
NIL
;
Oid
finalfn_ret_type
=
InvalidOid
;
int
finalfn_nargs
=
0
;
Node
*
arg0
;
Node
*
arg1
;
int
i
;
int
i
;
/* Planner should have assigned aggregate to correct level */
/* Planner should have assigned aggregate to correct level */
...
@@ -1251,166 +1238,6 @@ ExecInitAgg(Agg *node, EState *estate)
...
@@ -1251,166 +1238,6 @@ ExecInitAgg(Agg *node, EState *estate)
&
peraggstate
->
transtypeLen
,
&
peraggstate
->
transtypeLen
,
&
peraggstate
->
transtypeByVal
);
&
peraggstate
->
transtypeByVal
);
peraggstate
->
transfn_oid
=
transfn_oid
=
aggform
->
aggtransfn
;
peraggstate
->
finalfn_oid
=
finalfn_oid
=
aggform
->
aggfinalfn
;
/* get the runtime aggregate argument type */
fargs
=
aggref
->
args
;
agg_rt_type
=
exprType
((
Node
*
)
nth
(
0
,
fargs
));
/* get the transition function argument and return types */
transfn_ret_type
=
get_func_rettype
(
transfn_oid
);
transfn_arg_types
=
get_func_argtypes
(
transfn_oid
,
&
transfn_nargs
);
/* resolve any polymorphic types */
if
(
transfn_nargs
==
2
)
/* base type was not ANY */
{
if
(
transfn_arg_types
[
1
]
==
ANYARRAYOID
||
transfn_arg_types
[
1
]
==
ANYELEMENTOID
)
transfn_arg_types
[
1
]
=
agg_rt_type
;
transfn_arg_types
[
0
]
=
resolve_type
(
transfn_arg_types
[
0
],
agg_rt_type
);
/*
* Build arg list to use on the transfn FuncExpr node. We really
* only care that the node type is correct so that the transfn
* can discover the actual argument types at runtime using
* get_fn_expr_argtype()
*/
arg0
=
(
Node
*
)
makeRelabelType
((
Expr
*
)
NULL
,
transfn_arg_types
[
0
],
-
1
,
COERCE_DONTCARE
);
arg1
=
(
Node
*
)
makeRelabelType
((
Expr
*
)
NULL
,
transfn_arg_types
[
1
],
-
1
,
COERCE_DONTCARE
);
transfn_args
=
makeList2
(
arg0
,
arg1
);
/*
* the state transition function always returns the same type
* as its first argument
*/
if
(
transfn_ret_type
==
ANYARRAYOID
||
transfn_ret_type
==
ANYELEMENTOID
)
transfn_ret_type
=
transfn_arg_types
[
0
];
}
else
if
(
transfn_nargs
==
1
)
/*
* base type was ANY, therefore the aggregate return type should
* be non-polymorphic
*/
{
Oid
finaltype
=
get_func_rettype
(
aggref
->
aggfnoid
);
/*
* this should have been prevented in AggregateCreate,
* but check anyway
*/
if
(
finaltype
==
ANYARRAYOID
||
finaltype
==
ANYELEMENTOID
)
elog
(
ERROR
,
"aggregate with base type ANY must have a "
\
"non-polymorphic return type"
);
/* see if we have a final function */
if
(
OidIsValid
(
finalfn_oid
))
{
finalfn_arg_types
=
get_func_argtypes
(
finalfn_oid
,
&
finalfn_nargs
);
if
(
finalfn_nargs
!=
1
)
elog
(
ERROR
,
"final function takes unexpected number "
\
"of arguments: %d"
,
finalfn_nargs
);
/*
* final function argument is always the same as the state
* function return type
*/
if
(
finalfn_arg_types
[
0
]
!=
ANYARRAYOID
&&
finalfn_arg_types
[
0
]
!=
ANYELEMENTOID
)
{
/* if it is not ambiguous, use it */
transfn_ret_type
=
finalfn_arg_types
[
0
];
}
else
{
/* if it is ambiguous, try to derive it */
finalfn_ret_type
=
finaltype
;
finalfn_arg_types
[
0
]
=
resolve_type
(
finalfn_arg_types
[
0
],
finalfn_ret_type
);
transfn_ret_type
=
finalfn_arg_types
[
0
];
}
}
else
transfn_ret_type
=
finaltype
;
transfn_arg_types
[
0
]
=
resolve_type
(
transfn_arg_types
[
0
],
transfn_ret_type
);
/*
* Build arg list to use on the transfn FuncExpr node. We really
* only care that the node type is correct so that the transfn
* can discover the actual argument types at runtime using
* get_fn_expr_argtype()
*/
arg0
=
(
Node
*
)
makeRelabelType
((
Expr
*
)
NULL
,
transfn_arg_types
[
0
],
-
1
,
COERCE_DONTCARE
);
transfn_args
=
makeList1
(
arg0
);
}
else
elog
(
ERROR
,
"state transition function takes unexpected number "
\
"of arguments: %d"
,
transfn_nargs
);
if
(
OidIsValid
(
finalfn_oid
))
{
/* get the final function argument and return types */
if
(
finalfn_ret_type
==
InvalidOid
)
finalfn_ret_type
=
get_func_rettype
(
finalfn_oid
);
if
(
!
finalfn_arg_types
)
{
finalfn_arg_types
=
get_func_argtypes
(
finalfn_oid
,
&
finalfn_nargs
);
if
(
finalfn_nargs
!=
1
)
elog
(
ERROR
,
"final function takes unexpected number "
\
"of arguments: %d"
,
finalfn_nargs
);
}
/*
* final function argument is always the same as the state
* function return type, which by now should have been resolved
*/
if
(
finalfn_arg_types
[
0
]
==
ANYARRAYOID
||
finalfn_arg_types
[
0
]
==
ANYELEMENTOID
)
finalfn_arg_types
[
0
]
=
transfn_ret_type
;
/*
* Build arg list to use on the finalfn FuncExpr node. We really
* only care that the node type is correct so that the finalfn
* can discover the actual argument type at runtime using
* get_fn_expr_argtype()
*/
arg0
=
(
Node
*
)
makeRelabelType
((
Expr
*
)
NULL
,
finalfn_arg_types
[
0
],
-
1
,
COERCE_DONTCARE
);
finalfn_args
=
makeList1
(
arg0
);
finalfn_ret_type
=
resolve_type
(
finalfn_ret_type
,
finalfn_arg_types
[
0
]);
}
fmgr_info
(
transfn_oid
,
&
peraggstate
->
transfn
);
transfnexpr
=
(
FuncExpr
*
)
make_funcclause
(
transfn_oid
,
transfn_ret_type
,
false
,
/* cannot be a set */
COERCE_DONTCARE
,
/* to match any user expr */
transfn_args
);
peraggstate
->
transfn
.
fn_expr
=
(
Node
*
)
transfnexpr
;
if
(
OidIsValid
(
finalfn_oid
))
{
fmgr_info
(
finalfn_oid
,
&
peraggstate
->
finalfn
);
finalfnexpr
=
(
FuncExpr
*
)
make_funcclause
(
finalfn_oid
,
finalfn_ret_type
,
false
,
/* cannot be a set */
COERCE_DONTCARE
,
/* to match any user expr */
finalfn_args
);
peraggstate
->
finalfn
.
fn_expr
=
(
Node
*
)
finalfnexpr
;
}
/*
/*
* initval is potentially null, so don't try to access it as a
* initval is potentially null, so don't try to access it as a
* struct field. Must do it the hard way with SysCacheGetAttr.
* struct field. Must do it the hard way with SysCacheGetAttr.
...
@@ -1423,7 +1250,14 @@ ExecInitAgg(Agg *node, EState *estate)
...
@@ -1423,7 +1250,14 @@ ExecInitAgg(Agg *node, EState *estate)
peraggstate
->
initValue
=
(
Datum
)
0
;
peraggstate
->
initValue
=
(
Datum
)
0
;
else
else
peraggstate
->
initValue
=
GetAggInitVal
(
textInitVal
,
peraggstate
->
initValue
=
GetAggInitVal
(
textInitVal
,
transfn_arg_types
[
0
]);
aggform
->
aggtranstype
);
peraggstate
->
transfn_oid
=
transfn_oid
=
aggform
->
aggtransfn
;
peraggstate
->
finalfn_oid
=
finalfn_oid
=
aggform
->
aggfinalfn
;
fmgr_info
(
transfn_oid
,
&
peraggstate
->
transfn
);
if
(
OidIsValid
(
finalfn_oid
))
fmgr_info
(
finalfn_oid
,
&
peraggstate
->
finalfn
);
/*
/*
* If the transfn is strict and the initval is NULL, make sure
* If the transfn is strict and the initval is NULL, make sure
...
@@ -1635,36 +1469,3 @@ aggregate_dummy(PG_FUNCTION_ARGS)
...
@@ -1635,36 +1469,3 @@ aggregate_dummy(PG_FUNCTION_ARGS)
fcinfo
->
flinfo
->
fn_oid
);
fcinfo
->
flinfo
->
fn_oid
);
return
(
Datum
)
0
;
/* keep compiler quiet */
return
(
Datum
)
0
;
/* keep compiler quiet */
}
}
static
Oid
resolve_type
(
Oid
type_to_resolve
,
Oid
context_type
)
{
Oid
resolved_type
;
if
(
context_type
==
ANYARRAYOID
||
context_type
==
ANYELEMENTOID
)
resolved_type
=
type_to_resolve
;
else
if
(
type_to_resolve
==
ANYARRAYOID
)
/* any array */
{
Oid
context_type_arraytype
=
get_array_type
(
context_type
);
if
(
context_type_arraytype
!=
InvalidOid
)
resolved_type
=
context_type_arraytype
;
else
resolved_type
=
context_type
;
}
else
if
(
type_to_resolve
==
ANYELEMENTOID
)
/* any element */
{
Oid
context_type_elemtype
=
get_element_type
(
context_type
);
if
(
context_type_elemtype
!=
InvalidOid
)
resolved_type
=
context_type_elemtype
;
else
resolved_type
=
context_type
;
}
else
resolved_type
=
type_to_resolve
;
return
resolved_type
;
}
src/backend/executor/nodeSubplan.c
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.4
8 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.4
9 2003/06/25 21:30:29
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -28,6 +28,23 @@
...
@@ -28,6 +28,23 @@
#include "utils/datum.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/lsyscache.h"
typedef
struct
ArrayBuildState
{
MemoryContext
mcontext
;
/* where all the temp stuff is kept */
Datum
*
dvalues
;
/* array of accumulated Datums */
/*
* The allocated size of dvalues[] is always a multiple of
* ARRAY_ELEMS_CHUNKSIZE
*/
#define ARRAY_ELEMS_CHUNKSIZE 64
int
nelems
;
/* number of valid Datums in dvalues[] */
Oid
element_type
;
/* data type of the Datums */
int16
typlen
;
/* needed info about datatype */
bool
typbyval
;
char
typalign
;
}
ArrayBuildState
;
static
Datum
ExecHashSubPlan
(
SubPlanState
*
node
,
static
Datum
ExecHashSubPlan
(
SubPlanState
*
node
,
ExprContext
*
econtext
,
ExprContext
*
econtext
,
bool
*
isNull
);
bool
*
isNull
);
...
@@ -37,6 +54,13 @@ static Datum ExecScanSubPlan(SubPlanState *node,
...
@@ -37,6 +54,13 @@ static Datum ExecScanSubPlan(SubPlanState *node,
static
void
buildSubPlanHash
(
SubPlanState
*
node
);
static
void
buildSubPlanHash
(
SubPlanState
*
node
);
static
bool
findPartialMatch
(
TupleHashTable
hashtable
,
TupleTableSlot
*
slot
);
static
bool
findPartialMatch
(
TupleHashTable
hashtable
,
TupleTableSlot
*
slot
);
static
bool
tupleAllNulls
(
HeapTuple
tuple
);
static
bool
tupleAllNulls
(
HeapTuple
tuple
);
static
ArrayBuildState
*
accumArrayResult
(
ArrayBuildState
*
astate
,
Datum
dvalue
,
bool
disnull
,
Oid
element_type
,
MemoryContext
rcontext
);
static
Datum
makeArrayResult
(
ArrayBuildState
*
astate
,
MemoryContext
rcontext
);
/* ----------------------------------------------------------------
/* ----------------------------------------------------------------
* ExecSubPlan
* ExecSubPlan
...
@@ -200,7 +224,6 @@ ExecScanSubPlan(SubPlanState *node,
...
@@ -200,7 +224,6 @@ ExecScanSubPlan(SubPlanState *node,
PlanState
*
planstate
=
node
->
planstate
;
PlanState
*
planstate
=
node
->
planstate
;
SubLinkType
subLinkType
=
subplan
->
subLinkType
;
SubLinkType
subLinkType
=
subplan
->
subLinkType
;
bool
useOr
=
subplan
->
useOr
;
bool
useOr
=
subplan
->
useOr
;
bool
isExpr
=
subplan
->
isExpr
;
MemoryContext
oldcontext
;
MemoryContext
oldcontext
;
TupleTableSlot
*
slot
;
TupleTableSlot
*
slot
;
Datum
result
;
Datum
result
;
...
@@ -271,11 +294,6 @@ ExecScanSubPlan(SubPlanState *node,
...
@@ -271,11 +294,6 @@ ExecScanSubPlan(SubPlanState *node,
bool
rownull
=
false
;
bool
rownull
=
false
;
int
col
=
1
;
int
col
=
1
;
List
*
plst
;
List
*
plst
;
int
numelems
;
int
elemnum
;
Datum
dvalue
;
Datum
*
dvalues
=
NULL
;
bool
disnull
;
if
(
subLinkType
==
EXISTS_SUBLINK
)
if
(
subLinkType
==
EXISTS_SUBLINK
)
{
{
...
@@ -313,6 +331,9 @@ ExecScanSubPlan(SubPlanState *node,
...
@@ -313,6 +331,9 @@ ExecScanSubPlan(SubPlanState *node,
if
(
subLinkType
==
ARRAY_SUBLINK
)
if
(
subLinkType
==
ARRAY_SUBLINK
)
{
{
Datum
dvalue
;
bool
disnull
;
found
=
true
;
found
=
true
;
/* stash away current value */
/* stash away current value */
dvalue
=
heap_getattr
(
tup
,
1
,
tdesc
,
&
disnull
);
dvalue
=
heap_getattr
(
tup
,
1
,
tdesc
,
&
disnull
);
...
@@ -330,164 +351,99 @@ ExecScanSubPlan(SubPlanState *node,
...
@@ -330,164 +351,99 @@ ExecScanSubPlan(SubPlanState *node,
found
=
true
;
found
=
true
;
/*
/*
* When isExpr is true, we have either a scalar expression or an
* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining
* array. In the former case, this is no different than the !isExpr
* operators for columns of tuple.
* case. In the latter case, iterate over the elements as if they
* were from multiple input tuples.
*/
*/
if
(
!
isExpr
)
plst
=
subplan
->
paramIds
;
numelems
=
1
;
foreach
(
lst
,
node
->
exprs
)
else
{
{
Oid
expr_typeid
=
tdesc
->
attrs
[
0
]
->
atttypid
;
ExprState
*
exprstate
=
(
ExprState
*
)
lfirst
(
lst
);
int
paramid
=
lfirsti
(
plst
);
ParamExecData
*
prmdata
;
Datum
expresult
;
bool
expnull
;
if
(
expr_typeid
!=
subplan
->
exprtype
)
/*
{
* Load up the Param representing this column of the sub-select.
subplan
->
exprtype
=
expr_typeid
;
*/
subplan
->
elemtype
=
get_element_type
(
expr_typeid
);
prmdata
=
&
(
econtext
->
ecxt_param_exec_vals
[
paramid
]);
Assert
(
prmdata
->
execPlan
==
NULL
);
if
(
subplan
->
elemtype
!=
InvalidOid
)
prmdata
->
value
=
heap_getattr
(
tup
,
col
,
tdesc
,
get_typlenbyvalalign
(
subplan
->
elemtype
,
&
(
prmdata
->
isnull
));
&
subplan
->
elmlen
,
&
subplan
->
elmbyval
,
&
subplan
->
elmalign
);
}
/* get current value */
/*
dvalue
=
heap_getattr
(
tup
,
1
,
tdesc
,
&
disnull
);
* Now we can eval the combining operator for this column.
*/
expresult
=
ExecEvalExprSwitchContext
(
exprstate
,
econtext
,
&
expnull
,
NULL
);
/* XXX this will need work if/when arrays support NULL elements */
/*
if
(
!
disnull
)
* Combine the result into the row result as appropriate.
*/
if
(
col
==
1
)
{
{
if
(
subplan
->
elemtype
!=
InvalidOid
)
rowresult
=
expresult
;
{
rownull
=
expnull
;
ArrayType
*
v
=
DatumGetArrayTypeP
(
dvalue
);
}
else
if
(
useOr
)
deconstruct_array
(
v
,
subplan
->
elemtype
,
subplan
->
elmlen
,
{
subplan
->
elmbyval
,
subplan
->
elmalign
,
/* combine within row per OR semantics */
&
dvalues
,
&
numelems
);
if
(
expnull
)
}
rownull
=
true
;
else
else
if
(
DatumGetBool
(
expresult
))
{
{
numelems
=
1
;
rowresult
=
BoolGetDatum
(
true
)
;
dvalues
=
(
Datum
*
)
palloc
(
numelems
*
sizeof
(
Datum
))
;
rownull
=
false
;
dvalues
[
0
]
=
dvalue
;
break
;
/* needn't look at any more columns */
}
}
}
}
else
else
{
{
numelems
=
1
;
/* combine within row per AND semantics */
dvalues
=
(
Datum
*
)
palloc
(
numelems
*
sizeof
(
Datum
));
if
(
expnull
)
dvalues
[
0
]
=
(
Datum
)
0
;
rownull
=
true
;
else
if
(
!
DatumGetBool
(
expresult
))
{
rowresult
=
BoolGetDatum
(
false
);
rownull
=
false
;
break
;
/* needn't look at any more columns */
}
}
}
plst
=
lnext
(
plst
);
col
++
;
}
}
for
(
elemnum
=
0
;
elemnum
<
numelems
;
elemnum
++
)
if
(
subLinkType
==
ANY_SUBLINK
)
{
{
/*
/* combine across rows per OR semantics */
* For ALL, ANY, and MULTIEXPR sublinks, iterate over combining
if
(
rownull
)
* operators for columns of tuple.
*
isNull
=
true
;
*/
else
if
(
DatumGetBool
(
rowresult
))
col
=
1
;
plst
=
subplan
->
paramIds
;
foreach
(
lst
,
node
->
exprs
)
{
{
ExprState
*
exprstate
=
(
ExprState
*
)
lfirst
(
lst
);
result
=
BoolGetDatum
(
true
);
int
paramid
=
lfirsti
(
plst
);
*
isNull
=
false
;
ParamExecData
*
prmdata
;
break
;
/* needn't look at any more rows */
Datum
expresult
;
bool
expnull
;
/*
* Load up the Param representing this column of the sub-select.
*/
prmdata
=
&
(
econtext
->
ecxt_param_exec_vals
[
paramid
]);
Assert
(
prmdata
->
execPlan
==
NULL
);
if
(
!
isExpr
)
prmdata
->
value
=
heap_getattr
(
tup
,
col
,
tdesc
,
&
(
prmdata
->
isnull
));
else
{
prmdata
->
value
=
dvalues
[
elemnum
];
prmdata
->
isnull
=
disnull
;
}
/*
* Now we can eval the combining operator for this column.
*/
expresult
=
ExecEvalExprSwitchContext
(
exprstate
,
econtext
,
&
expnull
,
NULL
);
/*
* Combine the result into the row result as appropriate.
*/
if
(
col
==
1
)
{
rowresult
=
expresult
;
rownull
=
expnull
;
}
else
if
(
useOr
)
{
/* combine within row per OR semantics */
if
(
expnull
)
rownull
=
true
;
else
if
(
DatumGetBool
(
expresult
))
{
rowresult
=
BoolGetDatum
(
true
);
rownull
=
false
;
break
;
/* needn't look at any more columns */
}
}
else
{
/* combine within row per AND semantics */
if
(
expnull
)
rownull
=
true
;
else
if
(
!
DatumGetBool
(
expresult
))
{
rowresult
=
BoolGetDatum
(
false
);
rownull
=
false
;
break
;
/* needn't look at any more columns */
}
}
plst
=
lnext
(
plst
);
col
++
;
}
if
(
subLinkType
==
ANY_SUBLINK
)
{
/* combine across rows per OR semantics */
if
(
rownull
)
*
isNull
=
true
;
else
if
(
DatumGetBool
(
rowresult
))
{
result
=
BoolGetDatum
(
true
);
*
isNull
=
false
;
break
;
/* needn't look at any more rows */
}
}
else
if
(
subLinkType
==
ALL_SUBLINK
)
{
/* combine across rows per AND semantics */
if
(
rownull
)
*
isNull
=
true
;
else
if
(
!
DatumGetBool
(
rowresult
))
{
result
=
BoolGetDatum
(
false
);
*
isNull
=
false
;
break
;
/* needn't look at any more rows */
}
}
}
else
}
else
if
(
subLinkType
==
ALL_SUBLINK
)
{
/* combine across rows per AND semantics */
if
(
rownull
)
*
isNull
=
true
;
else
if
(
!
DatumGetBool
(
rowresult
))
{
{
/* must be MULTIEXPR_SUBLINK */
result
=
BoolGetDatum
(
false
);
result
=
rowresult
;
*
isNull
=
false
;
*
isNull
=
rownull
;
break
;
/* needn't look at any more rows */
}
}
}
}
else
{
/* must be MULTIEXPR_SUBLINK */
result
=
rowresult
;
*
isNull
=
rownull
;
}
}
}
if
(
!
found
)
if
(
!
found
)
...
@@ -524,7 +480,6 @@ static void
...
@@ -524,7 +480,6 @@ static void
buildSubPlanHash
(
SubPlanState
*
node
)
buildSubPlanHash
(
SubPlanState
*
node
)
{
{
SubPlan
*
subplan
=
(
SubPlan
*
)
node
->
xprstate
.
expr
;
SubPlan
*
subplan
=
(
SubPlan
*
)
node
->
xprstate
.
expr
;
bool
isExpr
=
subplan
->
isExpr
;
PlanState
*
planstate
=
node
->
planstate
;
PlanState
*
planstate
=
node
->
planstate
;
int
ncols
=
length
(
node
->
exprs
);
int
ncols
=
length
(
node
->
exprs
);
ExprContext
*
innerecontext
=
node
->
innerecontext
;
ExprContext
*
innerecontext
=
node
->
innerecontext
;
...
@@ -532,7 +487,6 @@ buildSubPlanHash(SubPlanState *node)
...
@@ -532,7 +487,6 @@ buildSubPlanHash(SubPlanState *node)
MemoryContext
oldcontext
;
MemoryContext
oldcontext
;
int
nbuckets
;
int
nbuckets
;
TupleTableSlot
*
slot
;
TupleTableSlot
*
slot
;
TupleTableSlot
*
arrslot
=
NULL
;
Assert
(
subplan
->
subLinkType
==
ANY_SUBLINK
);
Assert
(
subplan
->
subLinkType
==
ANY_SUBLINK
);
Assert
(
!
subplan
->
useOr
);
Assert
(
!
subplan
->
useOr
);
...
@@ -612,139 +566,43 @@ buildSubPlanHash(SubPlanState *node)
...
@@ -612,139 +566,43 @@ buildSubPlanHash(SubPlanState *node)
{
{
HeapTuple
tup
=
slot
->
val
;
HeapTuple
tup
=
slot
->
val
;
TupleDesc
tdesc
=
slot
->
ttc_tupleDescriptor
;
TupleDesc
tdesc
=
slot
->
ttc_tupleDescriptor
;
TupleDesc
arrtdesc
=
NULL
;
int
col
=
1
;
List
*
plst
;
List
*
plst
;
bool
isnew
;
bool
isnew
;
int
numelems
;
int
elemnum
;
Datum
dvalue
;
Datum
*
dvalues
=
NULL
;
bool
disnull
;
/*
/*
* When isExpr is true, we have either a scalar expression or an
* Load up the Params representing the raw sub-select outputs,
* array. In the former case, this is no different than the !isExpr
* then form the projection tuple to store in the hashtable.
* case. In the latter case, iterate over the elements as if they
* were from multiple input tuples.
*/
*/
if
(
!
isExpr
)
foreach
(
plst
,
subplan
->
paramIds
)
numelems
=
1
;
else
{
{
Oid
expr_typeid
=
tdesc
->
attrs
[
0
]
->
atttypid
;
int
paramid
=
lfirsti
(
plst
);
ParamExecData
*
prmdata
;
if
(
expr_typeid
!=
subplan
->
exprtype
)
{
prmdata
=
&
(
innerecontext
->
ecxt_param_exec_vals
[
paramid
]);
subplan
->
exprtype
=
expr_typeid
;
Assert
(
prmdata
->
execPlan
==
NULL
);
subplan
->
elemtype
=
get_element_type
(
expr_typeid
);
prmdata
->
value
=
heap_getattr
(
tup
,
col
,
tdesc
,
&
(
prmdata
->
isnull
));
if
(
subplan
->
elemtype
!=
InvalidOid
)
col
++
;
get_typlenbyvalalign
(
subplan
->
elemtype
,
&
subplan
->
elmlen
,
&
subplan
->
elmbyval
,
&
subplan
->
elmalign
);
}
/* get current value */
dvalue
=
heap_getattr
(
tup
,
1
,
tdesc
,
&
disnull
);
if
(
subplan
->
elemtype
!=
InvalidOid
)
{
TupleTable
tupleTable
;
ArrayType
*
v
=
DatumGetArrayTypeP
(
dvalue
);
arrtdesc
=
CreateTemplateTupleDesc
(
1
,
false
);
TupleDescInitEntry
(
arrtdesc
,
1
,
"elem"
,
subplan
->
elemtype
,
-
1
,
0
,
false
);
tupleTable
=
ExecCreateTupleTable
(
1
);
arrslot
=
ExecAllocTableSlot
(
tupleTable
);
ExecSetSlotDescriptor
(
arrslot
,
arrtdesc
,
true
);
/* XXX this will need work if/when arrays support NULL elements */
if
(
!
disnull
)
{
deconstruct_array
(
v
,
subplan
->
elemtype
,
subplan
->
elmlen
,
subplan
->
elmbyval
,
subplan
->
elmalign
,
&
dvalues
,
&
numelems
);
}
else
{
numelems
=
1
;
dvalues
=
(
Datum
*
)
palloc
(
numelems
*
sizeof
(
Datum
));
dvalues
[
0
]
=
(
Datum
)
0
;
}
}
else
{
numelems
=
1
;
dvalues
=
(
Datum
*
)
palloc
(
numelems
*
sizeof
(
Datum
));
dvalues
[
0
]
=
dvalue
;
}
}
}
slot
=
ExecProject
(
node
->
projRight
,
NULL
);
tup
=
slot
->
val
;
for
(
elemnum
=
0
;
elemnum
<
numelems
;
elemnum
++
)
/*
* If result contains any nulls, store separately or not at all.
* (Since we know the projection tuple has no junk columns, we
* can just look at the overall hasnull info bit, instead of
* groveling through the columns.)
*/
if
(
HeapTupleNoNulls
(
tup
))
{
{
int
col
=
1
;
(
void
)
LookupTupleHashEntry
(
node
->
hashtable
,
slot
,
&
isnew
);
node
->
havehashrows
=
true
;
if
(
!
isExpr
||
subplan
->
elemtype
==
InvalidOid
)
}
{
else
if
(
node
->
hashnulls
)
/*
{
* Load up the Params representing the raw sub-select outputs,
(
void
)
LookupTupleHashEntry
(
node
->
hashnulls
,
slot
,
&
isnew
);
* then form the projection tuple to store in the hashtable.
node
->
havenullrows
=
true
;
*/
foreach
(
plst
,
subplan
->
paramIds
)
{
int
paramid
=
lfirsti
(
plst
);
ParamExecData
*
prmdata
;
prmdata
=
&
(
innerecontext
->
ecxt_param_exec_vals
[
paramid
]);
Assert
(
prmdata
->
execPlan
==
NULL
);
prmdata
->
value
=
heap_getattr
(
tup
,
col
,
tdesc
,
&
(
prmdata
->
isnull
));
col
++
;
}
slot
=
ExecProject
(
node
->
projRight
,
NULL
);
tup
=
slot
->
val
;
}
else
{
/*
* For array type expressions, we need to build up our own
* tuple and slot
*/
char
nullflag
;
nullflag
=
disnull
?
'n'
:
' '
;
tup
=
heap_formtuple
(
arrtdesc
,
&
dvalues
[
elemnum
],
&
nullflag
);
arrslot
=
ExecStoreTuple
(
tup
,
arrslot
,
InvalidBuffer
,
true
);
}
/*
* If result contains any nulls, store separately or not at all.
* (Since we know the projection tuple has no junk columns, we
* can just look at the overall hasnull info bit, instead of
* groveling through the columns.)
*/
if
(
HeapTupleNoNulls
(
tup
))
{
if
(
!
isExpr
)
(
void
)
LookupTupleHashEntry
(
node
->
hashtable
,
slot
,
&
isnew
);
else
(
void
)
LookupTupleHashEntry
(
node
->
hashtable
,
arrslot
,
&
isnew
);
node
->
havehashrows
=
true
;
}
else
if
(
node
->
hashnulls
)
{
if
(
!
isExpr
)
(
void
)
LookupTupleHashEntry
(
node
->
hashnulls
,
slot
,
&
isnew
);
else
(
void
)
LookupTupleHashEntry
(
node
->
hashnulls
,
arrslot
,
&
isnew
);
node
->
havenullrows
=
true
;
}
}
}
/*
/*
...
@@ -761,8 +619,6 @@ buildSubPlanHash(SubPlanState *node)
...
@@ -761,8 +619,6 @@ buildSubPlanHash(SubPlanState *node)
* have the potential for a double free attempt.
* have the potential for a double free attempt.
*/
*/
ExecClearTuple
(
node
->
projRight
->
pi_slot
);
ExecClearTuple
(
node
->
projRight
->
pi_slot
);
if
(
arrslot
)
ExecClearTuple
(
arrslot
);
MemoryContextSwitchTo
(
oldcontext
);
MemoryContextSwitchTo
(
oldcontext
);
}
}
...
@@ -1243,3 +1099,101 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
...
@@ -1243,3 +1099,101 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
parent
->
chgParam
=
bms_add_member
(
parent
->
chgParam
,
paramid
);
parent
->
chgParam
=
bms_add_member
(
parent
->
chgParam
,
paramid
);
}
}
}
}
/*
* accumArrayResult - accumulate one (more) Datum for an ARRAY_SUBLINK
*
* astate is working state (NULL on first call)
* rcontext is where to keep working state
*/
static
ArrayBuildState
*
accumArrayResult
(
ArrayBuildState
*
astate
,
Datum
dvalue
,
bool
disnull
,
Oid
element_type
,
MemoryContext
rcontext
)
{
MemoryContext
arr_context
,
oldcontext
;
if
(
astate
==
NULL
)
{
/* First time through --- initialize */
/* Make a temporary context to hold all the junk */
arr_context
=
AllocSetContextCreate
(
rcontext
,
"ARRAY_SUBLINK Result"
,
ALLOCSET_DEFAULT_MINSIZE
,
ALLOCSET_DEFAULT_INITSIZE
,
ALLOCSET_DEFAULT_MAXSIZE
);
oldcontext
=
MemoryContextSwitchTo
(
arr_context
);
astate
=
(
ArrayBuildState
*
)
palloc
(
sizeof
(
ArrayBuildState
));
astate
->
mcontext
=
arr_context
;
astate
->
dvalues
=
(
Datum
*
)
palloc
(
ARRAY_ELEMS_CHUNKSIZE
*
sizeof
(
Datum
));
astate
->
nelems
=
0
;
astate
->
element_type
=
element_type
;
get_typlenbyvalalign
(
element_type
,
&
astate
->
typlen
,
&
astate
->
typbyval
,
&
astate
->
typalign
);
}
else
{
oldcontext
=
MemoryContextSwitchTo
(
astate
->
mcontext
);
Assert
(
astate
->
element_type
==
element_type
);
/* enlarge dvalues[] if needed */
if
((
astate
->
nelems
%
ARRAY_ELEMS_CHUNKSIZE
)
==
0
)
astate
->
dvalues
=
(
Datum
*
)
repalloc
(
astate
->
dvalues
,
(
astate
->
nelems
+
ARRAY_ELEMS_CHUNKSIZE
)
*
sizeof
(
Datum
));
}
if
(
disnull
)
elog
(
ERROR
,
"NULL elements not allowed in Arrays"
);
/* Use datumCopy to ensure pass-by-ref stuff is copied into mcontext */
astate
->
dvalues
[
astate
->
nelems
++
]
=
datumCopy
(
dvalue
,
astate
->
typbyval
,
astate
->
typlen
);
MemoryContextSwitchTo
(
oldcontext
);
return
astate
;
}
/*
* makeArrayResult - produce final result of ARRAY_SUBLINK
*
* astate is working state (not NULL)
* rcontext is where to construct result
*/
static
Datum
makeArrayResult
(
ArrayBuildState
*
astate
,
MemoryContext
rcontext
)
{
ArrayType
*
result
;
int
dims
[
1
];
int
lbs
[
1
];
MemoryContext
oldcontext
;
/* Build the final array result in rcontext */
oldcontext
=
MemoryContextSwitchTo
(
rcontext
);
dims
[
0
]
=
astate
->
nelems
;
lbs
[
0
]
=
1
;
result
=
construct_md_array
(
astate
->
dvalues
,
1
,
dims
,
lbs
,
astate
->
element_type
,
astate
->
typlen
,
astate
->
typbyval
,
astate
->
typalign
);
MemoryContextSwitchTo
(
oldcontext
);
/* Clean up all the junk */
MemoryContextDelete
(
astate
->
mcontext
);
return
PointerGetDatum
(
result
);
}
src/backend/nodes/copyfuncs.c
View file @
111d8e52
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.25
5 2003/06/25 04:19:24
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.25
6 2003/06/25 21:30:29
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -728,7 +728,6 @@ _copyAggref(Aggref *from)
...
@@ -728,7 +728,6 @@ _copyAggref(Aggref *from)
COPY_SCALAR_FIELD
(
agglevelsup
);
COPY_SCALAR_FIELD
(
agglevelsup
);
COPY_SCALAR_FIELD
(
aggstar
);
COPY_SCALAR_FIELD
(
aggstar
);
COPY_SCALAR_FIELD
(
aggdistinct
);
COPY_SCALAR_FIELD
(
aggdistinct
);
COPY_NODE_FIELD
(
args
);
return
newnode
;
return
newnode
;
}
}
...
@@ -827,7 +826,6 @@ _copySubLink(SubLink *from)
...
@@ -827,7 +826,6 @@ _copySubLink(SubLink *from)
COPY_SCALAR_FIELD
(
subLinkType
);
COPY_SCALAR_FIELD
(
subLinkType
);
COPY_SCALAR_FIELD
(
useOr
);
COPY_SCALAR_FIELD
(
useOr
);
COPY_SCALAR_FIELD
(
isExpr
);
COPY_NODE_FIELD
(
lefthand
);
COPY_NODE_FIELD
(
lefthand
);
COPY_NODE_FIELD
(
operName
);
COPY_NODE_FIELD
(
operName
);
COPY_OIDLIST_FIELD
(
operOids
);
COPY_OIDLIST_FIELD
(
operOids
);
...
@@ -846,12 +844,6 @@ _copySubPlan(SubPlan *from)
...
@@ -846,12 +844,6 @@ _copySubPlan(SubPlan *from)
COPY_SCALAR_FIELD
(
subLinkType
);
COPY_SCALAR_FIELD
(
subLinkType
);
COPY_SCALAR_FIELD
(
useOr
);
COPY_SCALAR_FIELD
(
useOr
);
COPY_SCALAR_FIELD
(
isExpr
);
COPY_SCALAR_FIELD
(
exprtype
);
COPY_SCALAR_FIELD
(
elemtype
);
COPY_SCALAR_FIELD
(
elmlen
);
COPY_SCALAR_FIELD
(
elmbyval
);
COPY_SCALAR_FIELD
(
elmalign
);
COPY_NODE_FIELD
(
exprs
);
COPY_NODE_FIELD
(
exprs
);
COPY_INTLIST_FIELD
(
paramIds
);
COPY_INTLIST_FIELD
(
paramIds
);
COPY_NODE_FIELD
(
plan
);
COPY_NODE_FIELD
(
plan
);
...
...
src/backend/nodes/equalfuncs.c
View file @
111d8e52
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.19
8 2003/06/25 04:19:24
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.19
9 2003/06/25 21:30:29
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -205,7 +205,6 @@ _equalAggref(Aggref *a, Aggref *b)
...
@@ -205,7 +205,6 @@ _equalAggref(Aggref *a, Aggref *b)
COMPARE_SCALAR_FIELD
(
agglevelsup
);
COMPARE_SCALAR_FIELD
(
agglevelsup
);
COMPARE_SCALAR_FIELD
(
aggstar
);
COMPARE_SCALAR_FIELD
(
aggstar
);
COMPARE_SCALAR_FIELD
(
aggdistinct
);
COMPARE_SCALAR_FIELD
(
aggdistinct
);
COMPARE_NODE_FIELD
(
args
);
return
true
;
return
true
;
}
}
...
@@ -302,7 +301,6 @@ _equalSubLink(SubLink *a, SubLink *b)
...
@@ -302,7 +301,6 @@ _equalSubLink(SubLink *a, SubLink *b)
{
{
COMPARE_SCALAR_FIELD
(
subLinkType
);
COMPARE_SCALAR_FIELD
(
subLinkType
);
COMPARE_SCALAR_FIELD
(
useOr
);
COMPARE_SCALAR_FIELD
(
useOr
);
COMPARE_SCALAR_FIELD
(
isExpr
);
COMPARE_NODE_FIELD
(
lefthand
);
COMPARE_NODE_FIELD
(
lefthand
);
COMPARE_NODE_FIELD
(
operName
);
COMPARE_NODE_FIELD
(
operName
);
COMPARE_OIDLIST_FIELD
(
operOids
);
COMPARE_OIDLIST_FIELD
(
operOids
);
...
@@ -316,12 +314,6 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
...
@@ -316,12 +314,6 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
{
{
COMPARE_SCALAR_FIELD
(
subLinkType
);
COMPARE_SCALAR_FIELD
(
subLinkType
);
COMPARE_SCALAR_FIELD
(
useOr
);
COMPARE_SCALAR_FIELD
(
useOr
);
COMPARE_SCALAR_FIELD
(
isExpr
);
COMPARE_SCALAR_FIELD
(
exprtype
);
COMPARE_SCALAR_FIELD
(
elemtype
);
COMPARE_SCALAR_FIELD
(
elmlen
);
COMPARE_SCALAR_FIELD
(
elmbyval
);
COMPARE_SCALAR_FIELD
(
elmalign
);
COMPARE_NODE_FIELD
(
exprs
);
COMPARE_NODE_FIELD
(
exprs
);
COMPARE_INTLIST_FIELD
(
paramIds
);
COMPARE_INTLIST_FIELD
(
paramIds
);
/* should compare plans, but have to settle for comparing plan IDs */
/* should compare plans, but have to settle for comparing plan IDs */
...
...
src/backend/nodes/outfuncs.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.2
09 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.2
10 2003/06/25 21:30:29
momjian Exp $
*
*
* NOTES
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
* Every node type that can appear in stored rules' parsetrees *must*
...
@@ -616,7 +616,6 @@ _outAggref(StringInfo str, Aggref *node)
...
@@ -616,7 +616,6 @@ _outAggref(StringInfo str, Aggref *node)
WRITE_UINT_FIELD
(
agglevelsup
);
WRITE_UINT_FIELD
(
agglevelsup
);
WRITE_BOOL_FIELD
(
aggstar
);
WRITE_BOOL_FIELD
(
aggstar
);
WRITE_BOOL_FIELD
(
aggdistinct
);
WRITE_BOOL_FIELD
(
aggdistinct
);
WRITE_NODE_FIELD
(
args
);
}
}
static
void
static
void
...
@@ -702,7 +701,6 @@ _outSubLink(StringInfo str, SubLink *node)
...
@@ -702,7 +701,6 @@ _outSubLink(StringInfo str, SubLink *node)
WRITE_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
WRITE_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
WRITE_BOOL_FIELD
(
useOr
);
WRITE_BOOL_FIELD
(
useOr
);
WRITE_BOOL_FIELD
(
isExpr
);
WRITE_NODE_FIELD
(
lefthand
);
WRITE_NODE_FIELD
(
lefthand
);
WRITE_NODE_FIELD
(
operName
);
WRITE_NODE_FIELD
(
operName
);
WRITE_OIDLIST_FIELD
(
operOids
);
WRITE_OIDLIST_FIELD
(
operOids
);
...
@@ -716,12 +714,6 @@ _outSubPlan(StringInfo str, SubPlan *node)
...
@@ -716,12 +714,6 @@ _outSubPlan(StringInfo str, SubPlan *node)
WRITE_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
WRITE_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
WRITE_BOOL_FIELD
(
useOr
);
WRITE_BOOL_FIELD
(
useOr
);
WRITE_BOOL_FIELD
(
isExpr
);
WRITE_OID_FIELD
(
exprtype
);
WRITE_OID_FIELD
(
elemtype
);
WRITE_INT_FIELD
(
elmlen
);
WRITE_BOOL_FIELD
(
elmbyval
);
WRITE_CHAR_FIELD
(
elmalign
);
WRITE_NODE_FIELD
(
exprs
);
WRITE_NODE_FIELD
(
exprs
);
WRITE_INTLIST_FIELD
(
paramIds
);
WRITE_INTLIST_FIELD
(
paramIds
);
WRITE_NODE_FIELD
(
plan
);
WRITE_NODE_FIELD
(
plan
);
...
...
src/backend/nodes/readfuncs.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.15
5 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.15
6 2003/06/25 21:30:30
momjian Exp $
*
*
* NOTES
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
* Path and Plan nodes do not have any readfuncs support, because we
...
@@ -416,7 +416,6 @@ _readAggref(void)
...
@@ -416,7 +416,6 @@ _readAggref(void)
READ_UINT_FIELD
(
agglevelsup
);
READ_UINT_FIELD
(
agglevelsup
);
READ_BOOL_FIELD
(
aggstar
);
READ_BOOL_FIELD
(
aggstar
);
READ_BOOL_FIELD
(
aggdistinct
);
READ_BOOL_FIELD
(
aggdistinct
);
READ_NODE_FIELD
(
args
);
READ_DONE
();
READ_DONE
();
}
}
...
@@ -546,7 +545,6 @@ _readSubLink(void)
...
@@ -546,7 +545,6 @@ _readSubLink(void)
READ_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
READ_ENUM_FIELD
(
subLinkType
,
SubLinkType
);
READ_BOOL_FIELD
(
useOr
);
READ_BOOL_FIELD
(
useOr
);
READ_BOOL_FIELD
(
isExpr
);
READ_NODE_FIELD
(
lefthand
);
READ_NODE_FIELD
(
lefthand
);
READ_NODE_FIELD
(
operName
);
READ_NODE_FIELD
(
operName
);
READ_OIDLIST_FIELD
(
operOids
);
READ_OIDLIST_FIELD
(
operOids
);
...
...
src/backend/optimizer/plan/subselect.c
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.7
7 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.7
8 2003/06/25 21:30:30
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -83,7 +83,7 @@ typedef struct finalize_primnode_context
...
@@ -83,7 +83,7 @@ typedef struct finalize_primnode_context
static
List
*
convert_sublink_opers
(
List
*
lefthand
,
List
*
operOids
,
static
List
*
convert_sublink_opers
(
List
*
lefthand
,
List
*
operOids
,
List
*
targetlist
,
int
rtindex
,
List
*
targetlist
,
int
rtindex
,
bool
isExpr
,
List
**
righthandIds
);
List
**
righthandIds
);
static
bool
subplan_is_hashable
(
SubLink
*
slink
,
SubPlan
*
node
);
static
bool
subplan_is_hashable
(
SubLink
*
slink
,
SubPlan
*
node
);
static
Node
*
replace_correlation_vars_mutator
(
Node
*
node
,
void
*
context
);
static
Node
*
replace_correlation_vars_mutator
(
Node
*
node
,
void
*
context
);
static
Node
*
process_sublinks_mutator
(
Node
*
node
,
bool
*
isTopQual
);
static
Node
*
process_sublinks_mutator
(
Node
*
node
,
bool
*
isTopQual
);
...
@@ -299,12 +299,6 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
...
@@ -299,12 +299,6 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
*/
*/
node
->
subLinkType
=
slink
->
subLinkType
;
node
->
subLinkType
=
slink
->
subLinkType
;
node
->
useOr
=
slink
->
useOr
;
node
->
useOr
=
slink
->
useOr
;
node
->
isExpr
=
slink
->
isExpr
;
node
->
exprtype
=
InvalidOid
;
node
->
elemtype
=
InvalidOid
;
node
->
elmlen
=
0
;
node
->
elmbyval
=
false
;
node
->
elmalign
=
'\0'
;
node
->
exprs
=
NIL
;
node
->
exprs
=
NIL
;
node
->
paramIds
=
NIL
;
node
->
paramIds
=
NIL
;
node
->
useHashTable
=
false
;
node
->
useHashTable
=
false
;
...
@@ -380,7 +374,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
...
@@ -380,7 +374,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
exprs
=
convert_sublink_opers
(
lefthand
,
exprs
=
convert_sublink_opers
(
lefthand
,
slink
->
operOids
,
slink
->
operOids
,
plan
->
targetlist
,
plan
->
targetlist
,
0
,
node
->
isExpr
,
0
,
&
node
->
paramIds
);
&
node
->
paramIds
);
node
->
setParam
=
listCopy
(
node
->
paramIds
);
node
->
setParam
=
listCopy
(
node
->
paramIds
);
PlannerInitPlan
=
lappend
(
PlannerInitPlan
,
node
);
PlannerInitPlan
=
lappend
(
PlannerInitPlan
,
node
);
...
@@ -463,7 +457,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
...
@@ -463,7 +457,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
node
->
exprs
=
convert_sublink_opers
(
lefthand
,
node
->
exprs
=
convert_sublink_opers
(
lefthand
,
slink
->
operOids
,
slink
->
operOids
,
plan
->
targetlist
,
plan
->
targetlist
,
0
,
node
->
isExpr
,
0
,
&
node
->
paramIds
);
&
node
->
paramIds
);
/*
/*
...
@@ -505,7 +499,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
...
@@ -505,7 +499,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
static
List
*
static
List
*
convert_sublink_opers
(
List
*
lefthand
,
List
*
operOids
,
convert_sublink_opers
(
List
*
lefthand
,
List
*
operOids
,
List
*
targetlist
,
int
rtindex
,
List
*
targetlist
,
int
rtindex
,
bool
isExpr
,
List
**
righthandIds
)
List
**
righthandIds
)
{
{
List
*
result
=
NIL
;
List
*
result
=
NIL
;
List
*
lst
;
List
*
lst
;
...
@@ -560,38 +554,13 @@ convert_sublink_opers(List *lefthand, List *operOids,
...
@@ -560,38 +554,13 @@ convert_sublink_opers(List *lefthand, List *operOids,
* are not expecting to have to resolve unknown Params, so
* are not expecting to have to resolve unknown Params, so
* it's okay to pass a null pstate.)
* it's okay to pass a null pstate.)
*/
*/
if
(
!
isExpr
)
result
=
lappend
(
result
,
{
make_op_expr
(
NULL
,
result
=
lappend
(
result
,
tup
,
make_op_expr
(
NULL
,
leftop
,
tup
,
rightop
,
leftop
,
exprType
(
leftop
),
rightop
,
te
->
resdom
->
restype
));
exprType
(
leftop
),
te
->
resdom
->
restype
));
}
else
{
Oid
exprtype
=
te
->
resdom
->
restype
;
Oid
elemtype
=
get_element_type
(
exprtype
);
if
(
elemtype
!=
InvalidOid
)
result
=
lappend
(
result
,
make_op_expr
(
NULL
,
tup
,
leftop
,
rightop
,
exprType
(
leftop
),
elemtype
));
else
result
=
lappend
(
result
,
make_op_expr
(
NULL
,
tup
,
leftop
,
rightop
,
exprType
(
leftop
),
exprtype
));
}
ReleaseSysCache
(
tup
);
ReleaseSysCache
(
tup
);
...
@@ -702,17 +671,13 @@ convert_IN_to_join(Query *parse, SubLink *sublink)
...
@@ -702,17 +671,13 @@ convert_IN_to_join(Query *parse, SubLink *sublink)
/*
/*
* The sublink type must be "= ANY" --- that is, an IN operator.
* The sublink type must be "= ANY" --- that is, an IN operator.
* (We require the operator name to be unqualified, which may be
* (We require the operator name to be unqualified, which may be
* overly paranoid, or may not be.) It must not be an Expression
* overly paranoid, or may not be.)
* sublink.
*/
*/
if
(
sublink
->
subLinkType
!=
ANY_SUBLINK
)
if
(
sublink
->
subLinkType
!=
ANY_SUBLINK
)
return
NULL
;
return
NULL
;
if
(
length
(
sublink
->
operName
)
!=
1
||
if
(
length
(
sublink
->
operName
)
!=
1
||
strcmp
(
strVal
(
lfirst
(
sublink
->
operName
)),
"="
)
!=
0
)
strcmp
(
strVal
(
lfirst
(
sublink
->
operName
)),
"="
)
!=
0
)
return
NULL
;
return
NULL
;
if
(
sublink
->
isExpr
)
return
NULL
;
/*
/*
* The sub-select must not refer to any Vars of the parent query.
* The sub-select must not refer to any Vars of the parent query.
* (Vars of higher levels should be okay, though.)
* (Vars of higher levels should be okay, though.)
...
@@ -765,7 +730,7 @@ convert_IN_to_join(Query *parse, SubLink *sublink)
...
@@ -765,7 +730,7 @@ convert_IN_to_join(Query *parse, SubLink *sublink)
exprs
=
convert_sublink_opers
(
sublink
->
lefthand
,
exprs
=
convert_sublink_opers
(
sublink
->
lefthand
,
sublink
->
operOids
,
sublink
->
operOids
,
subselect
->
targetList
,
subselect
->
targetList
,
rtindex
,
sublink
->
isExpr
,
rtindex
,
&
ininfo
->
sub_targetlist
);
&
ininfo
->
sub_targetlist
);
return
(
Node
*
)
make_ands_explicit
(
exprs
);
return
(
Node
*
)
make_ands_explicit
(
exprs
);
}
}
...
...
src/backend/optimizer/util/clauses.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.14
0 2003/06/24 23:14:43
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.14
1 2003/06/25 21:30:30
momjian Exp $
*
*
* HISTORY
* HISTORY
* AUTHOR DATE MAJOR EVENT
* AUTHOR DATE MAJOR EVENT
...
@@ -132,28 +132,6 @@ get_rightop(Expr *clause)
...
@@ -132,28 +132,6 @@ get_rightop(Expr *clause)
return
NULL
;
return
NULL
;
}
}
/*****************************************************************************
* FUNCTION clause functions
*****************************************************************************/
/*
* make_funcclause
* Creates a function clause given its function info and argument list.
*/
Expr
*
make_funcclause
(
Oid
funcid
,
Oid
funcresulttype
,
bool
funcretset
,
CoercionForm
funcformat
,
List
*
funcargs
)
{
FuncExpr
*
expr
=
makeNode
(
FuncExpr
);
expr
->
funcid
=
funcid
;
expr
->
funcresulttype
=
funcresulttype
;
expr
->
funcretset
=
funcretset
;
expr
->
funcformat
=
funcformat
;
expr
->
args
=
funcargs
;
return
(
Expr
*
)
expr
;
}
/*****************************************************************************
/*****************************************************************************
* NOT clause functions
* NOT clause functions
*****************************************************************************/
*****************************************************************************/
...
...
src/backend/parser/gram.y
View file @
111d8e52
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.42
0 2003/06/25 04:19:24
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.42
1 2003/06/25 21:30:30
momjian Exp $
*
*
* HISTORY
* HISTORY
* AUTHOR DATE MAJOR EVENT
* AUTHOR DATE MAJOR EVENT
...
@@ -5505,7 +5505,6 @@ r_expr: row IN_P select_with_parens
...
@@ -5505,7 +5505,6 @@ r_expr: row IN_P select_with_parens
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = ANY_SUBLINK;
n->subLinkType = ANY_SUBLINK;
n->isExpr = false;
n->lefthand = $1;
n->lefthand = $1;
n->operName = makeList1(makeString("="));
n->operName = makeList1(makeString("="));
n->subselect = $3;
n->subselect = $3;
...
@@ -5516,7 +5515,6 @@ r_expr: row IN_P select_with_parens
...
@@ -5516,7 +5515,6 @@ r_expr: row IN_P select_with_parens
/* Make an IN node */
/* Make an IN node */
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = ANY_SUBLINK;
n->subLinkType = ANY_SUBLINK;
n->isExpr = false;
n->lefthand = $1;
n->lefthand = $1;
n->operName = makeList1(makeString("="));
n->operName = makeList1(makeString("="));
n->subselect = $4;
n->subselect = $4;
...
@@ -5528,7 +5526,6 @@ r_expr: row IN_P select_with_parens
...
@@ -5528,7 +5526,6 @@ r_expr: row IN_P select_with_parens
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = $3;
n->subLinkType = $3;
n->isExpr = false;
n->lefthand = $1;
n->lefthand = $1;
n->operName = $2;
n->operName = $2;
n->subselect = $4;
n->subselect = $4;
...
@@ -5539,7 +5536,6 @@ r_expr: row IN_P select_with_parens
...
@@ -5539,7 +5536,6 @@ r_expr: row IN_P select_with_parens
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = MULTIEXPR_SUBLINK;
n->subLinkType = MULTIEXPR_SUBLINK;
n->isExpr = false;
n->lefthand = $1;
n->lefthand = $1;
n->operName = $2;
n->operName = $2;
n->subselect = $3;
n->subselect = $3;
...
@@ -5923,7 +5919,6 @@ a_expr: c_expr { $$ = $1; }
...
@@ -5923,7 +5919,6 @@ a_expr: c_expr { $$ = $1; }
{
{
SubLink *n = (SubLink *)$3;
SubLink *n = (SubLink *)$3;
n->subLinkType = ANY_SUBLINK;
n->subLinkType = ANY_SUBLINK;
n->isExpr = false;
n->lefthand = makeList1($1);
n->lefthand = makeList1($1);
n->operName = makeList1(makeString("="));
n->operName = makeList1(makeString("="));
$$ = (Node *)n;
$$ = (Node *)n;
...
@@ -5951,7 +5946,6 @@ a_expr: c_expr { $$ = $1; }
...
@@ -5951,7 +5946,6 @@ a_expr: c_expr { $$ = $1; }
{
{
/* Make an IN node */
/* Make an IN node */
SubLink *n = (SubLink *)$4;
SubLink *n = (SubLink *)$4;
n->isExpr = false;
n->subLinkType = ANY_SUBLINK;
n->subLinkType = ANY_SUBLINK;
n->lefthand = makeList1($1);
n->lefthand = makeList1($1);
n->operName = makeList1(makeString("="));
n->operName = makeList1(makeString("="));
...
@@ -5978,38 +5972,11 @@ a_expr: c_expr { $$ = $1; }
...
@@ -5978,38 +5972,11 @@ a_expr: c_expr { $$ = $1; }
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = $3;
n->subLinkType = $3;
n->isExpr = false;
n->lefthand = makeList1($1);
n->lefthand = makeList1($1);
n->operName = $2;
n->operName = $2;
n->subselect = $4;
n->subselect = $4;
$$ = (Node *)n;
$$ = (Node *)n;
}
}
| a_expr qual_all_Op sub_type '(' a_expr ')' %prec Op
{
SubLink *n = makeNode(SubLink);
SelectStmt *s = makeNode(SelectStmt);
ResTarget *r = makeNode(ResTarget);
r->name = NULL;
r->indirection = NIL;
r->val = (Node *)$5;
s->distinctClause = NIL;
s->targetList = makeList1(r);
s->into = NULL;
s->intoColNames = NIL;
s->fromClause = NIL;
s->whereClause = NULL;
s->groupClause = NIL;
s->havingClause = NULL;
n->subLinkType = $3;
n->isExpr = true;
n->lefthand = makeList1($1);
n->operName = $2;
n->subselect = (Node *) s;
$$ = (Node *)n;
}
| UNIQUE select_with_parens %prec Op
| UNIQUE select_with_parens %prec Op
{
{
/* Not sure how to get rid of the parentheses
/* Not sure how to get rid of the parentheses
...
@@ -6586,7 +6553,6 @@ c_expr: columnref { $$ = (Node *) $1; }
...
@@ -6586,7 +6553,6 @@ c_expr: columnref { $$ = (Node *) $1; }
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = EXPR_SUBLINK;
n->subLinkType = EXPR_SUBLINK;
n->isExpr = false;
n->lefthand = NIL;
n->lefthand = NIL;
n->operName = NIL;
n->operName = NIL;
n->subselect = $1;
n->subselect = $1;
...
@@ -6596,7 +6562,6 @@ c_expr: columnref { $$ = (Node *) $1; }
...
@@ -6596,7 +6562,6 @@ c_expr: columnref { $$ = (Node *) $1; }
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = EXISTS_SUBLINK;
n->subLinkType = EXISTS_SUBLINK;
n->isExpr = false;
n->lefthand = NIL;
n->lefthand = NIL;
n->operName = NIL;
n->operName = NIL;
n->subselect = $2;
n->subselect = $2;
...
@@ -6606,7 +6571,6 @@ c_expr: columnref { $$ = (Node *) $1; }
...
@@ -6606,7 +6571,6 @@ c_expr: columnref { $$ = (Node *) $1; }
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->subLinkType = ARRAY_SUBLINK;
n->subLinkType = ARRAY_SUBLINK;
n->isExpr = false;
n->lefthand = NIL;
n->lefthand = NIL;
n->operName = NIL;
n->operName = NIL;
n->subselect = $2;
n->subselect = $2;
...
@@ -6781,7 +6745,6 @@ trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); }
...
@@ -6781,7 +6745,6 @@ trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); }
in_expr: select_with_parens
in_expr: select_with_parens
{
{
SubLink *n = makeNode(SubLink);
SubLink *n = makeNode(SubLink);
n->isExpr = false;
n->subselect = $1;
n->subselect = $1;
/* other fields will be filled later */
/* other fields will be filled later */
$$ = (Node *)n;
$$ = (Node *)n;
...
...
src/backend/parser/parse_coerce.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.
99 2003/06/25 04:32:03
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.
100 2003/06/25 21:30:31
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -859,11 +859,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
...
@@ -859,11 +859,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
/* Get the element type based on the array type, if we have one */
/* Get the element type based on the array type, if we have one */
if
(
OidIsValid
(
array_typeid
))
if
(
OidIsValid
(
array_typeid
))
{
{
if
(
array_typeid
!=
ANYARRAYOID
)
array_typelem
=
get_element_type
(
array_typeid
);
array_typelem
=
get_element_type
(
array_typeid
);
else
array_typelem
=
ANYELEMENTOID
;
if
(
!
OidIsValid
(
array_typelem
))
if
(
!
OidIsValid
(
array_typelem
))
elog
(
ERROR
,
"Argument declared ANYARRAY is not an array: %s"
,
elog
(
ERROR
,
"Argument declared ANYARRAY is not an array: %s"
,
format_type_be
(
array_typeid
));
format_type_be
(
array_typeid
));
...
@@ -923,11 +919,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
...
@@ -923,11 +919,7 @@ enforce_generic_type_consistency(Oid *actual_arg_types,
{
{
if
(
!
OidIsValid
(
array_typeid
))
if
(
!
OidIsValid
(
array_typeid
))
{
{
if
(
elem_typeid
!=
ANYELEMENTOID
)
array_typeid
=
get_array_type
(
elem_typeid
);
array_typeid
=
get_array_type
(
elem_typeid
);
else
array_typeid
=
ANYARRAYOID
;
if
(
!
OidIsValid
(
array_typeid
))
if
(
!
OidIsValid
(
array_typeid
))
elog
(
ERROR
,
"Cannot find array type for datatype %s"
,
elog
(
ERROR
,
"Cannot find array type for datatype %s"
,
format_type_be
(
elem_typeid
));
format_type_be
(
elem_typeid
));
...
@@ -1178,11 +1170,6 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
...
@@ -1178,11 +1170,6 @@ IsBinaryCoercible(Oid srctype, Oid targettype)
if
(
srctype
==
targettype
)
if
(
srctype
==
targettype
)
return
true
;
return
true
;
/* Last of the fast-paths: check for matching polymorphic arrays */
if
(
targettype
==
ANYARRAYOID
)
if
(
get_element_type
(
srctype
)
!=
InvalidOid
)
return
true
;
/* Else look in pg_cast */
/* Else look in pg_cast */
tuple
=
SearchSysCache
(
CASTSOURCETARGET
,
tuple
=
SearchSysCache
(
CASTSOURCETARGET
,
ObjectIdGetDatum
(
srctype
),
ObjectIdGetDatum
(
srctype
),
...
...
src/backend/parser/parse_expr.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.1
49 2003/06/24 23:14:45
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.1
50 2003/06/25 21:30:31
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -436,7 +436,6 @@ transformExpr(ParseState *pstate, Node *expr)
...
@@ -436,7 +436,6 @@ transformExpr(ParseState *pstate, Node *expr)
sublink
->
operName
=
NIL
;
sublink
->
operName
=
NIL
;
sublink
->
operOids
=
NIL
;
sublink
->
operOids
=
NIL
;
sublink
->
useOr
=
FALSE
;
sublink
->
useOr
=
FALSE
;
sublink
->
isExpr
=
FALSE
;
}
}
else
if
(
sublink
->
subLinkType
==
EXPR_SUBLINK
||
else
if
(
sublink
->
subLinkType
==
EXPR_SUBLINK
||
sublink
->
subLinkType
==
ARRAY_SUBLINK
)
sublink
->
subLinkType
==
ARRAY_SUBLINK
)
...
@@ -464,7 +463,6 @@ transformExpr(ParseState *pstate, Node *expr)
...
@@ -464,7 +463,6 @@ transformExpr(ParseState *pstate, Node *expr)
sublink
->
operName
=
NIL
;
sublink
->
operName
=
NIL
;
sublink
->
operOids
=
NIL
;
sublink
->
operOids
=
NIL
;
sublink
->
useOr
=
FALSE
;
sublink
->
useOr
=
FALSE
;
sublink
->
isExpr
=
FALSE
;
}
}
else
else
{
{
...
@@ -540,30 +538,10 @@ transformExpr(ParseState *pstate, Node *expr)
...
@@ -540,30 +538,10 @@ transformExpr(ParseState *pstate, Node *expr)
* here, because make_subplan() will insert type
* here, because make_subplan() will insert type
* coercion calls if needed.
* coercion calls if needed.
*/
*/
if
(
!
sublink
->
isExpr
)
optup
=
oper
(
op
,
{
exprType
(
lexpr
),
optup
=
oper
(
op
,
exprType
((
Node
*
)
tent
->
expr
),
exprType
(
lexpr
),
false
);
exprType
((
Node
*
)
tent
->
expr
),
false
);
}
else
{
Oid
exprtype
=
exprType
((
Node
*
)
tent
->
expr
);
Oid
elemtype
=
get_element_type
(
exprtype
);
if
(
elemtype
!=
InvalidOid
)
optup
=
oper
(
op
,
exprType
(
lexpr
),
elemtype
,
false
);
else
optup
=
oper
(
op
,
exprType
(
lexpr
),
exprtype
,
false
);
}
opform
=
(
Form_pg_operator
)
GETSTRUCT
(
optup
);
opform
=
(
Form_pg_operator
)
GETSTRUCT
(
optup
);
if
(
opform
->
oprresult
!=
BOOLOID
)
if
(
opform
->
oprresult
!=
BOOLOID
)
...
@@ -765,7 +743,7 @@ transformExpr(ParseState *pstate, Node *expr)
...
@@ -765,7 +743,7 @@ transformExpr(ParseState *pstate, Node *expr)
ArrayExpr
*
e
=
(
ArrayExpr
*
)
lfirst
(
element
);
ArrayExpr
*
e
=
(
ArrayExpr
*
)
lfirst
(
element
);
if
(
!
IsA
(
e
,
ArrayExpr
))
if
(
!
IsA
(
e
,
ArrayExpr
))
elog
(
ERROR
,
"Multidimensional ARRAY[] must be built from nested array expressions"
);
elog
(
ERROR
,
"Multi
-
dimensional ARRAY[] must be built from nested array expressions"
);
if
(
ndims
==
0
)
if
(
ndims
==
0
)
ndims
=
e
->
ndims
;
ndims
=
e
->
ndims
;
else
if
(
e
->
ndims
!=
ndims
)
else
if
(
e
->
ndims
!=
ndims
)
...
...
src/backend/parser/parse_func.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.15
1 2003/06/25 20:07:39 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.15
2 2003/06/25 21:30:31 momjian
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -336,7 +336,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
...
@@ -336,7 +336,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
aggref
->
target
=
lfirst
(
fargs
);
aggref
->
target
=
lfirst
(
fargs
);
aggref
->
aggstar
=
agg_star
;
aggref
->
aggstar
=
agg_star
;
aggref
->
aggdistinct
=
agg_distinct
;
aggref
->
aggdistinct
=
agg_distinct
;
aggref
->
args
=
fargs
;
/* parse_agg.c does additional aggregate-specific processing */
/* parse_agg.c does additional aggregate-specific processing */
transformAggregateCall
(
pstate
,
aggref
);
transformAggregateCall
(
pstate
,
aggref
);
...
...
src/backend/parser/parse_oper.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.6
5 2003/06/24 23:14:45
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.6
6 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -137,33 +137,6 @@ Operator
...
@@ -137,33 +137,6 @@ Operator
equality_oper
(
Oid
argtype
,
bool
noError
)
equality_oper
(
Oid
argtype
,
bool
noError
)
{
{
Operator
optup
;
Operator
optup
;
Oid
elem_type
=
get_element_type
(
argtype
);
if
(
OidIsValid
(
elem_type
))
{
bool
found
=
false
;
/*
* If the datatype is an array, look for an "=" operator for the
* element datatype. We require it to be an exact or binary-compatible
* match, since most callers are not prepared to cope with adding any
* run-time type coercion steps.
*/
optup
=
equality_oper
(
elem_type
,
true
);
if
(
optup
!=
NULL
)
{
found
=
true
;
ReleaseSysCache
(
optup
);
}
if
(
!
found
)
{
if
(
!
noError
)
elog
(
ERROR
,
"Unable to identify an equality operator for "
\
"array type's element type %s"
,
format_type_be
(
elem_type
));
return
NULL
;
}
}
/*
/*
* Look for an "=" operator for the datatype. We require it to be
* Look for an "=" operator for the datatype. We require it to be
...
@@ -202,33 +175,6 @@ Operator
...
@@ -202,33 +175,6 @@ Operator
ordering_oper
(
Oid
argtype
,
bool
noError
)
ordering_oper
(
Oid
argtype
,
bool
noError
)
{
{
Operator
optup
;
Operator
optup
;
Oid
elem_type
=
get_element_type
(
argtype
);
if
(
OidIsValid
(
elem_type
))
{
bool
found
=
false
;
/*
* If the datatype is an array, find the array element type's equality
* operator, and use its lsortop (it *must* be mergejoinable). We use
* this definition because for sorting and grouping purposes, it's
* important that the equality and ordering operators are consistent.
*/
optup
=
ordering_oper
(
elem_type
,
true
);
if
(
optup
!=
NULL
)
{
found
=
true
;
ReleaseSysCache
(
optup
);
}
if
(
!
found
)
{
if
(
!
noError
)
elog
(
ERROR
,
"Unable to identify an ordering operator for "
\
"array type's element type %s"
,
format_type_be
(
elem_type
));
return
NULL
;
}
}
/*
/*
* Find the type's equality operator, and use its lsortop (it *must*
* Find the type's equality operator, and use its lsortop (it *must*
...
@@ -274,21 +220,6 @@ equality_oper_funcid(Oid argtype)
...
@@ -274,21 +220,6 @@ equality_oper_funcid(Oid argtype)
return
result
;
return
result
;
}
}
/*
* ordering_oper_funcid - convenience routine for oprfuncid(ordering_oper())
*/
Oid
ordering_oper_funcid
(
Oid
argtype
)
{
Operator
optup
;
Oid
result
;
optup
=
ordering_oper
(
argtype
,
false
);
result
=
oprfuncid
(
optup
);
ReleaseSysCache
(
optup
);
return
result
;
}
/*
/*
* ordering_oper_opid - convenience routine for oprid(ordering_oper())
* ordering_oper_opid - convenience routine for oprid(ordering_oper())
*
*
...
...
src/backend/utils/adt/acl.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.
89 2003/06/24 23:14:45
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.
90 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -427,15 +427,6 @@ aclitemeq(const AclItem *a1, const AclItem *a2)
...
@@ -427,15 +427,6 @@ aclitemeq(const AclItem *a1, const AclItem *a2)
a1
->
ai_grantor
==
a2
->
ai_grantor
;
a1
->
ai_grantor
==
a2
->
ai_grantor
;
}
}
/*
* user-facing version of aclitemeq() for use as the
* aclitem equality operator
*/
Datum
aclitem_eq
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
aclitemeq
(
PG_GETARG_ACLITEM_P
(
0
),
PG_GETARG_ACLITEM_P
(
1
)));
}
/*
/*
* acldefault() --- create an ACL describing default access permissions
* acldefault() --- create an ACL describing default access permissions
...
...
src/backend/utils/adt/array_userfuncs.c
View file @
111d8e52
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Copyright (c) 2003, PostgreSQL Global Development Group
* Copyright (c) 2003, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.
2 2003/06/24 23:14:45
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.
3 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -18,6 +18,35 @@
...
@@ -18,6 +18,35 @@
#include "utils/lsyscache.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
/*-----------------------------------------------------------------------------
* singleton_array :
* Form a multi-dimensional array given one starting element.
*
* - first argument is the datum with which to build the array
* - second argument is the number of dimensions the array should have;
* defaults to 1 if no second argument is provided
*----------------------------------------------------------------------------
*/
Datum
singleton_array
(
PG_FUNCTION_ARGS
)
{
Oid
elem_type
=
get_fn_expr_argtype
(
fcinfo
,
0
);
int
ndims
;
if
(
elem_type
==
InvalidOid
)
elog
(
ERROR
,
"Cannot determine input datatype"
);
if
(
PG_NARGS
()
==
2
)
ndims
=
PG_GETARG_INT32
(
1
);
else
ndims
=
1
;
PG_RETURN_ARRAYTYPE_P
(
create_singleton_array
(
elem_type
,
PG_GETARG_DATUM
(
0
),
ndims
));
}
/*-----------------------------------------------------------------------------
/*-----------------------------------------------------------------------------
* array_push :
* array_push :
* push an element onto either end of a one-dimensional array
* push an element onto either end of a one-dimensional array
...
@@ -41,7 +70,6 @@ array_push(PG_FUNCTION_ARGS)
...
@@ -41,7 +70,6 @@ array_push(PG_FUNCTION_ARGS)
Oid
arg1_typeid
=
get_fn_expr_argtype
(
fcinfo
,
1
);
Oid
arg1_typeid
=
get_fn_expr_argtype
(
fcinfo
,
1
);
Oid
arg0_elemid
;
Oid
arg0_elemid
;
Oid
arg1_elemid
;
Oid
arg1_elemid
;
ArrayMetaState
*
my_extra
;
if
(
arg0_typeid
==
InvalidOid
||
arg1_typeid
==
InvalidOid
)
if
(
arg0_typeid
==
InvalidOid
||
arg1_typeid
==
InvalidOid
)
elog
(
ERROR
,
"array_push: cannot determine input data types"
);
elog
(
ERROR
,
"array_push: cannot determine input data types"
);
...
@@ -67,61 +95,28 @@ array_push(PG_FUNCTION_ARGS)
...
@@ -67,61 +95,28 @@ array_push(PG_FUNCTION_ARGS)
PG_RETURN_NULL
();
/* keep compiler quiet */
PG_RETURN_NULL
();
/* keep compiler quiet */
}
}
if
(
ARR_NDIM
(
v
)
==
1
)
/* Sanity check: do we have a one-dimensional array */
{
if
(
ARR_NDIM
(
v
)
!=
1
)
lb
=
ARR_LBOUND
(
v
);
elog
(
ERROR
,
"Arrays greater than one-dimension are not supported"
);
dimv
=
ARR_DIMS
(
v
);
if
(
arg0_elemid
!=
InvalidOid
)
{
/* append newelem */
int
ub
=
dimv
[
0
]
+
lb
[
0
]
-
1
;
indx
=
ub
+
1
;
}
else
{
/* prepend newelem */
indx
=
lb
[
0
]
-
1
;
}
}
else
if
(
ARR_NDIM
(
v
)
==
0
)
indx
=
1
;
else
elog
(
ERROR
,
"only empty and one-dimensional arrays are supported"
);
/*
* 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
!=
element_type
)
lb
=
ARR_LBOUND
(
v
);
dimv
=
ARR_DIMS
(
v
);
if
(
arg0_elemid
!=
InvalidOid
)
{
{
/* Get info about element type */
/* append newelem */
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
int
ub
=
dimv
[
0
]
+
lb
[
0
]
-
1
;
indx
=
ub
+
1
;
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typalign
=
typalign
;
}
}
else
else
{
{
typlen
=
my_extra
->
typlen
;
/* prepend newelem */
typbyval
=
my_extra
->
typbyval
;
indx
=
lb
[
0
]
-
1
;
typalign
=
my_extra
->
typalign
;
}
}
result
=
array_set
(
v
,
1
,
&
indx
,
newelem
,
-
1
,
typlen
,
typbyval
,
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
typalign
,
&
isNull
);
result
=
array_set
(
v
,
1
,
&
indx
,
newelem
,
-
1
,
typlen
,
typbyval
,
typalign
,
&
isNull
);
PG_RETURN_ARRAYTYPE_P
(
result
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
}
...
@@ -150,28 +145,13 @@ array_cat(PG_FUNCTION_ARGS)
...
@@ -150,28 +145,13 @@ array_cat(PG_FUNCTION_ARGS)
/*
/*
* We must have one of the following combinations of inputs:
* We must have one of the following combinations of inputs:
* 1) one empty array, and one non-empty array
* 1) two arrays with ndims1 == ndims2
* 2) both arrays empty
* 2) ndims1 == ndims2 - 1
* 3) two arrays with ndims1 == ndims2
* 3) ndims1 == ndims2 + 1
* 4) ndims1 == ndims2 - 1
* 5) ndims1 == ndims2 + 1
*/
*/
ndims1
=
ARR_NDIM
(
v1
);
ndims1
=
ARR_NDIM
(
v1
);
ndims2
=
ARR_NDIM
(
v2
);
ndims2
=
ARR_NDIM
(
v2
);
/*
* short circuit - if one input array is empty, and the other is not,
* we return the non-empty one as the result
*
* if both are empty, return the first one
*/
if
(
ndims1
==
0
&&
ndims2
>
0
)
PG_RETURN_ARRAYTYPE_P
(
v2
);
if
(
ndims2
==
0
)
PG_RETURN_ARRAYTYPE_P
(
v1
);
/* the rest fall into combo 2, 3, or 4 */
if
(
ndims1
!=
ndims2
&&
ndims1
!=
ndims2
-
1
&&
ndims1
!=
ndims2
+
1
)
if
(
ndims1
!=
ndims2
&&
ndims1
!=
ndims2
-
1
&&
ndims1
!=
ndims2
+
1
)
elog
(
ERROR
,
"Cannot concatenate incompatible arrays of %d and "
elog
(
ERROR
,
"Cannot concatenate incompatible arrays of %d and "
"%d dimensions"
,
ndims1
,
ndims2
);
"%d dimensions"
,
ndims1
,
ndims2
);
...
@@ -286,15 +266,147 @@ array_cat(PG_FUNCTION_ARGS)
...
@@ -286,15 +266,147 @@ array_cat(PG_FUNCTION_ARGS)
PG_RETURN_ARRAYTYPE_P
(
result
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
}
/*----------------------------------------------------------------------------
* array_accum :
* accumulator to build a 1-D array from input values -- this can be used
* to create custom aggregates.
*
* This function is not marked strict, so we have to be careful about nulls.
*----------------------------------------------------------------------------
*/
Datum
array_accum
(
PG_FUNCTION_ARGS
)
{
/* return NULL if both arguments are NULL */
if
(
PG_ARGISNULL
(
0
)
&&
PG_ARGISNULL
(
1
))
PG_RETURN_NULL
();
/* create a new 1-D array from the new element if the array is NULL */
if
(
PG_ARGISNULL
(
0
))
{
Oid
tgt_type
=
get_fn_expr_rettype
(
fcinfo
);
Oid
tgt_elem_type
;
if
(
tgt_type
==
InvalidOid
)
elog
(
ERROR
,
"Cannot determine target array type"
);
tgt_elem_type
=
get_element_type
(
tgt_type
);
if
(
tgt_elem_type
==
InvalidOid
)
elog
(
ERROR
,
"Target type is not an array"
);
PG_RETURN_ARRAYTYPE_P
(
create_singleton_array
(
tgt_elem_type
,
PG_GETARG_DATUM
(
1
),
1
));
}
/* return the array if the new element is NULL */
if
(
PG_ARGISNULL
(
1
))
PG_RETURN_ARRAYTYPE_P
(
PG_GETARG_ARRAYTYPE_P_COPY
(
0
));
/*
* Otherwise this is equivalent to array_push. We hack the call a little
* so that array_push can see the fn_expr information.
*/
return
array_push
(
fcinfo
);
}
/*-----------------------------------------------------------------------------
* array_assign :
* assign an element of an array to a new value and return the
* redefined array
*----------------------------------------------------------------------------
*/
Datum
array_assign
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
v
;
int
idx_to_chg
;
Datum
newelem
;
int
*
dimv
,
*
lb
,
ub
;
ArrayType
*
result
;
bool
isNull
;
Oid
element_type
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
v
=
PG_GETARG_ARRAYTYPE_P
(
0
);
idx_to_chg
=
PG_GETARG_INT32
(
1
);
newelem
=
PG_GETARG_DATUM
(
2
);
/* Sanity check: do we have a one-dimensional array */
if
(
ARR_NDIM
(
v
)
!=
1
)
elog
(
ERROR
,
"Arrays greater than one-dimension are not supported"
);
lb
=
ARR_LBOUND
(
v
);
dimv
=
ARR_DIMS
(
v
);
ub
=
dimv
[
0
]
+
lb
[
0
]
-
1
;
if
(
idx_to_chg
<
lb
[
0
]
||
idx_to_chg
>
ub
)
elog
(
ERROR
,
"Cannot alter nonexistent array element: %d"
,
idx_to_chg
);
element_type
=
ARR_ELEMTYPE
(
v
);
/* Sanity check: do we have a non-zero element type */
if
(
element_type
==
0
)
elog
(
ERROR
,
"Invalid array element type: %u"
,
element_type
);
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
result
=
array_set
(
v
,
1
,
&
idx_to_chg
,
newelem
,
-
1
,
typlen
,
typbyval
,
typalign
,
&
isNull
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
/*-----------------------------------------------------------------------------
* array_subscript :
* return specific element of an array
*----------------------------------------------------------------------------
*/
Datum
array_subscript
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
v
;
int
idx
;
int
*
dimv
,
*
lb
,
ub
;
Datum
result
;
bool
isNull
;
Oid
element_type
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
v
=
PG_GETARG_ARRAYTYPE_P
(
0
);
idx
=
PG_GETARG_INT32
(
1
);
/* Sanity check: do we have a one-dimensional array */
if
(
ARR_NDIM
(
v
)
!=
1
)
elog
(
ERROR
,
"Arrays greater than one-dimension are not supported"
);
lb
=
ARR_LBOUND
(
v
);
dimv
=
ARR_DIMS
(
v
);
ub
=
dimv
[
0
]
+
lb
[
0
]
-
1
;
if
(
idx
<
lb
[
0
]
||
idx
>
ub
)
elog
(
ERROR
,
"Cannot return nonexistent array element: %d"
,
idx
);
element_type
=
ARR_ELEMTYPE
(
v
);
/* Sanity check: do we have a non-zero element type */
if
(
element_type
==
0
)
elog
(
ERROR
,
"Invalid array element type: %u"
,
element_type
);
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
result
=
array_ref
(
v
,
1
,
&
idx
,
-
1
,
typlen
,
typbyval
,
typalign
,
&
isNull
);
PG_RETURN_DATUM
(
result
);
}
/*
/*
* used by text_to_array() in varlena.c
* actually does the work for singleton_array(), and array_accum() if it is
* given a null input array.
*/
*/
ArrayType
*
ArrayType
*
create_singleton_array
(
FunctionCallInfo
fcinfo
,
create_singleton_array
(
Oid
element_type
,
Datum
element
,
int
ndims
)
Oid
element_type
,
Datum
element
,
int
ndims
)
{
{
Datum
dvalues
[
1
];
Datum
dvalues
[
1
];
int16
typlen
;
int16
typlen
;
...
@@ -303,7 +415,6 @@ create_singleton_array(FunctionCallInfo fcinfo,
...
@@ -303,7 +415,6 @@ create_singleton_array(FunctionCallInfo fcinfo,
int
dims
[
MAXDIM
];
int
dims
[
MAXDIM
];
int
lbs
[
MAXDIM
];
int
lbs
[
MAXDIM
];
int
i
;
int
i
;
ArrayMetaState
*
my_extra
;
if
(
element_type
==
0
)
if
(
element_type
==
0
)
elog
(
ERROR
,
"Invalid array element type: %u"
,
element_type
);
elog
(
ERROR
,
"Invalid array element type: %u"
,
element_type
);
...
@@ -318,35 +429,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
...
@@ -318,35 +429,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
lbs
[
i
]
=
1
;
lbs
[
i
]
=
1
;
}
}
/*
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
* 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
!=
element_type
)
{
/* Get info about element type */
get_typlenbyvalalign
(
element_type
,
&
typlen
,
&
typbyval
,
&
typalign
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typalign
=
typalign
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typalign
=
my_extra
->
typalign
;
}
return
construct_md_array
(
dvalues
,
ndims
,
dims
,
lbs
,
element_type
,
return
construct_md_array
(
dvalues
,
ndims
,
dims
,
lbs
,
element_type
,
typlen
,
typbyval
,
typalign
);
typlen
,
typbyval
,
typalign
);
...
...
src/backend/utils/adt/arrayfuncs.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.9
0 2003/06/24 23:14:45
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.9
1 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -21,10 +21,8 @@
...
@@ -21,10 +21,8 @@
#include "catalog/pg_type.h"
#include "catalog/pg_type.h"
#include "libpq/pqformat.h"
#include "libpq/pqformat.h"
#include "parser/parse_coerce.h"
#include "parser/parse_coerce.h"
#include "parser/parse_oper.h"
#include "utils/array.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/memutils.h"
#include "utils/memutils.h"
#include "utils/lsyscache.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/syscache.h"
...
@@ -72,6 +70,16 @@
...
@@ -72,6 +70,16 @@
#define RETURN_NULL(type) do { *isNull = true; return (type) 0; } while (0)
#define RETURN_NULL(type) do { *isNull = true; return (type) 0; } while (0)
/* I/O function selector for system_cache_lookup */
typedef
enum
IOFuncSelector
{
IOFunc_input
,
IOFunc_output
,
IOFunc_receive
,
IOFunc_send
}
IOFuncSelector
;
static
int
ArrayCount
(
char
*
str
,
int
*
dim
,
char
typdelim
);
static
int
ArrayCount
(
char
*
str
,
int
*
dim
,
char
typdelim
);
static
Datum
*
ReadArrayStr
(
char
*
arrayStr
,
int
nitems
,
int
ndim
,
int
*
dim
,
static
Datum
*
ReadArrayStr
(
char
*
arrayStr
,
int
nitems
,
int
ndim
,
int
*
dim
,
FmgrInfo
*
inputproc
,
Oid
typelem
,
int32
typmod
,
FmgrInfo
*
inputproc
,
Oid
typelem
,
int32
typmod
,
...
@@ -85,6 +93,10 @@ static Datum *ReadArrayBinary(StringInfo buf, int nitems,
...
@@ -85,6 +93,10 @@ static Datum *ReadArrayBinary(StringInfo buf, int nitems,
static
void
CopyArrayEls
(
char
*
p
,
Datum
*
values
,
int
nitems
,
static
void
CopyArrayEls
(
char
*
p
,
Datum
*
values
,
int
nitems
,
int
typlen
,
bool
typbyval
,
char
typalign
,
int
typlen
,
bool
typbyval
,
char
typalign
,
bool
freedata
);
bool
freedata
);
static
void
system_cache_lookup
(
Oid
element_type
,
IOFuncSelector
which_func
,
int
*
typlen
,
bool
*
typbyval
,
char
*
typdelim
,
Oid
*
typelem
,
Oid
*
proc
,
char
*
typalign
);
static
Datum
ArrayCast
(
char
*
value
,
bool
byval
,
int
len
);
static
Datum
ArrayCast
(
char
*
value
,
bool
byval
,
int
len
);
static
int
ArrayCastAndSet
(
Datum
src
,
static
int
ArrayCastAndSet
(
Datum
src
,
int
typlen
,
bool
typbyval
,
char
typalign
,
int
typlen
,
bool
typbyval
,
char
typalign
,
...
@@ -107,7 +119,7 @@ static void array_insert_slice(int ndim, int *dim, int *lb,
...
@@ -107,7 +119,7 @@ static void array_insert_slice(int ndim, int *dim, int *lb,
char
*
destPtr
,
char
*
destPtr
,
int
*
st
,
int
*
endp
,
char
*
srcPtr
,
int
*
st
,
int
*
endp
,
char
*
srcPtr
,
int
typlen
,
bool
typbyval
,
char
typalign
);
int
typlen
,
bool
typbyval
,
char
typalign
);
static
int
array_cmp
(
FunctionCallInfo
fcinfo
);
/*---------------------------------------------------------------------
/*---------------------------------------------------------------------
* array_in :
* array_in :
...
@@ -142,49 +154,12 @@ array_in(PG_FUNCTION_ARGS)
...
@@ -142,49 +154,12 @@ array_in(PG_FUNCTION_ARGS)
dim
[
MAXDIM
],
dim
[
MAXDIM
],
lBound
[
MAXDIM
];
lBound
[
MAXDIM
];
char
typalign
;
char
typalign
;
ArrayMetaState
*
my_extra
;
/*
* We arrange to look up info about element type, including its input
* conversion proc 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
!=
element_type
)
/* Get info about element type, including its input conversion proc */
{
system_cache_lookup
(
element_type
,
IOFunc_input
,
/* Get info about element type, including its input conversion proc */
&
typlen
,
&
typbyval
,
&
typdelim
,
get_type_metadata
(
element_type
,
IOFunc_input
,
&
typelem
,
&
typinput
,
&
typalign
);
&
typlen
,
&
typbyval
,
&
typdelim
,
fmgr_info
(
typinput
,
&
inputproc
);
&
typelem
,
&
typinput
,
&
typalign
);
fmgr_info
(
typinput
,
&
inputproc
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typinput
;
my_extra
->
typalign
=
typalign
;
my_extra
->
proc
=
inputproc
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typinput
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
inputproc
=
my_extra
->
proc
;
}
/* Make a modifiable copy of the input */
/* Make a modifiable copy of the input */
/* XXX why are we allocating an extra 2 bytes here? */
/* XXX why are we allocating an extra 2 bytes here? */
...
@@ -661,51 +636,12 @@ array_out(PG_FUNCTION_ARGS)
...
@@ -661,51 +636,12 @@ array_out(PG_FUNCTION_ARGS)
indx
[
MAXDIM
];
indx
[
MAXDIM
];
int
ndim
,
int
ndim
,
*
dim
;
*
dim
;
ArrayMetaState
*
my_extra
;
element_type
=
ARR_ELEMTYPE
(
v
);
element_type
=
ARR_ELEMTYPE
(
v
);
system_cache_lookup
(
element_type
,
IOFunc_output
,
/*
&
typlen
,
&
typbyval
,
&
typdelim
,
* We arrange to look up info about element type, including its input
&
typelem
,
&
typoutput
,
&
typalign
);
* conversion proc only once per series of calls, assuming the element
fmgr_info
(
typoutput
,
&
outputproc
);
* 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
!=
element_type
)
{
/* Get info about element type, including its output conversion proc */
get_type_metadata
(
element_type
,
IOFunc_output
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typoutput
,
&
typalign
);
fmgr_info
(
typoutput
,
&
outputproc
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typoutput
;
my_extra
->
typalign
=
typalign
;
my_extra
->
proc
=
outputproc
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typoutput
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
outputproc
=
my_extra
->
proc
;
}
ndim
=
ARR_NDIM
(
v
);
ndim
=
ARR_NDIM
(
v
);
dim
=
ARR_DIMS
(
v
);
dim
=
ARR_DIMS
(
v
);
...
@@ -864,7 +800,6 @@ array_recv(PG_FUNCTION_ARGS)
...
@@ -864,7 +800,6 @@ array_recv(PG_FUNCTION_ARGS)
dim
[
MAXDIM
],
dim
[
MAXDIM
],
lBound
[
MAXDIM
];
lBound
[
MAXDIM
];
char
typalign
;
char
typalign
;
ArrayMetaState
*
my_extra
;
/* Get the array header information */
/* Get the array header information */
ndim
=
pq_getmsgint
(
buf
,
4
);
ndim
=
pq_getmsgint
(
buf
,
4
);
...
@@ -896,50 +831,14 @@ array_recv(PG_FUNCTION_ARGS)
...
@@ -896,50 +831,14 @@ array_recv(PG_FUNCTION_ARGS)
PG_RETURN_ARRAYTYPE_P
(
retval
);
PG_RETURN_ARRAYTYPE_P
(
retval
);
}
}
/*
/* Get info about element type, including its receive conversion proc */
* We arrange to look up info about element type, including its receive
system_cache_lookup
(
element_type
,
IOFunc_receive
,
* conversion proc only once per series of calls, assuming the element
&
typlen
,
&
typbyval
,
&
typdelim
,
* type doesn't change underneath us.
&
typelem
,
&
typreceive
,
&
typalign
);
*/
if
(
!
OidIsValid
(
typreceive
))
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
elog
(
ERROR
,
"No binary input function available for type %s"
,
if
(
my_extra
==
NULL
)
format_type_be
(
element_type
));
{
fmgr_info
(
typreceive
,
&
receiveproc
);
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
!=
element_type
)
{
/* Get info about element type, including its receive conversion proc */
get_type_metadata
(
element_type
,
IOFunc_receive
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typreceive
,
&
typalign
);
if
(
!
OidIsValid
(
typreceive
))
elog
(
ERROR
,
"No binary input function available for type %s"
,
format_type_be
(
element_type
));
fmgr_info
(
typreceive
,
&
receiveproc
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typreceive
;
my_extra
->
typalign
=
typalign
;
my_extra
->
proc
=
receiveproc
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typreceive
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
receiveproc
=
my_extra
->
proc
;
}
dataPtr
=
ReadArrayBinary
(
buf
,
nitems
,
&
receiveproc
,
typelem
,
dataPtr
=
ReadArrayBinary
(
buf
,
nitems
,
&
receiveproc
,
typelem
,
typlen
,
typbyval
,
typalign
,
typlen
,
typbyval
,
typalign
,
...
@@ -1077,54 +976,15 @@ array_send(PG_FUNCTION_ARGS)
...
@@ -1077,54 +976,15 @@ array_send(PG_FUNCTION_ARGS)
int
ndim
,
int
ndim
,
*
dim
;
*
dim
;
StringInfoData
buf
;
StringInfoData
buf
;
ArrayMetaState
*
my_extra
;
/* Get information about the element type and the array dimensions */
/* Get information about the element type and the array dimensions */
element_type
=
ARR_ELEMTYPE
(
v
);
element_type
=
ARR_ELEMTYPE
(
v
);
system_cache_lookup
(
element_type
,
IOFunc_send
,
&
typlen
,
&
typbyval
,
/*
&
typdelim
,
&
typelem
,
&
typsend
,
&
typalign
);
* We arrange to look up info about element type, including its send
if
(
!
OidIsValid
(
typsend
))
* proc only once per series of calls, assuming the element
elog
(
ERROR
,
"No binary output function available for type %s"
,
* type doesn't change underneath us.
format_type_be
(
element_type
));
*/
fmgr_info
(
typsend
,
&
sendproc
);
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
!=
element_type
)
{
/* Get info about element type, including its send proc */
get_type_metadata
(
element_type
,
IOFunc_send
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typsend
,
&
typalign
);
if
(
!
OidIsValid
(
typsend
))
elog
(
ERROR
,
"No binary output function available for type %s"
,
format_type_be
(
element_type
));
fmgr_info
(
typsend
,
&
sendproc
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typsend
;
my_extra
->
typalign
=
typalign
;
my_extra
->
proc
=
sendproc
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typsend
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
sendproc
=
my_extra
->
proc
;
}
ndim
=
ARR_NDIM
(
v
);
ndim
=
ARR_NDIM
(
v
);
dim
=
ARR_DIMS
(
v
);
dim
=
ARR_DIMS
(
v
);
...
@@ -1616,26 +1476,6 @@ array_set(ArrayType *array,
...
@@ -1616,26 +1476,6 @@ array_set(ArrayType *array,
array
=
DatumGetArrayTypeP
(
PointerGetDatum
(
array
));
array
=
DatumGetArrayTypeP
(
PointerGetDatum
(
array
));
ndim
=
ARR_NDIM
(
array
);
ndim
=
ARR_NDIM
(
array
);
/*
* if number of dims is zero, i.e. an empty array, create an array
* with nSubscripts dimensions, and set the lower bounds to the supplied
* subscripts
*/
if
(
ndim
==
0
)
{
Oid
elmtype
=
ARR_ELEMTYPE
(
array
);
for
(
i
=
0
;
i
<
nSubscripts
;
i
++
)
{
dim
[
i
]
=
1
;
lb
[
i
]
=
indx
[
i
];
}
return
construct_md_array
(
&
dataValue
,
nSubscripts
,
dim
,
lb
,
elmtype
,
elmlen
,
elmbyval
,
elmalign
);
}
if
(
ndim
!=
nSubscripts
||
ndim
<=
0
||
ndim
>
MAXDIM
)
if
(
ndim
!=
nSubscripts
||
ndim
<=
0
||
ndim
>
MAXDIM
)
elog
(
ERROR
,
"Invalid array subscripts"
);
elog
(
ERROR
,
"Invalid array subscripts"
);
...
@@ -1792,31 +1632,6 @@ array_set_slice(ArrayType *array,
...
@@ -1792,31 +1632,6 @@ array_set_slice(ArrayType *array,
/* note: we assume srcArray contains no toasted elements */
/* note: we assume srcArray contains no toasted elements */
ndim
=
ARR_NDIM
(
array
);
ndim
=
ARR_NDIM
(
array
);
/*
* if number of dims is zero, i.e. an empty array, create an array
* with nSubscripts dimensions, and set the upper and lower bounds
* to the supplied subscripts
*/
if
(
ndim
==
0
)
{
Datum
*
dvalues
;
int
nelems
;
Oid
elmtype
=
ARR_ELEMTYPE
(
array
);
deconstruct_array
(
srcArray
,
elmtype
,
elmlen
,
elmbyval
,
elmalign
,
&
dvalues
,
&
nelems
);
for
(
i
=
0
;
i
<
nSubscripts
;
i
++
)
{
dim
[
i
]
=
1
+
upperIndx
[
i
]
-
lowerIndx
[
i
];
lb
[
i
]
=
lowerIndx
[
i
];
}
return
construct_md_array
(
dvalues
,
nSubscripts
,
dim
,
lb
,
elmtype
,
elmlen
,
elmbyval
,
elmalign
);
}
if
(
ndim
<
nSubscripts
||
ndim
<=
0
||
ndim
>
MAXDIM
)
if
(
ndim
<
nSubscripts
||
ndim
<=
0
||
ndim
>
MAXDIM
)
elog
(
ERROR
,
"Invalid array subscripts"
);
elog
(
ERROR
,
"Invalid array subscripts"
);
...
@@ -1996,13 +1811,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
...
@@ -1996,13 +1811,6 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
Oid
typelem
;
Oid
typelem
;
Oid
proc
;
Oid
proc
;
char
*
s
;
char
*
s
;
typedef
struct
{
ArrayMetaState
*
inp_extra
;
ArrayMetaState
*
ret_extra
;
}
am_extra
;
am_extra
*
my_extra
;
ArrayMetaState
*
inp_extra
;
ArrayMetaState
*
ret_extra
;
/* Get input array */
/* Get input array */
if
(
fcinfo
->
nargs
<
1
)
if
(
fcinfo
->
nargs
<
1
)
...
@@ -2021,81 +1829,11 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
...
@@ -2021,81 +1829,11 @@ array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType)
if
(
nitems
<=
0
)
if
(
nitems
<=
0
)
PG_RETURN_ARRAYTYPE_P
(
v
);
PG_RETURN_ARRAYTYPE_P
(
v
);
/*
/* Lookup source and result types. Unneeded variables are reused. */
* We arrange to look up info about input and return element types only
system_cache_lookup
(
inpType
,
IOFunc_input
,
&
inp_typlen
,
&
inp_typbyval
,
* once per series of calls, assuming the element type doesn't change
&
typdelim
,
&
typelem
,
&
proc
,
&
inp_typalign
);
* underneath us.
system_cache_lookup
(
retType
,
IOFunc_input
,
&
typlen
,
&
typbyval
,
*/
&
typdelim
,
&
typelem
,
&
proc
,
&
typalign
);
my_extra
=
(
am_extra
*
)
fcinfo
->
flinfo
->
fn_extra
;
if
(
my_extra
==
NULL
)
{
fcinfo
->
flinfo
->
fn_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
am_extra
));
my_extra
=
(
am_extra
*
)
fcinfo
->
flinfo
->
fn_extra
;
my_extra
->
inp_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
inp_extra
=
my_extra
->
inp_extra
;
inp_extra
->
element_type
=
InvalidOid
;
my_extra
->
ret_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
ret_extra
=
my_extra
->
ret_extra
;
ret_extra
->
element_type
=
InvalidOid
;
}
else
{
inp_extra
=
my_extra
->
inp_extra
;
ret_extra
=
my_extra
->
ret_extra
;
}
if
(
inp_extra
->
element_type
!=
inpType
)
{
/* Lookup source and result types. Unneeded variables are reused. */
get_type_metadata
(
inpType
,
IOFunc_input
,
&
inp_typlen
,
&
inp_typbyval
,
&
typdelim
,
&
typelem
,
&
proc
,
&
inp_typalign
);
inp_extra
->
element_type
=
inpType
;
inp_extra
->
typlen
=
inp_typlen
;
inp_extra
->
typbyval
=
inp_typbyval
;
inp_extra
->
typdelim
=
typdelim
;
inp_extra
->
typelem
=
typelem
;
inp_extra
->
typiofunc
=
proc
;
inp_extra
->
typalign
=
inp_typalign
;
}
else
{
inp_typlen
=
inp_extra
->
typlen
;
inp_typbyval
=
inp_extra
->
typbyval
;
typdelim
=
inp_extra
->
typdelim
;
typelem
=
inp_extra
->
typelem
;
proc
=
inp_extra
->
typiofunc
;
inp_typalign
=
inp_extra
->
typalign
;
}
if
(
ret_extra
->
element_type
!=
retType
)
{
/* Lookup source and result types. Unneeded variables are reused. */
get_type_metadata
(
retType
,
IOFunc_input
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
proc
,
&
typalign
);
ret_extra
->
element_type
=
retType
;
ret_extra
->
typlen
=
typlen
;
ret_extra
->
typbyval
=
typbyval
;
ret_extra
->
typdelim
=
typdelim
;
ret_extra
->
typelem
=
typelem
;
ret_extra
->
typiofunc
=
proc
;
ret_extra
->
typalign
=
typalign
;
}
else
{
typlen
=
ret_extra
->
typlen
;
typbyval
=
ret_extra
->
typbyval
;
typdelim
=
ret_extra
->
typdelim
;
typelem
=
ret_extra
->
typelem
;
proc
=
ret_extra
->
typiofunc
;
typalign
=
ret_extra
->
typalign
;
}
/* Allocate temporary array for new values */
/* Allocate temporary array for new values */
values
=
(
Datum
*
)
palloc
(
nitems
*
sizeof
(
Datum
));
values
=
(
Datum
*
)
palloc
(
nitems
*
sizeof
(
Datum
));
...
@@ -2311,6 +2049,8 @@ deconstruct_array(ArrayType *array,
...
@@ -2311,6 +2049,8 @@ deconstruct_array(ArrayType *array,
* compares two arrays for equality
* compares two arrays for equality
* result :
* result :
* returns true if the arrays are equal, false otherwise.
* returns true if the arrays are equal, false otherwise.
*
* XXX bitwise equality is pretty bogus ...
*-----------------------------------------------------------------------------
*-----------------------------------------------------------------------------
*/
*/
Datum
Datum
...
@@ -2318,118 +2058,12 @@ array_eq(PG_FUNCTION_ARGS)
...
@@ -2318,118 +2058,12 @@ array_eq(PG_FUNCTION_ARGS)
{
{
ArrayType
*
array1
=
PG_GETARG_ARRAYTYPE_P
(
0
);
ArrayType
*
array1
=
PG_GETARG_ARRAYTYPE_P
(
0
);
ArrayType
*
array2
=
PG_GETARG_ARRAYTYPE_P
(
1
);
ArrayType
*
array2
=
PG_GETARG_ARRAYTYPE_P
(
1
);
char
*
p1
=
(
char
*
)
ARR_DATA_PTR
(
array1
);
char
*
p2
=
(
char
*
)
ARR_DATA_PTR
(
array2
);
int
ndims1
=
ARR_NDIM
(
array1
);
int
ndims2
=
ARR_NDIM
(
array2
);
int
*
dims1
=
ARR_DIMS
(
array1
);
int
*
dims2
=
ARR_DIMS
(
array2
);
int
nitems1
=
ArrayGetNItems
(
ndims1
,
dims1
);
int
nitems2
=
ArrayGetNItems
(
ndims2
,
dims2
);
Oid
element_type
=
ARR_ELEMTYPE
(
array1
);
FmgrInfo
*
ae_fmgr_info
=
fcinfo
->
flinfo
;
bool
result
=
true
;
bool
result
=
true
;
int
typlen
;
bool
typbyval
;
char
typdelim
;
Oid
typelem
;
char
typalign
;
Oid
typiofunc
;
int
i
;
ArrayMetaState
*
my_extra
;
FunctionCallInfoData
locfcinfo
;
/* fast path if the arrays do not have the same number of elements */
if
(
ARR_SIZE
(
array1
)
!=
ARR_SIZE
(
array2
))
if
(
nitems1
!=
nitems2
)
result
=
false
;
else
if
(
memcmp
(
array1
,
array2
,
ARR_SIZE
(
array1
))
!=
0
)
result
=
false
;
result
=
false
;
else
{
/*
* We arrange to look up the equality function only once per series of
* calls, assuming the element type doesn't change underneath us.
*/
my_extra
=
(
ArrayMetaState
*
)
ae_fmgr_info
->
fn_extra
;
if
(
my_extra
==
NULL
)
{
ae_fmgr_info
->
fn_extra
=
MemoryContextAlloc
(
ae_fmgr_info
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
my_extra
=
(
ArrayMetaState
*
)
ae_fmgr_info
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
}
if
(
my_extra
->
element_type
!=
element_type
)
{
Oid
opfuncid
=
equality_oper_funcid
(
element_type
);
if
(
OidIsValid
(
opfuncid
))
fmgr_info_cxt
(
opfuncid
,
&
my_extra
->
proc
,
ae_fmgr_info
->
fn_mcxt
);
else
elog
(
ERROR
,
"array_eq: cannot find equality operator for type: %u"
,
element_type
);
get_type_metadata
(
element_type
,
IOFunc_output
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typiofunc
,
&
typalign
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typiofunc
;
my_extra
->
typalign
=
typalign
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typiofunc
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
}
/*
* apply the operator to each pair of array elements.
*/
MemSet
(
&
locfcinfo
,
0
,
sizeof
(
locfcinfo
));
locfcinfo
.
flinfo
=
&
my_extra
->
proc
;
locfcinfo
.
nargs
=
2
;
/* Loop over source data */
for
(
i
=
0
;
i
<
nitems1
;
i
++
)
{
Datum
elt1
;
Datum
elt2
;
bool
oprresult
;
/* Get element pair */
elt1
=
fetch_att
(
p1
,
typbyval
,
typlen
);
elt2
=
fetch_att
(
p2
,
typbyval
,
typlen
);
p1
=
att_addlength
(
p1
,
typlen
,
PointerGetDatum
(
p1
));
p1
=
(
char
*
)
att_align
(
p1
,
typalign
);
p2
=
att_addlength
(
p2
,
typlen
,
PointerGetDatum
(
p2
));
p2
=
(
char
*
)
att_align
(
p2
,
typalign
);
/*
* Apply the operator to the element pair
*/
locfcinfo
.
arg
[
0
]
=
elt1
;
locfcinfo
.
arg
[
1
]
=
elt2
;
locfcinfo
.
argnull
[
0
]
=
false
;
locfcinfo
.
argnull
[
1
]
=
false
;
locfcinfo
.
isnull
=
false
;
oprresult
=
DatumGetBool
(
FunctionCallInvoke
(
&
locfcinfo
));
if
(
!
oprresult
)
{
result
=
false
;
break
;
}
}
}
/* Avoid leaking memory when handed toasted input. */
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY
(
array1
,
0
);
PG_FREE_IF_COPY
(
array1
,
0
);
...
@@ -2439,190 +2073,53 @@ array_eq(PG_FUNCTION_ARGS)
...
@@ -2439,190 +2073,53 @@ array_eq(PG_FUNCTION_ARGS)
}
}
/*-----------------------------------------------------------------------------
* array-array bool operators:
* Given two arrays, iterate comparison operators
* over the array. Uses logic similar to text comparison
* functions, except element-by-element instead of
* character-by-character.
*----------------------------------------------------------------------------
*/
Datum
array_ne
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
!
DatumGetBool
(
array_eq
(
fcinfo
)));
}
Datum
array_lt
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
array_cmp
(
fcinfo
)
<
0
);
}
Datum
array_gt
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
array_cmp
(
fcinfo
)
>
0
);
}
Datum
array_le
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
array_cmp
(
fcinfo
)
<=
0
);
}
Datum
array_ge
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_BOOL
(
array_cmp
(
fcinfo
)
>=
0
);
}
Datum
btarraycmp
(
PG_FUNCTION_ARGS
)
{
PG_RETURN_INT32
(
array_cmp
(
fcinfo
));
}
/*
* array_cmp()
* Internal comparison function for arrays.
*
* Returns -1, 0 or 1
*/
static
int
array_cmp
(
FunctionCallInfo
fcinfo
)
{
ArrayType
*
array1
=
PG_GETARG_ARRAYTYPE_P
(
0
);
ArrayType
*
array2
=
PG_GETARG_ARRAYTYPE_P
(
1
);
FmgrInfo
*
ac_fmgr_info
=
fcinfo
->
flinfo
;
Datum
opresult
;
int
result
=
0
;
Oid
element_type
=
InvalidOid
;
int
typlen
;
bool
typbyval
;
char
typdelim
;
Oid
typelem
;
char
typalign
;
Oid
typiofunc
;
Datum
*
dvalues1
;
int
nelems1
;
Datum
*
dvalues2
;
int
nelems2
;
int
min_nelems
;
int
i
;
typedef
struct
{
Oid
element_type
;
int
typlen
;
bool
typbyval
;
char
typdelim
;
Oid
typelem
;
Oid
typiofunc
;
char
typalign
;
FmgrInfo
eqproc
;
FmgrInfo
ordproc
;
}
ac_extra
;
ac_extra
*
my_extra
;
element_type
=
ARR_ELEMTYPE
(
array1
);
/*
* We arrange to look up the element type operator function only once
* per series of calls, assuming the element type and opname don't
* change underneath us.
*/
my_extra
=
(
ac_extra
*
)
ac_fmgr_info
->
fn_extra
;
if
(
my_extra
==
NULL
)
{
ac_fmgr_info
->
fn_extra
=
MemoryContextAlloc
(
ac_fmgr_info
->
fn_mcxt
,
sizeof
(
ac_extra
));
my_extra
=
(
ac_extra
*
)
ac_fmgr_info
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
}
if
(
my_extra
->
element_type
!=
element_type
)
{
Oid
eqfuncid
=
equality_oper_funcid
(
element_type
);
Oid
ordfuncid
=
ordering_oper_funcid
(
element_type
);
fmgr_info_cxt
(
eqfuncid
,
&
my_extra
->
eqproc
,
ac_fmgr_info
->
fn_mcxt
);
fmgr_info_cxt
(
ordfuncid
,
&
my_extra
->
ordproc
,
ac_fmgr_info
->
fn_mcxt
);
if
(
my_extra
->
eqproc
.
fn_nargs
!=
2
)
elog
(
ERROR
,
"Equality operator does not take 2 arguments: %u"
,
eqfuncid
);
if
(
my_extra
->
ordproc
.
fn_nargs
!=
2
)
elog
(
ERROR
,
"Ordering operator does not take 2 arguments: %u"
,
ordfuncid
);
get_type_metadata
(
element_type
,
IOFunc_output
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typiofunc
,
&
typalign
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
InvalidOid
;
my_extra
->
typalign
=
typalign
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typalign
=
my_extra
->
typalign
;
}
/* extract a C array of arg array datums */
deconstruct_array
(
array1
,
element_type
,
typlen
,
typbyval
,
typalign
,
&
dvalues1
,
&
nelems1
);
deconstruct_array
(
array2
,
element_type
,
typlen
,
typbyval
,
typalign
,
&
dvalues2
,
&
nelems2
);
min_nelems
=
Min
(
nelems1
,
nelems2
);
for
(
i
=
0
;
i
<
min_nelems
;
i
++
)
{
/* are they equal */
opresult
=
FunctionCall2
(
&
my_extra
->
eqproc
,
dvalues1
[
i
],
dvalues2
[
i
]);
if
(
!
DatumGetBool
(
opresult
))
{
/* nope, see if arg1 is less than arg2 */
opresult
=
FunctionCall2
(
&
my_extra
->
ordproc
,
dvalues1
[
i
],
dvalues2
[
i
]);
if
(
DatumGetBool
(
opresult
))
{
/* arg1 is less than arg2 */
result
=
-
1
;
break
;
}
else
{
/* arg1 is greater than arg2 */
result
=
1
;
break
;
}
}
}
if
((
result
==
0
)
&&
(
nelems1
!=
nelems2
))
result
=
(
nelems1
<
nelems2
)
?
-
1
:
1
;
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY
(
array1
,
0
);
PG_FREE_IF_COPY
(
array2
,
1
);
return
result
;
}
/***************************************************************************/
/***************************************************************************/
/******************| Support Routines |*****************/
/******************| Support Routines |*****************/
/***************************************************************************/
/***************************************************************************/
static
void
system_cache_lookup
(
Oid
element_type
,
IOFuncSelector
which_func
,
int
*
typlen
,
bool
*
typbyval
,
char
*
typdelim
,
Oid
*
typelem
,
Oid
*
proc
,
char
*
typalign
)
{
HeapTuple
typeTuple
;
Form_pg_type
typeStruct
;
typeTuple
=
SearchSysCache
(
TYPEOID
,
ObjectIdGetDatum
(
element_type
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
typeTuple
))
elog
(
ERROR
,
"cache lookup failed for type %u"
,
element_type
);
typeStruct
=
(
Form_pg_type
)
GETSTRUCT
(
typeTuple
);
*
typlen
=
typeStruct
->
typlen
;
*
typbyval
=
typeStruct
->
typbyval
;
*
typdelim
=
typeStruct
->
typdelim
;
*
typelem
=
typeStruct
->
typelem
;
*
typalign
=
typeStruct
->
typalign
;
switch
(
which_func
)
{
case
IOFunc_input
:
*
proc
=
typeStruct
->
typinput
;
break
;
case
IOFunc_output
:
*
proc
=
typeStruct
->
typoutput
;
break
;
case
IOFunc_receive
:
*
proc
=
typeStruct
->
typreceive
;
break
;
case
IOFunc_send
:
*
proc
=
typeStruct
->
typsend
;
break
;
}
ReleaseSysCache
(
typeTuple
);
}
/*
/*
* Fetch array element at pointer, converted correctly to a Datum
* Fetch array element at pointer, converted correctly to a Datum
*/
*/
...
@@ -2926,18 +2423,6 @@ array_type_coerce(PG_FUNCTION_ARGS)
...
@@ -2926,18 +2423,6 @@ array_type_coerce(PG_FUNCTION_ARGS)
if
(
tgt_elem_type
==
InvalidOid
)
if
(
tgt_elem_type
==
InvalidOid
)
elog
(
ERROR
,
"Target type is not an array"
);
elog
(
ERROR
,
"Target type is not an array"
);
/*
* We don't deal with domain constraints yet, so bail out.
* This isn't currently a problem, because we also don't
* support arrays of domain type elements either. But in the
* future we might. At that point consideration should be given
* to removing the check below and adding a domain constraints
* check to the coercion.
*/
if
(
getBaseType
(
tgt_elem_type
)
!=
tgt_elem_type
)
elog
(
ERROR
,
"array coercion to domain type elements not "
\
"currently supported"
);
if
(
!
find_coercion_pathway
(
tgt_elem_type
,
src_elem_type
,
if
(
!
find_coercion_pathway
(
tgt_elem_type
,
src_elem_type
,
COERCION_EXPLICIT
,
&
funcId
))
COERCION_EXPLICIT
,
&
funcId
))
{
{
...
@@ -2954,16 +2439,10 @@ array_type_coerce(PG_FUNCTION_ARGS)
...
@@ -2954,16 +2439,10 @@ array_type_coerce(PG_FUNCTION_ARGS)
}
}
/*
/*
* If it's binary-compatible, modify the element type in the array header,
* If it's binary-compatible, return the array unmodified.
* but otherwise leave the array as we received it.
*/
*/
if
(
my_extra
->
coerce_finfo
.
fn_oid
==
InvalidOid
)
if
(
my_extra
->
coerce_finfo
.
fn_oid
==
InvalidOid
)
{
PG_RETURN_ARRAYTYPE_P
(
src
);
ArrayType
*
result
=
DatumGetArrayTypePCopy
(
PG_GETARG_DATUM
(
0
));
ARR_ELEMTYPE
(
result
)
=
my_extra
->
desttype
;
PG_RETURN_ARRAYTYPE_P
(
result
);
}
/*
/*
* Use array_map to apply the function to each array element.
* Use array_map to apply the function to each array element.
...
@@ -2975,118 +2454,3 @@ array_type_coerce(PG_FUNCTION_ARGS)
...
@@ -2975,118 +2454,3 @@ array_type_coerce(PG_FUNCTION_ARGS)
return
array_map
(
&
locfcinfo
,
my_extra
->
srctype
,
my_extra
->
desttype
);
return
array_map
(
&
locfcinfo
,
my_extra
->
srctype
,
my_extra
->
desttype
);
}
}
/*
* accumArrayResult - accumulate one (more) Datum for an ARRAY_SUBLINK
*
* astate is working state (NULL on first call)
* rcontext is where to keep working state
*/
ArrayBuildState
*
accumArrayResult
(
ArrayBuildState
*
astate
,
Datum
dvalue
,
bool
disnull
,
Oid
element_type
,
MemoryContext
rcontext
)
{
MemoryContext
arr_context
,
oldcontext
;
if
(
astate
==
NULL
)
{
/* First time through --- initialize */
/* Make a temporary context to hold all the junk */
arr_context
=
AllocSetContextCreate
(
rcontext
,
"accumArrayResult"
,
ALLOCSET_DEFAULT_MINSIZE
,
ALLOCSET_DEFAULT_INITSIZE
,
ALLOCSET_DEFAULT_MAXSIZE
);
oldcontext
=
MemoryContextSwitchTo
(
arr_context
);
astate
=
(
ArrayBuildState
*
)
palloc
(
sizeof
(
ArrayBuildState
));
astate
->
mcontext
=
arr_context
;
astate
->
dvalues
=
(
Datum
*
)
palloc
(
ARRAY_ELEMS_CHUNKSIZE
*
sizeof
(
Datum
));
astate
->
nelems
=
0
;
astate
->
element_type
=
element_type
;
get_typlenbyvalalign
(
element_type
,
&
astate
->
typlen
,
&
astate
->
typbyval
,
&
astate
->
typalign
);
}
else
{
oldcontext
=
MemoryContextSwitchTo
(
astate
->
mcontext
);
Assert
(
astate
->
element_type
==
element_type
);
/* enlarge dvalues[] if needed */
if
((
astate
->
nelems
%
ARRAY_ELEMS_CHUNKSIZE
)
==
0
)
astate
->
dvalues
=
(
Datum
*
)
repalloc
(
astate
->
dvalues
,
(
astate
->
nelems
+
ARRAY_ELEMS_CHUNKSIZE
)
*
sizeof
(
Datum
));
}
if
(
disnull
)
elog
(
ERROR
,
"NULL elements not allowed in Arrays"
);
/* Use datumCopy to ensure pass-by-ref stuff is copied into mcontext */
astate
->
dvalues
[
astate
->
nelems
++
]
=
datumCopy
(
dvalue
,
astate
->
typbyval
,
astate
->
typlen
);
MemoryContextSwitchTo
(
oldcontext
);
return
astate
;
}
/*
* makeArrayResult - produce final result of accumArrayResult
*
* astate is working state (not NULL)
* rcontext is where to construct result
*/
Datum
makeArrayResult
(
ArrayBuildState
*
astate
,
MemoryContext
rcontext
)
{
int
dims
[
1
];
int
lbs
[
1
];
dims
[
0
]
=
astate
->
nelems
;
lbs
[
0
]
=
1
;
return
makeMdArrayResult
(
astate
,
1
,
dims
,
lbs
,
rcontext
);
}
/*
* makeMdArrayResult - produce md final result of accumArrayResult
*
* astate is working state (not NULL)
* rcontext is where to construct result
*/
Datum
makeMdArrayResult
(
ArrayBuildState
*
astate
,
int
ndims
,
int
*
dims
,
int
*
lbs
,
MemoryContext
rcontext
)
{
ArrayType
*
result
;
MemoryContext
oldcontext
;
/* Build the final array result in rcontext */
oldcontext
=
MemoryContextSwitchTo
(
rcontext
);
result
=
construct_md_array
(
astate
->
dvalues
,
ndims
,
dims
,
lbs
,
astate
->
element_type
,
astate
->
typlen
,
astate
->
typbyval
,
astate
->
typalign
);
MemoryContextSwitchTo
(
oldcontext
);
/* Clean up all the junk */
MemoryContextDelete
(
astate
->
mcontext
);
return
PointerGetDatum
(
result
);
}
src/backend/utils/adt/varlena.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.
99 2003/06/24 23:14:46
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.
100 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -19,14 +19,11 @@
...
@@ -19,14 +19,11 @@
#include "mb/pg_wchar.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "miscadmin.h"
#include "access/tuptoaster.h"
#include "access/tuptoaster.h"
#include "catalog/pg_type.h"
#include "lib/stringinfo.h"
#include "lib/stringinfo.h"
#include "libpq/crypt.h"
#include "libpq/crypt.h"
#include "libpq/pqformat.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "utils/pg_locale.h"
#include "utils/pg_locale.h"
#include "utils/lsyscache.h"
typedef
struct
varlena
unknown
;
typedef
struct
varlena
unknown
;
...
@@ -1986,7 +1983,8 @@ split_text(PG_FUNCTION_ARGS)
...
@@ -1986,7 +1983,8 @@ split_text(PG_FUNCTION_ARGS)
if
(
fldnum
==
1
)
/* first field - just return the input
if
(
fldnum
==
1
)
/* first field - just return the input
* string */
* string */
PG_RETURN_TEXT_P
(
inputstring
);
PG_RETURN_TEXT_P
(
inputstring
);
else
/* otherwise return an empty string */
else
/* otherwise return an empty string */
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
""
));
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
""
));
}
}
...
@@ -2006,7 +2004,8 @@ split_text(PG_FUNCTION_ARGS)
...
@@ -2006,7 +2004,8 @@ split_text(PG_FUNCTION_ARGS)
if
(
fldnum
==
1
)
/* first field - just return the input
if
(
fldnum
==
1
)
/* first field - just return the input
* string */
* string */
PG_RETURN_TEXT_P
(
inputstring
);
PG_RETURN_TEXT_P
(
inputstring
);
else
/* otherwise return an empty string */
else
/* otherwise return an empty string */
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
""
));
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
""
));
}
}
else
if
((
start_posn
!=
0
)
&&
(
end_posn
==
0
))
else
if
((
start_posn
!=
0
)
&&
(
end_posn
==
0
))
...
@@ -2029,191 +2028,6 @@ split_text(PG_FUNCTION_ARGS)
...
@@ -2029,191 +2028,6 @@ split_text(PG_FUNCTION_ARGS)
}
}
}
}
/*
* text_to_array
* parse input string
* return text array of elements
* based on provided field separator
*/
Datum
text_to_array
(
PG_FUNCTION_ARGS
)
{
text
*
inputstring
=
PG_GETARG_TEXT_P
(
0
);
int
inputstring_len
=
TEXTLEN
(
inputstring
);
text
*
fldsep
=
PG_GETARG_TEXT_P
(
1
);
int
fldsep_len
=
TEXTLEN
(
fldsep
);
int
fldnum
;
int
start_posn
=
0
;
int
end_posn
=
0
;
text
*
result_text
=
NULL
;
ArrayBuildState
*
astate
=
NULL
;
MemoryContext
oldcontext
=
CurrentMemoryContext
;
/* return NULL for empty input string */
if
(
inputstring_len
<
1
)
PG_RETURN_NULL
();
/* empty field separator
* return one element, 1D, array using the input string */
if
(
fldsep_len
<
1
)
PG_RETURN_ARRAYTYPE_P
(
create_singleton_array
(
fcinfo
,
TEXTOID
,
CStringGetDatum
(
inputstring
),
1
));
/* start with end position holding the initial start position */
end_posn
=
0
;
for
(
fldnum
=
1
;;
fldnum
++
)
/* field number is 1 based */
{
Datum
dvalue
;
bool
disnull
=
false
;
start_posn
=
end_posn
;
end_posn
=
text_position
(
PointerGetDatum
(
inputstring
),
PointerGetDatum
(
fldsep
),
fldnum
);
if
((
start_posn
==
0
)
&&
(
end_posn
==
0
))
/* fldsep not found */
{
if
(
fldnum
==
1
)
{
/* first element
* return one element, 1D, array using the input string */
PG_RETURN_ARRAYTYPE_P
(
create_singleton_array
(
fcinfo
,
TEXTOID
,
CStringGetDatum
(
inputstring
),
1
));
}
else
{
/* otherwise create array and exit */
PG_RETURN_ARRAYTYPE_P
(
makeArrayResult
(
astate
,
oldcontext
));
}
}
else
if
((
start_posn
!=
0
)
&&
(
end_posn
==
0
))
{
/* last field requested */
result_text
=
text_substring
(
PointerGetDatum
(
inputstring
),
start_posn
+
fldsep_len
,
-
1
,
true
);
}
else
if
((
start_posn
==
0
)
&&
(
end_posn
!=
0
))
{
/* first field requested */
result_text
=
LEFT
(
inputstring
,
fldsep
);
}
else
{
/* prior to last field requested */
result_text
=
text_substring
(
PointerGetDatum
(
inputstring
),
start_posn
+
fldsep_len
,
end_posn
-
start_posn
-
fldsep_len
,
false
);
}
/* stash away current value */
dvalue
=
PointerGetDatum
(
result_text
);
astate
=
accumArrayResult
(
astate
,
dvalue
,
disnull
,
TEXTOID
,
oldcontext
);
}
/* never reached -- keep compiler quiet */
PG_RETURN_NULL
();
}
/*
* array_to_text
* concatenate Cstring representation of input array elements
* using provided field separator
*/
Datum
array_to_text
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
v
=
PG_GETARG_ARRAYTYPE_P
(
0
);
char
*
fldsep
=
PG_TEXTARG_GET_STR
(
1
);
int
nitems
,
*
dims
,
ndims
;
char
*
p
;
Oid
element_type
;
int
typlen
;
bool
typbyval
;
char
typdelim
;
Oid
typoutput
,
typelem
;
FmgrInfo
outputproc
;
char
typalign
;
StringInfo
result_str
=
makeStringInfo
();
int
i
;
ArrayMetaState
*
my_extra
;
p
=
ARR_DATA_PTR
(
v
);
ndims
=
ARR_NDIM
(
v
);
dims
=
ARR_DIMS
(
v
);
nitems
=
ArrayGetNItems
(
ndims
,
dims
);
/* if there are no elements, return an empty string */
if
(
nitems
==
0
)
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
""
));
element_type
=
ARR_ELEMTYPE
(
v
);
/*
* We arrange to look up info about element type, including its output
* conversion proc 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
!=
element_type
)
{
/* Get info about element type, including its output conversion proc */
get_type_metadata
(
element_type
,
IOFunc_output
,
&
typlen
,
&
typbyval
,
&
typdelim
,
&
typelem
,
&
typoutput
,
&
typalign
);
fmgr_info
(
typoutput
,
&
outputproc
);
my_extra
->
element_type
=
element_type
;
my_extra
->
typlen
=
typlen
;
my_extra
->
typbyval
=
typbyval
;
my_extra
->
typdelim
=
typdelim
;
my_extra
->
typelem
=
typelem
;
my_extra
->
typiofunc
=
typoutput
;
my_extra
->
typalign
=
typalign
;
my_extra
->
proc
=
outputproc
;
}
else
{
typlen
=
my_extra
->
typlen
;
typbyval
=
my_extra
->
typbyval
;
typdelim
=
my_extra
->
typdelim
;
typelem
=
my_extra
->
typelem
;
typoutput
=
my_extra
->
typiofunc
;
typalign
=
my_extra
->
typalign
;
outputproc
=
my_extra
->
proc
;
}
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
Datum
itemvalue
;
char
*
value
;
itemvalue
=
fetch_att
(
p
,
typbyval
,
typlen
);
value
=
DatumGetCString
(
FunctionCall3
(
&
outputproc
,
itemvalue
,
ObjectIdGetDatum
(
typelem
),
Int32GetDatum
(
-
1
)));
if
(
i
>
0
)
appendStringInfo
(
result_str
,
"%s%s"
,
fldsep
,
value
);
else
appendStringInfo
(
result_str
,
"%s"
,
value
);
p
=
att_addlength
(
p
,
typlen
,
PointerGetDatum
(
p
));
p
=
(
char
*
)
att_align
(
p
,
typalign
);
}
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
result_str
->
data
));
}
#define HEXBASE 16
#define HEXBASE 16
/*
/*
* Convert a int32 to a string containing a base 16 (hex) representation of
* Convert a int32 to a string containing a base 16 (hex) representation of
...
...
src/backend/utils/cache/lsyscache.c
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.9
8 2003/06/25 03:56:31
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.9
9 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* Eventually, the index information should go through here, too.
* Eventually, the index information should go through here, too.
...
@@ -718,40 +718,6 @@ get_func_rettype(Oid funcid)
...
@@ -718,40 +718,6 @@ get_func_rettype(Oid funcid)
return
result
;
return
result
;
}
}
/*
* get_func_argtypes
* Given procedure id, return the function's argument types.
* Also pass back the number of arguments.
*/
Oid
*
get_func_argtypes
(
Oid
funcid
,
int
*
nargs
)
{
HeapTuple
tp
;
Form_pg_proc
procstruct
;
Oid
*
result
=
NULL
;
int
i
;
tp
=
SearchSysCache
(
PROCOID
,
ObjectIdGetDatum
(
funcid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
tp
))
elog
(
ERROR
,
"Function OID %u does not exist"
,
funcid
);
procstruct
=
(
Form_pg_proc
)
GETSTRUCT
(
tp
);
*
nargs
=
(
int
)
procstruct
->
pronargs
;
if
(
*
nargs
>
0
)
{
result
=
(
Oid
*
)
palloc
(
*
nargs
*
sizeof
(
Oid
));
for
(
i
=
0
;
i
<
*
nargs
;
i
++
)
result
[
i
]
=
procstruct
->
proargtypes
[
i
];
}
ReleaseSysCache
(
tp
);
return
result
;
}
/*
/*
* get_func_retset
* get_func_retset
* Given procedure id, return the function's proretset flag.
* Given procedure id, return the function's proretset flag.
...
@@ -1124,56 +1090,6 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
...
@@ -1124,56 +1090,6 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
ReleaseSysCache
(
tp
);
ReleaseSysCache
(
tp
);
}
}
/*
* get_type_metadata
*
* A six-fer: given the type OID, return typlen, typbyval, typalign,
* typdelim, typelem, IO function Oid. The IO function
* returned is controlled by IOFuncSelector
*/
void
get_type_metadata
(
Oid
element_type
,
IOFuncSelector
which_func
,
int
*
typlen
,
bool
*
typbyval
,
char
*
typdelim
,
Oid
*
typelem
,
Oid
*
proc
,
char
*
typalign
)
{
HeapTuple
typeTuple
;
Form_pg_type
typeStruct
;
typeTuple
=
SearchSysCache
(
TYPEOID
,
ObjectIdGetDatum
(
element_type
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
typeTuple
))
elog
(
ERROR
,
"cache lookup failed for type %u"
,
element_type
);
typeStruct
=
(
Form_pg_type
)
GETSTRUCT
(
typeTuple
);
*
typlen
=
typeStruct
->
typlen
;
*
typbyval
=
typeStruct
->
typbyval
;
*
typdelim
=
typeStruct
->
typdelim
;
*
typelem
=
typeStruct
->
typelem
;
*
typalign
=
typeStruct
->
typalign
;
switch
(
which_func
)
{
case
IOFunc_input
:
*
proc
=
typeStruct
->
typinput
;
break
;
case
IOFunc_output
:
*
proc
=
typeStruct
->
typoutput
;
break
;
case
IOFunc_receive
:
*
proc
=
typeStruct
->
typreceive
;
break
;
case
IOFunc_send
:
*
proc
=
typeStruct
->
typsend
;
break
;
}
ReleaseSysCache
(
typeTuple
);
}
#ifdef NOT_USED
#ifdef NOT_USED
char
char
get_typalign
(
Oid
typid
)
get_typalign
(
Oid
typid
)
...
...
src/backend/utils/fmgr/fmgr.c
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.
69 2003/06/24 23:14:46
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.
70 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -1673,29 +1673,3 @@ get_fn_expr_argtype(FunctionCallInfo fcinfo, int argnum)
...
@@ -1673,29 +1673,3 @@ get_fn_expr_argtype(FunctionCallInfo fcinfo, int argnum)
return
exprType
((
Node
*
)
nth
(
argnum
,
args
));
return
exprType
((
Node
*
)
nth
(
argnum
,
args
));
}
}
/*
* Get the OID of the function or operator
*
* Returns InvalidOid if information is not available
*/
Oid
get_fn_expr_functype
(
FunctionCallInfo
fcinfo
)
{
Node
*
expr
;
/*
* can't return anything useful if we have no FmgrInfo or if
* its fn_expr node has not been initialized
*/
if
(
!
fcinfo
||
!
fcinfo
->
flinfo
||
!
fcinfo
->
flinfo
->
fn_expr
)
return
InvalidOid
;
expr
=
fcinfo
->
flinfo
->
fn_expr
;
if
(
IsA
(
expr
,
FuncExpr
))
return
((
FuncExpr
*
)
expr
)
->
funcid
;
else
if
(
IsA
(
expr
,
OpExpr
))
return
((
OpExpr
*
)
expr
)
->
opno
;
else
return
InvalidOid
;
}
src/include/catalog/pg_amop.h
View file @
111d8e52
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_amop.h,v 1.5
1 2003/06/24 23:14:46
momjian Exp $
* $Id: pg_amop.h,v 1.5
2 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* the genbki.sh script reads this file and generates .bki
* the genbki.sh script reads this file and generates .bki
...
@@ -418,15 +418,6 @@ DATA(insert ( 2098 3 f 2334 ));
...
@@ -418,15 +418,6 @@ DATA(insert ( 2098 3 f 2334 ));
DATA
(
insert
(
2098
4
f
2335
));
DATA
(
insert
(
2098
4
f
2335
));
DATA
(
insert
(
2098
5
f
2336
));
DATA
(
insert
(
2098
5
f
2336
));
/*
* btree array_ops
*/
DATA
(
insert
(
397
1
f
1072
));
DATA
(
insert
(
397
2
f
1074
));
DATA
(
insert
(
397
3
f
1070
));
DATA
(
insert
(
397
4
f
1075
));
DATA
(
insert
(
397
5
f
1073
));
/*
/*
* hash index _ops
* hash index _ops
...
...
src/include/catalog/pg_amproc.h
View file @
111d8e52
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_amproc.h,v 1.
39 2003/06/24 23:14:46
momjian Exp $
* $Id: pg_amproc.h,v 1.
40 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* the genbki.sh script reads this file and generates .bki
* the genbki.sh script reads this file and generates .bki
...
@@ -78,7 +78,6 @@ DATA(insert ( 1993 3 199 ));
...
@@ -78,7 +78,6 @@ DATA(insert ( 1993 3 199 ));
/* btree */
/* btree */
DATA
(
insert
(
397
1
382
));
DATA
(
insert
(
421
1
357
));
DATA
(
insert
(
421
1
357
));
DATA
(
insert
(
423
1
1596
));
DATA
(
insert
(
423
1
1596
));
DATA
(
insert
(
424
1
1693
));
DATA
(
insert
(
424
1
1693
));
...
...
src/include/catalog/pg_opclass.h
View file @
111d8e52
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_opclass.h,v 1.5
2 2003/06/24 23:14:46
momjian Exp $
* $Id: pg_opclass.h,v 1.5
3 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* the genbki.sh script reads this file and generates .bki
* the genbki.sh script reads this file and generates .bki
...
@@ -87,8 +87,6 @@ typedef FormData_pg_opclass *Form_pg_opclass;
...
@@ -87,8 +87,6 @@ typedef FormData_pg_opclass *Form_pg_opclass;
*/
*/
DATA
(
insert
OID
=
421
(
403
abstime_ops
PGNSP
PGUID
702
t
0
));
DATA
(
insert
OID
=
421
(
403
abstime_ops
PGNSP
PGUID
702
t
0
));
DATA
(
insert
OID
=
397
(
403
array_ops
PGNSP
PGUID
2277
t
0
));
#define ARRAY_BTREE_OPS_OID 397
DATA
(
insert
OID
=
422
(
402
bigbox_ops
PGNSP
PGUID
603
f
0
));
DATA
(
insert
OID
=
422
(
402
bigbox_ops
PGNSP
PGUID
603
f
0
));
DATA
(
insert
OID
=
423
(
403
bit_ops
PGNSP
PGUID
1560
t
0
));
DATA
(
insert
OID
=
423
(
403
bit_ops
PGNSP
PGUID
1560
t
0
));
DATA
(
insert
OID
=
424
(
403
bool_ops
PGNSP
PGUID
16
t
0
));
DATA
(
insert
OID
=
424
(
403
bool_ops
PGNSP
PGUID
16
t
0
));
...
...
src/include/catalog/pg_operator.h
View file @
111d8e52
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_operator.h,v 1.11
6 2003/06/24 23:14:46
momjian Exp $
* $Id: pg_operator.h,v 1.11
7 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* the genbki.sh script reads this file and generates .bki
* the genbki.sh script reads this file and generates .bki
...
@@ -116,15 +116,10 @@ DATA(insert OID = 96 ( "=" PGNSP PGUID b t 23 23 16 96 518 97 97 97 521 int
...
@@ -116,15 +116,10 @@ DATA(insert OID = 96 ( "=" PGNSP PGUID b t 23 23 16 96 518 97 97 97 521 int
DATA
(
insert
OID
=
97
(
"<"
PGNSP
PGUID
b
f
23
23
16
521
525
0
0
0
0
int4lt
scalarltsel
scalarltjoinsel
));
DATA
(
insert
OID
=
97
(
"<"
PGNSP
PGUID
b
f
23
23
16
521
525
0
0
0
0
int4lt
scalarltsel
scalarltjoinsel
));
DATA
(
insert
OID
=
98
(
"="
PGNSP
PGUID
b
t
25
25
16
98
531
664
664
664
666
texteq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
98
(
"="
PGNSP
PGUID
b
t
25
25
16
98
531
664
664
664
666
texteq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
1070
(
"="
PGNSP
PGUID
b
f
2277
2277
16
1070
1071
1072
1072
1072
1073
array_eq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
329
(
"="
PGNSP
PGUID
b
f
2277
2277
16
329
0
0
0
0
0
array_eq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
1071
(
"<>"
PGNSP
PGUID
b
f
2277
2277
16
1071
1070
0
0
0
0
array_ne
neqsel
neqjoinsel
));
DATA
(
insert
OID
=
349
(
"||"
PGNSP
PGUID
b
f
2277
2283
2277
0
0
0
0
0
0
array_append
-
-
));
DATA
(
insert
OID
=
1072
(
"<"
PGNSP
PGUID
b
f
2277
2277
16
1073
1075
0
0
0
0
array_lt
scalarltsel
scalarltjoinsel
));
DATA
(
insert
OID
=
374
(
"||"
PGNSP
PGUID
b
f
2283
2277
2277
0
0
0
0
0
0
array_prepend
-
-
));
DATA
(
insert
OID
=
1073
(
">"
PGNSP
PGUID
b
f
2277
2277
16
1072
1074
0
0
0
0
array_gt
scalargtsel
scalargtjoinsel
));
DATA
(
insert
OID
=
375
(
"||"
PGNSP
PGUID
b
f
2277
2277
2277
0
0
0
0
0
0
array_cat
-
-
));
DATA
(
insert
OID
=
1074
(
"<="
PGNSP
PGUID
b
f
2277
2277
16
1075
1073
0
0
0
0
array_le
scalarltsel
scalarltjoinsel
));
DATA
(
insert
OID
=
1075
(
">="
PGNSP
PGUID
b
f
2277
2277
16
1074
1072
0
0
0
0
array_ge
scalargtsel
scalargtjoinsel
));
DATA
(
insert
OID
=
349
(
"||"
PGNSP
PGUID
b
f
2277
2283
2277
0
0
0
0
0
0
array_append
-
-
));
DATA
(
insert
OID
=
374
(
"||"
PGNSP
PGUID
b
f
2283
2277
2277
0
0
0
0
0
0
array_prepend
-
-
));
DATA
(
insert
OID
=
375
(
"||"
PGNSP
PGUID
b
f
2277
2277
2277
0
0
0
0
0
0
array_cat
-
-
));
DATA
(
insert
OID
=
352
(
"="
PGNSP
PGUID
b
t
28
28
16
352
0
0
0
0
0
xideq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
352
(
"="
PGNSP
PGUID
b
t
28
28
16
352
0
0
0
0
0
xideq
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
353
(
"="
PGNSP
PGUID
b
f
28
23
16
0
0
0
0
0
0
xideqint4
eqsel
eqjoinsel
));
DATA
(
insert
OID
=
353
(
"="
PGNSP
PGUID
b
f
28
23
16
0
0
0
0
0
0
xideqint4
eqsel
eqjoinsel
));
...
@@ -430,7 +425,6 @@ DATA(insert OID = 965 ( "^" PGNSP PGUID b f 701 701 701 0 0 0 0 0 0 dpow -
...
@@ -430,7 +425,6 @@ DATA(insert OID = 965 ( "^" PGNSP PGUID b f 701 701 701 0 0 0 0 0 0 dpow -
DATA
(
insert
OID
=
966
(
"+"
PGNSP
PGUID
b
f
1034
1033
1034
0
0
0
0
0
0
aclinsert
-
-
));
DATA
(
insert
OID
=
966
(
"+"
PGNSP
PGUID
b
f
1034
1033
1034
0
0
0
0
0
0
aclinsert
-
-
));
DATA
(
insert
OID
=
967
(
"-"
PGNSP
PGUID
b
f
1034
1033
1034
0
0
0
0
0
0
aclremove
-
-
));
DATA
(
insert
OID
=
967
(
"-"
PGNSP
PGUID
b
f
1034
1033
1034
0
0
0
0
0
0
aclremove
-
-
));
DATA
(
insert
OID
=
968
(
"~"
PGNSP
PGUID
b
f
1034
1033
16
0
0
0
0
0
0
aclcontains
-
-
));
DATA
(
insert
OID
=
968
(
"~"
PGNSP
PGUID
b
f
1034
1033
16
0
0
0
0
0
0
aclcontains
-
-
));
DATA
(
insert
OID
=
974
(
"="
PGNSP
PGUID
b
f
1033
1033
16
0
0
0
0
0
0
aclitemeq
eqsel
eqjoinsel
));
/* additional geometric operators - thomas 1997-07-09 */
/* additional geometric operators - thomas 1997-07-09 */
DATA
(
insert
OID
=
969
(
"@@"
PGNSP
PGUID
l
f
0
601
600
0
0
0
0
0
0
lseg_center
-
-
));
DATA
(
insert
OID
=
969
(
"@@"
PGNSP
PGUID
l
f
0
601
600
0
0
0
0
0
0
lseg_center
-
-
));
...
...
src/include/catalog/pg_proc.h
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: pg_proc.h,v 1.30
6 2003/06/24 23:14:47
momjian Exp $
* $Id: pg_proc.h,v 1.30
7 2003/06/25 21:30:32
momjian Exp $
*
*
* NOTES
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
* The script catalog/genbki.sh reads this file and generates .bki
...
@@ -758,8 +758,6 @@ DATA(insert OID = 359 ( btnamecmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btn
...
@@ -758,8 +758,6 @@ DATA(insert OID = 359 ( btnamecmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btn
DESCR
(
"btree less-equal-greater"
);
DESCR
(
"btree less-equal-greater"
);
DATA
(
insert
OID
=
360
(
bttextcmp
PGNSP
PGUID
12
f
f
t
f
i
2
23
"25 25"
bttextcmp
-
_null_
));
DATA
(
insert
OID
=
360
(
bttextcmp
PGNSP
PGUID
12
f
f
t
f
i
2
23
"25 25"
bttextcmp
-
_null_
));
DESCR
(
"btree less-equal-greater"
);
DESCR
(
"btree less-equal-greater"
);
DATA
(
insert
OID
=
382
(
btarraycmp
PGNSP
PGUID
12
f
f
t
f
i
2
23
"2277 2277"
btarraycmp
-
_null_
));
DESCR
(
"btree less-equal-greater"
);
DATA
(
insert
OID
=
361
(
lseg_distance
PGNSP
PGUID
12
f
f
t
f
i
2
701
"601 601"
lseg_distance
-
_null_
));
DATA
(
insert
OID
=
361
(
lseg_distance
PGNSP
PGUID
12
f
f
t
f
i
2
701
"601 601"
lseg_distance
-
_null_
));
DESCR
(
"distance between"
);
DESCR
(
"distance between"
);
...
@@ -990,23 +988,14 @@ DESCR("greater-than");
...
@@ -990,23 +988,14 @@ DESCR("greater-than");
DATA
(
insert
OID
=
743
(
text_ge
PGNSP
PGUID
12
f
f
t
f
i
2
16
"25 25"
text_ge
-
_null_
));
DATA
(
insert
OID
=
743
(
text_ge
PGNSP
PGUID
12
f
f
t
f
i
2
16
"25 25"
text_ge
-
_null_
));
DESCR
(
"greater-than-or-equal"
);
DESCR
(
"greater-than-or-equal"
);
DATA
(
insert
OID
=
744
(
array_eq
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_eq
-
_null_
));
DESCR
(
"array equal"
);
DATA
(
insert
OID
=
745
(
current_user
PGNSP
PGUID
12
f
f
t
f
s
0
19
""
current_user
-
_null_
));
DATA
(
insert
OID
=
745
(
current_user
PGNSP
PGUID
12
f
f
t
f
s
0
19
""
current_user
-
_null_
));
DESCR
(
"current user name"
);
DESCR
(
"current user name"
);
DATA
(
insert
OID
=
746
(
session_user
PGNSP
PGUID
12
f
f
t
f
s
0
19
""
session_user
-
_null_
));
DATA
(
insert
OID
=
746
(
session_user
PGNSP
PGUID
12
f
f
t
f
s
0
19
""
session_user
-
_null_
));
DESCR
(
"session user name"
);
DESCR
(
"session user name"
);
DATA
(
insert
OID
=
744
(
array_eq
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_eq
-
_null_
));
DESCR
(
"array equal"
);
DATA
(
insert
OID
=
390
(
array_ne
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_ne
-
_null_
));
DESCR
(
"array not equal"
);
DATA
(
insert
OID
=
391
(
array_lt
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_lt
-
_null_
));
DESCR
(
"array less than"
);
DATA
(
insert
OID
=
392
(
array_gt
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_gt
-
_null_
));
DESCR
(
"array greater than"
);
DATA
(
insert
OID
=
393
(
array_le
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_le
-
_null_
));
DESCR
(
"array less than or equal"
);
DATA
(
insert
OID
=
396
(
array_ge
PGNSP
PGUID
12
f
f
t
f
i
2
16
"2277 2277"
array_ge
-
_null_
));
DESCR
(
"array greater than or equal"
);
DATA
(
insert
OID
=
747
(
array_dims
PGNSP
PGUID
12
f
f
t
f
i
1
25
"2277"
array_dims
-
_null_
));
DATA
(
insert
OID
=
747
(
array_dims
PGNSP
PGUID
12
f
f
t
f
i
1
25
"2277"
array_dims
-
_null_
));
DESCR
(
"array dimensions"
);
DESCR
(
"array dimensions"
);
DATA
(
insert
OID
=
750
(
array_in
PGNSP
PGUID
12
f
f
t
f
s
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_
));
...
@@ -1017,18 +1006,22 @@ DATA(insert OID = 2091 ( array_lower PGNSP PGUID 12 f f t f i 2 23 "2277 23"
...
@@ -1017,18 +1006,22 @@ DATA(insert OID = 2091 ( array_lower PGNSP PGUID 12 f f t f i 2 23 "2277 23"
DESCR
(
"array lower dimension"
);
DESCR
(
"array lower dimension"
);
DATA
(
insert
OID
=
2092
(
array_upper
PGNSP
PGUID
12
f
f
t
f
i
2
23
"2277 23"
array_upper
-
_null_
));
DATA
(
insert
OID
=
2092
(
array_upper
PGNSP
PGUID
12
f
f
t
f
i
2
23
"2277 23"
array_upper
-
_null_
));
DESCR
(
"array upper dimension"
);
DESCR
(
"array upper dimension"
);
DATA
(
insert
OID
=
377
(
singleton_array
PGNSP
PGUID
12
f
f
t
f
i
1
2277
"2283"
singleton_array
-
_null_
));
DESCR
(
"create array from single element"
);
DATA
(
insert
OID
=
378
(
array_append
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2277 2283"
array_push
-
_null_
));
DATA
(
insert
OID
=
378
(
array_append
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2277 2283"
array_push
-
_null_
));
DESCR
(
"append element onto end of array"
);
DESCR
(
"append element onto end of array"
);
DATA
(
insert
OID
=
379
(
array_prepend
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2283 2277"
array_push
-
_null_
));
DATA
(
insert
OID
=
379
(
array_prepend
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2283 2277"
array_push
-
_null_
));
DESCR
(
"prepend element onto front of array"
);
DESCR
(
"prepend element onto front of array"
);
DATA
(
insert
OID
=
380
(
array_accum
PGNSP
PGUID
12
f
f
f
f
i
2
2277
"2277 2283"
array_accum
-
_null_
));
DESCR
(
"push element onto end of array, creating array if needed"
);
DATA
(
insert
OID
=
381
(
array_assign
PGNSP
PGUID
12
f
f
t
f
i
3
2277
"2277 23 2283"
array_assign
-
_null_
));
DESCR
(
"assign specific array element"
);
DATA
(
insert
OID
=
382
(
array_subscript
PGNSP
PGUID
12
f
f
t
f
i
2
2283
"2277 23"
array_subscript
-
_null_
));
DESCR
(
"return specific array element"
);
DATA
(
insert
OID
=
383
(
array_cat
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2277 2277"
array_cat
-
_null_
));
DATA
(
insert
OID
=
383
(
array_cat
PGNSP
PGUID
12
f
f
t
f
i
2
2277
"2277 2277"
array_cat
-
_null_
));
DESCR
(
"concatenate two arrays"
);
DESCR
(
"concatenate two arrays"
);
DATA
(
insert
OID
=
384
(
array_coerce
PGNSP
PGUID
12
f
f
t
f
i
1
2277
"2277"
array_type_coerce
-
_null_
));
DATA
(
insert
OID
=
384
(
array_coerce
PGNSP
PGUID
12
f
f
t
f
i
1
2277
"2277"
array_type_coerce
-
_null_
));
DESCR
(
"coerce array type to another array type"
);
DESCR
(
"coerce array type to another array type"
);
DATA
(
insert
OID
=
394
(
string_to_array
PGNSP
PGUID
12
f
f
t
f
i
2
1009
"25 25"
text_to_array
-
_null_
));
DESCR
(
"split delimited text into text[]"
);
DATA
(
insert
OID
=
395
(
array_to_string
PGNSP
PGUID
12
f
f
t
f
i
2
25
"2277 25"
array_to_text
-
_null_
));
DESCR
(
"concatenate array elements, using delimiter, into text"
);
DATA
(
insert
OID
=
760
(
smgrin
PGNSP
PGUID
12
f
f
t
f
s
1
210
"2275"
smgrin
-
_null_
));
DATA
(
insert
OID
=
760
(
smgrin
PGNSP
PGUID
12
f
f
t
f
s
1
210
"2275"
smgrin
-
_null_
));
DESCR
(
"I/O"
);
DESCR
(
"I/O"
);
...
@@ -1329,8 +1322,6 @@ DATA(insert OID = 1036 ( aclremove PGNSP PGUID 12 f f t f s 2 1034 "1034 10
...
@@ -1329,8 +1322,6 @@ DATA(insert OID = 1036 ( aclremove PGNSP PGUID 12 f f t f s 2 1034 "1034 10
DESCR
(
"remove ACL item"
);
DESCR
(
"remove ACL item"
);
DATA
(
insert
OID
=
1037
(
aclcontains
PGNSP
PGUID
12
f
f
t
f
s
2
16
"1034 1033"
aclcontains
-
_null_
));
DATA
(
insert
OID
=
1037
(
aclcontains
PGNSP
PGUID
12
f
f
t
f
s
2
16
"1034 1033"
aclcontains
-
_null_
));
DESCR
(
"does ACL contain item?"
);
DESCR
(
"does ACL contain item?"
);
DATA
(
insert
OID
=
1062
(
aclitemeq
PGNSP
PGUID
12
f
f
t
f
s
2
16
"1033 1033"
aclitem_eq
-
_null_
));
DESCR
(
"equality operator for ACL items"
);
DATA
(
insert
OID
=
1365
(
makeaclitem
PGNSP
PGUID
12
f
f
t
f
s
5
1033
"23 23 23 25 16"
makeaclitem
-
_null_
));
DATA
(
insert
OID
=
1365
(
makeaclitem
PGNSP
PGUID
12
f
f
t
f
s
5
1033
"23 23 23 25 16"
makeaclitem
-
_null_
));
DESCR
(
"make ACL item"
);
DESCR
(
"make ACL item"
);
DATA
(
insert
OID
=
1038
(
seteval
PGNSP
PGUID
12
f
f
t
t
v
1
23
"26"
seteval
-
_null_
));
DATA
(
insert
OID
=
1038
(
seteval
PGNSP
PGUID
12
f
f
t
t
v
1
23
"26"
seteval
-
_null_
));
...
...
src/include/fmgr.h
View file @
111d8e52
...
@@ -11,14 +11,13 @@
...
@@ -11,14 +11,13 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: fmgr.h,v 1.2
8 2003/06/24 23:14:46
momjian Exp $
* $Id: fmgr.h,v 1.2
9 2003/06/25 21:30:32
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
#ifndef FMGR_H
#ifndef FMGR_H
#define FMGR_H
#define FMGR_H
#include "nodes/nodes.h"
/*
/*
* All functions that can be called directly by fmgr must have this signature.
* All functions that can be called directly by fmgr must have this signature.
...
@@ -373,14 +372,14 @@ extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
...
@@ -373,14 +372,14 @@ extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
Datum
arg6
,
Datum
arg7
,
Datum
arg8
,
Datum
arg6
,
Datum
arg7
,
Datum
arg8
,
Datum
arg9
);
Datum
arg9
);
/*
/*
* Routines in fmgr.c
* Routines in fmgr.c
*/
*/
extern
Pg_finfo_record
*
fetch_finfo_record
(
void
*
filehandle
,
char
*
funcname
);
extern
Pg_finfo_record
*
fetch_finfo_record
(
void
*
filehandle
,
char
*
funcname
);
extern
Oid
fmgr_internal_function
(
const
char
*
proname
);
extern
Oid
fmgr_internal_function
(
const
char
*
proname
);
extern
Oid
get_fn_expr_rettype
(
FunctionCallInfo
fcinfo
);
extern
Oid
get_fn_expr_rettype
(
FunctionCallInfo
fcinfo
);
extern
Oid
get_fn_expr_argtype
(
FunctionCallInfo
fcinfo
,
int
argnum
);
extern
Oid
get_fn_expr_argtype
(
FunctionCallInfo
fcinfo
,
int
argnum
);
extern
Oid
get_fn_expr_functype
(
FunctionCallInfo
fcinfo
);
/*
/*
* Routines in dfmgr.c
* Routines in dfmgr.c
...
...
src/include/nodes/primnodes.h
View file @
111d8e52
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: primnodes.h,v 1.8
4 2003/06/24 23:14:48
momjian Exp $
* $Id: primnodes.h,v 1.8
5 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -226,7 +226,6 @@ typedef struct Aggref
...
@@ -226,7 +226,6 @@ typedef struct Aggref
Index
agglevelsup
;
/* > 0 if agg belongs to outer query */
Index
agglevelsup
;
/* > 0 if agg belongs to outer query */
bool
aggstar
;
/* TRUE if argument was really '*' */
bool
aggstar
;
/* TRUE if argument was really '*' */
bool
aggdistinct
;
/* TRUE if it's agg(DISTINCT ...) */
bool
aggdistinct
;
/* TRUE if it's agg(DISTINCT ...) */
List
*
args
;
/* arguments to the aggregate */
}
Aggref
;
}
Aggref
;
/* ----------------
/* ----------------
...
@@ -359,19 +358,15 @@ typedef struct BoolExpr
...
@@ -359,19 +358,15 @@ typedef struct BoolExpr
/* ----------------
/* ----------------
* SubLink
* SubLink
*
*
* A SubLink represents a subselect
, or an expression, appearing in an
* A SubLink represents a subselect
appearing in an expression, and in some
*
expression, and in some cases also the combining operator(s) just abov
e
*
cases also the combining operator(s) just above it. The subLinkTyp
e
* i
t. The subLinkType i
ndicates the form of the expression represented:
* indicates the form of the expression represented:
* EXISTS_SUBLINK EXISTS(SELECT ...)
* EXISTS_SUBLINK EXISTS(SELECT ...)
* ALL_SUBLINK (lefthand) op ALL (SELECT ...)
* ALL_SUBLINK (lefthand) op ALL (SELECT ...)
* ANY_SUBLINK (lefthand) op ANY (SELECT ...)
* ANY_SUBLINK (lefthand) op ANY (SELECT ...)
* MULTIEXPR_SUBLINK (lefthand) op (SELECT ...)
* MULTIEXPR_SUBLINK (lefthand) op (SELECT ...)
* EXPR_SUBLINK (SELECT with single targetlist item ...)
* EXPR_SUBLINK (SELECT with single targetlist item ...)
* ARRAY_SUBLINK ARRAY(SELECT with single targetlist item ...)
* ARRAY_SUBLINK ARRAY(SELECT with single targetlist item ...)
* If an expression is used in place of the subselect, it is transformed
* into a simple "(SELECT expr)" in gram.y. This is to allow arrays to be
* used as if they were the result of a single column subselect. If the
* expression is scalar, it is treated as a one element array.
* For ALL, ANY, and MULTIEXPR, the lefthand is a list of expressions of the
* For ALL, ANY, and MULTIEXPR, the lefthand is a list of expressions of the
* same length as the subselect's targetlist. MULTIEXPR will *always* have
* same length as the subselect's targetlist. MULTIEXPR will *always* have
* a list with more than one entry; if the subselect has just one target
* a list with more than one entry; if the subselect has just one target
...
@@ -420,8 +415,6 @@ typedef struct SubLink
...
@@ -420,8 +415,6 @@ typedef struct SubLink
SubLinkType
subLinkType
;
/* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
SubLinkType
subLinkType
;
/* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
bool
useOr
;
/* TRUE to combine column results with
bool
useOr
;
/* TRUE to combine column results with
* "OR" not "AND" */
* "OR" not "AND" */
bool
isExpr
;
/* TRUE if the subselect is really derived
* from a single expression */
List
*
lefthand
;
/* list of outer-query expressions on the
List
*
lefthand
;
/* list of outer-query expressions on the
* left */
* left */
List
*
operName
;
/* originally specified operator name */
List
*
operName
;
/* originally specified operator name */
...
@@ -463,15 +456,6 @@ typedef struct SubPlan
...
@@ -463,15 +456,6 @@ typedef struct SubPlan
SubLinkType
subLinkType
;
/* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
SubLinkType
subLinkType
;
/* EXISTS, ALL, ANY, MULTIEXPR, EXPR */
bool
useOr
;
/* TRUE to combine column results with
bool
useOr
;
/* TRUE to combine column results with
* "OR" not "AND" */
* "OR" not "AND" */
bool
isExpr
;
/* TRUE if the subselect is really derived
* from a single expression */
/* runtime cache for single array expressions */
Oid
exprtype
;
/* array and element type, and other info
* needed deconstruct the array */
Oid
elemtype
;
int16
elmlen
;
bool
elmbyval
;
char
elmalign
;
/* The combining operators, transformed to executable expressions: */
/* The combining operators, transformed to executable expressions: */
List
*
exprs
;
/* list of OpExpr expression trees */
List
*
exprs
;
/* list of OpExpr expression trees */
List
*
paramIds
;
/* IDs of Params embedded in the above */
List
*
paramIds
;
/* IDs of Params embedded in the above */
...
...
src/include/optimizer/clauses.h
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: clauses.h,v 1.6
4 2003/06/24 23:14:49
momjian Exp $
* $Id: clauses.h,v 1.6
5 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -28,9 +28,6 @@ extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
...
@@ -28,9 +28,6 @@ extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset,
extern
Node
*
get_leftop
(
Expr
*
clause
);
extern
Node
*
get_leftop
(
Expr
*
clause
);
extern
Node
*
get_rightop
(
Expr
*
clause
);
extern
Node
*
get_rightop
(
Expr
*
clause
);
extern
Expr
*
make_funcclause
(
Oid
funcid
,
Oid
funcresulttype
,
bool
funcretset
,
CoercionForm
funcformat
,
List
*
funcargs
);
extern
bool
not_clause
(
Node
*
clause
);
extern
bool
not_clause
(
Node
*
clause
);
extern
Expr
*
make_notclause
(
Expr
*
notclause
);
extern
Expr
*
make_notclause
(
Expr
*
notclause
);
extern
Expr
*
get_notclausearg
(
Expr
*
notclause
);
extern
Expr
*
get_notclausearg
(
Expr
*
notclause
);
...
...
src/include/parser/parse_oper.h
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: parse_oper.h,v 1.2
6 2003/06/24 23:14:49
momjian Exp $
* $Id: parse_oper.h,v 1.2
7 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -44,7 +44,6 @@ extern Operator ordering_oper(Oid argtype, bool noError);
...
@@ -44,7 +44,6 @@ extern Operator ordering_oper(Oid argtype, bool noError);
/* Convenience routines for common calls on the above */
/* Convenience routines for common calls on the above */
extern
Oid
compatible_oper_opid
(
List
*
op
,
Oid
arg1
,
Oid
arg2
,
bool
noError
);
extern
Oid
compatible_oper_opid
(
List
*
op
,
Oid
arg1
,
Oid
arg2
,
bool
noError
);
extern
Oid
equality_oper_funcid
(
Oid
argtype
);
extern
Oid
equality_oper_funcid
(
Oid
argtype
);
extern
Oid
ordering_oper_funcid
(
Oid
argtype
);
extern
Oid
ordering_oper_opid
(
Oid
argtype
);
extern
Oid
ordering_oper_opid
(
Oid
argtype
);
/* Extract operator OID or underlying-function OID from an Operator tuple */
/* Extract operator OID or underlying-function OID from an Operator tuple */
...
...
src/include/utils/acl.h
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: acl.h,v 1.5
3 2003/06/24 23:14:49
momjian Exp $
* $Id: acl.h,v 1.5
4 2003/06/25 21:30:33
momjian Exp $
*
*
* NOTES
* NOTES
* For backward-compatibility purposes we have to allow there
* For backward-compatibility purposes we have to allow there
...
@@ -192,7 +192,6 @@ extern Datum aclinsert(PG_FUNCTION_ARGS);
...
@@ -192,7 +192,6 @@ extern Datum aclinsert(PG_FUNCTION_ARGS);
extern
Datum
aclremove
(
PG_FUNCTION_ARGS
);
extern
Datum
aclremove
(
PG_FUNCTION_ARGS
);
extern
Datum
aclcontains
(
PG_FUNCTION_ARGS
);
extern
Datum
aclcontains
(
PG_FUNCTION_ARGS
);
extern
Datum
makeaclitem
(
PG_FUNCTION_ARGS
);
extern
Datum
makeaclitem
(
PG_FUNCTION_ARGS
);
extern
Datum
aclitem_eq
(
PG_FUNCTION_ARGS
);
/*
/*
* prototypes for functions in aclchk.c
* prototypes for functions in aclchk.c
...
...
src/include/utils/array.h
View file @
111d8e52
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: array.h,v 1.
39 2003/06/24 23:14:49
momjian Exp $
* $Id: array.h,v 1.
40 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -32,37 +32,6 @@ typedef struct
...
@@ -32,37 +32,6 @@ typedef struct
Oid
elemtype
;
/* element type OID */
Oid
elemtype
;
/* element type OID */
}
ArrayType
;
}
ArrayType
;
typedef
struct
ArrayBuildState
{
MemoryContext
mcontext
;
/* where all the temp stuff is kept */
Datum
*
dvalues
;
/* array of accumulated Datums */
/*
* The allocated size of dvalues[] is always a multiple of
* ARRAY_ELEMS_CHUNKSIZE
*/
#define ARRAY_ELEMS_CHUNKSIZE 64
int
nelems
;
/* number of valid Datums in dvalues[] */
Oid
element_type
;
/* data type of the Datums */
int16
typlen
;
/* needed info about datatype */
bool
typbyval
;
char
typalign
;
}
ArrayBuildState
;
/*
* structure to cache type metadata needed for array manipulation
*/
typedef
struct
ArrayMetaState
{
Oid
element_type
;
int
typlen
;
bool
typbyval
;
char
typdelim
;
Oid
typelem
;
Oid
typiofunc
;
char
typalign
;
FmgrInfo
proc
;
}
ArrayMetaState
;
/*
/*
* fmgr macros for array objects
* fmgr macros for array objects
*/
*/
...
@@ -117,15 +86,11 @@ extern Datum array_recv(PG_FUNCTION_ARGS);
...
@@ -117,15 +86,11 @@ extern Datum array_recv(PG_FUNCTION_ARGS);
extern
Datum
array_send
(
PG_FUNCTION_ARGS
);
extern
Datum
array_send
(
PG_FUNCTION_ARGS
);
extern
Datum
array_length_coerce
(
PG_FUNCTION_ARGS
);
extern
Datum
array_length_coerce
(
PG_FUNCTION_ARGS
);
extern
Datum
array_eq
(
PG_FUNCTION_ARGS
);
extern
Datum
array_eq
(
PG_FUNCTION_ARGS
);
extern
Datum
array_ne
(
PG_FUNCTION_ARGS
);
extern
Datum
array_lt
(
PG_FUNCTION_ARGS
);
extern
Datum
array_gt
(
PG_FUNCTION_ARGS
);
extern
Datum
array_le
(
PG_FUNCTION_ARGS
);
extern
Datum
array_ge
(
PG_FUNCTION_ARGS
);
extern
Datum
btarraycmp
(
PG_FUNCTION_ARGS
);
extern
Datum
array_dims
(
PG_FUNCTION_ARGS
);
extern
Datum
array_dims
(
PG_FUNCTION_ARGS
);
extern
Datum
array_lower
(
PG_FUNCTION_ARGS
);
extern
Datum
array_lower
(
PG_FUNCTION_ARGS
);
extern
Datum
array_upper
(
PG_FUNCTION_ARGS
);
extern
Datum
array_upper
(
PG_FUNCTION_ARGS
);
extern
Datum
array_assign
(
PG_FUNCTION_ARGS
);
extern
Datum
array_subscript
(
PG_FUNCTION_ARGS
);
extern
Datum
array_type_coerce
(
PG_FUNCTION_ARGS
);
extern
Datum
array_type_coerce
(
PG_FUNCTION_ARGS
);
extern
Datum
array_ref
(
ArrayType
*
array
,
int
nSubscripts
,
int
*
indx
,
extern
Datum
array_ref
(
ArrayType
*
array
,
int
nSubscripts
,
int
*
indx
,
...
@@ -159,14 +124,7 @@ extern void deconstruct_array(ArrayType *array,
...
@@ -159,14 +124,7 @@ extern void deconstruct_array(ArrayType *array,
Oid
elmtype
,
Oid
elmtype
,
int
elmlen
,
bool
elmbyval
,
char
elmalign
,
int
elmlen
,
bool
elmbyval
,
char
elmalign
,
Datum
**
elemsp
,
int
*
nelemsp
);
Datum
**
elemsp
,
int
*
nelemsp
);
extern
ArrayBuildState
*
accumArrayResult
(
ArrayBuildState
*
astate
,
Datum
dvalue
,
bool
disnull
,
Oid
element_type
,
MemoryContext
rcontext
);
extern
Datum
makeArrayResult
(
ArrayBuildState
*
astate
,
MemoryContext
rcontext
);
extern
Datum
makeMdArrayResult
(
ArrayBuildState
*
astate
,
int
ndims
,
int
*
dims
,
int
*
lbs
,
MemoryContext
rcontext
);
/*
/*
* prototypes for functions defined in arrayutils.c
* prototypes for functions defined in arrayutils.c
...
@@ -183,11 +141,12 @@ extern int mda_next_tuple(int n, int *curr, int *span);
...
@@ -183,11 +141,12 @@ extern int mda_next_tuple(int n, int *curr, int *span);
/*
/*
* prototypes for functions defined in array_userfuncs.c
* prototypes for functions defined in array_userfuncs.c
*/
*/
extern
Datum
singleton_array
(
PG_FUNCTION_ARGS
);
extern
Datum
array_push
(
PG_FUNCTION_ARGS
);
extern
Datum
array_push
(
PG_FUNCTION_ARGS
);
extern
Datum
array_accum
(
PG_FUNCTION_ARGS
);
extern
Datum
array_cat
(
PG_FUNCTION_ARGS
);
extern
Datum
array_cat
(
PG_FUNCTION_ARGS
);
extern
ArrayType
*
create_singleton_array
(
FunctionCallInfo
fcinfo
,
extern
ArrayType
*
create_singleton_array
(
Oid
element_type
,
Oid
element_type
,
Datum
element
,
Datum
element
,
int
ndims
);
int
ndims
);
...
...
src/include/utils/builtins.h
View file @
111d8e52
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: builtins.h,v 1.22
1 2003/06/24 23:14:49
momjian Exp $
* $Id: builtins.h,v 1.22
2 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -530,8 +530,6 @@ extern bool SplitIdentifierString(char *rawstring, char separator,
...
@@ -530,8 +530,6 @@ extern bool SplitIdentifierString(char *rawstring, char separator,
List
**
namelist
);
List
**
namelist
);
extern
Datum
replace_text
(
PG_FUNCTION_ARGS
);
extern
Datum
replace_text
(
PG_FUNCTION_ARGS
);
extern
Datum
split_text
(
PG_FUNCTION_ARGS
);
extern
Datum
split_text
(
PG_FUNCTION_ARGS
);
extern
Datum
text_to_array
(
PG_FUNCTION_ARGS
);
extern
Datum
array_to_text
(
PG_FUNCTION_ARGS
);
extern
Datum
to_hex32
(
PG_FUNCTION_ARGS
);
extern
Datum
to_hex32
(
PG_FUNCTION_ARGS
);
extern
Datum
to_hex64
(
PG_FUNCTION_ARGS
);
extern
Datum
to_hex64
(
PG_FUNCTION_ARGS
);
extern
Datum
md5_text
(
PG_FUNCTION_ARGS
);
extern
Datum
md5_text
(
PG_FUNCTION_ARGS
);
...
...
src/include/utils/lsyscache.h
View file @
111d8e52
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: lsyscache.h,v 1.7
3 2003/06/25 03:56:31
momjian Exp $
* $Id: lsyscache.h,v 1.7
4 2003/06/25 21:30:33
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -15,15 +15,6 @@
...
@@ -15,15 +15,6 @@
#include "access/htup.h"
#include "access/htup.h"
/* I/O function selector for system_cache_lookup */
typedef
enum
IOFuncSelector
{
IOFunc_input
,
IOFunc_output
,
IOFunc_receive
,
IOFunc_send
}
IOFuncSelector
;
extern
bool
op_in_opclass
(
Oid
opno
,
Oid
opclass
);
extern
bool
op_in_opclass
(
Oid
opno
,
Oid
opclass
);
extern
bool
op_requires_recheck
(
Oid
opno
,
Oid
opclass
);
extern
bool
op_requires_recheck
(
Oid
opno
,
Oid
opclass
);
extern
Oid
get_opclass_member
(
Oid
opclass
,
int16
strategy
);
extern
Oid
get_opclass_member
(
Oid
opclass
,
int16
strategy
);
...
@@ -50,7 +41,6 @@ extern RegProcedure get_oprrest(Oid opno);
...
@@ -50,7 +41,6 @@ extern RegProcedure get_oprrest(Oid opno);
extern
RegProcedure
get_oprjoin
(
Oid
opno
);
extern
RegProcedure
get_oprjoin
(
Oid
opno
);
extern
char
*
get_func_name
(
Oid
funcid
);
extern
char
*
get_func_name
(
Oid
funcid
);
extern
Oid
get_func_rettype
(
Oid
funcid
);
extern
Oid
get_func_rettype
(
Oid
funcid
);
extern
Oid
*
get_func_argtypes
(
Oid
funcid
,
int
*
nargs
);
extern
bool
get_func_retset
(
Oid
funcid
);
extern
bool
get_func_retset
(
Oid
funcid
);
extern
bool
func_strict
(
Oid
funcid
);
extern
bool
func_strict
(
Oid
funcid
);
extern
char
func_volatile
(
Oid
funcid
);
extern
char
func_volatile
(
Oid
funcid
);
...
@@ -66,14 +56,6 @@ extern bool get_typbyval(Oid typid);
...
@@ -66,14 +56,6 @@ extern bool get_typbyval(Oid typid);
extern
void
get_typlenbyval
(
Oid
typid
,
int16
*
typlen
,
bool
*
typbyval
);
extern
void
get_typlenbyval
(
Oid
typid
,
int16
*
typlen
,
bool
*
typbyval
);
extern
void
get_typlenbyvalalign
(
Oid
typid
,
int16
*
typlen
,
bool
*
typbyval
,
extern
void
get_typlenbyvalalign
(
Oid
typid
,
int16
*
typlen
,
bool
*
typbyval
,
char
*
typalign
);
char
*
typalign
);
extern
void
get_type_metadata
(
Oid
element_type
,
IOFuncSelector
which_func
,
int
*
typlen
,
bool
*
typbyval
,
char
*
typdelim
,
Oid
*
typelem
,
Oid
*
proc
,
char
*
typalign
);
extern
char
get_typstorage
(
Oid
typid
);
extern
char
get_typstorage
(
Oid
typid
);
extern
int32
get_typtypmod
(
Oid
typid
);
extern
int32
get_typtypmod
(
Oid
typid
);
extern
Node
*
get_typdefault
(
Oid
typid
);
extern
Node
*
get_typdefault
(
Oid
typid
);
...
...
src/interfaces/ecpg/preproc/preproc.y
View file @
111d8e52
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.23
8 2003/06/25 10:44:21 meskes
Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.23
9 2003/06/25 21:30:33 momjian
Exp $ */
/* Copyright comment */
/* Copyright comment */
%{
%{
...
@@ -4599,7 +4599,7 @@ type_declaration: S_TYPEDEF
...
@@ -4599,7 +4599,7 @@ type_declaration: S_TYPEDEF
$3.type_enum != ECPGt_char &&
$3.type_enum != ECPGt_char &&
$3.type_enum != ECPGt_unsigned_char &&
$3.type_enum != ECPGt_unsigned_char &&
atoi(this->type->type_index) >= 0)
atoi(this->type->type_index) >= 0)
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
mmerror(PARSE_ERROR, ET_ERROR, "No multi
-
dimensional array support for simple data types");
types = this;
types = this;
}
}
...
@@ -5419,7 +5419,7 @@ ECPGTypedef: TYPE_P
...
@@ -5419,7 +5419,7 @@ ECPGTypedef: TYPE_P
$5.type_enum != ECPGt_char &&
$5.type_enum != ECPGt_char &&
$5.type_enum != ECPGt_unsigned_char &&
$5.type_enum != ECPGt_unsigned_char &&
atoi(this->type->type_index) >= 0)
atoi(this->type->type_index) >= 0)
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
mmerror(PARSE_ERROR, ET_ERROR, "No multi
-
dimensional array support for simple data types");
types = this;
types = this;
}
}
...
@@ -5486,7 +5486,7 @@ ECPGVar: SQL_VAR
...
@@ -5486,7 +5486,7 @@ ECPGVar: SQL_VAR
default:
default:
if (atoi(length) >= 0)
if (atoi(length) >= 0)
mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
mmerror(PARSE_ERROR, ET_ERROR, "No multi
-
dimensional array support for simple data types");
if (atoi(dimension) < 0)
if (atoi(dimension) < 0)
type = ECPGmake_simple_type($5.type_enum, make_str("1"));
type = ECPGmake_simple_type($5.type_enum, make_str("1"));
...
...
src/interfaces/ecpg/preproc/type.c
View file @
111d8e52
...
@@ -504,7 +504,7 @@ ECPGfree_type(struct ECPGtype * type)
...
@@ -504,7 +504,7 @@ ECPGfree_type(struct ECPGtype * type)
switch
(
type
->
u
.
element
->
type
)
switch
(
type
->
u
.
element
->
type
)
{
{
case
ECPGt_array
:
case
ECPGt_array
:
yyerror
(
"internal error, found multidimensional array
\n
"
);
yyerror
(
"internal error, found multi
-
dimensional array
\n
"
);
break
;
break
;
case
ECPGt_struct
:
case
ECPGt_struct
:
case
ECPGt_union
:
case
ECPGt_union
:
...
...
src/interfaces/ecpg/preproc/variable.c
View file @
111d8e52
...
@@ -436,7 +436,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -436,7 +436,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
if
(
atoi
(
type_index
)
>=
0
)
if
(
atoi
(
type_index
)
>=
0
)
{
{
if
(
atoi
(
*
length
)
>=
0
)
if
(
atoi
(
*
length
)
>=
0
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support"
);
*
length
=
type_index
;
*
length
=
type_index
;
}
}
...
@@ -444,7 +444,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -444,7 +444,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
if
(
atoi
(
type_dimension
)
>=
0
)
if
(
atoi
(
type_dimension
)
>=
0
)
{
{
if
(
atoi
(
*
dimension
)
>=
0
&&
atoi
(
*
length
)
>=
0
)
if
(
atoi
(
*
dimension
)
>=
0
&&
atoi
(
*
length
)
>=
0
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support"
);
if
(
atoi
(
*
dimension
)
>=
0
)
if
(
atoi
(
*
dimension
)
>=
0
)
*
length
=
*
dimension
;
*
length
=
*
dimension
;
...
@@ -463,10 +463,10 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -463,10 +463,10 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No pointer to pointer supported for this type"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No pointer to pointer supported for this type"
);
if
(
pointer_len
>
1
&&
(
atoi
(
*
length
)
>=
0
||
atoi
(
*
dimension
)
>=
0
))
if
(
pointer_len
>
1
&&
(
atoi
(
*
length
)
>=
0
||
atoi
(
*
dimension
)
>=
0
))
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support"
);
if
(
atoi
(
*
length
)
>=
0
&&
atoi
(
*
dimension
)
>=
0
&&
pointer_len
)
if
(
atoi
(
*
length
)
>=
0
&&
atoi
(
*
dimension
)
>=
0
&&
pointer_len
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support"
);
switch
(
type_enum
)
switch
(
type_enum
)
{
{
...
@@ -480,7 +480,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -480,7 +480,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
}
}
if
(
atoi
(
*
length
)
>=
0
)
if
(
atoi
(
*
length
)
>=
0
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support for structures"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support for structures"
);
break
;
break
;
case
ECPGt_varchar
:
case
ECPGt_varchar
:
...
@@ -525,7 +525,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
...
@@ -525,7 +525,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
}
}
if
(
atoi
(
*
length
)
>=
0
)
if
(
atoi
(
*
length
)
>=
0
)
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multidimensional array support for simple data types"
);
mmerror
(
PARSE_ERROR
,
ET_FATAL
,
"No multi
-
dimensional array support for simple data types"
);
break
;
break
;
}
}
...
...
src/test/regress/expected/arrays.out
View file @
111d8e52
...
@@ -178,13 +178,19 @@ SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY";
...
@@ -178,13 +178,19 @@ SELECT ARRAY(select f2 from arrtest_f order by f2) AS "ARRAY";
(1 row)
(1 row)
-- functions
-- functions
SELECT array_append(array[42], 6) AS "{42,6}";
SELECT singleton_array(42) AS "{42}";
{42}
------
{42}
(1 row)
SELECT array_append(singleton_array(42), 6) AS "{42,6}";
{42,6}
{42,6}
--------
--------
{42,6}
{42,6}
(1 row)
(1 row)
SELECT array_prepend(6,
array[42]
) AS "{6,42}";
SELECT array_prepend(6,
singleton_array(42)
) AS "{6,42}";
{6,42}
{6,42}
--------
--------
{6,42}
{6,42}
...
@@ -208,6 +214,24 @@ SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
...
@@ -208,6 +214,24 @@ SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
{{3,4},{5,6},{1,2}}
{{3,4},{5,6},{1,2}}
(1 row)
(1 row)
SELECT array_subscript(n, 2) AS "1.2" FROM arrtest2;
1.2
-----
1.2
(1 row)
SELECT array_assign(n, 2, 9.99) AS "{1.1,9.99,1.3}" FROM arrtest2;
{1.1,9.99,1.3}
----------------
{1.1,9.99,1.3}
(1 row)
SELECT array_subscript(array_assign(n, 2, 9.99), 2) AS "9.99" FROM arrtest2;
9.99
------
9.99
(1 row)
-- operators
-- operators
SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]];
SELECT a FROM arrtest WHERE b = ARRAY[[[113,142],[1,147]]];
a
a
...
...
src/test/regress/sql/arrays.sql
View file @
111d8e52
...
@@ -130,11 +130,15 @@ SELECT ARRAY[ARRAY['hello'],ARRAY['world']];
...
@@ -130,11 +130,15 @@ SELECT ARRAY[ARRAY['hello'],ARRAY['world']];
SELECT
ARRAY
(
select
f2
from
arrtest_f
order
by
f2
)
AS
"ARRAY"
;
SELECT
ARRAY
(
select
f2
from
arrtest_f
order
by
f2
)
AS
"ARRAY"
;
-- functions
-- functions
SELECT
array_append
(
array
[
42
],
6
)
AS
"{42,6}"
;
SELECT
singleton_array
(
42
)
AS
"{42}"
;
SELECT
array_prepend
(
6
,
array
[
42
])
AS
"{6,42}"
;
SELECT
array_append
(
singleton_array
(
42
),
6
)
AS
"{42,6}"
;
SELECT
array_prepend
(
6
,
singleton_array
(
42
))
AS
"{6,42}"
;
SELECT
array_cat
(
ARRAY
[
1
,
2
],
ARRAY
[
3
,
4
])
AS
"{{1,2},{3,4}}"
;
SELECT
array_cat
(
ARRAY
[
1
,
2
],
ARRAY
[
3
,
4
])
AS
"{{1,2},{3,4}}"
;
SELECT
array_cat
(
ARRAY
[
1
,
2
],
ARRAY
[[
3
,
4
],[
5
,
6
]])
AS
"{{1,2},{3,4},{5,6}}"
;
SELECT
array_cat
(
ARRAY
[
1
,
2
],
ARRAY
[[
3
,
4
],[
5
,
6
]])
AS
"{{1,2},{3,4},{5,6}}"
;
SELECT
array_cat
(
ARRAY
[[
3
,
4
],[
5
,
6
]],
ARRAY
[
1
,
2
])
AS
"{{3,4},{5,6},{1,2}}"
;
SELECT
array_cat
(
ARRAY
[[
3
,
4
],[
5
,
6
]],
ARRAY
[
1
,
2
])
AS
"{{3,4},{5,6},{1,2}}"
;
SELECT
array_subscript
(
n
,
2
)
AS
"1.2"
FROM
arrtest2
;
SELECT
array_assign
(
n
,
2
,
9
.
99
)
AS
"{1.1,9.99,1.3}"
FROM
arrtest2
;
SELECT
array_subscript
(
array_assign
(
n
,
2
,
9
.
99
),
2
)
AS
"9.99"
FROM
arrtest2
;
-- operators
-- operators
SELECT
a
FROM
arrtest
WHERE
b
=
ARRAY
[[[
113
,
142
],[
1
,
147
]]];
SELECT
a
FROM
arrtest
WHERE
b
=
ARRAY
[[[
113
,
142
],[
1
,
147
]]];
...
...
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