diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/catalog/sql_features.txt | 2 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 4 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 16 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 54 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/arrays.out | 16 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 22 | ||||
-rw-r--r-- | src/test/regress/expected/with.out | 28 | ||||
-rw-r--r-- | src/test/regress/sql/arrays.sql | 4 | ||||
-rw-r--r-- | src/test/regress/sql/domain.sql | 5 | ||||
-rw-r--r-- | src/test/regress/sql/with.sql | 6 |
11 files changed, 38 insertions, 120 deletions
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index b6e58e84939..caa971c4356 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 4504b1503b9..f26498cea2d 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 2cb377d0342..efc9c997541 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 f5165863d77..36002f059d1 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 a2dcdef3fad..d1f9ef29ca0 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 5abfeb6773b..e0f870e9d7b 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 2a033a6e11e..411d5c003ef 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 96835a517ee..9429e9fd28f 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 906fd712b71..199049b2a27 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 1291d550d68..549c0b5adfa 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 b1b79eb1722..ad976de5311 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 |