Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6b0706a

Browse files
committed
Arrange for an explicit cast applied to an ARRAY[] constructor to be applied
directly to all the member expressions, instead of the previous implementationwhere the ARRAY[] constructor would infer a common element type and then we'dcoerce the finished array after the fact. This has a number of benefits,one being that we can allow an empty ARRAY[] construct so long as itselement type is specified by such a cast.Brendan Jurd, minor fixes by me.
1 parent8759b79 commit6b0706a

File tree

11 files changed

+311
-99
lines changed

11 files changed

+311
-99
lines changed

‎doc/src/sgml/syntax.sgml

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.121 2008/01/23 19:51:29 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/syntax.sgml,v 1.122 2008/03/20 21:42:47 tgl Exp $ -->
22

33
<chapter id="sql-syntax">
44
<title>SQL Syntax</title>
@@ -1305,7 +1305,7 @@ sqrt(2)
13051305

13061306
where <replaceable>aggregate_name</replaceable> is a previously
13071307
defined aggregate (possibly qualified with a schema name), and
1308-
<replaceable>expression</replaceable> is
1308+
<replaceable>expression</replaceable> is
13091309
any value expression that does not itself contain an aggregate
13101310
expression.
13111311
</para>
@@ -1335,7 +1335,7 @@ sqrt(2)
13351335
<para>
13361336
The predefined aggregate functions are described in <xref
13371337
linkend="functions-aggregate">. Other aggregate functions can be added
1338-
by the user.
1338+
by the user.
13391339
</para>
13401340

13411341
<para>
@@ -1495,9 +1495,9 @@ SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)
14951495
<para>
14961496
An array constructor is an expression that builds an
14971497
array value from values for its member elements. A simple array
1498-
constructor
1498+
constructor
14991499
consists of the key word <literal>ARRAY</literal>, a left square bracket
1500-
<literal>[</>,one or more expressions (separated by commas) for the
1500+
<literal>[</>,a list of expressions (separated by commas) for the
15011501
array element values, and finally a right square bracket <literal>]</>.
15021502
For example:
15031503
<programlisting>
@@ -1507,9 +1507,22 @@ SELECT ARRAY[1,2,3+4];
15071507
{1,2,7}
15081508
(1 row)
15091509
</programlisting>
1510-
The array element type is the common type of the member expressions,
1510+
By default,
1511+
the array element type is the common type of the member expressions,
15111512
determined using the same rules as for <literal>UNION</> or
1512-
<literal>CASE</> constructs (see <xref linkend="typeconv-union-case">).
1513+
<literal>CASE</> constructs (see <xref linkend="typeconv-union-case">).
1514+
You can override this by explicitly casting the array constructor to the
1515+
desired type, for example:
1516+
<programlisting>
1517+
SELECT ARRAY[1,2,22.7]::integer[];
1518+
array
1519+
----------
1520+
{1,2,23}
1521+
(1 row)
1522+
</programlisting>
1523+
This has the same effect as casting each expression to the array
1524+
element type individually.
1525+
For more on casting, see <xref linkend="sql-syntax-type-casts">.
15131526
</para>
15141527

15151528
<para>
@@ -1534,6 +1547,8 @@ SELECT ARRAY[[1,2],[3,4]];
15341547

15351548
Since multidimensional arrays must be rectangular, inner constructors
15361549
at the same level must produce sub-arrays of identical dimensions.
1550+
Any cast applied to the outer <literal>ARRAY</> constructor propagates
1551+
automatically to all the inner constructors.
15371552
</para>
15381553

15391554
<para>
@@ -1553,6 +1568,19 @@ SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
15531568
</programlisting>
15541569
</para>
15551570

1571+
<para>
1572+
You can construct an empty array, but since it's impossible to have an
1573+
array with no type, you must explicitly cast your empty array to the
1574+
desired type. For example:
1575+
<programlisting>
1576+
SELECT ARRAY[]::integer[];
1577+
array
1578+
-------
1579+
{}
1580+
(1 row)
1581+
</programlisting>
1582+
</para>
1583+
15561584
<para>
15571585
It is also possible to construct an array from the results of a
15581586
subquery. In this form, the array constructor is written with the

‎src/backend/nodes/copyfuncs.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.388 2008/02/07 20:19:47 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.389 2008/03/20 21:42:47 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1684,6 +1684,16 @@ _copyA_Indirection(A_Indirection *from)
16841684
returnnewnode;
16851685
}
16861686

