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

Commit926fa80

Browse files
committed
Remove undocumented IS [NOT] OF syntax.
This feature was added a long time ago, in7c1e67b andeb121ba,but never documented in any user-facing way. (Documentation addedin6126d3e was commented out almost immediately, in8272fc3.)That's because, while this syntax is defined by SQL:99, ourimplementation is only vaguely related to the standard's semantics.The standard appears to intend a run-time not parse-time test, andit definitely intends that the test should understand subtyperelationships.No one has stepped up to fix that in the intervening years, butpeople keep coming across the code and asking why it's not documented.Let's just get rid of it: if anyone ever wants to make it work perspec, they can easily recover whatever parts of this code are stillof value from our git history.If there's anyone out there who's actually using this despite itsundocumented status, they can switch to using pg_typeof() instead,eg. "pg_typeof(something) = 'mytype'::regtype". That givesessentially the same semantics as what our IS OF code did.(We didn't have that function last time this was discussed, orwe would have ripped out IS OF then.)Discussion:https://postgr.es/m/CAKFQuwZ2pTc-DSkOiTfjauqLYkNREeNZvWmeg12Q-_69D+sYZA@mail.gmail.comDiscussion:https://postgr.es/m/BAY20-F23E9F2B4DAB3E4E88D3623F99B0@phx.gblDiscussion:https://postgr.es/m/3E7CF81D.1000203@joeconway.com
1 parent97390fe commit926fa80

File tree

12 files changed

+38
-139
lines changed

12 files changed

+38
-139
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -762,25 +762,6 @@ repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue>
762762
expression must be of Boolean type.
763763
</para>
764764

765-
<!-- IS OF does not conform to the ISO SQL behavior, so it is undocumented here
766-
<para>
767-
<indexterm>
768-
<primary>IS OF</primary>
769-
</indexterm>
770-
<indexterm>
771-
<primary>IS NOT OF</primary>
772-
</indexterm>
773-
It is possible to check the data type of an expression using the
774-
predicates
775-
<synopsis>
776-
<replaceable>expression</replaceable> IS OF (typename, ...)
777-
<replaceable>expression</replaceable> IS NOT OF (typename, ...)
778-
</synopsis>
779-
They return a boolean value based on whether the expression's data
780-
type is one of the listed data types.
781-
</para>
782-
-->
783-
784765
<para>
785766
Some comparison-related functions are also available, as shown in <xref
786767
linkend="functions-comparison-func-table"/>.

‎src/backend/catalog/sql_features.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ S096Optional array boundsYES
373373
S097Array element assignmentNO
374374
S098ARRAY_AGGYES
375375
S111ONLY in query expressionsYES
376-
S151Type predicateNO
376+
S151Type predicateNOsee pg_typeof()
377377
S161Subtype treatmentNO
378378
S162Subtype treatment for referencesNO
379379
S201SQL-invoked routines on arraysYES

‎src/backend/nodes/outfuncs.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,10 +3213,6 @@ _outAExpr(StringInfo str, const A_Expr *node)
32133213
appendStringInfoString(str," NULLIF ");
32143214
WRITE_NODE_FIELD(name);
32153215
break;
3216-
caseAEXPR_OF:
3217-
appendStringInfoString(str," OF ");
3218-
WRITE_NODE_FIELD(name);
3219-
break;
32203216
caseAEXPR_IN:
32213217
appendStringInfoString(str," IN ");
32223218
WRITE_NODE_FIELD(name);

‎src/backend/parser/gram.y

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13238,14 +13238,6 @@ a_expr:c_expr{ $$ = $1; }
1323813238
{
1323913239
$$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT,"=",$1,$6,@2);
1324013240
}
13241-
|a_exprISOF'('type_list')'%precIS
13242-
{
13243-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF,"=",$1, (Node *)$5,@2);
13244-
}
13245-
|a_exprISNOTOF'('type_list')'%precIS
13246-
{
13247-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF,"<>",$1, (Node *)$6,@2);
13248-
}
1324913241
|a_exprBETWEENopt_asymmetricb_exprANDa_expr%precBETWEEN
1325013242
{
1325113243
$$ = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN,
@@ -13464,14 +13456,6 @@ b_expr:c_expr
1346413456
{
1346513457
$$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT,"=",$1,$6,@2);
1346613458
}
13467-
|b_exprISOF'('type_list')'%precIS
13468-
{
13469-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF,"=",$1, (Node *)$5,@2);
13470-
}
13471-
|b_exprISNOTOF'('type_list')'%precIS
13472-
{
13473-
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF,"<>",$1, (Node *)$6,@2);
13474-
}
1347513459
|b_exprISDOCUMENT_P%precIS
1347613460
{
1347713461
$$ = makeXmlExpr(IS_DOCUMENT,NULL, NIL,

‎src/backend/parser/parse_expr.c

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ static Node *transformAExprOpAny(ParseState *pstate, A_Expr *a);
9494
staticNode*transformAExprOpAll(ParseState*pstate,A_Expr*a);
9595
staticNode*transformAExprDistinct(ParseState*pstate,A_Expr*a);
9696
staticNode*transformAExprNullIf(ParseState*pstate,A_Expr*a);
97-
staticNode*transformAExprOf(ParseState*pstate,A_Expr*a);
9897
staticNode*transformAExprIn(ParseState*pstate,A_Expr*a);
9998
staticNode*transformAExprBetween(ParseState*pstate,A_Expr*a);
10099
staticNode*transformBoolExpr(ParseState*pstate,BoolExpr*a);
@@ -228,9 +227,6 @@ transformExprRecurse(ParseState *pstate, Node *expr)
228227
caseAEXPR_NULLIF:
229228
result=transformAExprNullIf(pstate,a);
230229
break;
231-
caseAEXPR_OF:
232-
result=transformAExprOf(pstate,a);
233-
break;
234230
caseAEXPR_IN:
235231
result=transformAExprIn(pstate,a);
236232
break;
@@ -1168,51 +1164,6 @@ transformAExprNullIf(ParseState *pstate, A_Expr *a)
11681164
return (Node*)result;
11691165
}
11701166

1171-
/*
1172-
* Checking an expression for match to a list of type names. Will result
1173-
* in a boolean constant node.
1174-
*/
1175-
staticNode*
1176-
transformAExprOf(ParseState*pstate,A_Expr*a)
1177-
{
1178-
Node*lexpr=a->lexpr;
1179-
Const*result;
1180-
ListCell*telem;
1181-
Oidltype,
1182-
rtype;
1183-
boolmatched= false;
1184-
1185-
if (operator_precedence_warning)
1186-
emit_precedence_warnings(pstate,PREC_GROUP_POSTFIX_IS,"IS",
1187-
lexpr,NULL,
1188-
a->location);
1189-
1190-
lexpr=transformExprRecurse(pstate,lexpr);
1191-
1192-
ltype=exprType(lexpr);
1193-
foreach(telem, (List*)a->rexpr)
1194-
{
1195-
rtype=typenameTypeId(pstate,lfirst(telem));
1196-
matched= (rtype==ltype);
1197-
if (matched)
1198-
break;
1199-
}
1200-
1201-
/*
1202-
* We have two forms: equals or not equals. Flip the sense of the result
1203-
* for not equals.
1204-
*/
1205-
if (strcmp(strVal(linitial(a->name)),"<>")==0)
1206-
matched= (!matched);
1207-
1208-
result= (Const*)makeBoolConst(matched, false);
1209-
1210-
/* Make the result have the original input's parse location */
1211-
result->location=exprLocation((Node*)a);
1212-
1213-
return (Node*)result;
1214-
}
1215-
12161167
staticNode*
12171168
transformAExprIn(ParseState*pstate,A_Expr*a)
12181169
{
@@ -3257,11 +3208,6 @@ operator_precedence_group(Node *node, const char **nodename)
32573208
*nodename="IS";
32583209
group=PREC_GROUP_INFIX_IS;
32593210
}
3260-
elseif (aexpr->kind==AEXPR_OF)
3261-
{
3262-
*nodename="IS";
3263-
group=PREC_GROUP_POSTFIX_IS;
3264-
}
32653211
elseif (aexpr->kind==AEXPR_IN)
32663212
{
32673213
*nodename="IN";

‎src/include/nodes/parsenodes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ typedef enum A_Expr_Kind
258258
AEXPR_DISTINCT,/* IS DISTINCT FROM - name must be "=" */
259259
AEXPR_NOT_DISTINCT,/* IS NOT DISTINCT FROM - name must be "=" */
260260
AEXPR_NULLIF,/* NULLIF - name must be "=" */
261-
AEXPR_OF,/* IS [NOT] OF - name must be "=" or "<>" */
262261
AEXPR_IN,/* [NOT] IN - name must be "=" or "<>" */
263262
AEXPR_LIKE,/* [NOT] LIKE - name must be "~~" or "!~~" */
264263
AEXPR_ILIKE,/* [NOT] ILIKE - name must be "~~*" or "!~~*" */

‎src/test/regress/expected/arrays.out

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,10 +1149,10 @@ SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
11491149
{1,2,3}
11501150
(1 row)
11511151

1152-
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[]) as "TRUE";
1153-
TRUE
1154-
------
1155-
t
1152+
SELECTpg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]";
1153+
double precision[]
1154+
--------------------
1155+
double precision[]
11561156
(1 row)
11571157

