SELECT _id_template(
  $sql$
    CREATE OR REPLACE FUNCTION id_gen_monotonic() RETURNS bigint
    LANGUAGE plpgsql
    SET search_path FROM CURRENT
    AS $$
    -- Generates next globally-unique monotonic id.
    --   EssssNNNNN...
    -- where decimal positions are:
    -- a) E is environment number (1..7)
    -- b) s is microshard number (0..9999)
    -- c) N is monotonic sequence (up to 10^14)
    DECLARE
      seq text := {current_schema} || '.id_monotonic_seq';
      plain_id bigint;
      id bigint;
    BEGIN
      plain_id := nextval(seq::regclass);
      IF plain_id < 0 OR plain_id >= {CONST_RND_MUL} THEN
        RAISE EXCEPTION 'Too many ids generated by %: % (max %)', seq, plain_id, {CONST_RND_MUL};
      END IF;
      id := {I:current_schema}.id_env_no();
      id := id * {CONST_SHARD_MUL} + {I:current_schema}.id_shard_no();
      id := id * {CONST_RND_MUL} + plain_id;
      RETURN id;
    END
    $$;
  $sql$,
  'CONST_SHARD_MUL', :'CONST_SHARD_MUL',
  'CONST_RND_MUL', :'CONST_RND_MUL',
  'current_schema', current_schema
) AS tmp \gset
:tmp

COMMENT ON FUNCTION id_gen_monotonic() IS
  'Generates next globally-unique monotonic id. Monotonic ids are more friendly '
  'to heavy INSERTs since they maximize the chance for btree index to reuse '
  'the newly created leaf pages.';
