2014-04-04 6 views
5

stavo leggendo su Instagrams sharding solution e ho notato la seguente linea:Che cosa significa %% in PL/pgSQL significa?

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

Cosa significa il %% nella linea SELEZIONA di cui sopra? Ho cercato PostgreSQL e l'unica cosa che ho trovato è che %% è utilizzato quando vuoi usare un carattere percentuale letterale.

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

di sicuro * sembra * come se fosse utilizzato come operatore mod ma ho pensato mod è stato solo uno '%' – Brad

+0

La mia ipotesi è che la particolare CMS non come un singolo '%' e che l'autore ha cercato di evaderlo raddoppiandolo. (o ancora peggio: il CMS lo sfugge raddoppiandolo sull'output) – joop

+0

Normalmente ['%%' sarebbe un operatore unario da 'hstore'] (http://www.postgresql.org/docs/current/static/hstore .html) ma questo non sembra essere il caso qui come sottolineato da @pozs. Operatore personalizzato nella loro installazione, forse? –

risposta

3

solo posizione a cui posso pensare, dove uno % sarebbe raddoppiato in Postgres standard è all'interno della funzione format(), comunemente utilizzata per produrre una stringa di query per SQL dinamico. Compare examples here on SO.

The manual:

Oltre agli identificatori di formato sopra descritti, la particolare sequenza %% può essere utilizzato per produrre un letterale % carattere.

Ingannevole quando si utilizza il modulo operator % in una dichiarazione dinamica!

Ho il sospetto che stiano eseguendo SQL dinamico dietro le tende, che hanno generalizzato e semplificato per l'articolo. (Il nome di schema della sequenza è 'insta5.table_id_seq' e la tabella non si chiamerà "tabella".) Nel processo si è dimenticato di "scansionare" l'operatore modulo.
questo è quello che possono effettivamente essere in esecuzione:

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

Con l'installazione di default (il 9.2):

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

Quindi direi che potrebbe essere

  • un custom operator
  • o un errore di battitura, e vogliono dare l'operatore modulo: %
+0

Typo è la risposta. Leggendo l'articolo, la logica richiede l'operatore modulo al suo posto. Ho postato un'ipotesi su come sarebbe potuto succedere ... –