2014-04-04 16 views
5

czytałem ponad Instagrams sharding solution i zauważyłem następujący wiersz:Co oznacza %% w PL/pgSQL?

SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id; 

Czego %% w linii SELECT powyżej zrobić? Sprawdziłem PostgreSQL i jedyną rzeczą jaką odkryłem było to, że %% jest używane, gdy chcesz użyć dosłownie procentowego znaku.

CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $$ 
DECLARE 
    our_epoch bigint := 1314220021721; 
    seq_id bigint; 
    now_millis bigint; 
    shard_id int := 5; 
BEGIN 
    SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id; 

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis; 
    result := (now_millis - our_epoch) << 23; 
    result := result | (shard_id << 10); 
    result := result | (seq_id); 
END; 
$$ LANGUAGE PLPGSQL; 
+1

pewno * patrzy * jak jest on używany jak operator mod ale myślałem mod był tylko jeden '%' – Brad

+0

Domyślam się, że dany CMS nie lubisz pojedyncze '%' i że autor próbował uciec z niego poprzez podwojenie go. (lub jeszcze gorzej: CMS ucieka przez podwojenie go na wyjściu) – joop

+0

Normalnie ['%%' byłby operatorem jednokierunkowym z 'hstore'] (http://www.postgresql.org/docs/current/static/hstore .html), ale nie wydaje się, aby tak było w tym przypadku, jak wskazał @pozs. Może jakiś niestandardowy operator w swojej instalacji? –

Odpowiedz

3

Tylko Miejsce, które mogę wymyślić, gdzie % zostanie podwojona w standardowym Postgresie, jest wewnątrz funkcji format(), powszechnie używanej do tworzenia ciągu zapytania dla dynamicznego SQL. Compare examples here on SO.

The manual:

Poza formatami opisanych powyżej, szczególne sekwencja %% mogą być stosowane do produkcji dosłownego % charakter.

Tricky podczas korzystania z modulo operator % w dynamicznej instrukcji!

Podejrzewam, że używają dynamicznego SQL za zasłonami - które uogólniono i uproszczono dla artykułu. (Nazwa kwalifikowana do schematu to 'insta5.table_id_seq', a tabela nie ma nazwy "tabela".) W trakcie procesu zapomnieli "unescape" operatora modulo.
To właśnie one mogą być rzeczywiście działa:

EXECUTE format($$SELECT nextval('%I') %% 1024$$, seq_name) 
INTO seq_id; 
2

Przy domyślnej instalacji (na 9.2):

ERROR: operator does not exist: bigint %% integer 
SQL state: 42883 

więc powiedziałbym to może być

+0

Typo jest odpowiedzią. Czytając artykuł, logika wymaga od operatora modulo na swoim miejscu. Wysłałem hipotezę, jak to się mogło stać ... –