Catégories :

Fonctions de chaîne et fonctions binaires (Général)

PARSE_IP

Renvoie un objet JSON composé de tous les composants d’une chaîne INET (Protocole Internet) ou CIDR (Classless Internet Domain Routing) IPv4 ou IPv6 valide.

Syntaxe

PARSE_IP(<expr>, '<type>' [, <permissive>])

Arguments

Obligatoire :

expr

Une expression de chaîne.

type

Chaîne qui identifie le type d’adresse IP. Prend en charge INET ou CIDR ; la valeur est insensible à la casse.

Facultatif :

permissif

Drapeau déterminant comment les erreurs d’analyse sont traitées :

  • Si la valeur est définie sur 0, les erreurs d’analyse entraînent l’échec de la fonction.

  • Si la valeur est définie sur 1, les erreurs d’analyse génèrent un objet dont le champ error est défini sur le message d’erreur correspondant (et aucun autre champ défini).

La valeur par défaut est 0.

Renvoie

OBJECT.

Notes sur l’utilisation

  • La fonction analyse une adresse IP et renvoie un objet JSON.

    Les éléments suivants sont toujours renvoyés :

    family

    Valeur numérique. 4 (IPv4) ou 6 (IPv6).

    ip_type

    Valeur de chaîne. inet ou cidr de l’entrée.

    host

    Valeur de chaîne. Adresse d’hôte de l’expression d’entrée.

    ip_fields

    Tableau de 4 champs numériques, chacun étant une valeur comprise entre 0 et 4 294 967 295 (2^32 - 1), inclus. Les valeurs de bits de ce tableau sont mappées sur les bits bruts de l’adresse de l’hôte.

    • Adresses IPv4 : Affiche uniquement les 32 bits les plus à droite de l’adresse de l’hôte.

    • Adresses IPv6 : Affiche chacun des champs 32 bits mappés sur l’adresse brute de l’hôte 128 bits, de gauche à droite.

    Si un masque de sous-réseau est saisi, les résultats incluent network_prefix_length, une valeur numérique identifiant la longueur du masque de sous-réseau.

    Les éléments suivants sont renvoyés pour les adresses IPv4 :

    ipv4

    Adresse IP numérique qui correspond au premier champ de ip_fields.

    ipv4_range_start

    Adresse numérique de départ du réseau, affichée lorsqu’un masque de sous-réseau est inclus dans l’entrée.

    ipv4_range_end

    Adresse numérique de fin du réseau, affichée lorsqu’un masque de sous-réseau est inclus dans l’entrée.

    Les éléments suivants sont renvoyés pour les adresses IPv6 :

    hex_ipv6

    Adresse IP exprimée sous forme de valeur hexadécimale entièrement complétée et de taille fixe.

    hex_ipv6_range_start

    Adresse hexadécimale de départ du réseau, de taille fixe et entièrement complétée, affichée lorsqu’un masque de sous-réseau est inclus dans l’entrée.

    hex_ipv6_range_end

    Adresse hexadécimale de fin du réseau, de taille fixe et entièrement complétée, affichée lorsqu’un masque de sous-réseau est inclus dans l’entrée.

    L’élément snowflake$type est réservé à l’utilisation interne de Snowflake.

  • Pour les calculs de plage d’adresses IP ou les recherches de masque de sous-réseau, effectuez directement une requête au niveau des éléments JSON individuels. Voir les exemples ci-dessous.

  • Lors de la saisie d’un masque de sous-réseau, Snowflake recommande de stocker la sortie de la fonction dans une colonne VARIANT et d’effectuer une requête sur les éléments générés pour améliorer les performances. Voir les exemples.

Exemples

SELECT column1, PARSE_IP(column1, 'INET') FROM VALUES('192.168.242.188/24'), ('192.168.243.189/24');
--------------------+-----------------------------------+
 COLUMN1            | PARSE_IP(COLUMN1, 'INET')         |
--------------------+-----------------------------------|
 192.168.242.188/24 | {                                 |
                    |   "family": 4,                    |
                    |   "host": "192.168.242.188",      |
                    |   "ip_fields": [                  |
                    |     3232297660,                   |
                    |     0,                            |
                    |     0,                            |
                    |     0                             |
                    |   ],                              |
                    |   "ip_type": "inet",              |
                    |   "ipv4": 3232297660,             |
                    |   "ipv4_range_end": 3232297727,   |
                    |   "ipv4_range_start": 3232297472, |
                    |   "netmask_prefix_length": 24,    |
                    |   "snowflake$type": "ip_address"  |
                    | }                                 |
 192.168.243.189/24 | {                                 |
                    |   "family": 4,                    |
                    |   "host": "192.168.243.189",      |
                    |   "ip_fields": [                  |
                    |     3232297917,                   |
                    |     0,                            |
                    |     0,                            |
                    |     0                             |
                    |   ],                              |
                    |   "ip_type": "inet",              |
                    |   "ipv4": 3232297917,             |
                    |   "ipv4_range_end": 3232297983,   |
                    |   "ipv4_range_start": 3232297728, |
                    |   "netmask_prefix_length": 24,    |
                    |   "snowflake$type": "ip_address"  |
                    | }                                 |
