diff --git a/README.md b/README.md index 56daf87b..33551573 100644 --- a/README.md +++ b/README.md @@ -632,6 +632,7 @@ Array support is experimental. Please be careful. - SQLite does not support `numeric` type as PostgreSQL. Therefore, it does not allow to store numbers with too high precision and scale. Error out of range occurs. - SQLite does not support `NaN` special value for IEEE 754-2008 numbers. Please use this special value very cerefully because there is no such conception in SQLite at all and `NaN` value treated in SQLite as `NULL`. - SQLite support `+Infinity` and `-Infinity` special values for IEEE 754-2008 numbers in SQL expressions with numeric context. This values can be readed with both `text` and `real` affiniy, but can be writed to SQLite only with `real` affinity (as signed out of range value `9.0e999`). +- Please note you can turn off processing of IEEE 754-2008 values with `text` affiniy thorough `real` value of `column_type` option. This can increase `SELECT` or `ORDER` speed, becasuse there will be no normalize function wrapping, but in this case any query will have unsuccessfilly result in case of any value with `text` affiniy. ### Boolean values - `sqlite_fdw` boolean values support exists only for `bool` columns in foreign table. SQLite documentation recommends to store boolean as value with `integer` [affinity](https://www.sqlite.org/datatype3.html). `NULL` isn't converted, 1 converted to `true`, all other `NOT NULL` values converted to `false`. During `SELECT ... WHERE condition_column` condition converted only to `condition_column`. diff --git a/deparse.c b/deparse.c index e7927965..83e90df4 100644 --- a/deparse.c +++ b/deparse.c @@ -2384,12 +2384,22 @@ sqlite_deparse_column_ref(StringInfo buf, int varno, int varattno, PlannerInfo * case FLOAT4OID: case NUMERICOID: { - elog(DEBUG2, "floatN unification for \"%s\"", colname); - appendStringInfoString(buf, "sqlite_fdw_float("); - if (qualify_col) - ADD_REL_QUALIFIER(buf, varno); - appendStringInfoString(buf, sqlite_quote_identifier(colname, '`')); - appendStringInfoString(buf, ")"); + if (colaff != SQLITE_FLOAT) + { + elog(DEBUG2, "floatN unification for \"%s\"", colname); + appendStringInfoString(buf, "sqlite_fdw_float("); + if (qualify_col) + ADD_REL_QUALIFIER(buf, varno); + appendStringInfoString(buf, sqlite_quote_identifier(colname, '`')); + appendStringInfoString(buf, ")"); + } + else + { + elog(DEBUG2, "floatN real affinity only for \"%s\"", colname); + if (qualify_col) + ADD_REL_QUALIFIER(buf, varno); + appendStringInfoString(buf, sqlite_quote_identifier(colname, '`')); + } break; } case BOOLOID: @@ -3048,6 +3058,21 @@ get_complementary_var_node(Expr *node) } } +/* IEEE 754-2008 : ∞ and NaN */ +const char * CHAR_INF_SHORT = "Inf"; +const char * CHAR_INF_LONG = "Infinity"; +const char * CHAR_NAN = "NaN"; + +bool +isInfinity (const char * s) +{ +return strcasecmp(s, CHAR_INF_SHORT) == 0 || + strcasecmp(s, CHAR_INF_LONG) == 0 || + strcasecmp(s + sizeof(char), CHAR_INF_SHORT) == 0 || + strcasecmp(s + sizeof(char), CHAR_INF_LONG) == 0; +} + + /* * Deparse given constant value into context->buf. * @@ -3127,10 +3152,7 @@ sqlite_deparse_const(Const *node, deparse_expr_cxt *context, int showtype) else appendStringInfoString(buf, extval); } - else if (strcasecmp(extval, infs) == 0 || - strcasecmp(extval, infl) == 0 || - strcasecmp(extval + 1, infs) == 0 || - strcasecmp(extval + 1, infl) == 0) + else if (isInfinity(extval)) { bool is_negative_or_positive = false; if (extval[0] == '-' || extval[0] == '+') diff --git a/expected/13.15/types/float4.out b/expected/13.15/types/float4.out index 7b53576e..8f540bb4 100644 --- a/expected/13.15/types/float4.out +++ b/expected/13.15/types/float4.out @@ -1885,12 +1885,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/13.15/types/float8.out b/expected/13.15/types/float8.out index 0ea3f770..c5edb33c 100644 --- a/expected/13.15/types/float8.out +++ b/expected/13.15/types/float8.out @@ -2304,12 +2304,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/14.12/types/float4.out b/expected/14.12/types/float4.out index 1bbaed3f..46b42460 100644 --- a/expected/14.12/types/float4.out +++ b/expected/14.12/types/float4.out @@ -1907,12 +1907,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/14.12/types/float8.out b/expected/14.12/types/float8.out index f7607012..160711e6 100644 --- a/expected/14.12/types/float8.out +++ b/expected/14.12/types/float8.out @@ -2633,12 +2633,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/15.7/types/float4.out b/expected/15.7/types/float4.out index 1bbaed3f..46b42460 100644 --- a/expected/15.7/types/float4.out +++ b/expected/15.7/types/float4.out @@ -1907,12 +1907,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/15.7/types/float8.out b/expected/15.7/types/float8.out index f7607012..160711e6 100644 --- a/expected/15.7/types/float8.out +++ b/expected/15.7/types/float8.out @@ -2633,12 +2633,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/16.3/types/float4.out b/expected/16.3/types/float4.out index 1d3d83e2..123ba9d5 100644 --- a/expected/16.3/types/float4.out +++ b/expected/16.3/types/float4.out @@ -1934,12 +1934,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/16.3/types/float8.out b/expected/16.3/types/float8.out index aff54f77..55e6d972 100644 --- a/expected/16.3/types/float8.out +++ b/expected/16.3/types/float8.out @@ -2701,12 +2701,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/17.0/types/float4.out b/expected/17.0/types/float4.out index 1d3d83e2..123ba9d5 100644 --- a/expected/17.0/types/float4.out +++ b/expected/17.0/types/float4.out @@ -1934,12 +1934,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/expected/17.0/types/float8.out b/expected/17.0/types/float8.out index aff54f77..55e6d972 100644 --- a/expected/17.0/types/float8.out +++ b/expected/17.0/types/float8.out @@ -2701,12 +2701,81 @@ SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; (6 rows) --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public."type_FLOAT_INF" + Output: i, f + SQLite query: SELECT `i`, `f` FROM main."type_FLOAT_INF" +(3 rows) + --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public."type_FLOAT_INF+" + Output: i, f, t, l + SQLite query: SELECT `i`, sqlite_fdw_float(`f`), `t`, `l` FROM main."type_FLOAT_INF+" +(3 rows) + +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +ERROR: you should disable column_type = real for this column for infinity value processing +HINT: SQLite value with "text" affinity (8 bytes) : 'Infinity' +CONTEXT: foreign table "type_FLOAT_INF" foreign column "f" have data type "double precision" (usual affinity "real"), in query there is reference to foreign column +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; + i | f +----+----------- + 1 | -Infinity + 2 | Infinity + 3 | -Infinity + 4 | Infinity + 5 | -1e+308 + 6 | 0 + 7 | 1e+308 + 10 | Infinity + 11 | Infinity + 12 | -Infinity + 13 | Infinity + 14 | Infinity + 15 | -Infinity + 16 | +(14 rows) + +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + i | f | t | l +----+-----------+------+--- + 1 | -Infinity | real | 4 + 2 | Infinity | real | 3 + 3 | -Infinity | real | 4 + 4 | Infinity | real | 3 + 5 | -1e+308 | real | 9 + 6 | 0 | real | 3 + 7 | 1e+308 | real | 8 + 10 | Infinity | real | 3 + 11 | Infinity | real | 3 + 12 | -Infinity | real | 4 + 13 | Infinity | real | 3 + 14 | Infinity | real | 3 + 15 | -Infinity | real | 4 + 16 | | null | +(14 rows) + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/13.15/types/float4.sql b/sql/13.15/types/float4.sql index 7532f63b..25df1f69 100644 --- a/sql/13.15/types/float4.sql +++ b/sql/13.15/types/float4.sql @@ -825,13 +825,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/13.15/types/float8.sql b/sql/13.15/types/float8.sql index 92330e74..166ad3e9 100644 --- a/sql/13.15/types/float8.sql +++ b/sql/13.15/types/float8.sql @@ -1074,13 +1074,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/14.12/types/float4.sql b/sql/14.12/types/float4.sql index ede07e7a..d26033d6 100644 --- a/sql/14.12/types/float4.sql +++ b/sql/14.12/types/float4.sql @@ -837,13 +837,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/14.12/types/float8.sql b/sql/14.12/types/float8.sql index 18f74da7..3626ed73 100644 --- a/sql/14.12/types/float8.sql +++ b/sql/14.12/types/float8.sql @@ -1261,13 +1261,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/15.7/types/float4.sql b/sql/15.7/types/float4.sql index ede07e7a..d26033d6 100644 --- a/sql/15.7/types/float4.sql +++ b/sql/15.7/types/float4.sql @@ -837,13 +837,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/15.7/types/float8.sql b/sql/15.7/types/float8.sql index 18f74da7..3626ed73 100644 --- a/sql/15.7/types/float8.sql +++ b/sql/15.7/types/float8.sql @@ -1261,13 +1261,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/16.3/types/float4.sql b/sql/16.3/types/float4.sql index 85a75181..4ba5ed93 100644 --- a/sql/16.3/types/float4.sql +++ b/sql/16.3/types/float4.sql @@ -846,13 +846,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/16.3/types/float8.sql b/sql/16.3/types/float8.sql index ae9d234b..1f691b4e 100644 --- a/sql/16.3/types/float8.sql +++ b/sql/16.3/types/float8.sql @@ -1286,13 +1286,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/17.0/types/float4.sql b/sql/17.0/types/float4.sql index 85a75181..4ba5ed93 100644 --- a/sql/17.0/types/float4.sql +++ b/sql/17.0/types/float4.sql @@ -846,13 +846,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sql/17.0/types/float8.sql b/sql/17.0/types/float8.sql index ae9d234b..1f691b4e 100644 --- a/sql/17.0/types/float8.sql +++ b/sql/17.0/types/float8.sql @@ -1286,13 +1286,30 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "type_FLOAT_INF+" WHERE f = 'NaN' ORDER BY i; --Testcase 351: -DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +ALTER FOREIGN TABLE "type_FLOAT_INF" ALTER COLUMN f OPTIONS (ADD column_type 'real'); --Testcase 352: -DROP FOREIGN TABLE "type_FLOAT_INF"; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF"; --Testcase 353: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM "type_FLOAT_INF+"; +--Testcase 354: ERR - remove real +SELECT * FROM "type_FLOAT_INF"; +--Testcase 355: +DELETE FROM "type_FLOAT_INF" WHERE i IN (SELECT i FROM "type_FLOAT_INF+" WHERE t = 'text'); +--Testcase 356: +SELECT * FROM "type_FLOAT_INF"; +--Testcase 357: +SELECT * FROM "type_FLOAT_INF+"; + +--Testcase 358: +DELETE FROM "type_FLOAT_INF" WHERE i >= 10; +--Testcase 359: +DROP FOREIGN TABLE "type_FLOAT_INF"; +--Testcase 360: DROP FOREIGN TABLE "type_FLOAT_INF+"; ---Testcase 270: +--Testcase 390: DROP SERVER sqlite_svr; ---Testcase 271: +--Testcase 391: DROP EXTENSION sqlite_fdw CASCADE; diff --git a/sqlite_data_norm.c b/sqlite_data_norm.c index adf6ada0..b29fcb2c 100644 --- a/sqlite_data_norm.c +++ b/sqlite_data_norm.c @@ -349,31 +349,28 @@ sqlite_fdw_data_norm_bool(sqlite3_context* context, int argc, sqlite3_value** ar sqlite3_result_value(context, arg); } -/* Base ∞ constants */ -const char * infs = "Inf"; -const char * infl = "Infinity"; /* * Try to check SQLite value if there is any ∞ value with text affinity */ -static bool +static bool inline infinity_processing (double* d, const char* t) { - static const char * neg_infs = "-Inf"; - static const char * neg_infl = "-Infinity"; - static const char * pos_infs = "+Inf"; - static const char * pos_infl = "+Infinity"; - - if (strcasecmp(t, infs) == 0 || - strcasecmp(t, pos_infs) == 0 || - strcasecmp(t, infl) == 0 || - strcasecmp(t, pos_infl) == 0) + if (strcasecmp(t, CHAR_INF_SHORT) == 0 || + strcasecmp(t, CHAR_INF_LONG) == 0 || + (t[0] == '+' && + (strcasecmp(t + sizeof(char), CHAR_INF_SHORT) == 0 || + strcasecmp(t + sizeof(char), CHAR_INF_LONG) == 0) + ) + ) { *d = INFINITY; return true; } - if (strcasecmp(t, neg_infs) == 0 || - strcasecmp(t, neg_infl) == 0) + if (t[0] == '-' && + (strcasecmp(t + sizeof(char), CHAR_INF_SHORT) == 0 || + strcasecmp(t + sizeof(char), CHAR_INF_LONG) == 0) + ) { *d = -INFINITY; return true; @@ -410,7 +407,7 @@ sqlite_fdw_data_norm_float(sqlite3_context* context, int argc, sqlite3_value** a } l = sqlite3_value_bytes(arg); - if (l > strlen(infl) + 2 || l < strlen(infs)) + if (l > strlen(CHAR_INF_LONG) + 2 || l < strlen(CHAR_INF_SHORT)) { sqlite3_result_value(context, arg); return; diff --git a/sqlite_fdw.h b/sqlite_fdw.h index 8e109bae..64bf30c9 100644 --- a/sqlite_fdw.h +++ b/sqlite_fdw.h @@ -384,6 +384,11 @@ extern void sqlite_classify_conditions(PlannerInfo *root, List *input_conds, List **remote_conds, List **local_conds); +bool isInfinity (const char * s); +/* IEEE 754-2008 : ∞ and NaN */ +extern const char* CHAR_INF_SHORT; +extern const char* CHAR_INF_LONG; +extern const char* CHAR_NAN; /* connection.c headers */ sqlite3 *sqlite_get_connection(ForeignServer *server, bool truncatable); diff --git a/sqlite_query.c b/sqlite_query.c index 20602919..7c8b968a 100644 --- a/sqlite_query.c +++ b/sqlite_query.c @@ -257,6 +257,11 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * const char* text_value = (const char*) sqlite3_value_text(val); if (strcasecmp(text_value, "NaN") == 0) return (struct NullableDatum) {Float8GetDatum(NAN), false}; + else if (isInfinity(text_value)) + { + ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_DATA_TYPE), + errmsg("you should disable column_type = real for this column for infinity value processing"))); + } else sqlite_value_to_pg_error(); } @@ -290,6 +295,11 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * const char* text_value = (const char*) sqlite3_value_text(val); if (strcasecmp(text_value, "NaN") == 0) return (struct NullableDatum) {Float8GetDatum(NAN), false}; + else if (isInfinity(text_value)) + { + ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_DATA_TYPE), + errmsg("you should disable column_type = real for this column for infinity value processing"))); + } else sqlite_value_to_pg_error(); } @@ -340,14 +350,14 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * break; } case SQLITE3_TEXT: - { - if (value_byte_size_blob_or_utf8) - valstr = sqlite_text_value_to_pg_db_encoding(val); - /* !!! use valstr later! */ - else - pg_column_void_text_error(); - break; - } + { + if (value_byte_size_blob_or_utf8) + valstr = sqlite_text_value_to_pg_db_encoding(val); + /* !!! use valstr later! */ + else + pg_column_void_text_error(); + break; + } } break; } @@ -370,19 +380,25 @@ sqlite_convert_to_pg(Form_pg_attribute att, sqlite3_value * val, AttInMetadata * break; } case SQLITE3_TEXT: - { - if (value_byte_size_blob_or_utf8) { - const char* text_value = (const char*) sqlite3_value_text(val); - if (strcasecmp(text_value, "NaN") == 0) - return (struct NullableDatum) {Float8GetDatum(NAN), false}; + if (value_byte_size_blob_or_utf8) + { + const char* text_value = (const char*) sqlite3_value_text(val); + + if (strcasecmp(text_value, "NaN") == 0) + return (struct NullableDatum) {Float8GetDatum(NAN), false}; + else if (isInfinity(text_value)) + { + ereport(ERROR, (errcode(ERRCODE_FDW_INVALID_DATA_TYPE), + errmsg("you should disable column_type = real for this column for infinity value processing"))); + } + else + sqlite_value_to_pg_error(); + } else - sqlite_value_to_pg_error(); - } - else - pg_column_void_text_error(); - break; - } + pg_column_void_text_error(); + break; + } } break; }