11581158
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}";
@@ -1161,10 +1161,10 @@ SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk
11611161
{{a,bc},{def,hijk}}
11621162
(1 row)
11631163

1164-
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[]) as "TRUE";
1165-
TRUE
1166-
------
1167-
t
1164+
SELECTpg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]";
1165+
character varying[]
1166+
---------------------
1167+
character varying[]
11681168
(1 row)
11691169

11701170
SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";

‎src/test/regress/expected/domain.out

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,16 @@ from basictest;
7070
(3 rows)
7171

7272
-- check that union/case/coalesce type resolution handles domains properly
73-
select coalesce(4::domainint4, 7) is of (int4) as t;
74-
t
75-
---
76-
t
77-
(1 row)
78-
79-
select coalesce(4::domainint4, 7) is of (domainint4) as f;
80-
f
81-
---
82-
f
73+
select pg_typeof(coalesce(4::domainint4, 7));
74+
pg_typeof
75+
-----------
76+
integer
8377
(1 row)
8478

85-
select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
86-
t
87-
---
88-
t
79+
selectpg_typeof(coalesce(4::domainint4, 7::domainint4));
80+
pg_typeof
81+
------------
82+
domainint4
8983
(1 row)
9084

9185
drop table basictest;

‎src/test/regress/expected/with.out

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,26 +142,26 @@ SELECT * FROM t LIMIT 10;
142142