--------------------+-----------------------------------+
SELECT PARSE_IP('fe80::20c:29ff:fe2c:429/64', 'INET');

----------------------------------------------------------------+
  PARSE_IP('FE80::20C:29FF:FE2C:429/64', 'INET')                |
----------------------------------------------------------------|
  {                                                             |
    "family": 6,                                                |
    "hex_ipv6": "FE80000000000000020C29FFFE2C0429",             |
    "hex_ipv6_range_end": "FE80000000000000FFFFFFFFFFFFFFFF",   |
    "hex_ipv6_range_start": "FE800000000000000000000000000000", |
    "host": "fe80::20c:29ff:fe2c:429",                          |
    "ip_fields": [                                              |
      4269801472,                                               |
      0,                                                        |
      34351615,                                                 |
      4264297513                                                |
    ],                                                          |
    "ip_type": "inet",                                          |
    "netmask_prefix_length": 64,                                |
    "snowflake$type": "ip_address"                              |
  }                                                             |
----------------------------------------------------------------+
WITH
lookup AS (
  SELECT column1 AS tag, PARSE_IP(column2, 'INET') AS obj FROM VALUES('San Francisco', '192.168.242.0/24'), ('New York', '192.168.243.0/24')
),
entries AS (
  SELECT PARSE_IP(column1, 'INET') AS ipv4 FROM VALUES('192.168.242.188/24'), ('192.168.243.189/24')
)
SELECT lookup.tag, entries.ipv4:host, entries.ipv4
FROM lookup, entries
WHERE lookup.tag = 'San Francisco'
AND entries.IPv4:ipv4 BETWEEN lookup.obj:ipv4_range_start AND lookup.obj:ipv4_range_end;

---------------+-------------------+-----------------------------------+
 TAG           | ENTRIES.IPV4:HOST | IPV4                              |
---------------+-------------------+-----------------------------------|
 San Francisco | "192.168.242.188" | {                                 |
               |                   |   "family": 4,                    |
               |                   |   "host": "192.168.242.188",      |
               |                   |   "ip_fields": [                  |
               |                   |     3232297660,                   |
               |                   |     0,                            |
               |                   |     0,                            |
               |                   |     0                             |
               |                   |   ],                              |
               |                   |   "ip_type": "inet",              |
               |                   |   "ipv4": 3232297660,             |
               |                   |   "ipv4_range_end": 3232297727,   |
               |                   |   "ipv4_range_start": 3232297472, |
               |                   |   "netmask_prefix_length": 24,    |
               |                   |   "snowflake$type": "ip_address"  |
               |                   | }                                 |
---------------+-------------------+-----------------------------------+
CREATE OR REPLACE TABLE ipv6_lookup (tag String, obj VARIANT);

-----------------------------------------+
 status                                  |
-----------------------------------------|
 Table IPV6_LOOKUP successfully created. |
-----------------------------------------+

INSERT INTO ipv6_lookup
    SELECT column1 AS tag, parse_ip(column2, 'INET') AS obj
    FROM VALUES('west', 'fe80:12:20c:29ff::/64'), ('east', 'fe80:12:1:29ff::/64');

-------------------------+
 number of rows inserted |
-------------------------|
                       2 |
-------------------------+

CREATE OR REPLACE TABLE ipv6_entries (obj VARIANT);
------------------------------------------+
 status                                   |
------------------------------------------|
 Table IPV6_ENTRIES successfully created. |
------------------------------------------+

INSERT INTO ipv6_entries
    SELECT parse_ip(column1, 'INET') as obj
    FROM VALUES
        ('fe80:12:20c:29ff:fe2c:430:370:2/64'),
        ('fe80:12:20c:29ff:fe2c:430:370:00F0/64'),
        ('fe80:12:20c:29ff:fe2c:430:370:0F00/64'),
        ('fe80:12:20c:29ff:fe2c:430:370:F000/64'),
        ('fe80:12:20c:29ff:fe2c:430:370:FFFF/64'),
        ('fe80:12:1:29ff:fe2c:430:370:FFFF/64'),
        ('fe80:12:1:29ff:fe2c:430:370:F000/64'),
        ('fe80:12:1:29ff:fe2c:430:370:0F00/64'),
        ('fe80:12:1:29ff:fe2c:430:370:00F0/64'),
        ('fe80:12:1:29ff:fe2c:430:370:2/64');

-------------------------+
 number of rows inserted |
-------------------------|
                      10 |
-------------------------+

SELECT lookup.tag, entries.obj:host
    FROM ipv6_lookup AS lookup, ipv6_entries AS entries
    WHERE lookup.tag = 'east'
    AND entries.obj:hex_ipv6 BETWEEN lookup.obj:hex_ipv6_range_start AND lookup.obj:hex_ipv6_range_end;

------+------------------------------------+
 TAG  | ENTRIES.OBJ:HOST                   |
------+------------------------------------|
 east | "fe80:12:1:29ff:fe2c:430:370:FFFF" |
 east | "fe80:12:1:29ff:fe2c:430:370:F000" |
 east | "fe80:12:1:29ff:fe2c:430:370:0F00" |
 east | "fe80:12:1:29ff:fe2c:430:370:00F0" |
 east | "fe80:12:1:29ff:fe2c:430:370:2"    |
------+------------------------------------+