1687+
staticA_ArrayExpr*
1688+
_copyA_ArrayExpr(A_ArrayExpr*from)
1689+
{
1690+
A_ArrayExpr*newnode=makeNode(A_ArrayExpr);
1691+
1692+
COPY_NODE_FIELD(elements);
1693+
1694+
returnnewnode;
1695+
}
1696+
16871697
staticResTarget*
16881698
_copyResTarget(ResTarget*from)
16891699
{
@@ -3543,6 +3553,9 @@ copyObject(void *from)
35433553
caseT_A_Indirection:
35443554
retval=_copyA_Indirection(from);
35453555
break;
3556+
caseT_A_ArrayExpr:
3557+
retval=_copyA_ArrayExpr(from);
3558+
break;
35463559
caseT_ResTarget:
35473560
retval=_copyResTarget(from);
35483561
break;

‎src/backend/nodes/equalfuncs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.318 2008/02/07 20:19:47 tgl Exp $
21+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.319 2008/03/20 21:42:48 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -1729,6 +1729,14 @@ _equalA_Indirection(A_Indirection *a, A_Indirection *b)
17291729
return true;
17301730
}
17311731

1732+
staticbool
1733+
_equalA_ArrayExpr(A_ArrayExpr*a,A_ArrayExpr*b)
1734+
{
1735+
COMPARE_NODE_FIELD(elements);
1736+
1737+
return true;
1738+
}
1739+
17321740
staticbool
17331741
_equalResTarget(ResTarget*a,ResTarget*b)
17341742
{
@@ -2469,6 +2477,9 @@ equal(void *a, void *b)
24692477
caseT_A_Indirection:
24702478
retval=_equalA_Indirection(a,b);
24712479
break;
2480+
caseT_A_ArrayExpr:
2481+
retval=_equalA_ArrayExpr(a,b);
2482+
break;
24722483
caseT_ResTarget:
24732484
retval=_equalResTarget(a,b);
24742485
break;

‎src/backend/nodes/outfuncs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.322 2008/01/09 08:46:44 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.323 2008/03/20 21:42:48 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1971,6 +1971,14 @@ _outA_Indirection(StringInfo str, A_Indirection *node)
19711971
WRITE_NODE_FIELD(indirection);
19721972
}
19731973

1974+
staticvoid
1975+
_outA_ArrayExpr(StringInfostr,A_ArrayExpr*node)
1976+
{
1977+
WRITE_NODE_TYPE("A_ARRAYEXPR");
1978+
1979+
WRITE_NODE_FIELD(elements);
1980+
}
1981+
19741982
staticvoid
19751983
_outResTarget(StringInfostr,ResTarget*node)
19761984
{
@@ -2417,6 +2425,9 @@ _outNode(StringInfo str, void *obj)
24172425
caseT_A_Indirection:
24182426
_outA_Indirection(str,obj);
24192427
break;
2428+
caseT_A_ArrayExpr:
2429+
_outA_ArrayExpr(str,obj);
2430+
break;
24202431
caseT_ResTarget:
24212432
_outResTarget(str,obj);
24222433
break;

‎src/backend/parser/gram.y

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.608 2008/03/19 18:38:30 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.609 2008/03/20 21:42:48 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -107,6 +107,7 @@ static void insertSelectOptions(SelectStmt *stmt,
107107
static Node *makeSetOp(SetOperation op,bool all, Node *larg, Node *rarg);
108108
static Node *doNegate(Node *n,int location);
109109
staticvoiddoNegateFloat(Value *v);
110+
static Node *makeAArrayExpr(List *elements);
110111
static Node *makeXmlExpr(XmlExprOp op,char *name, List *named_args, List *args);
111112

112113
%}
@@ -8429,45 +8430,43 @@ expr_list:a_expr
84298430
}
84308431
;
84318432

8432-
extract_list:
8433-
extract_arg FROM a_expr
8434-
{
8435-
A_Const *n = makeNode(A_Const);
8436-
n->val.type = T_String;
8437-
n->val.val.str =$1;
8438-
$$ = list_make2((Node *) n,$3);
8439-
}
8440-
|/*EMPTY*/{$$ = NIL; }
8441-
;
8442-
84438433
type_list:Typename{$$ = list_make1($1); }
84448434
| type_list',' Typename{$$ = lappend($1,$3); }
84458435
;
84468436

