# Check that error messages and error codes are being surfaced correctly
#
# For these tests, a statement containing an intentional error is made and the
# crdb_internal.node_statement_statistics virtual table is queried to validate that the error code
# is recorded. When querying the node statistics table, we are ignoring statements made internally
# by CRDB ("$ internal-migration-manager-find-jobs" for example) since they can be flaky. We are
# also ordering by "last_error_code" to maintain consistency.

user root

# Test 1: division by zero. Error code "22012" should be added.
statement error division by zero
SELECT 2/0;

query TT
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
----
22012  division by zero

# Test 2: database does not exist. Error code "3D000" should be added.
query TTTTTT colnames,rowsort
SHOW DATABASES
----
database_name  owner  primary_region  secondary_region  regions  survival_goal
defaultdb      root   NULL            NULL              {}       NULL
postgres       root   NULL            NULL              {}       NULL
system         node   NULL            NULL              {}       NULL
test           root   NULL            NULL              {}       NULL

statement error pq: database "posgres" does not exist
use posgres

query TT
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
----
22012  division by zero
3D000  database "posgres" does not exist

# Test 3: Nonexistant user. Error code "42704" should be added.
statement error pq: role/user "who" does not exist
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES to who

query TT
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
----
22012  division by zero
3D000  database "posgres" does not exist
42704  role/user "who" does not exist 

# Test 4: Insufficient privilege. Error code "42501" should be added.
statement error schema cannot be modified: "crdb_internal"
CREATE TABLE crdb_internal.example (abc INT)

query TT
SELECT last_error_code, last_error FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
----
22012  division by zero
3D000  database "posgres" does not exist
42501  schema cannot be modified: "crdb_internal"
42704  role/user "who" does not exist

# Test 5: Foreign key violation. Error code "23503" should be added.
statement ok
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
CREATE TABLE src(x VARCHAR PRIMARY KEY);
CREATE TABLE dst(x VARCHAR REFERENCES src(x));
INSERT INTO src(x) VALUES ('example');
INSERT INTO dst(x) VALUES ('example');
COMMIT;

statement error foreign key
UPDATE dst SET x = 'xyz'

query TT
SELECT last_error_code, last_error   FROM crdb_internal.node_statement_statistics WHERE last_error_code!='NULL' AND application_name NOT LIKE '$ %' ORDER BY last_error_code ASC;
----
22012  division by zero
23503  update on table "dst" violates foreign key constraint "dst_x_fkey"
3D000  database "posgres" does not exist
42501  schema cannot be modified: "crdb_internal"
42704  role/user "who" does not exist
