|
|
|
Open |
|
Linux Red Hat |
|
15.2 e02.x |
|
|
|
|
|
|
sp_iqversionuse fail with Function 'hextoint' has invalid parameter or return negative version IDs. |
|
Workaround Description |
|
2012-10-09 ltang
====================
I found a possible workaround.
By creating a new temp table in the IQ store instead of IN SYSTEM, you can run hextoint
without conversion issues or getting a negative value for versionID.
CREATE PROCEDURE test_iqversionuse()
result( VersionID unsigned bigint,
Server char(128),
IQConnID unsigned bigint,
WasReported unsigned bigint,
MinKBRelease unsigned bigint,
MaxKBRelease unsigned bigint )
begin
declare oldestver unsigned bigint;
declare newestver unsigned bigint;
declare writerID unsigned bigint;
declare myID unsigned bigint;
declare local temporary table #iqtrantmp(
TxnID unsigned bigint not null,
VersionID unsigned bigint null,
State char(16) null,
CreateKB unsigned bigint null,
DropKB unsigned bigint null,
CursorCount unsigned bigint null,
IQConnID unsigned bigint null,
primary key(TxnID),) in SYSTEM on commit preserve rows;
declare local temporary table #iqversionlist(
VersionID unsigned bigint not null,
CreateKB unsigned bigint null,
DropKB unsigned bigint null,) in SYSTEM on commit preserve rows;
declare local temporary table #iqversionuse(
VersionID unsigned bigint null,
ServerID unsigned bigint null,
WasReported unsigned bigint null,
IQConnID unsigned bigint null,) in SYSTEM on commit preserve rows;
declare local temporary table sp_iqactiveversions_table(
server_id unsigned integer null,
active_versions long varchar null,) in SYSTEM on commit delete rows;
/* CREATE A TEMP TABLE IN IQ STORE */
declare local temporary table sp_iqactiveversions_tmp(
server_id unsigned integer null,
active_versions char (8) null,
active_versions_hex bigint null ) on commit delete rows;
call dbo.sp_iqversionuse_internal();
set writerID = (select server_id
from SYS.SYSIQMPXSERVER
where role = 0);
set myID = (select server_id from SYS.SYSIQMPXSERVER
where server_name = @@servername);
insert into #iqtrantmp
select TxnID,
case VersionID when 0 then CmtID else VersionID end,
State,MainTableKBCr,MainTableKBDr,CursorCount,IQConnID
from dbo.sp_iqtransaction();
if myID = writerID then
insert into #iqversionlist
select VersionID,CreateKB,DropKB
from #iqtrantmp
where State in( 'COMMITTED','APPLIED' ) ;
/*
REPLACE THIS SELECT, BY THE 3 CMD: INSERT + UPDATE + SELECT BELOW
select isnull(min(hextoint(substr(active_versions,1,locate(active_versions,'Z')-1))),1)
into oldestver from sp_iqactiveversions_table
where locate(active_versions,'Z') > 1;
*/
insert sp_iqactiveversions_tmp (server_id, active_versions)
(select server_id, substr(active_versions,1,locate(active_versions,'Z')-1)
from sp_iqactiveversions_table
where locate(active_versions,'Z') > 1);
update sp_iqactiveversions_tmp set active_versions_hex = hextoint (active_versions);
select isnull(min(active_versions_hex), 1) into oldestver from sp_iqactiveversions_tmp;
-- Add a row for the oldest version if it does not appear in sp_iqtransaction
if not exists(select *
from #iqversionlist as it
where it.VersionID = oldestver) then
insert into #iqversionlist values( oldestver,0,0 )
end if;
-- Calculate version usage for active transactions on this server
insert into #iqversionuse
select(select isnull(max(it2.VersionID),1)
from #iqversionlist as it2
where it2.VersionID <> 0
and it2.VersionID < it.TxnID),
myID,1,IQConnID
from #iqtrantmp as it
where it.State = 'ACTIVE';
-- Add rows for versions used by query servers reported back by SQL remote
insert into #iqversionuse
select it.VersionID,vl.server_id,1,0
from sp_iqactiveversions_table as av,SYS.SYSIQMPXSERVER as vl,#iqversionlist as it
where vl.role <> 0
and vl.status = 0
and it.VersionID <> 0
and av.server_id = vl.server_id
and lower(replace('Z'+av.active_versions,'Z','Z000000000000000'))
like lower('%'+inttohex(it.VersionID)+'Z%');
-- Add rows for versions used by query servers not reported back by SQL remote
insert into #iqversionuse
select it.VersionID,mi.server_id,0,0
from SYS.SYSIQMPXSERVER as mi,#iqversionlist as it
where mi.role <> 0
and mi.status = 0
and it.VersionID > (select isnull(max(VersionID),0)
from #iqversionuse as vt
where vt.ServerID = mi.server_id)
else -- Query server
-- Gather version list from sp_iqtransaction
insert into #iqversionlist select distinct VersionID,0,0 from #iqtrantmp where(State = 'ACTIVE' or CursorCount > 0);
-- Calculate version usage for active transactions on this server
insert into #iqversionuse select VersionID,myID,
isnull((select 1
where exists(select *
from sp_iqactiveversions_table as av
where lower(replace('Z'+av.active_versions,'Z','Z000000000000000'))
like lower('%'+inttohex(it.VersionID)+'Z%'))),0),IQConnID from #iqtrantmp as it where(State = 'ACTIVE' or CursorCount > 0);
-- Add a row for the latest version
select max(VersionID) into newestver from dbo.sp_iqmpxversioninfo();
if newestver <> 0 and not exists(select * from #iqversionlist
where VersionID = newestver) then
insert into #iqversionlist values( newestver,0,0 ) ;
insert into #iqversionuse values( newestver,myID,0,0 )
end if
end if;
set oldestver = (select min(vu.VersionID) from #iqversionuse as vu);
select vt.VersionID as VersionID,
isnull((select mi.server_name
from SYS.SYSIQMPXSERVER as mi
where mi.server_id = vt.ServerID),@@SERVERNAME) as Server,
vt.IQConnID as IQConnID,
vt.WasReported as WasReported,
case vt.VersionID
when oldestver then it2.DropKB
else 0
end as MinKBRelease,
case vt.VersionID
when oldestver then it2.DropKB
when it2.VersionID then 0
else case sign(cast(it2.DropKB as bigint)-cast(it.CreateKB as bigint))
when 1 then it.CreateKB
else it2.DropKB
end
end as MaxKBRelease
from #iqversionuse as vt,#iqversionlist as it,#iqversionlist as it2
where vt.VersionID = it.VersionID
-- it2.VersionID is the previous version used to calculated release
and it2.VersionID = (select isnull(min(it3.VersionID),it.VersionID)
from #iqversionlist as it3
where it3.VersionID > vt.VersionID)
order by vt.VersionID asc,vt.ServerID asc,vt.IQConnID asc
end ; |
|
|
|