mirror of
https://github.com/postgres/postgres.git
synced 2025-11-26 23:43:30 +03:00
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in operator/function resolution. Introduce a well-defined promotion hierarchy for numeric datatypes (int2->int4->int8->numeric->float4->float8). Change make_const to initially label numeric literals as int4, int8, or numeric (never float8 anymore). Explicitly mark Func and RelabelType nodes to indicate whether they came from a function call, explicit cast, or implicit cast; use this to do reverse-listing more accurately and without so many heuristics. Explicit casts to char, varchar, bit, varbit will truncate or pad without raising an error (the pre-7.2 behavior), while assigning to a column without any explicit cast will still raise an error for wrong-length data like 7.3. This more nearly follows the SQL spec than 7.2 behavior (we should be reporting a 'completion condition' in the explicit-cast cases, but we have no mechanism for that, so just do silent truncation). Fix some problems with enforcement of typmod for array elements; it didn't work at all in 'UPDATE ... SET array[n] = foo', for example. Provide a generalized array_length_coerce() function to replace the specialized per-array-type functions that used to be needed (and were missing for NUMERIC as well as all the datetime types). Add missing conversions int8<->float4, text<->numeric, oid<->int8. initdb forced.
This commit is contained in:
@@ -13,10 +13,14 @@ create domain domainvarchar varchar(5);
|
||||
create domain domainnumeric numeric(8,2);
|
||||
create domain domainint4 int4;
|
||||
create domain domaintext text;
|
||||
-- Test coercions
|
||||
SELECT cast('123456' as domainvarchar); -- fail
|
||||
ERROR: value too long for type character varying(5)
|
||||
SELECT cast('12345' as domainvarchar); -- pass
|
||||
-- Test explicit coercions --- these should succeed (and truncate)
|
||||
SELECT cast('123456' as domainvarchar);
|
||||
domainvarchar
|
||||
---------------
|
||||
12345
|
||||
(1 row)
|
||||
|
||||
SELECT cast('12345' as domainvarchar);
|
||||
domainvarchar
|
||||
---------------
|
||||
12345
|
||||
|
||||
@@ -354,12 +354,16 @@ SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am";
|
||||
Sat Jan 01 10:00:00 1994
|
||||
(1 row)
|
||||
|
||||
SELECT date '1994-01-01' + time '11:00-5' AS "Jan_01_1994_8am";
|
||||
ERROR: Bad time external representation '11:00-5'
|
||||
SELECT "timestamp"(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_11am";
|
||||
Jan_01_1994_11am
|
||||
--------------------------
|
||||
Sat Jan 01 11:00:00 1994
|
||||
SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL;
|
||||
@@ -762,9 +766,9 @@ SELECT interval '04:30' - time '01:02' AS "20:32:00";
|
||||
(1 row)
|
||||
|
||||
SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01";
|
||||
ERROR: Cannot cast type 'time with time zone' to 'interval'
|
||||
ERROR: Cannot cast type time with time zone to interval
|
||||
SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08";
|
||||
ERROR: Cannot cast type 'interval' to 'time with time zone'
|
||||
ERROR: Cannot cast type interval to time with time zone
|
||||
SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08";
|
||||
23:29:00-08
|
||||
-------------
|
||||
|
||||
@@ -354,12 +354,16 @@ SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am";
|
||||
Sat Jan 01 10:00:00 1994
|
||||
(1 row)
|
||||
|
||||
SELECT date '1994-01-01' + time '11:00-5' AS "Jan_01_1994_8am";
|
||||
ERROR: Bad time external representation '11:00-5'
|
||||
SELECT "timestamp"(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_11am";
|
||||
Jan_01_1994_11am
|
||||
--------------------------
|
||||
Sat Jan 01 11:00:00 1994
|
||||
SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL;
|
||||
@@ -762,9 +766,9 @@ SELECT interval '04:30' - time '01:02' AS "20:32:00";
|
||||
(1 row)
|
||||
|
||||
SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01";
|
||||
ERROR: Cannot cast type 'time with time zone' to 'interval'
|
||||
ERROR: Cannot cast type time with time zone to interval
|
||||
SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08";
|
||||
ERROR: Cannot cast type 'interval' to 'time with time zone'
|
||||
ERROR: Cannot cast type interval to time with time zone
|
||||
SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08";
|
||||
23:29:00-08
|
||||
-------------
|
||||
|
||||
@@ -354,12 +354,16 @@ SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am";
|
||||
Sat Jan 01 10:00:00 1994
|
||||
(1 row)
|
||||
|
||||
SELECT date '1994-01-01' + time '11:00-5' AS "Jan_01_1994_8am";
|
||||
ERROR: Bad time external representation '11:00-5'
|
||||
SELECT "timestamp"(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_11am";
|
||||
Jan_01_1994_11am
|
||||
--------------------------
|
||||
Sat Jan 01 11:00:00 1994
|
||||
SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am";
|
||||
Jan_01_1994_8am
|
||||
------------------------------
|
||||
Sat Jan 01 08:00:00 1994 PST
|
||||
(1 row)
|
||||
|
||||
SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL;
|
||||
@@ -762,9 +766,9 @@ SELECT interval '04:30' - time '01:02' AS "20:32:00";
|
||||
(1 row)
|
||||
|
||||
SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01";
|
||||
ERROR: Cannot cast type 'time with time zone' to 'interval'
|
||||
ERROR: Cannot cast type time with time zone to interval
|
||||
SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08";
|
||||
ERROR: Cannot cast type 'interval' to 'time with time zone'
|
||||
ERROR: Cannot cast type interval to time with time zone
|
||||
SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08";
|
||||
23:29:00-08
|
||||
-------------
|
||||
|
||||
@@ -202,33 +202,35 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
|
||||
|
||||
-- **************** pg_cast ****************
|
||||
-- Look for casts from and to the same type. This is not harmful, but
|
||||
-- useless.
|
||||
-- useless. Also catch bogus values in pg_cast columns (other than
|
||||
-- cases detected by oidjoins test).
|
||||
SELECT *
|
||||
FROM pg_cast c
|
||||
WHERE c.castsource = c.casttarget;
|
||||
castsource | casttarget | castfunc | castimplicit
|
||||
------------+------------+----------+--------------
|
||||
WHERE castsource = casttarget OR castsource = 0 OR casttarget = 0
|
||||
OR castcontext NOT IN ('e', 'a', 'i');
|
||||
castsource | casttarget | castfunc | castcontext
|
||||
------------+------------+----------+-------------
|
||||
(0 rows)
|
||||
|
||||
-- Look for cast functions with incorrect number or type of argument
|
||||
-- or return value.
|
||||
-- Look for cast functions that don't have the right signature. The
|
||||
-- argument and result types in pg_proc must be the same as, or binary
|
||||
-- compatible with, what it says in pg_cast.
|
||||
SELECT c.*
|
||||
FROM pg_cast c, pg_proc p
|
||||
WHERE c.castfunc = p.oid AND
|
||||
(p.pronargs <> 1 OR
|
||||
p.proargtypes[0] <> c.castsource OR
|
||||
p.prorettype <> c.casttarget);
|
||||
castsource | casttarget | castfunc | castimplicit
|
||||
------------+------------+----------+--------------
|
||||
(0 rows)
|
||||
|
||||
-- Look for binary compatible casts that are not implicit. This is
|
||||
-- legal, but probably not intended.
|
||||
SELECT *
|
||||
FROM pg_cast c
|
||||
WHERE c.castfunc = 0 AND NOT c.castimplicit;
|
||||
castsource | casttarget | castfunc | castimplicit
|
||||
------------+------------+----------+--------------
|
||||
(p.pronargs <> 1
|
||||
OR NOT (c.castsource = p.proargtypes[0] OR
|
||||
EXISTS (SELECT 1 FROM pg_cast k
|
||||
WHERE k.castfunc = 0 AND
|
||||
k.castsource = c.castsource AND
|
||||
k.casttarget = p.proargtypes[0]))
|
||||
OR NOT (p.prorettype = c.casttarget OR
|
||||
EXISTS (SELECT 1 FROM pg_cast k
|
||||
WHERE k.castfunc = 0 AND
|
||||
k.castsource = p.prorettype AND
|
||||
k.casttarget = c.casttarget)));
|
||||
castsource | casttarget | castfunc | castcontext
|
||||
------------+------------+----------+-------------
|
||||
(0 rows)
|
||||
|
||||
-- Look for binary compatible casts that do not have the reverse
|
||||
@@ -241,8 +243,8 @@ WHERE c.castfunc = 0 AND
|
||||
WHERE k.castfunc = 0 AND
|
||||
k.castsource = c.casttarget AND
|
||||
k.casttarget = c.castsource);
|
||||
castsource | casttarget | castfunc | castimplicit
|
||||
------------+------------+----------+--------------
|
||||
castsource | casttarget | castfunc | castcontext
|
||||
------------+------------+----------+-------------
|
||||
(0 rows)
|
||||
|
||||
-- **************** pg_operator ****************
|
||||
@@ -414,20 +416,18 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
|
||||
-- Hashing only works on simple equality operators "type = sametype",
|
||||
-- since the hash itself depends on the bitwise representation of the type.
|
||||
-- Check that allegedly hashable operators look like they might be "=".
|
||||
-- NOTE: in 7.2, this search finds int4eqoid, oideqint4, and xideqint4.
|
||||
-- NOTE: in 7.3, this search finds xideqint4.
|
||||
-- Until we have some cleaner way of dealing with binary-equivalent types,
|
||||
-- just leave those three tuples in the expected output.
|
||||
-- just leave that tuple in the expected output.
|
||||
SELECT p1.oid, p1.oprname
|
||||
FROM pg_operator AS p1
|
||||
WHERE p1.oprcanhash AND NOT
|
||||
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
|
||||
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
|
||||
oid | oprname
|
||||
------+---------
|
||||
353 | =
|
||||
1136 | =
|
||||
1137 | =
|
||||
(3 rows)
|
||||
oid | oprname
|
||||
-----+---------
|
||||
353 | =
|
||||
(1 row)
|
||||
|
||||
-- In 6.5 we accepted hashable array equality operators when the array element
|
||||
-- type is hashable. However, what we actually need to make hashjoin work on
|
||||
|
||||
@@ -75,7 +75,7 @@ EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 500::oid, 4::bigint, true);
|
||||
ERROR: Wrong number of parameters, expected 6 but got 7
|
||||
-- wrong param types
|
||||
EXECUTE q3(5::smallint, 10.5::float, false, 500::oid, 4::bigint, 'bytea');
|
||||
ERROR: Parameter $2 of type double precision cannot be coerced into the expected type integer
|
||||
ERROR: Parameter $3 of type boolean cannot be coerced into the expected type double precision
|
||||
You will need to rewrite or cast the expression
|
||||
-- invalid type
|
||||
PREPARE q4(nonexistenttype) AS SELECT $1;
|
||||
|
||||
@@ -1321,10 +1321,10 @@ SELECT tablename, rulename, definition FROM pg_rules
|
||||
rtest_nothn1 | rtest_nothn_r2 | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING;
|
||||
rtest_nothn2 | rtest_nothn_r3 | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b);
|
||||
rtest_nothn2 | rtest_nothn_r4 | CREATE RULE rtest_nothn_r4 AS ON INSERT TO rtest_nothn2 DO INSTEAD NOTHING;
|
||||
rtest_order1 | rtest_order_r1 | CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 1 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r2 | CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 2 - this should run 1st'::text);
|
||||
rtest_order1 | rtest_order_r3 | CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 3 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r4 | CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE (new.a < 100) DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, int4(nextval('rtest_seq'::text)), 'rule 4 - this should run 2nd'::text);
|
||||
rtest_order1 | rtest_order_r1 | CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 1 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r2 | CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 2 - this should run 1st'::text);
|
||||
rtest_order1 | rtest_order_r3 | CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 3 - this should run 3rd or 4th'::text);
|
||||
rtest_order1 | rtest_order_r4 | CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE (new.a < 100) DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 4 - this should run 2nd'::text);
|
||||
rtest_person | rtest_pers_del | CREATE RULE rtest_pers_del AS ON DELETE TO rtest_person DO DELETE FROM rtest_admin WHERE (rtest_admin.pname = old.pname);
|
||||
rtest_person | rtest_pers_upd | CREATE RULE rtest_pers_upd AS ON UPDATE TO rtest_person DO UPDATE rtest_admin SET pname = new.pname WHERE (rtest_admin.pname = old.pname);
|
||||
rtest_system | rtest_sys_del | CREATE RULE rtest_sys_del AS ON DELETE TO rtest_system DO (DELETE FROM rtest_interface WHERE (rtest_interface.sysname = old.sysname); DELETE FROM rtest_admin WHERE (rtest_admin.sysname = old.sysname); );
|
||||
|
||||
@@ -47,8 +47,15 @@ SELECT CAST(name 'namefield' AS text) AS "text(name)";
|
||||
namefield
|
||||
(1 row)
|
||||
|
||||
SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; -- fail
|
||||
ERROR: value too long for type character(10)
|
||||
-- since this is an explicit cast, it should truncate w/o error:
|
||||
SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL;
|
||||
char(text)
|
||||
------------
|
||||
doh!
|
||||
hi de ho n
|
||||
(2 rows)
|
||||
|
||||
-- note: implicit-cast case is tested in char.sql
|
||||
SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
|
||||
char(text)
|
||||
----------------------
|
||||
|
||||
@@ -90,7 +90,7 @@ SELECT 1.1 AS two UNION ALL SELECT 2;
|
||||
SELECT 1.0 AS two UNION ALL SELECT 1;
|
||||
two
|
||||
-----
|
||||
1
|
||||
1.0
|
||||
1
|
||||
(2 rows)
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ create domain domainnumeric numeric(8,2);
|
||||
create domain domainint4 int4;
|
||||
create domain domaintext text;
|
||||
|
||||
-- Test coercions
|
||||
SELECT cast('123456' as domainvarchar); -- fail
|
||||
SELECT cast('12345' as domainvarchar); -- pass
|
||||
-- Test explicit coercions --- these should succeed (and truncate)
|
||||
SELECT cast('123456' as domainvarchar);
|
||||
SELECT cast('12345' as domainvarchar);
|
||||
|
||||
-- Test tables using domains
|
||||
create table basictest
|
||||
|
||||
@@ -90,8 +90,8 @@ SELECT (timestamp without time zone 'tomorrow' > 'now') as "True";
|
||||
-- to enable support for SQL99 timestamp type syntax.
|
||||
SELECT date '1994-01-01' + time '11:00' AS "Jan_01_1994_11am";
|
||||
SELECT date '1994-01-01' + time '10:00' AS "Jan_01_1994_10am";
|
||||
SELECT date '1994-01-01' + time '11:00-5' AS "Jan_01_1994_8am";
|
||||
SELECT "timestamp"(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_11am";
|
||||
SELECT date '1994-01-01' + timetz '11:00-5' AS "Jan_01_1994_8am";
|
||||
SELECT timestamptz(date '1994-01-01', time with time zone '11:00-5') AS "Jan_01_1994_8am";
|
||||
|
||||
SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMP_TBL;
|
||||
SELECT '' AS "64", d1 - interval '1 year' AS one_year FROM TIMESTAMP_TBL;
|
||||
|
||||
@@ -162,28 +162,32 @@ WHERE p1.prorettype = 'internal'::regtype AND NOT
|
||||
-- **************** pg_cast ****************
|
||||
|
||||
-- Look for casts from and to the same type. This is not harmful, but
|
||||
-- useless.
|
||||
-- useless. Also catch bogus values in pg_cast columns (other than
|
||||
-- cases detected by oidjoins test).
|
||||
|
||||
SELECT *
|
||||
FROM pg_cast c
|
||||
WHERE c.castsource = c.casttarget;
|
||||
WHERE castsource = casttarget OR castsource = 0 OR casttarget = 0
|
||||
OR castcontext NOT IN ('e', 'a', 'i');
|
||||
|
||||
-- Look for cast functions with incorrect number or type of argument
|
||||
-- or return value.
|
||||
-- Look for cast functions that don't have the right signature. The
|
||||
-- argument and result types in pg_proc must be the same as, or binary
|
||||
-- compatible with, what it says in pg_cast.
|
||||
|
||||
SELECT c.*
|
||||
FROM pg_cast c, pg_proc p
|
||||
WHERE c.castfunc = p.oid AND
|
||||
(p.pronargs <> 1 OR
|
||||
p.proargtypes[0] <> c.castsource OR
|
||||
p.prorettype <> c.casttarget);
|
||||
|
||||
-- Look for binary compatible casts that are not implicit. This is
|
||||
-- legal, but probably not intended.
|
||||
|
||||
SELECT *
|
||||
FROM pg_cast c
|
||||
WHERE c.castfunc = 0 AND NOT c.castimplicit;
|
||||
(p.pronargs <> 1
|
||||
OR NOT (c.castsource = p.proargtypes[0] OR
|
||||
EXISTS (SELECT 1 FROM pg_cast k
|
||||
WHERE k.castfunc = 0 AND
|
||||
k.castsource = c.castsource AND
|
||||
k.casttarget = p.proargtypes[0]))
|
||||
OR NOT (p.prorettype = c.casttarget OR
|
||||
EXISTS (SELECT 1 FROM pg_cast k
|
||||
WHERE k.castfunc = 0 AND
|
||||
k.castsource = p.prorettype AND
|
||||
k.casttarget = c.casttarget)));
|
||||
|
||||
-- Look for binary compatible casts that do not have the reverse
|
||||
-- direction registered as well, or where the reverse direction is not
|
||||
@@ -341,9 +345,9 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
|
||||
-- Hashing only works on simple equality operators "type = sametype",
|
||||
-- since the hash itself depends on the bitwise representation of the type.
|
||||
-- Check that allegedly hashable operators look like they might be "=".
|
||||
-- NOTE: in 7.2, this search finds int4eqoid, oideqint4, and xideqint4.
|
||||
-- NOTE: in 7.3, this search finds xideqint4.
|
||||
-- Until we have some cleaner way of dealing with binary-equivalent types,
|
||||
-- just leave those three tuples in the expected output.
|
||||
-- just leave that tuple in the expected output.
|
||||
|
||||
SELECT p1.oid, p1.oprname
|
||||
FROM pg_operator AS p1
|
||||
|
||||
@@ -27,7 +27,9 @@ SELECT CAST(f1 AS text) AS "text(varchar)" FROM VARCHAR_TBL;
|
||||
|
||||
SELECT CAST(name 'namefield' AS text) AS "text(name)";
|
||||
|
||||
SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL; -- fail
|
||||
-- since this is an explicit cast, it should truncate w/o error:
|
||||
SELECT CAST(f1 AS char(10)) AS "char(text)" FROM TEXT_TBL;
|
||||
-- note: implicit-cast case is tested in char.sql
|
||||
|
||||
SELECT CAST(f1 AS char(20)) AS "char(text)" FROM TEXT_TBL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user