Operators Describes the built-in operators available in Postgres. Postgres provides a large number of built-in operators on system types. These operators are declared in the system catalog pg_operator. Every entry in pg_operator includes the name of the procedure that implements the operator and the class OIDs of the input and output types. To view all variations of the || string concatenation operator, try SELECT oprleft, oprright, oprresult, oprcode FROM pg_operator WHERE oprname = '||'; oprleft|oprright|oprresult|oprcode -------+--------+---------+------- 25| 25| 25|textcat 1042| 1042| 1042|textcat 1043| 1043| 1043|textcat (3 rows) Users may invoke operators using the operator name, as in: select * from emp where salary < 40000; Alternatively, users may call the functions that implement the operators directly. In this case, the query above would be expressed as: select * from emp where int4lt(salary, 40000); psql has a command (\dd) to show these operators. Lexical Precedence Operators have a precedence which is currently hardcoded into the parser. Most operators have the same precedence and are left-associative. This may lead to non-intuitive behavior; for example the boolean operators "<" and ">" have a different precedence that the boolean operators "<=" and ">=". Operator Ordering (decreasing precedence) Element Precedence Description UNION left SQL select construct :: Postgres typecasting [ ] left array delimiters . left table/column delimiter - right unary minus ; left statement termination, logarithm : right exponentiation | left start of interval * / % left multiplication, division + - left addition, subtraction IS test for TRUE, FALSE, NULL ISNULL test for NULL NOTNULL test for NOT NULL (all other operators) native and user-defined IN set membership BETWEEN containment LIKE string pattern matching < > boolean inequality = right equality NOT right negation AND left logical intersection OR left logical union
General Operators The operators listed here are defined for a number of native data types, ranging from numeric types to data/time types. <ProductName>Postgres</ProductName> OperatorsOperators Operator Description Usage < Less than? 1 < 2 <= Less than or equal to? 1 <= 2 <> Not equal? 1 <> 2 = Equal? 1 = 1 > Greater than? 2 > 1 >= Greater than or equal to? 2 >= 1 || Concatenate strings 'Postgre' || 'SQL' !!= NOT IN 3 !!= i ~~ LIKE 'scrappy,marc,hermit' ~~ '%scrappy%' !~~ NOT LIKE 'bruce' !~~ '%al%' ~ Match (regex), case sensitive 'thomas' ~ '.*thomas.*' ~* Match (regex), case insensitive 'thomas' ~* '.*Thomas.*' !~ Does not match (regex), case sensitive 'thomas' !~ '.*Thomas.*' !~* Does not match (regex), case insensitive 'thomas' !~* '.*vadim.*'
Numerical Operators <ProductName>Postgres</ProductName> Numerical OperatorsOperators Operator Description Usage ! Factorial 3 ! !! Factorial (left operator) !! 3 % Modulo 5 % 4 % Truncate % 4.5 * Multiplication 2 * 3 + Addition 2 + 3 - Subtraction 2 - 3 / Division 4 / 2 : Natural Exponentiation : 3.0 ; Natural Logarithm (; 5.0) @ Absolute value @ -5.0 ^ Exponentiation 2.0 ^ 3.0 |/ Square root |/ 25.0 ||/ Cube root ||/ 27.0
Geometric Operators <ProductName>Postgres</ProductName> Geometric OperatorsOperators Operator Description Usage + Translation '((0,0),(1,1))'::box + '(2.0,0)'::point - Translation '((0,0),(1,1))'::box - '(2.0,0)'::point * Scaling/rotation '((0,0),(1,1))'::box * '(2.0,0)'::point / Scaling/rotation '((0,0),(2,2))'::box / '(2.0,0)'::point # Intersection '((1,-1),(-1,1))' # '((1,1),(-1,-1))' # Number of points in polygon # '((1,0),(0,1),(-1,0))' ## Point of closest proximity '(0,0)'::point ## '((2,0),(0,2))'::lseg && Overlaps? '((0,0),(1,1))'::box && '((0,0),(2,2))'::box &< Overlaps to left? '((0,0),(1,1))'::box &< '((0,0),(2,2))'::box &> Overlaps to right? '((0,0),(3,3))'::box &> '((0,0),(2,2))'::box <-> Distance between '((0,0),1)'::circle <-> '((5,0),1)'::circle << Left of? '((0,0),1)'::circle << '((5,0),1)'::circle <^ Is below? '((0,0),1)'::circle <^ '((0,5),1)'::circle >> Is right of? '((5,0),1)'::circle >> '((0,0),1)'::circle >^ Is above? '((0,5),1)'::circle >^ '((0,0),1)'::circle ?# Intersects or overlaps '((-1,0),(1,0))'::lseg ?# '((-2,-2),(2,2))'::box; ?- Is horizontal? '(1,0)'::point ?- '(0,0)'::point ?-| Is perpendicular? '((0,0),(0,1))'::lseg ?-| '((0,0),(1,0))'::lseg @-@ Length or circumference @-@ '((0,0),(1,0))'::path ?| Is vertical? '(0,1)'::point ?| '(0,0)'::point ?|| Is parallel? '((-1,0),(1,0))'::lseg ?|| '((-1,2),(1,2))'::lseg @ Contained or on '(1,1)'::point @ '((0,0),2)'::circle @@ Center of @@ '((0,0),10)'::circle ~= Same as '((0,0),(1,1))'::polygon ~= '((1,1),(0,0))'::polygon
Time Interval Operators The time interval data type tinterval is a legacy from the original date/time types and is not as well supported as the more modern types. There are several operators for this type. <ProductName>Postgres</ProductName> Time Interval OperatorsOperators Operator Description Usage #< Interval less than? #<= Interval less than or equal to? #<> Interval not equal? #= Interval equal? #> Interval greater than? #>= Interval greater than or equal to? <#> Convert to time interval << Interval less than? | Start of interval ~= Same as <?> Time inside interval?
IP V4 CIDR Operators <ProductName>Postgres</ProductName>IP V4 CIDR OperatorsOperators Operator Description Usage < Less than '192.168.1.5'::cidr < '192.168.1.6'::cidr <= Less than or equal '192.168.1.5'::cidr <= '192.168.1.5'::cidr = Equals '192.168.1.5'::cidr = '192.168.1.5'::cidr >= Greater or equal '192.168.1.5'::cidr >= '192.168.1.5'::cidr > Greater '192.168.1.5'::cidr > '192.168.1.4'::cidr <> Not equal '192.168.1.5'::cidr <> '192.168.1.4'::cidr << is contained within '192.168.1.5'::cidr << '192.168.1/24'::cidr <<= is contained within or equals '192.168.1/24'::cidr <<= '192.168.1/24'::cidr >> contains '192.168.1/24'::cidr >> '192.168.1.5'::cidr >>= contains or equals '192.168.1/24'::cidr >>= '192.168.1/24'::cidr
IP V4 INET Operators <ProductName>Postgres</ProductName>IP V4 INET OperatorsOperators Operator Description Usage < Less than '192.168.1.5'::inet < '192.168.1.6'::inet <= Less than or equal '192.168.1.5'::inet <= '192.168.1.5'::inet = Equals '192.168.1.5'::inet = '192.168.1.5'::inet >= Greater or equal '192.168.1.5'::inet >= '192.168.1.5'::inet > Greater '192.168.1.5'::inet > '192.168.1.4'::inet <> Not equal '192.168.1.5'::inet <> '192.168.1.4'::inet << is contained within '192.168.1.5'::inet << '192.168.1/24'::inet <<= is contained within or equals '192.168.1/24'::inet <<= '192.168.1/24'::inet >> contains '192.168.1/24'::inet >> '192.168.1.5'::inet >>= contains or equals '192.168.1/24'::inet >>= '192.168.1/24'::inet