HiveBrain v1.2.0
Get Started
← Back to all entries
debugsqlMinor

Fixing logs that overlap

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
overlapfixinglogsthat

Problem

Here we trying to fix logs that have overlaps with each other. Am I doing it right? Is there any way to improve/refactor it?

DROP TYPE IF EXISTS logs_with_error;
  CREATE TYPE logs_with_error AS (
      model_id INT,
      model_type TEXT,
      initiator_id INT,
      initiator_type TEXT,
      error_type_id INT,
      state INT
  );

  CREATE OR REPLACE FUNCTION normalize_moderation_log_overflow() RETURNS INTEGER AS
      $BODY$
  DECLARE
      logs logs_with_error%rowtype;
      model moderation_logs%rowtype;
      initiator moderation_logs%rowtype;
  BEGIN
      FOR logs IN SELECT model_id, model_type, initiator_id, initiator_type, error_type_id, state
    FROM errors
    WHERE state = #{ Error.states[:initial] } 
    AND error_type_id = (SELECT id FROM error_types WHERE normalizer_type = 'moderation_log_overflow')
      LOOP
        SELECT * INTO model FROM moderation_logs WHERE id = logs.model_id;
        SELECT * INTO initiator FROM moderation_logs WHERE id = logs.initiator_id;

        IF model.curr_state = initiator.curr_state AND model.next_state = initiator.next_state THEN
          IF model.ended_at < initiator.ended_at THEN
            UPDATE moderation_logs SET ended_at = initiator.ended_at WHERE id = model.id;
          END IF;
          DELETE FROM moderation_logs WHERE id = initiator.id;
        ELSE
          UPDATE moderation_logs SET started_at = model.ended_at WHERE id = initiator.id;
        END IF;

        UPDATE errors 
        SET state = #{ Error.states[:resolved] };

        RAISE NOTICE '%', logs;
      END LOOP;
      RETURN 1;
  END
  $BODY$
  LANGUAGE 'plpgsql' ;

Solution

There's really only rather small things I'd change / adapt

CREATE OR REPLACE FUNCTION normalize_moderation_log_overflow() RETURNS INTEGER AS


Since you always return 1, this function actually should be a void.

CREATE OR REPLACE FUNCTION normalize_moderation_log_oveflow () RETURNS VOID AS


Your Indentation seems off a little:

BEGIN
    FOR logs ...
  FROM ...


I'd prefer to indent the SELECT statement in reference to the FOR .. LOOP like this:

BEGIN
  FOR logs IN SELECT ...
      FROM errors


AND error_type_id = (SELECT id FROM error_types WHERE normalizer_type = 'moderation_log_overflow')


This can (and probably should be) extracted into a constant

log_overflow CONSTANT INT := SELECT id FROM error_types WHERE normalizer_type = 'moderation_log_overflow' LIMIT 1;


Which makes the condition look like this:

AND error_type_id = log_overflow


UPDATE errors 
    SET state = #{ Error.states[:resolved] };


All other DML statements you have are in a single line, why not this one, too?

UPDATE errors SET state = #{ Error.states[:resolved] };

Code Snippets

CREATE OR REPLACE FUNCTION normalize_moderation_log_overflow() RETURNS INTEGER AS
CREATE OR REPLACE FUNCTION normalize_moderation_log_oveflow () RETURNS VOID AS
BEGIN
    FOR logs ...
  FROM ...
BEGIN
  FOR logs IN SELECT ...
      FROM errors
AND error_type_id = (SELECT id FROM error_types WHERE normalizer_type = 'moderation_log_overflow')

Context

StackExchange Code Review Q#96400, answer score: 4

Revisions (0)

No revisions yet.