debugsqlMinor
Fixing logs that overlap
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
Since you always
Your Indentation seems off a little:
I'd prefer to indent the SELECT statement in reference to the
This can (and probably should be) extracted into a constant
Which makes the condition look like this:
All other DML statements you have are in a single line, why not this one, too?
CREATE OR REPLACE FUNCTION normalize_moderation_log_overflow() RETURNS INTEGER ASSince you always
return 1, this function actually should be a void.CREATE OR REPLACE FUNCTION normalize_moderation_log_oveflow () RETURNS VOID ASYour 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 errorsAND 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_overflowUPDATE 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 ASCREATE OR REPLACE FUNCTION normalize_moderation_log_oveflow () RETURNS VOID ASBEGIN
FOR logs ...
FROM ...BEGIN
FOR logs IN SELECT ...
FROM errorsAND 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.