2016-02-10 8 views
3

Учитывая следующую схему для PostGreSQL базы данных 9.5:Postgresql (PLPGSQL) назначение триггера вопрос

 -- 
     -- DOMAINS 
     -- 
     CREATE DOMAIN data_sources_url_domain AS text NOT NULL; 
     CREATE OR REPLACE FUNCTION validates_format_of_url(url text) RETURNS bool AS $$ 
     BEGIN 
      RETURN url ~* '^https?://'; 
     END; 
     $$ LANGUAGE plpgsql; 
     ALTER DOMAIN data_sources_url_domain ADD CONSTRAINT format_validation CHECK (validates_format_of_url(value)); 

     -- 
     -- TABLES 
     -- 
     CREATE TABLE data_sources (
     id UUID PRIMARY KEY DEFAULT uuid_generate_v1mc(), 
     url data_sources_url_domain 
    ); 

     -- 
     -- TRIGGERS & FUNCTIONS 
     -- 
     CREATE OR REPLACE FUNCTION format_data_source_url() RETURNS trigger AS $format_data_source_url$ 
     DECLARE 
      up_to_querystring text; 
      querystring_to_end text; 
      querystring_minus_fragment text; 
     BEGIN 
      up_to_querystring := split_part(NEW.url, '?', 1); 

      IF length(up_to_querystring) = length(NEW.url) THEN 
      NEW.url := lower(up_to_querystring); 
      RETURN NEW; 
      END IF; 

      querystring_to_end := split_part(NEW.url, '?', 2); 
      querystring_minus_fragment := split_part(querystring_to_end, '#', 1); 

      NEW.url := lower(up_to_querystring) || '?' || querystring_minus_fragment; 
      RETURN NEW; 
     END; 
     $format_data_source_url$ LANGUAGE plpgsql; 

     CREATE TRIGGER format_data_source_url BEFORE INSERT OR UPDATE ON data_sources 
     FOR EACH ROW EXECUTE PROCEDURE format_data_source_url(); 

ОБА следующего SQL заявление:

INSERT INTO data_sources (url) VALUES ('HtTpS://www.example.com/things?foo=bar#fragment'); 
INSERT INTO data_sources (url) VALUES ('HtTpS://www.example.com/things'); 

Производит следующее сообщение об ошибке:

ERROR: SPI_connect failed: SPI_ERROR_CONNECT
CONTEXT: PL/pgSQL function format_data_source_url() line X at assignment

С line X относится к одной из следующих линий:

10: NEW.url := lower(up_to_querystring); 
17: NEW.url := lower(up_to_querystring) || '?' || querystring_minus_fragment; 

Любые идеи о том, что вызывает это?

Единственная документация, которую я действительно могу найти о SPI, - here, и, похоже, это триггеры, написанные на C; этот триггер находится в PL/PGSQL.

Заранее спасибо.

ответ

1

Перед назначением NEW.url необходимо явно указать data_sources_url_domain.

CREATE OR REPLACE FUNCTION format_data_source_url() RETURNS trigger AS $format_data_source_url$ 
    DECLARE 
     up_to_querystring text; 
     querystring_to_end text; 
     querystring_minus_fragment text; 
    BEGIN 
     up_to_querystring := split_part(NEW.url, '?', 1); 

     IF length(up_to_querystring) = length(NEW.url) THEN 
     NEW.url := lower(up_to_querystring)::data_sources_url_domain; 
     RETURN NEW; 
     END IF; 

     querystring_to_end := split_part(NEW.url, '?', 2); 
     querystring_minus_fragment := split_part(querystring_to_end, '#', 1); 

     NEW.url := (lower(up_to_querystring) || '?' || querystring_minus_fragment)::data_sources_url_domain; 
     RETURN NEW; 
    END; 
    $format_data_source_url$ LANGUAGE plpgsql; 

Ошибка является странной.

+1

Спасибо. Как вы думаете, из-за неточной ошибки, это то, что нужно поделиться с разработчиками Postgresql? – ouroboros

+1

@ouroboros Да, это похоже на ошибку. Postgresql 9.4 вообще не жаловался на это. – fl0cke

Смежные вопросы