8447-
array_expr_list: array_expr
8448-
{$$ = list_make1($1);}
8449-
| array_expr_list',' array_expr
8450-
{$$ = lappend($1,$3);}
8451-
;
8452-
84538437
array_expr:'[' expr_list']'
84548438
{
8455-
ArrayExpr *n = makeNode(ArrayExpr);
8456-
n->elements =$2;
8457-
$$ = (Node *)n;
8439+
$$ = makeAArrayExpr($2);
84588440
}
84598441
|'[' array_expr_list']'
84608442
{
8461-
ArrayExpr *n = makeNode(ArrayExpr);
8462-
n->elements =$2;
8463-
$$ = (Node *)n;
8443+
$$ = makeAArrayExpr($2);
8444+
}
8445+
|'['']'
8446+
{
8447+
$$ = makeAArrayExpr(NIL);
8448+
}
8449+
;
8450+
8451+
array_expr_list: array_expr{$$ = list_make1($1); }
8452+
| array_expr_list',' array_expr{$$ = lappend($1,$3); }
8453+
;
8454+
8455+
8456+
extract_list:
8457+
extract_arg FROM a_expr
8458+
{
8459+
A_Const *n = makeNode(A_Const);
8460+
n->val.type = T_String;
8461+
n->val.val.str =$1;
8462+
$$ = list_make2((Node *) n,$3);
84648463
}
8464+
|/*EMPTY*/{$$ = NIL; }
84658465
;
84668466

84678467
/* Allow delimited string SCONST in extract_arg as an SQL extension.
84688468
* - thomas 2001-04-12
84698469
*/
8470-
84718470
extract_arg:
84728471
IDENT{$$ =$1; }
84738472
| YEAR_P{$$ ="year"; }
@@ -9502,13 +9501,6 @@ makeColumnRef(char *relname, List *indirection, int location)
95029501
static Node *
95039502
makeTypeCast(Node *arg, TypeName *typename)
95049503
{
9505-
/*
9506-
* Simply generate a TypeCast node.
9507-
*
9508-
* Earlier we would determine whether an A_Const would
9509-
* be acceptable, however Domains require coerce_type()
9510-
* to process them -- applying constraints as required.
9511-
*/
95129504
TypeCast *n = makeNode(TypeCast);
95139505
n->arg = arg;
95149506
n->typename = typename;
@@ -9582,7 +9574,7 @@ makeBoolAConst(bool state)
95829574
{
95839575
A_Const *n = makeNode(A_Const);
95849576
n->val.type = T_String;
9585-
n->val.val.str = (state? "t": "f");
9577+
n->val.val.str = (state? "t": "f");
95869578
n->typename = SystemTypeName("bool");
95879579
return n;
95889580
}
@@ -9763,15 +9755,6 @@ SystemTypeName(char *name)
97639755
makeString(name)));
97649756
}
97659757

9766-
/* parser_init()
9767-
* Initialize to parse one query string
9768-
*/
9769-
void
9770-
parser_init(void)
9771-
{
9772-
QueryIsRule = FALSE;
9773-
}
9774-
97759758
/* doNegate()
97769759
* Handle negation of a numeric constant.
97779760
*
@@ -9827,6 +9810,15 @@ doNegateFloat(Value *v)
98279810
}
98289811
}
98299812

9813+
static Node *
9814+
makeAArrayExpr(List *elements)
9815+
{
9816+
A_ArrayExpr *n = makeNode(A_ArrayExpr);
9817+
9818+
n->elements = elements;
9819+
return (Node *) n;
9820+
}
9821+
98309822
static Node *
98319823
makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
98329824
{
@@ -9844,6 +9836,15 @@ makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
98449836
return (Node *) x;
98459837
}
98469838

9839+
/* parser_init()
9840+
* Initialize to parse one query string
9841+
*/
9842+
void
9843+
parser_init(void)
9844+
{
9845+
QueryIsRule = FALSE;
9846+
}
9847+
98479848
/*
98489849
* Must undefine base_yylex before including scan.c, since we want it
98499850
* to create the function base_yylex not filtered_base_yylex.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp