네트워크 주소 함수·연산자
네트워크 주소 함수·연산자 (inet·cidr)
IP 주소를 다루다 보면 "이 주소가 이 서브넷 안에 있나?", "브로드캐스트 주소가 뭐지?", "호스트 주소만 뽑으려면?" 같은 질문이 생겨요. PostgreSQL은 cidr과 inet 타입을 위한 전용 연산자와 함수를 제공해서, 이런 작업을 SQL 안에서 바로 해결할 수 있어요. 이 페이지에서 그 핵심을 살펴볼게요.
출처: PostgreSQL 공식 문서 — Network Address Functions and Operators
inet과 cidr의 관계
IP 네트워크 주소 타입 cidr과 inet은 일반 비교 연산자와 함께, 전용 연산자·함수도 지원해요. 어떤 cidr 값은 암묵적으로 inet으로 캐스팅될 수 있어서, 아래에서 inet을 대상으로 하는 연산자·함수는 cidr 값에도 동작해요. (inet과 cidr 전용 함수가 따로 있는 경우는 두 경우의 동작이 달라야 하기 때문이에요.)
또한 inet 값을 cidr로 캐스팅하는 것도 허용돼요. 이때 넷마스크 오른쪽의 모든 비트는 유효한 cidr 값을 만들기 위해 조용히 0으로 채워져요.
IP 주소 연산자
inet 연산자 중 서브넷 포함 관계를 검사하는 것들이 핵심이에요. <<, <<=, >>, >>=, && 이 다섯 연산자는 두 주소의 네트워크 부분만 고려해서(넷마스크 오른쪽 비트는 무시) 하나가 다른 하나의 서브넷과 같은지 판정해요.
| 연산자 | 설명 | 예시 |
|---|---|---|
inet << inet → boolean |
서브넷이 다른 서브넷에 엄격히 포함되나요? | inet '192.168.1.5' << inet '192.168.1/24' → t |
inet <<= inet → boolean |
서브넷이 포함되거나 같은가요? | inet '192.168.1/24' <<= inet '192.168.1/24' → t |
inet >> inet → boolean |
서브넷을 엄격히 포함하나요? | inet '192.168.1/24' >> inet '192.168.1.5' → t |
inet >>= inet → boolean |
서브넷이 포함하거나 같은가요? | inet '192.168.1/24' >>= inet '192.168.1/24' → t |
inet && inet → boolean |
둘 중 하나가 다른 하나를 포함하거나 같은가요? | inet '192.168.1/24' && inet '192.168.1.80/28' → t |
~ inet → inet |
비트 NOT. | ~ inet '192.168.1.6' → 63.87.254.249 |
inet & inet → inet |
비트 AND. | inet '192.168.1.6' & inet '0.0.0.255' → 0.0.0.6 |
inet | inet → inet |
비트 OR. | inet '192.168.1.6' | inet '0.0.0.255' → 192.168.1.255 |
inet + bigint → inet |
주소에 오프셋을 더해요. | inet '192.168.1.6' + 25 → 192.168.1.31 |
bigint + inet → inet |
주소에 오프셋을 더해요. | 200 + inet '::ffff:fff0:1' → ::ffff:255.240.0.201 |
inet - bigint → inet |
주소에서 오프셋을 빼요. |
IP 주소 함수
주소를 다루는 주요 함수들을 볼게요.
abbrev(inet)→text: 축약 표시 형식의 텍스트를 만들어요.abbrev(inet '10.1.0.0/32')→10.1.0.0. (inet출력 함수와 결과가 같은데, 역사적 이유로 텍스트로 명시 캐스팅한 결과와 비교해 넷마스크 부분을 억제하는 점에서 '축약'이에요.)abbrev(cidr)→text: 넷마스크 오른쪽의 전부 0인 옥텟을 제거해 축약해요.abbrev(cidr '10.1.0.0/16')→10.1/16broadcast(inet)→inet: 주소의 네트워크 브로드캐스트 주소를 계산해요.broadcast(inet '192.168.1.5/24')→192.168.1.255/24family(inet)→integer: IPv4면 4, IPv6면 6을 반환해요.family(inet '::1')→6host(inet)→text: 넷마스크를 무시하고 IP 주소를 텍스트로 반환해요.host(inet '192.168.1.0/24')→192.168.1.0hostmask(inet)→inet: 네트워크의 호스트 마스크를 계산해요.hostmask(inet '192.168.23.20/30')→0.0.0.3inet_merge(inet, inet)→cidr: 두 네트워크를 모두 포함하는 가장 작은 네트워크를 계산해요.inet_merge(inet '192.168.1.5/24', inet '192.168.2.5/24')→192.168.0.0/22inet_same_family(inet, inet)→boolean: 두 주소가 같은 IP 계열인지 검사해요.inet_same_family(inet '192.168.1.5/24', inet '::1')→fmasklen(inet)→integer: 넷마스크 길이를 비트로 반환해요.masklen(inet '192.168.1.5/24')→24netmask(inet)→inet: 네트워크의 넷마스크를 계산해요.netmask(inet '192.168.1.5/24')→255.255.255.0network(inet)→cidr: 주소의 네트워크 부분을 반환하며, 넷마스크 오른쪽은 0으로 채워요(값을cidr로 캐스팅하는 것과 동일).network(inet '192.168.1.5/24')→192.168.1.0/24set_masklen(inet, integer)→inet: 넷마스크 길이를 설정해요.