143143
-- Test behavior with an unknown-type literal in the WITH
144144
WITH q AS (SELECT 'foo' AS x)
145-
SELECT x,x IS OF (text) AS is_text FROM q;
146-
x |is_text
147-
-----+---------
148-
foo |t
145+
SELECT x,pg_typeof(x) FROM q;
146+
x |pg_typeof
147+
-----+-----------
148+
foo |text
149149
(1 row)
150150

151151
WITH RECURSIVE t(n) AS (
152152
SELECT 'foo'
153153
UNION ALL
154154
SELECT n || ' bar' FROM t WHERE length(n) < 20
155155
)
156-
SELECT n,n IS OF (text) AS is_text FROM t;
157-
n |is_text
158-
-------------------------+---------
159-
foo |t
160-
foo bar |t
161-
foo bar bar |t
162-
foo bar bar bar |t
163-
foo bar bar bar bar |t
164-
foo bar bar bar bar bar |t
156+
SELECT n,pg_typeof(n) FROM t;
157+
n |pg_typeof
158+
-------------------------+-----------
159+
foo |text
160+
foo bar |text
161+
foo bar bar |text
162+
foo bar bar bar |text
163+
foo bar bar bar bar |text
164+
foo bar bar bar bar bar |text
165165
(6 rows)
166166

167167
-- In a perfect world, this would work and resolve the literal as int ...
@@ -171,7 +171,7 @@ WITH RECURSIVE t(n) AS (
171171
UNION ALL
172172
SELECT n+1 FROM t WHERE n < 10
173173
)
174-
SELECT n,n IS OF (int) AS is_int FROM t;
174+
SELECT n,pg_typeof(n) FROM t;
175175
ERROR: operator does not exist: text + integer
176176
LINE 4: SELECT n+1 FROM t WHERE n < 10
177177
^

‎src/test/regress/sql/arrays.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,9 @@ SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno;
343343

344344
-- array casts
345345
SELECT ARRAY[1,2,3]::text[]::int[]::float8[]AS"{1,2,3}";
346-
SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[])as"TRUE";
346+
SELECTpg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[])AS"double precision[]";
347347
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]AS"{{a,bc},{def,hijk}}";
348-
SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[])as"TRUE";
348+
SELECTpg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[])AS"character varying[]";
349349
SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]]astext[])as"{{{{{{a,bb,ccc}}}}}}";
350350
SELECTNULL::text[]::int[]AS"NULL";
351351

‎src/test/regress/sql/domain.sql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ select testtext || testvarchar as concat, testnumeric + 42 as sum
5959
from basictest;
6060

6161
-- check that union/case/coalesce type resolution handles domains properly
62-
select coalesce(4::domainint4,7) is of (int4)as t;
63-
select coalesce(4::domainint4,7) is of (domainint4)as f;
64-
select coalesce(4::domainint4,7::domainint4) is of (domainint4)as t;
62+
select pg_typeof(coalesce(4::domainint4,7));
63+
select pg_typeof(coalesce(4::domainint4,7::domainint4));
6564

6665
droptable basictest;
6766
dropdomain domainvarchar restrict;

‎src/test/regress/sql/with.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ SELECT * FROM t LIMIT 10;
7777

7878
-- Test behavior with an unknown-type literal in the WITH
7979
WITH qAS (SELECT'foo'AS x)
80-
SELECT x,x IS OF (text)AS is_textFROM q;
80+
SELECT x,pg_typeof(x)FROM q;
8181

8282
WITH RECURSIVE t(n)AS (
8383
SELECT'foo'
8484
UNION ALL
8585
SELECT n||' bar'FROM tWHERE length(n)<20
8686
)
87-
SELECT n,n IS OF (text)AS is_textFROM t;
87+
SELECT n,pg_typeof(n)FROM t;
8888

8989
-- In a perfect world, this would work and resolve the literal as int ...
9090
-- but for now, we have to be content with resolving to text too soon.
@@ -93,7 +93,7 @@ WITH RECURSIVE t(n) AS (
9393
UNION ALL
9494
SELECT n+1FROM tWHERE n<10
9595
)
96-
SELECT n,n IS OF (int)AS is_intFROM t;
96+
SELECT n,pg_typeof(n)FROM t;
9797

9898
--
9999
-- Some examples with a tree

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp