Should we document IS [NOT] OF?

Started by David G. Johnstonabout 5 years ago15 messages
#1David G. Johnston
david.g.johnston@gmail.com

Hackers,

Over in news [1]https://www.commandprompt.com/blog/is-of/ Josh Drake and Eric Ridge discovered the undocumented
feature "IS [NOT] OF"; introduced seemingly as an "oh-by-the-way" in 2002
via commit eb121ba2cfe [2]https://github.com/postgres/postgres/commit/eb121ba2cfe1dba9463301f612743df9b63e35ce.

Is there any reason not to document this back to 9.5, probably with a note
nearby to pg_typeof(any), which is a convoluted but documented way of
making this kind of test?

David J.

[1]: https://www.commandprompt.com/blog/is-of/
[2]: https://github.com/postgres/postgres/commit/eb121ba2cfe1dba9463301f612743df9b63e35ce
https://github.com/postgres/postgres/commit/eb121ba2cfe1dba9463301f612743df9b63e35ce

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#1)
Re: Should we document IS [NOT] OF?

"David G. Johnston" <david.g.johnston@gmail.com> writes:

Over in news [1] Josh Drake and Eric Ridge discovered the undocumented
feature "IS [NOT] OF"; introduced seemingly as an "oh-by-the-way" in 2002
via commit eb121ba2cfe [2].

Is there any reason not to document this back to 9.5,

As far as I can tell from reading the SQL spec, this has nothing much in
common with the SQL feature of that name except for the syntax. The SQL
feature seems to be a *run time* test on subtype inclusion, not something
that can be answered in parse analysis. Even if I'm getting that wrong,
it's clear that the spec intends IS OF to return true for subtype
relationships, not only exact type equality which is the only thing
transformAExprOf considers.

So my vote would be to rip it out, not document it. Somebody can try
again in future, perhaps. But if we document it we're just locking
ourselves into a SQL incompatibility.

regards, tom lane

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#2)
Re: Should we document IS [NOT] OF?

I wrote:

So my vote would be to rip it out, not document it. Somebody can try
again in future, perhaps. But if we document it we're just locking
ourselves into a SQL incompatibility.

Apparently, somebody already had that thought. See func.sgml
lines 765-782, which were commented out by 8272fc3f7.

regards, tom lane

#4David G. Johnston
david.g.johnston@gmail.com
In reply to: Tom Lane (#3)
Re: Should we document IS [NOT] OF?

On Wednesday, November 18, 2020, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I wrote:

So my vote would be to rip it out, not document it. Somebody can try
again in future, perhaps. But if we document it we're just locking
ourselves into a SQL incompatibility.

Apparently, somebody already had that thought. See func.sgml
lines 765-782, which were commented out by 8272fc3f7.

Is there a feature code? I skimmed the standard and non-standard tables in
our appendix and couldn’t find this in either.

David J.

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#4)
Re: Should we document IS [NOT] OF?

"David G. Johnston" <david.g.johnston@gmail.com> writes:

Is there a feature code? I skimmed the standard and non-standard tables in
our appendix and couldn’t find this in either.

a19d9d3c4 seems to have thought it was S151.

regards, tom lane

#6Joe Conway
mail@joeconway.com
In reply to: Tom Lane (#5)
Re: Should we document IS [NOT] OF?

On 11/19/20 2:03 AM, Tom Lane wrote:

"David G. Johnston" <david.g.johnston@gmail.com> writes:

Is there a feature code? I skimmed the standard and non-standard tables in
our appendix and couldn’t find this in either.

a19d9d3c4 seems to have thought it was S151.

Here is a link to previous list discussions:

/messages/by-id/45DA44F3.3010401@joeconway.com

HTH,

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Conway (#6)
Re: Should we document IS [NOT] OF?

Joe Conway <mail@joeconway.com> writes:

Here is a link to previous list discussions:
/messages/by-id/45DA44F3.3010401@joeconway.com

Ah, thanks, I was intending to go do some searching for that.

So at this point this has been re-debated at least three times.
I think it's time to put it out of its misery. You can get
equivalent behavior using something like
pg_typeof(foo) in ('int'::regtype, 'float8'::regtype)
so we've got the "another way to do it" covered. And I'm
still convinced that the existing implementation is not
anywhere near per-spec. The issue about NULL is somewhat
minor perhaps, but the real problem is that I think the
spec intends "foo is of (sometype)" to return true if foo
is of any subtype of sometype. We don't have subtypes in
the way SQL intends, but we do have inheritance children
which are more or less the same idea. The closest you can
get right now is to do something like

select * from parent_table t where t.tableoid = 'child1'::regclass

but this will fail to match grandchilden of child1.
I think a minimum expectation is that you could do
something like "where (t.*) is of (child1)", but
our existing code is nowhere near making that work.

Let's just rip it out and be done. If anyone is ever
motivated to make it work per spec, they can resurrect
whatever seems useful from the git history.

regards, tom lane

#8Joe Conway
mail@joeconway.com
In reply to: Tom Lane (#7)
Re: Should we document IS [NOT] OF?

On 11/19/20 11:06 AM, Tom Lane wrote:

Let's just rip it out and be done. If anyone is ever
motivated to make it work per spec, they can resurrect
whatever seems useful from the git history.

+1

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#9Bruce Momjian
bruce@momjian.us
In reply to: Joe Conway (#8)
Re: Should we document IS [NOT] OF?

On Thu, Nov 19, 2020 at 11:15:33AM -0500, Joe Conway wrote:

On 11/19/20 11:06 AM, Tom Lane wrote:

Let's just rip it out and be done. If anyone is ever
motivated to make it work per spec, they can resurrect
whatever seems useful from the git history.

+1

+1

--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EnterpriseDB https://enterprisedb.com

The usefulness of a cup is in its emptiness, Bruce Lee

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#9)
1 attachment(s)
Re: Should we document IS [NOT] OF?

Bruce Momjian <bruce@momjian.us> writes:

On Thu, Nov 19, 2020 at 11:15:33AM -0500, Joe Conway wrote:

On 11/19/20 11:06 AM, Tom Lane wrote:

Let's just rip it out and be done. If anyone is ever
motivated to make it work per spec, they can resurrect
whatever seems useful from the git history.

+1

+1

Here's a proposed patch for that. I was amused to discover that we have
a couple of regression test cases making use of IS OF. However, I think
using pg_typeof() is actually better for those tests anyway, since
printing the regtype result is clearer, and easier to debug if the test
ever goes wrong.

regards, tom lane

Attachments:

remove-IS-OF.patchtext/x-diff; charset=us-ascii; name=remove-IS-OF.patchDownload
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index df2c1c6f05..7d06b979eb 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -762,25 +762,6 @@ repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue>
     expression must be of Boolean type.
    </para>
 
-<!-- IS OF does not conform to the ISO SQL behavior, so it is undocumented here
-   <para>
-    <indexterm>
-     <primary>IS OF</primary>
-    </indexterm>
-    <indexterm>
-     <primary>IS NOT OF</primary>
-    </indexterm>
-    It is possible to check the data type of an expression using the
-    predicates
-<synopsis>
-<replaceable>expression</replaceable> IS OF (typename, ...)
-<replaceable>expression</replaceable> IS NOT OF (typename, ...)
-</synopsis>
-    They return a boolean value based on whether the expression's data
-    type is one of the listed data types.
-   </para>
--->
-
    <para>
     Some comparison-related functions are also available, as shown in <xref
     linkend="functions-comparison-func-table"/>.
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index b6e58e8493..caa971c435 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -373,7 +373,7 @@ S096	Optional array bounds			YES
 S097	Array element assignment			NO	
 S098	ARRAY_AGG			YES	
 S111	ONLY in query expressions			YES	
-S151	Type predicate			NO	
+S151	Type predicate			NO	see pg_typeof()
 S161	Subtype treatment			NO	
 S162	Subtype treatment for references			NO	
 S201	SQL-invoked routines on arrays			YES	
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 4504b1503b..f26498cea2 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -3213,10 +3213,6 @@ _outAExpr(StringInfo str, const A_Expr *node)
 			appendStringInfoString(str, " NULLIF ");
 			WRITE_NODE_FIELD(name);
 			break;
-		case AEXPR_OF:
-			appendStringInfoString(str, " OF ");
-			WRITE_NODE_FIELD(name);
-			break;
 		case AEXPR_IN:
 			appendStringInfoString(str, " IN ");
 			WRITE_NODE_FIELD(name);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 2cb377d034..efc9c99754 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -13238,14 +13238,6 @@ a_expr:		c_expr									{ $$ = $1; }
 				{
 					$$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2);
 				}
-			| a_expr IS OF '(' type_list ')'			%prec IS
-				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
-				}
-			| a_expr IS NOT OF '(' type_list ')'		%prec IS
-				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
-				}
 			| a_expr BETWEEN opt_asymmetric b_expr AND a_expr		%prec BETWEEN
 				{
 					$$ = (Node *) makeSimpleA_Expr(AEXPR_BETWEEN,
@@ -13464,14 +13456,6 @@ b_expr:		c_expr
 				{
 					$$ = (Node *) makeSimpleA_Expr(AEXPR_NOT_DISTINCT, "=", $1, $6, @2);
 				}
-			| b_expr IS OF '(' type_list ')'		%prec IS
-				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
-				}
-			| b_expr IS NOT OF '(' type_list ')'	%prec IS
-				{
-					$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
-				}
 			| b_expr IS DOCUMENT_P					%prec IS
 				{
 					$$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index f5165863d7..36002f059d 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -94,7 +94,6 @@ static Node *transformAExprOpAny(ParseState *pstate, A_Expr *a);
 static Node *transformAExprOpAll(ParseState *pstate, A_Expr *a);
 static Node *transformAExprDistinct(ParseState *pstate, A_Expr *a);
 static Node *transformAExprNullIf(ParseState *pstate, A_Expr *a);
-static Node *transformAExprOf(ParseState *pstate, A_Expr *a);
 static Node *transformAExprIn(ParseState *pstate, A_Expr *a);
 static Node *transformAExprBetween(ParseState *pstate, A_Expr *a);
 static Node *transformBoolExpr(ParseState *pstate, BoolExpr *a);
@@ -228,9 +227,6 @@ transformExprRecurse(ParseState *pstate, Node *expr)
 					case AEXPR_NULLIF:
 						result = transformAExprNullIf(pstate, a);
 						break;
-					case AEXPR_OF:
-						result = transformAExprOf(pstate, a);
-						break;
 					case AEXPR_IN:
 						result = transformAExprIn(pstate, a);
 						break;
@@ -1168,51 +1164,6 @@ transformAExprNullIf(ParseState *pstate, A_Expr *a)
 	return (Node *) result;
 }
 
-/*
- * Checking an expression for match to a list of type names. Will result
- * in a boolean constant node.
- */
-static Node *
-transformAExprOf(ParseState *pstate, A_Expr *a)
-{
-	Node	   *lexpr = a->lexpr;
-	Const	   *result;
-	ListCell   *telem;
-	Oid			ltype,
-				rtype;
-	bool		matched = false;
-
-	if (operator_precedence_warning)
-		emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS",
-								 lexpr, NULL,
-								 a->location);
-
-	lexpr = transformExprRecurse(pstate, lexpr);
-
-	ltype = exprType(lexpr);
-	foreach(telem, (List *) a->rexpr)
-	{
-		rtype = typenameTypeId(pstate, lfirst(telem));
-		matched = (rtype == ltype);
-		if (matched)
-			break;
-	}
-
-	/*
-	 * We have two forms: equals or not equals. Flip the sense of the result
-	 * for not equals.
-	 */
-	if (strcmp(strVal(linitial(a->name)), "<>") == 0)
-		matched = (!matched);
-
-	result = (Const *) makeBoolConst(matched, false);
-
-	/* Make the result have the original input's parse location */
-	result->location = exprLocation((Node *) a);
-
-	return (Node *) result;
-}
-
 static Node *
 transformAExprIn(ParseState *pstate, A_Expr *a)
 {
@@ -3257,11 +3208,6 @@ operator_precedence_group(Node *node, const char **nodename)
 			*nodename = "IS";
 			group = PREC_GROUP_INFIX_IS;
 		}
-		else if (aexpr->kind == AEXPR_OF)
-		{
-			*nodename = "IS";
-			group = PREC_GROUP_POSTFIX_IS;
-		}
 		else if (aexpr->kind == AEXPR_IN)
 		{
 			*nodename = "IN";
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index a2dcdef3fa..d1f9ef29ca 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -258,7 +258,6 @@ typedef enum A_Expr_Kind
 	AEXPR_DISTINCT,				/* IS DISTINCT FROM - name must be "=" */
 	AEXPR_NOT_DISTINCT,			/* IS NOT DISTINCT FROM - name must be "=" */
 	AEXPR_NULLIF,				/* NULLIF - name must be "=" */
-	AEXPR_OF,					/* IS [NOT] OF - name must be "=" or "<>" */
 	AEXPR_IN,					/* [NOT] IN - name must be "=" or "<>" */
 	AEXPR_LIKE,					/* [NOT] LIKE - name must be "~~" or "!~~" */
 	AEXPR_ILIKE,				/* [NOT] ILIKE - name must be "~~*" or "!~~*" */
diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index 5abfeb6773..e0f870e9d7 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -1149,10 +1149,10 @@ SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
  {1,2,3}
 (1 row)
 
-SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[]) as "TRUE";
- TRUE 
-------
- t
+SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]";
+ double precision[] 
+--------------------
+ double precision[]
 (1 row)
 
 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
  {{a,bc},{def,hijk}}
 (1 row)
 
-SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[]) as "TRUE";
- TRUE 
-------
- t
+SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]";
+ character varying[] 
+---------------------
+ character varying[]
 (1 row)
 
 SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 2a033a6e11..411d5c003e 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -70,22 +70,16 @@ from basictest;
 (3 rows)
 
 -- check that union/case/coalesce type resolution handles domains properly
-select coalesce(4::domainint4, 7) is of (int4) as t;
- t 
----
- t
-(1 row)
-
-select coalesce(4::domainint4, 7) is of (domainint4) as f;
- f 
----
- f
+select pg_typeof(coalesce(4::domainint4, 7));
+ pg_typeof 
+-----------
+ integer
 (1 row)
 
-select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
- t 
----
- t
+select pg_typeof(coalesce(4::domainint4, 7::domainint4));
+ pg_typeof  
+------------
+ domainint4
 (1 row)
 
 drop table basictest;
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index 96835a517e..9429e9fd28 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -142,10 +142,10 @@ SELECT * FROM t LIMIT 10;
 
 -- Test behavior with an unknown-type literal in the WITH
 WITH q AS (SELECT 'foo' AS x)
-SELECT x, x IS OF (text) AS is_text FROM q;
-  x  | is_text 
------+---------
- foo | t
+SELECT x, pg_typeof(x) FROM q;
+  x  | pg_typeof 
+-----+-----------
+ foo | text
 (1 row)
 
 WITH RECURSIVE t(n) AS (
@@ -153,15 +153,15 @@ WITH RECURSIVE t(n) AS (
 UNION ALL
     SELECT n || ' bar' FROM t WHERE length(n) < 20
 )
-SELECT n, n IS OF (text) AS is_text FROM t;
-            n            | is_text 
--------------------------+---------
- foo                     | t
- foo bar                 | t
- foo bar bar             | t
- foo bar bar bar         | t
- foo bar bar bar bar     | t
- foo bar bar bar bar bar | t
+SELECT n, pg_typeof(n) FROM t;
+            n            | pg_typeof 
+-------------------------+-----------
+ foo                     | text
+ foo bar                 | text
+ foo bar bar             | text
+ foo bar bar bar         | text
+ foo bar bar bar bar     | text
+ foo bar bar bar bar bar | text
 (6 rows)
 
 -- In a perfect world, this would work and resolve the literal as int ...
@@ -171,7 +171,7 @@ WITH RECURSIVE t(n) AS (
 UNION ALL
     SELECT n+1 FROM t WHERE n < 10
 )
-SELECT n, n IS OF (int) AS is_int FROM t;
+SELECT n, pg_typeof(n) FROM t;
 ERROR:  operator does not exist: text + integer
 LINE 4:     SELECT n+1 FROM t WHERE n < 10
                     ^
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 906fd712b7..199049b2a2 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -343,9 +343,9 @@ SELECT * FROM array_op_test WHERE t <@ '{}' ORDER BY seqno;
 
 -- array casts
 SELECT ARRAY[1,2,3]::text[]::int[]::float8[] AS "{1,2,3}";
-SELECT ARRAY[1,2,3]::text[]::int[]::float8[] is of (float8[]) as "TRUE";
+SELECT pg_typeof(ARRAY[1,2,3]::text[]::int[]::float8[]) AS "double precision[]";
 SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] AS "{{a,bc},{def,hijk}}";
-SELECT ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[] is of (varchar[]) as "TRUE";
+SELECT pg_typeof(ARRAY[['a','bc'],['def','hijk']]::text[]::varchar[]) AS "character varying[]";
 SELECT CAST(ARRAY[[[[[['a','bb','ccc']]]]]] as text[]) as "{{{{{{a,bb,ccc}}}}}}";
 SELECT NULL::text[]::int[] AS "NULL";
 
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index 1291d550d6..549c0b5adf 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -59,9 +59,8 @@ select testtext || testvarchar as concat, testnumeric + 42 as sum
 from basictest;
 
 -- check that union/case/coalesce type resolution handles domains properly
-select coalesce(4::domainint4, 7) is of (int4) as t;
-select coalesce(4::domainint4, 7) is of (domainint4) as f;
-select coalesce(4::domainint4, 7::domainint4) is of (domainint4) as t;
+select pg_typeof(coalesce(4::domainint4, 7));
+select pg_typeof(coalesce(4::domainint4, 7::domainint4));
 
 drop table basictest;
 drop domain domainvarchar restrict;
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index b1b79eb172..ad976de531 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -77,14 +77,14 @@ SELECT * FROM t LIMIT 10;
 
 -- Test behavior with an unknown-type literal in the WITH
 WITH q AS (SELECT 'foo' AS x)
-SELECT x, x IS OF (text) AS is_text FROM q;
+SELECT x, pg_typeof(x) FROM q;
 
 WITH RECURSIVE t(n) AS (
     SELECT 'foo'
 UNION ALL
     SELECT n || ' bar' FROM t WHERE length(n) < 20
 )
-SELECT n, n IS OF (text) AS is_text FROM t;
+SELECT n, pg_typeof(n) FROM t;
 
 -- In a perfect world, this would work and resolve the literal as int ...
 -- but for now, we have to be content with resolving to text too soon.
@@ -93,7 +93,7 @@ WITH RECURSIVE t(n) AS (
 UNION ALL
     SELECT n+1 FROM t WHERE n < 10
 )
-SELECT n, n IS OF (int) AS is_int FROM t;
+SELECT n, pg_typeof(n) FROM t;
 
 --
 -- Some examples with a tree
#11Joe Conway
mail@joeconway.com
In reply to: Tom Lane (#10)
Re: Should we document IS [NOT] OF?

On 11/19/20 12:08 PM, Tom Lane wrote:

Bruce Momjian <bruce@momjian.us> writes:

On Thu, Nov 19, 2020 at 11:15:33AM -0500, Joe Conway wrote:

On 11/19/20 11:06 AM, Tom Lane wrote:

Let's just rip it out and be done. If anyone is ever
motivated to make it work per spec, they can resurrect
whatever seems useful from the git history.

+1

+1

Here's a proposed patch for that. I was amused to discover that we have
a couple of regression test cases making use of IS OF.

I didn't check but those might be my fault ;-)

However, I think using pg_typeof() is actually better for those tests anyway, since
printing the regtype result is clearer, and easier to debug if the test
ever goes wrong.

Looks good to me.

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Conway (#11)
Re: Should we document IS [NOT] OF?

Joe Conway <mail@joeconway.com> writes:

On 11/19/20 12:08 PM, Tom Lane wrote:

Here's a proposed patch for that. I was amused to discover that we have
a couple of regression test cases making use of IS OF.

I didn't check but those might be my fault ;-)

I suspect at least one of them is mine ;-). But I didn't check.

Looks good to me.

Thanks for looking!

regards, tom lane

#13Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#12)
Re: Should we document IS [NOT] OF?

After digging a bit more I noticed that we'd discussed removing
IS OF in the 2007 thread, but forebore because there wasn't an easy
replacement. pg_typeof() was added a year later (b8fab2411), so we
could have done this at any point since then.

Pushed.

regards, tom lane

#14Joshua Drake
jd@commandprompt.com
In reply to: Tom Lane (#13)
Re: Should we document IS [NOT] OF?

Howdy,

Well I certainly wasn't trying to make work out of that blog but I am glad
to see it was productive.

JD

On Thu, Nov 19, 2020 at 2:43 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Show quoted text

After digging a bit more I noticed that we'd discussed removing
IS OF in the 2007 thread, but forebore because there wasn't an easy
replacement. pg_typeof() was added a year later (b8fab2411), so we
could have done this at any point since then.

Pushed.

regards, tom lane

#15John Naylor
john.naylor@enterprisedb.com
In reply to: Tom Lane (#13)
Re: Should we document IS [NOT] OF?

On Thu, Nov 19, 2020 at 6:43 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

After digging a bit more I noticed that we'd discussed removing
IS OF in the 2007 thread, but forebore because there wasn't an easy
replacement. pg_typeof() was added a year later (b8fab2411), so we
could have done this at any point since then.

Pushed.

Documenting or improving IS OF was a TODO, so I've removed that entry.

--
John Naylor
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company