One of the drawbacks of not being in the SQL team at Microsoft any longer is that I don’t know about all the undocumented features in the next release – I have to hunt around for them like everyone else :-( So I was poking about in SSMS in 2008 CTP-6 and noticed a function called sys.fn_PhysLocCracker that I’d never heard of. Doing an sp_helptext on it gets the following output: – Name: sys.fn_PhysLocCracker declare @page_id binary (4) – Page ID is the first four bytes, then 2 bytes of page ID, then 2 bytes of slot Cool – but something else I’ve never heard of %%physloc%% – what’s that? After playing around for a while, I figured out how to make it work. Just to be confusing, there’s another identical version of the function called sys.fn_PhysLocFormatter – and that’s the only one I could get to work. Here’s an example: CREATE TABLE TEST (c1 INT IDENTITY, c2 CHAR (4000) DEFAULT ‘a’); SELECT sys.fn_PhysLocFormatter (%%physloc%%) AS [Physical RID], * FROM TEST; Physical RID c1 It’s a physical-record locator function! Undocumented and unsupported (obviously), but hey, some of the best features are :-) It gives the database file, page within the file, and slot number on the page in the format (file:page:slot). I can think of a *bunch* of uses for this which I’ll be exploring over the next few months. How cool is that?!?!
–
– Description:
– Cracks the output of %%physloc%% virtual column
–
– Notes:
——————————————————————————-
create function sys.fn_PhysLocCracker (@physical_locator binary (8))
returns @dumploc_table table
(
[file_id] int not null,
[page_id] int not null,
[slot_id] int not null
)
as
begin
declare @file_id binary (2)
declare @slot_id binary (2)
–
select @page_id = convert (binary (4), reverse (substring (@physical_locator, 1, 4)))
select @file_id = convert (binary (2), reverse (substring (@physical_locator, 5, 2)))
select @slot_id = convert (binary (2), reverse (substring (@physical_locator, 7, 2)))
insert into @dumploc_table values (@file_id, @page_id, @slot_id)
return
end
GO
INSERT INTO TEST DEFAULT VALUES;
INSERT INTO TEST DEFAULT VALUES;
INSERT INTO TEST DEFAULT VALUES;
GO
GO
—————– ———–
(1:411:0) 1
(1:411:1) 2
(1:413:0) 3
8 Responses to SQL Server 2008: New (undocumented) physical row locator function
Very coll, its can be very useful.
Thanks for Support! :-)
Very cool, yet the possibility for misuse scares the *** out of me… I -almost- wish you hadn’t blogged it (but on the flip side, it certainly is useful — so thanks!)
In your page in "Create Function" you said "create function sys.fn_PhysLocCracker (@physical_locator binary (8))"
In SQL you said SELECT sys.fn_PhysLocFormatter (%%physloc%%) AS [Physical RID], * FROM TEST;
sys.fn_PhysLocCracker
sys.fn_PhysLocFormatter
Is it Cracker or Formatter?
Actually both of these exist but the only one I could get to work is sys.fn_PhysLocFormatter. I’ve put a comment in the post to that effect.
Thanks!
Is there a similar function for Sql Server 2005 ?
No – there’s nothing similar for 2005
I could get the cracker to work using it in the following way:
– get’s the root page of:
SELECT file_id, page_id
FROM sys.system_internals_allocation_units iau
INNER JOIN sys.partitions p ON iau.container_id = p.partition_id
CROSS APPLY sys.fn_PhysLocCracker(iau.root_page)
WHERE p.object_id = OBJECT_ID(@objectName)
AND p.index_id = 1
AND iau.type = 1
Michael Swart already made a similar comment, but once your TEST table is built, you can use sys.fn_PhysLocCracker like this:
SELECT *
FROM dbo.TEST
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%)
c1 c2 file_id page_id slot_id
———– ——— ———– ———– ———–
1 a 1 7706 0
2 a 1 7706 1
3 a 1 7708 0
4 a 1 7708 1
5 a 1 7709 0
6 a 1 7709 1
Cheers,
Chris