Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eE97l-0003MH-VN for pgsql-sql@arkaria.postgresql.org; Mon, 13 Nov 2017 07:25:42 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1eE97k-0006jU-8K for pgsql-sql@arkaria.postgresql.org; Mon, 13 Nov 2017 07:25:40 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eE97h-0006h6-68 for pgsql-sql@postgresql.org; Mon, 13 Nov 2017 07:25:37 +0000 Received: from host3.dynacom.ondsl.gr ([62.103.35.211] helo=smadev.internal.net) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1eE97Y-0006fU-Jr for pgsql-sql@postgresql.org; Mon, 13 Nov 2017 07:25:35 +0000 Received: from smadev.internal.net (smadev [10.9.200.131]) by smadev.internal.net (8.15.2/8.15.2) with ESMTP id vAD7PJjJ020941 for ; Mon, 13 Nov 2017 09:25:21 +0200 (EET) (envelope-from achill@matrix.gatewaynet.com) Subject: Re: md5 checksum of a previous row To: pgsql-sql@postgresql.org References: From: Achilleas Mantzios Message-ID: <1bd7533d-1b9d-8ac3-6133-5ae917f8745d@matrix.gatewaynet.com> Date: Mon, 13 Nov 2017 09:25:19 +0200 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------0C794E6465434CBA707EA7E7" Content-Language: en-US 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. --------------0C794E6465434CBA707EA7E7 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit You just need : - to define the way to find the previous row - an BEFORE INSERT trigger to compute the checksum, read up some pg/plsql or SQL to write your function. To read the row as a whole just use the table name without column in the select - two rules (update / delete) to do nothing On 13/11/2017 08:15, Iaam Onkara wrote: > 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 -- Achilleas Mantzios IT DEV Lead IT DEPT Dynacom Tankers Mgmt --------------0C794E6465434CBA707EA7E7 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit
You just need :
- to define the way to find the previous row
- an BEFORE INSERT trigger to compute the checksum, read up some pg/plsql or SQL to write your function. To read the row as a whole just use the table name without column in the select
- two rules (update / delete) to do nothing

On 13/11/2017 08:15, Iaam Onkara wrote:
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


-- 
Achilleas Mantzios
IT DEV Lead
IT DEPT
Dynacom Tankers Mgmt
--------------0C794E6465434CBA707EA7E7--