Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eE9P6-0004Y2-Ig for pgsql-sql@arkaria.postgresql.org; Mon, 13 Nov 2017 07:43:37 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1eE9P5-00087u-J3 for pgsql-sql@arkaria.postgresql.org; Mon, 13 Nov 2017 07:43:35 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eE9O1-0004cL-NT for pgsql-sql@postgresql.org; Mon, 13 Nov 2017 07:42:29 +0000 Received: from mail.inqbus.de ([2a00:b6c0:1108::1c8c]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eE9Ny-0002tV-9k for pgsql-sql@postgresql.org; Mon, 13 Nov 2017 07:42:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=stb-datenservice.de; s=20160215; h=Content-Type:In-Reply-To:MIME-Version: Date:Message-ID:From:References:Cc:To:Subject:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=dkFmKwiy00/9IIR/9ayj3S+6JFCmzs0Hlj6z9LCqDKs=; b=vk8xv5F2j0ZR3Fhzo4bVDxNov tPCOjCRzutBO7CxHr4OHJsL8Zo7gaSiUxCXhwriNoxEcvVe7GdxdEt7kbr5uKRTNlVsDnSgJegNHN Nf/bjvfHindtOZSjDOJJTkT4CTiCBZp/FmNQ/y7Wq8LkG2su91fvkf7I8EQpWFbECsH9g=; Received: from ip9234fcfc.dynamic.kabel-deutschland.de ([146.52.252.252]:61751 helo=[192.168.178.254]) by mail.inqbus.de with esmtpa (Exim 4.88) (envelope-from ) id 1eE9Nv-0003Eg-7U; Mon, 13 Nov 2017 08:42:24 +0100 Subject: Re: md5 checksum of a previous row To: Iaam Onkara Cc: pgsql-sql@postgresql.org References: <95a944da-e4f2-2500-b917-6aa825a28f03@stb-datenservice.de> From: "MS (direkt)" Message-ID: <01d43d07-5ed9-f74c-ae19-8b2f58953f6b@stb-datenservice.de> Date: Mon, 13 Nov 2017 08:42:22 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------F2FBF0FC30B8E19AF8904EF3" Content-Language: de List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org This is a multi-part message in MIME format. --------------F2FBF0FC30B8E19AF8904EF3 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit select m2.* from .... will do the job in my example Am 13.11.2017 um 08:39 schrieb Iaam Onkara: > Thanks that is very helpful. > > Now is there a way to fetch previous record without having to specify > the different column names? Seems to me this should be a  first class > function in PostgreSQL, but its not. > > On Mon, Nov 13, 2017 at 1:31 AM, MS (direkt) > > wrote: > > Hi, > > you can easily join the preceeding row, e.g. > > select sub.id , sub.created_at, preceedingid, m2.* > from ( > select m.id , m.created_at, lag(m.id ) > over(order by m.created_at) as preceedingid from test m > order by m.created_at) as sub > left join test m2 on m2.id =sub.preceedingid order > by sub.created_at; > > Regards, Martin > > > Am 13.11.2017 um 07:15 schrieb Iaam Onkara: >> Hi, >> >> I have a requirement to create an tamper proof chain of records >> for audit purposes. The pseudo code is as follows >> >> before_insert: >> 1. compute checksum of previous row (or conditionally selected row) >> 2. insert the computed checksum in the current row >> 3. using on-update or on-delete trigger raise error to prevent >> update/delete of any row. >> >> Here are the different options that I have tried using lag and >> md5 functions >> >> http://www.sqlfiddle.com/#!17/69843/2 >> >> >> CREATE TABLE test >>     ("id" uuid DEFAULT uuid_generate_v4() NOT NULL, >>      "value" decimal(5,2) NOT NULL, >>      "delta" decimal(5,2), >>      "created_at" timestamp default current_timestamp, >>      "words" text, >>      CONSTRAINT pid PRIMARY KEY (id) >>     ) >> ; >> >> INSERT INTO test >>     (value, words) >> VALUES >>     (51.0, 'A'), >>     (52.0, 'B'), >>     (54.0, 'C'), >>     (57.0, 'D') >> ; >> >> select >>   created_at, value, >>   value - lag(value, 1, 0.0) over(order by created_at) as delta, >>   md5(lag(words,1,words) over(order by created_at)) as the_word, >>   md5(textin(record_out(test))) as Hash >> FROM test >>   ORDER BY created_at; >> >> But how do I use lag function or something like lag to read the >> previous record as whole. >> >> Thanks, >> Onkara >> PS: This was earlier posted in 'pgsql-in-general' mailing list, >> but I think this is a more appropriate list, if I am wrong I am sorry > > -- > Widdersdorfer Str. 415, 50933 Köln > ; Tel.+49 / 221 / 9544 010 > HRB Köln HRB 75439, Geschäftsführer: S. Böhland, S. Rosenbauer > > -- Widdersdorfer Str. 415, 50933 Köln; Tel. +49 / 221 / 9544 010 HRB Köln HRB 75439, Geschäftsführer: S. Böhland, S. Rosenbauer --------------F2FBF0FC30B8E19AF8904EF3 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit select m2.* from .... will do the job in my example

Am 13.11.2017 um 08:39 schrieb Iaam Onkara:
Thanks that is very helpful.

Now is there a way to fetch previous record without having to specify the different column names? Seems to me this should be a  first class function in PostgreSQL, but its not.

On Mon, Nov 13, 2017 at 1:31 AM, MS (direkt) <martin.stoecker@stb-datenservice.de> wrote:
Hi,

you can easily join the preceeding row, e.g.

select sub.id, sub.created_at, preceedingid, m2.* from (
select m.id, m.created_at, lag(m.id) over(order by m.created_at) as preceedingid from test m
order by m.created_at) as sub
left join test m2 on m2.id=sub.preceedingid order by sub.created_at;

Regards, Martin


Am 13.11.2017 um 07:15 schrieb Iaam Onkara:
Hi,

I have a requirement to create an tamper proof chain of records for audit purposes. The pseudo code is as follows

before_insert:
1. compute checksum of previous row (or conditionally selected row)
2. insert the computed checksum in the current row
3. using on-update or on-delete trigger raise error to prevent update/delete of any row.

Here are the different options that I have tried using lag and md5 functions

http://www.sqlfiddle.com/#!17/69843/2

CREATE TABLE test
    ("id" uuid DEFAULT uuid_generate_v4() NOT NULL,
     "value" decimal(5,2) NOT NULL,
     "delta" decimal(5,2),
     "created_at" timestamp default current_timestamp,
     "words" text,
     CONSTRAINT pid PRIMARY KEY (id)
    )
;
   
INSERT INTO test
    (value, words)
VALUES
    (51.0, 'A'),
    (52.0, 'B'),
    (54.0, 'C'),
    (57.0, 'D')
;

select
  created_at, value,
  value - lag(value, 1, 0.0) over(order by created_at) as delta,
  md5(lag(words,1,words) over(order by created_at)) as the_word,
  md5(textin(record_out(test))) as Hash
FROM test
  ORDER BY created_at;

But how do I use lag function or something like lag to read the previous record as whole.

Thanks,
Onkara
PS: This was earlier posted in 'pgsql-in-general' mailing list, but I think this is a more appropriate list, if I am wrong I am sorry

-- 
Widdersdorfer Str. 415, 50933 Köln; Tel. +49 / 221 / 9544 010
HRB Köln HRB 75439, Geschäftsführer: S. Böhland, S. Rosenbauer 


-- 
Widdersdorfer Str. 415, 50933 Köln; Tel. +49 / 221 / 9544 010
HRB Köln HRB 75439, Geschäftsführer: S. Böhland, S. Rosenbauer 
--------------F2FBF0FC30B8E19AF8904EF3--