I'm finding that this rather simple postgresql 9.6 function
CREATE OR REPLACE FUNCTION public.trying_to_index_me()
RETURNS VOID AS
$BODY$
BEGIN
CREATE TABLE public.table_to_index (
id INTEGER NOT NULL,
this_id UUID NOT NULL,
that_id smallint NOT NULL,
CONSTRAINT idx_table_to_index_unique
UNIQUE (id,this_id,that_id)
);
CREATE INDEX idx_table_to_index_thisthat ON public.table_to_index(this_id,that_id);
DROP TABLE public.table_to_index;
END;
$BODY$ LANGUAGE plpgsql;
--SELECT public.trying_to_index_me();
is resulting in a schema "" does not exist error. The exact error is:
ERROR: schema "" does not exist
SQL state: 3F000
Context: SQL statement "CREATE INDEX idx_table_to_index_thisthat
ON public.table_to_index(this_id,that_id)"
PL/pgSQL function trying_to_index_me() line 10 at SQL statement
and occurs reliably on the second and subsequent executions. Cut/Pasting the above SQL chunk reproduces the error...for me. Quite interested if that's not the case for you. I have the following clues:
The schema detected in the error message varies. Mostly it is reported as "", but others like "0MA{Start of Text} " or some snippet of sql statement/comment from a previous statement in the transaction. Sounds memory pointer related.
It will error consistently once its in.
I find that if I CREATE OR REPLACE the function, I'll get one execution and then the errored state will occur again.
I find that if I open a new pgadminIII window (without dropping or recreating), I'll get the same one execution and then the errored state will occur again...regardless of if it was errored in a different window. Sounds connection related.
I find that commenting out the creation of either idx_temp_data_to_index_thisthat or idx_temp_data_to_index_unique resolves the issue.
Occurs in both "PostgreSQL 9.5.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16), 64-bit" and in the 9.6 implementation.
If the above function is executed from another function, the CREATE OR REPLACE FUNCTION 1-time resolve above does not work on the parent function, only when replacing the child function. And doesn't matter if that occurs in a separate pgadmin window. PSounds like neither the client or the transaction.
Truly appreciate your thoughts.
I think a comma is missing after that_id smallint NOT NULL
CREATE OR REPLACE FUNCTION trying_to_index_me()
RETURNS VOID AS
$BODY$
BEGIN
CREATE Temporary TABLE temp_data_to_index (
id INTEGER NOT NULL,
this_id UUID NOT NULL,
that_id smallint NOT NULL,
CONSTRAINT idx_temp_data_to_index_unique
UNIQUE (id,this_id,that_id)
);
CREATE INDEX idx_temp_data_to_index_thisthat ON temp_data_to_index(this_id,that_id);
DROP TABLE temp_data_to_index;
END;
$BODY$ LANGUAGE plpgsql VOLATILE COST 100;
This appears to have been caused by the citus data extension. The error is caused by corrupted memory that occurs once the default stack of 2M is exceeded. It doesn't show up in the logs, and never makes it to the "stack depth limit exceeded" exception that would have been thrown.
That's all speculative finger pointing.
Uninstalling citus extension resolved the issue for me.
Related
I found at several places to be able to drop a schema in DB2 along with all of its contents (indexes, SPs, triggers, sequences etc) using
CALL SYSPROC.ADMIN_DROP_SCHEMA('schema_name', NULL, 'ERRORSCHEMA', 'ERRORTAB');
However, I am getting the following error while using this command:
1) [Code: -469, SQL State: 42886] The parameter mode OUT or INOUT is not valid for a parameter in the routine named "ADMIN_DROP_SCHEMA" with specific name "ADMIN_DROP_SCHEMA" (parameter number "3", name "ERRORTABSCHEMA").. SQLCODE=-469, SQLSTATE=42886, DRIVER=4.22.29
2) [Code: -727, SQL State: 56098] An error occurred during implicit system action type "2". Information returned for the error includes SQLCODE "-469", SQLSTATE "42886" and message tokens "ADMIN_DROP_SCHEMA|ADMIN_DROP_SCHEMA|3|ERRORTABSCHEMA".. SQLCODE=-727, SQLSTATE=56098, DRIVER=4.22.29
Can anyone help me suggest what's wrong here? I tried to look at several places but didn't get any idea. It doesn't seem it's an authorization issue. Using DB2 version 11.5.
You are using the ADMIN_DROP_SCHEMA procedure parameters incorrectly, assuming you are CALLing the procedure from SQL and not the CLP.
The third and fourth parameters cannot be a literal (despite the documentation giving such an example), instead they must be host-variables (because the the procedure requires them to be input/output parameters).
If the stored-procedure completes without errors it sets these parameters to NULL. so your code should check for this.
If the stored-procedure detects errors, it creates and adds rows to the specified table and leaves the values of these parameters unchanged, and you must then query that table to list the error(s). You should drop this table before calling the stored procedure otherwise the procedure will fail with -601.
Example:
--#SET TERMINATOR #
drop table errschema.errtable#
set serveroutput on#
begin
declare v_errschema varchar(20) default 'ERRSCHEMA';
declare v_errtab varchar(20) default 'ERRTABLE';
CALL SYSPROC.ADMIN_DROP_SCHEMA('SOMESCHEMA', NULL, v_errschema, v_errtab);
if v_errschema is null and v_errtab is null
then
call dbms_output.put_line('The admin_drop_schema reported success');
else
call dbms_output.put_line('admin_drop_schema failed and created/populated table '||rtrim(v_errschema)||'.'||rtrim(v_errtab) );
end if;
end#
You can use global variables if you would like to use ADMIN_DROP_SCHEMA outside of compound SQL
E.g.
CREATE OR REPLACE VARIABLE ERROR_SCHEMA VARCHAR(128) DEFAULT 'SYSTOOLS';
CREATE OR REPLACE VARIABLE ERROR_TAB VARCHAR(128) DEFAULT 'ADS_ERRORS';
DROP TABLE IF EXISTS SYSTOOLS.ADS_ERRORS;
CALL ADMIN_DROP_SCHEMA('MY_SCHEMA', NULL, ERROR_SCHEMA, ERROR_TAB);
I have a function in PostgreSQL that calls multiple function depends on certain conditions. I create a temporary table in main function dynamically using "Execute" statement and using that temporary table for insertion and selection
in other functions (same dynamic process using "Execute" statement) those I am calling from main function.
However, its working fine as per my requirement. But sometimes it is throwing an error 'relation does not exists' on the temporary table when it is performing selection or insertion on the subroutine(internal function).
SAMPLE
Main Function
CREATE OR REPLACE FUNCTION public.sample_function(
param bigint)
RETURNS TABLE(isfinished boolean)
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE ROWS 1000.0
AS $function$
DECLARE
st_dt DATE;
end_dt DATE;
var4 CHARACTER VARYING := CURRENT_TIME;
var1 character varying;
BEGIN
SELECT SUBSTRING(REPLACE(REPLACE(REPLACE(var4,':',''),'.',''),'+','') FROM 5 FOR 7) INTO var4;
EXECUTE 'CREATE TABLE sampletable'||var4||' (
"emp_id" UUid,
"emp_name" Character Varying( 2044 ),
"start_date" Date,
"end_date" Date)';
select public.innerfunction (st_dt,end_dt,var4)
into var1;
EXECUTE 'DROP TABLE sampletable'||var4;
return query select true ;
END;
- Inner Function
CREATE OR REPLACE FUNCTION public.innerfunction(
st_dt timestamp without time zone,
end_dt timestamp without time zone,
var4 bigint)
RETURNS integer
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE
AS $function$
DECLARE
date1 timestamp without time zone:=st_dt
BEGIN
EXECUTE 'INSERT INTO sampletable'||var4||'
SELECT *
from "abc"'
;
return return_val;
END;
$function$;
- Error Message
ERROR:
relation "sampletable1954209" does not exist
LINE 1: INSERT INTO sampletable1954209
QUERY: INSERT INTO sampletable1954209
SELECT *
from "abc"
;
CONTEXT: PL/pgSQL function innerfunction(timestamp without time zone,
timestamp without time zone) line 51 at EXECUTE
SQL statement "SELECT public.innerfunction(st_dt ,end_dt)"
PL/pgSQL function sample_function(bigint) line 105 at SQL statement
********** Error **********
In above example I created a main function 'sample_function', and I am creating a temporary dynamic table 'sampletable with a random number attached to it. I am using that table on 'innerfunction' for insertion purpose.
When I am calling the main function it working as required but some times it gives the mentioned error 'relation "sampletable1954209" does not exist'.
I am not able to catch the issue.
I just ran into this problem. It turned out to be because the database was behind pgBouncer in transaction pooling mode, which meant each query could conceivably run in a different connection.
There were two symptoms of this behaviour:
I could run CREATE TEMPORARY TABLE test (LIKE sometable); in one connection, and then run SELECT * FROM test in another connection and see the temporary table. This isn't supposed to happen as temporary tables are meant to be session-specific, but because pgBouncer is pooling connections it means multiple sessions can share temporary tables unpredictably, if they are created outside of transactions.
Sometimes the connection would randomly change and my temporary table would disappear. I was creating and accessing the temporary table outside of a transaction which is why pgBouncer thought it was ok to switch connections.
The solution is to wrap everything up inside a transaction, however this was problematic for me because I was calling other code that used transactions. Postgres doesn't support nested transactions, so I was unable to wrap my code in one. (It does approximate nested transactions with savepoints, but this requires your code to use different SQL if it's running inside a transaction or not, which is not practical.)
Another solution is to change the pgBouncer configuration to session pooling instead, which causes it to run the DISCARD ALL statement when a client disconnects, before giving the session to another client. This drops all temporary tables and makes the connections behave more like direct connections.
There's a good write up of the issues at the VMWare support hub.
I see a problem with this code, but it does not quite match your exact error message:
You pass var4 to innerfunction as bigint.
Now if var4 starts with a zero like 0649940, then sample_function will use sampletable0649940, while innerfunction will try to access sampletable649940 because the leading zero is lost in the conversion.
Your error message has a seven-digit number though, so it might be a different problem.
Why don't you use a temporary table and use a fixed name for it? A temporary table is only visible in one session, and there cannot be any name collisions. That's what temporary tables are for.
I get a weird error while trying to create a trigger in my Oracle 11g database using SQL Developer. Here is what I did:
My table:
CREATE TABLE COUNTRY_CODE(
ID NUMBER(19,0) PRIMARY KEY NOT NULL,
Code VARCHAR2(2) NOT NULL,
Description VARCHAR2(50),
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by VARCHAR2(40) DEFAULT USER,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_updated_by VARCHAR2(40) DEFAULT USER,
archived CHAR(1) DEFAULT '0' NOT NULL );
The Sequence:
CREATE SEQUENCE COUNTRY_CODE_ID_SEQ START WITH 1 INCREMENT BY 1;
The trigger:
CREATE OR REPLACE TRIGGER COUNTRY_CODE_TRIGGER
BEFORE INSERT ON COUNTRY_CODE
FOR EACH ROW
DECLARE
max_id number;
cur_seq number;
BEGIN
IF :new.id IS NULL THEN
SELECT COUNTRY_CODE_ID_SEQ.nextval
INTO :new.id
FROM dual;
ELSE
SELECT GREATEST(NVL(MAX(id),0), :new.id)
INTO max_id
FROM COUNTRY_CODE;
SELECT COUNTRY_CODE_ID_SEQ.nextval
INTO cur_seq
FROM dual;
WHILE cur_seq < max_id
LOOP
SELECT COUNTRY_CODE_ID_SEQ.nextval
INTO cur_seq
FROM dual;
END LOOP;
END IF;
END;
Creating the table and the sequence works very well, but when I try to create my trigger, I get this error:
Error report:
ORA-00603: ORACLE server session terminated by fatal error
ORA-00600: internal error code, arguments: [kqlidchg0], [], [], [], [], [], [], [], [], [], [], []
ORA-00604: error occurred at recursive SQL level 1
ORA-00001: unique constraint (SYS.I_PLSCOPE_SIG_IDENTIFIER$) violated
00603. 00000 - "ORACLE server session terminated by fatal error"
*Cause: An ORACLE server session is in an unrecoverable state.
*Action: Login to ORACLE again so a new server session will be created
Does anyone know about this error?
Thanks
I finally found the answer to my problem:
Add this:
ALTER SESSION SET PLSCOPE_SETTINGS = 'IDENTIFIERS:NONE';
Or in Oracle SQL Developer:
Go to Tools | Preferences
Select Database | PL/SQL Compiler
Change the PLScope identifiers from All to None
Click on Ok
This fixes the issue...
There may be a solution for this here.
I have no other solution (and don't have the reputation to merely comment), but here is some information that might help get someone on the right track to solving this problem while still using PL/Scope.
I just had a similar issue, and looking into the PL/Scope feature helped me understand where the problem might come in. For my issue, I tried to create a trigger and the same exact error came up. I changed the body of the trigger to no avail, but changing the name worked fine.
It seems the the PL/Scope was holding onto information about the first instantiated trigger, before dropping it. A query on the triggers revealed my trigger was surely dropped, but a query on the (PL/Scope) identifiers ("all_identifiers") showed it was still there.
Some information on PL/Scope is here:
http://www.oracle.com/technetwork/testcontent/o67asktom-101004.html
Chapter 8 here (11g documentation) has more information:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28424.pdf
I have the "valid_id" check constraint on my requests table. But when it violates the constraint it shows following error
ERROR: new row for relation "requests" violates check constraint
"valid_name" DETAIL: Failing row contains ....
But instead of that I want to show message like "Failed to insert record. name is required".
Is there any way to show the custom error message in PostgreSQL?
This is kind of advanced territory here because you want to be pretty familiar with SQL states as well as existing error messages before you get started. Note that you want to re-used existing sql states as appropriate so that the application doesn't know you have overridden your check constraint.
But what you can do is create a function which runs the check and issues a raise exception if the check fails. Something like:
CREATE FUNCTION check_is_not_null(value text, column_name text) RETURNS BOOL
LANGUAGE plpgsql AS $$
begin
IF $1 IS NULL THEN
RAISE EXCEPTION 'Error: % is required', $2;
END IF;
RETURN TRUE;
END;
$$;
If you are using 8.4 or higher, you can specify an SQL state.
I am trying to isolate an issue (that resembles the topic in stackoverflow.com/q/483787/537284). The issue involves a stored procedure and occurs "randomly" once a week. To try and reproduce the issue, I created different procedure versions to mimic good and bad possible outcomes:
Good multi-row single resultset.
Good multi-row single resultset with informational message.
Good multi-row single resultset with Raiserror (less than level 11).
Good multi-row single resultset with Print.
Good empty single resultset.
Bad syntax error.
Bad syntax error with try/catch.
Bad error with Raiserror (level 11).
Bad error with Raiserror (level 11) and try/catch.
Between these tests, the syntax error with try/catch version behaved differently than what I would expect. Two resultsets (one empty and the other from the catch instruction) come back.
Does the syntax error get partially executed? I expected the catch block's result and not the try. I compared this with a Raiserror and using severity 11, it triggers the catch block with only one resultset returned. What is the difference between the syntax error and the Raiserror?
Here is my test procedure:
AS
BEGIN
SET NOCOUNT ON
SET ANSI_WARNINGS ON
SET IMPLICIT_TRANSACTIONS OFF
SET XACT_ABORT OFF
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRY
--RAISERROR ('goes to message tab yes?', 11, 1) WITH NOWAIT
SELECT '1' [myfield] FROM test_fulltext (nolock) WHERE CONTAINS(Command,'a monkey')
RETURN 0
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() [ErrorNumber]
END CATCH
RETURN -9999
END
Here is my test table (ripped from others):
CREATE TABLE test_fulltext
(
SPID INT NOT NULL,
Status VARCHAR(32) NULL,
Login SYSNAME NULL,
HostName SYSNAME NULL,
BlkBy SYSNAME NULL,
DBName SYSNAME NULL,
Command VARCHAR(32) NULL,
CPUTime INT NULL,
DiskIO INT NULL,
LastBatch VARCHAR(14) NULL,
ProgramName VARCHAR(32) NULL,
SPID2 INT
)
CREATE UNIQUE INDEX fulltextui ON test_fulltext(SPID);
CREATE FULLTEXT CATALOG fulltextft AS DEFAULT;
CREATE FULLTEXT INDEX ON test_fulltext(Command) KEY INDEX fulltextui;
Make sure to read the Remarks section fully on TRY...CATCH in Books Online. It explains this behavior in painful detail.
What I don't understand is this whole business about "forcing a syntax error"... If it's in a stored procedure and you have a syntax error in it, the SP won't even be created. Could it be that you're actually executing an older version of the stored procedure?