-- invalid input: parse errors
SELECT ''::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT ''::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT 'ABC'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT 'ABC'::cube AS cube;
+ ^
DETAIL: syntax error at or near "A"
SELECT '()'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '()'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[()]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[()]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[(1)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),2]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),2]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "2"
SELECT '[(1),(2),(3)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2),(3)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '1,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,2,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,2,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,,2'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,,2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,2,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,,2)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,,2)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
-- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2)],'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2,3),(2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2),(1,2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1),(2),'::cube AS cube; -- 2
ERROR: bad cube representation
+LINE 1: SELECT '(1),(2),'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3),(2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2),(1,2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1,2,3)ab'::cube AS cube; -- 4
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2,3)a'::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2)('::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2)('::cube AS cube;
+ ^
DETAIL: syntax error at or near "("
SELECT '1,2ab'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1,2ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1 e7'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1 e7'::cube AS cube;
+ ^
DETAIL: syntax error at or near "e"
SELECT '1,2a'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1,2a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1..2'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1..2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ".2"
--
-- Testing building cubes from float8 values
--
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
--
-- testing the operators
-- invalid input: parse errors
SELECT ''::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT ''::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT 'ABC'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT 'ABC'::cube AS cube;
+ ^
DETAIL: syntax error at or near "A"
SELECT '()'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '()'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[()]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[()]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[(1)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),2]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),2]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "2"
SELECT '[(1),(2),(3)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2),(3)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '1,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,2,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,2,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,,2'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,,2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,2,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,,2)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,,2)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
-- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2)],'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2,3),(2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2),(1,2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1),(2),'::cube AS cube; -- 2
ERROR: bad cube representation
+LINE 1: SELECT '(1),(2),'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3),(2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2),(1,2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1,2,3)ab'::cube AS cube; -- 4
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2,3)a'::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2)('::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2)('::cube AS cube;
+ ^
DETAIL: syntax error at or near "("
SELECT '1,2ab'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1,2ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1 e7'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1 e7'::cube AS cube;
+ ^
DETAIL: syntax error at or near "e"
SELECT '1,2a'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1,2a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1..2'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1..2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ".2"
--
-- Testing building cubes from float8 values
--
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
--
-- testing the operators
-- invalid input: parse errors
SELECT ''::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT ''::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT 'ABC'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT 'ABC'::cube AS cube;
+ ^
DETAIL: syntax error at or near "A"
SELECT '()'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '()'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[()]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[()]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '[(1)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "]"
SELECT '[(1),2]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),2]'::cube AS cube;
+ ^
DETAIL: syntax error at or near "2"
SELECT '[(1),(2),(3)]'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2),(3)]'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '1,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,2,'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,2,'::cube AS cube;
+ ^
DETAIL: syntax error at end of input
SELECT '1,,2'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '1,,2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,2,)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ")"
SELECT '(1,,2)'::cube AS cube;
ERROR: bad cube representation
+LINE 1: SELECT '(1,,2)'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
-- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0
ERROR: bad cube representation
+LINE 1: SELECT '[(1),(2)],'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2,3),(2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1
ERROR: bad cube representation
+LINE 1: SELECT '[(1,2),(1,2,3)]'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1),(2),'::cube AS cube; -- 2
ERROR: bad cube representation
+LINE 1: SELECT '(1),(2),'::cube AS cube;
+ ^
DETAIL: syntax error at or near ","
SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3),(2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2,3) and (2,3).
SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3
ERROR: bad cube representation
+LINE 1: SELECT '(1,2),(1,2,3)'::cube AS cube;
+ ^
DETAIL: Different point dimensions in (1,2) and (1,2,3).
SELECT '(1,2,3)ab'::cube AS cube; -- 4
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2,3)a'::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2,3)a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '(1,2)('::cube AS cube; -- 5
ERROR: bad cube representation
+LINE 1: SELECT '(1,2)('::cube AS cube;
+ ^
DETAIL: syntax error at or near "("
SELECT '1,2ab'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1,2ab'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1 e7'::cube AS cube; -- 6
ERROR: bad cube representation
+LINE 1: SELECT '1 e7'::cube AS cube;
+ ^
DETAIL: syntax error at or near "e"
SELECT '1,2a'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1,2a'::cube AS cube;
+ ^
DETAIL: syntax error at or near "a"
SELECT '1..2'::cube AS cube; -- 7
ERROR: bad cube representation
+LINE 1: SELECT '1..2'::cube AS cube;
+ ^
DETAIL: syntax error at or near ".2"
--
-- Testing building cubes from float8 values
--
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube;
ERROR: bad cube representation
+LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...
+ ^
DETAIL: A cube cannot have more than 100 dimensions.
--
-- testing the operators
-- invalid input
SELECT ''::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT ''::seg AS seg;
+ ^
DETAIL: syntax error at end of input
SELECT 'ABC'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT 'ABC'::seg AS seg;
+ ^
DETAIL: syntax error at or near "A"
SELECT '1ABC'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1ABC'::seg AS seg;
+ ^
DETAIL: syntax error at or near "A"
SELECT '1.'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1.'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1.....'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1.....'::seg AS seg;
+ ^
DETAIL: syntax error at or near ".."
SELECT '.1'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '.1'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1..2.'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1..2.'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1 e7'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1 e7'::seg AS seg;
+ ^
DETAIL: syntax error at or near "e"
SELECT '1e700'::seg AS seg;
ERROR: "1e700" is out of range for type real
+LINE 1: SELECT '1e700'::seg AS seg;
+ ^
--
-- testing the operators
--
-- invalid input
SELECT ''::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT ''::seg AS seg;
+ ^
DETAIL: syntax error at end of input
SELECT 'ABC'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT 'ABC'::seg AS seg;
+ ^
DETAIL: syntax error at or near "A"
SELECT '1ABC'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1ABC'::seg AS seg;
+ ^
DETAIL: syntax error at or near "A"
SELECT '1.'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1.'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1.....'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1.....'::seg AS seg;
+ ^
DETAIL: syntax error at or near ".."
SELECT '.1'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '.1'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1..2.'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1..2.'::seg AS seg;
+ ^
DETAIL: syntax error at or near "."
SELECT '1 e7'::seg AS seg;
ERROR: bad seg representation
+LINE 1: SELECT '1 e7'::seg AS seg;
+ ^
DETAIL: syntax error at or near "e"
SELECT '1e700'::seg AS seg;
ERROR: "1e700" is out of range for type real
+LINE 1: SELECT '1e700'::seg AS seg;
+ ^
--
-- testing the operators
--
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.92 2008/05/09 23:32:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.93 2008/09/01 20:42:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
do_start();
- DefineIndex(makeRangeVar(NULL, LexIDStr($6)),
+ DefineIndex(makeRangeVar(NULL, LexIDStr($6), -1),
LexIDStr($3),
$4,
LexIDStr($8),
{
do_start();
- DefineIndex(makeRangeVar(NULL, LexIDStr($7)),
+ DefineIndex(makeRangeVar(NULL, LexIDStr($7), -1),
LexIDStr($4),
$5,
LexIDStr($9),
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.244 2008/06/24 17:58:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.245 2008/09/01 20:42:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
elog(DEBUG4, "open relation %s, attrsize %d",
relname, (int) ATTRIBUTE_TUPLE_SIZE);
- boot_reldesc = heap_openrv(makeRangeVar(NULL, relname), NoLock);
+ boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock);
numattr = boot_reldesc->rd_rel->relnatts;
for (i = 0; i < numattr; i++)
{
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.110 2008/08/30 01:39:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.111 2008/09/01 20:42:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
RangeVar *
makeRangeVarFromNameList(List *names)
{
- RangeVar *rel = makeRangeVar(NULL, NULL);
+ RangeVar *rel = makeRangeVar(NULL, NULL, -1);
switch (list_length(names))
{
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.10 2008/05/09 23:32:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.11 2008/09/01 20:42:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
Relation rel;
- rel = heap_openrv(makeRangeVar(NULL, relName), AccessExclusiveLock);
+ rel = heap_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock);
/* Note: during bootstrap may see uncataloged relation */
if (rel->rd_rel->relkind != RELKIND_RELATION &&
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.264 2008/08/28 23:09:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.265 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Reconstruct a RangeVar for my relation (not passed in, unfortunately).
*/
myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)),
- pstrdup(RelationGetRelationName(rel)));
+ pstrdup(RelationGetRelationName(rel)),
+ -1);
/* Make changes-so-far visible */
CommandCounterIncrement();
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.236 2008/07/18 20:26:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.237 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
else
{
/* Work around ancient pg_dump bug that omitted constrrel */
- fkcon->pktable = makeRangeVar(NULL, pk_table_name);
+ fkcon->pktable = makeRangeVar(NULL, pk_table_name, -1);
}
}
else
else
{
/* Work around ancient pg_dump bug that omitted constrrel */
- atstmt->relation = makeRangeVar(NULL, fk_table_name);
+ atstmt->relation = makeRangeVar(NULL, fk_table_name, -1);
}
}
atstmt->cmds = list_make1(atcmd);
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.403 2008/08/30 01:39:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.404 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
COPY_SCALAR_FIELD(inhOpt);
COPY_SCALAR_FIELD(istemp);
COPY_NODE_FIELD(alias);
+ COPY_LOCATION_FIELD(location);
return newnode;
}
{
SortBy *newnode = makeNode(SortBy);
+ COPY_NODE_FIELD(node);
COPY_SCALAR_FIELD(sortby_dir);
COPY_SCALAR_FIELD(sortby_nulls);
COPY_NODE_FIELD(useOp);
- COPY_NODE_FIELD(node);
+ COPY_LOCATION_FIELD(location);
return newnode;
}
{
NotifyStmt *newnode = makeNode(NotifyStmt);
- COPY_NODE_FIELD(relation);
+ COPY_STRING_FIELD(conditionname);
return newnode;
}
{
ListenStmt *newnode = makeNode(ListenStmt);
- COPY_NODE_FIELD(relation);
+ COPY_STRING_FIELD(conditionname);
return newnode;
}
{
UnlistenStmt *newnode = makeNode(UnlistenStmt);
- COPY_NODE_FIELD(relation);
+ COPY_STRING_FIELD(conditionname);
return newnode;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.330 2008/08/30 01:39:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.331 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
COMPARE_SCALAR_FIELD(inhOpt);
COMPARE_SCALAR_FIELD(istemp);
COMPARE_NODE_FIELD(alias);
+ COMPARE_LOCATION_FIELD(location);
return true;
}
static bool
_equalNotifyStmt(NotifyStmt *a, NotifyStmt *b)
{
- COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(conditionname);
return true;
}
static bool
_equalListenStmt(ListenStmt *a, ListenStmt *b)
{
- COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(conditionname);
return true;
}
static bool
_equalUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
{
- COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(conditionname);
return true;
}
static bool
_equalSortBy(SortBy *a, SortBy *b)
{
+ COMPARE_NODE_FIELD(node);
COMPARE_SCALAR_FIELD(sortby_dir);
COMPARE_SCALAR_FIELD(sortby_nulls);
COMPARE_NODE_FIELD(useOp);
- COMPARE_NODE_FIELD(node);
+ COMPARE_LOCATION_FIELD(location);
return true;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.59 2008/08/28 23:09:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.60 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* creates a RangeVar node (rather oversimplified case)
*/
RangeVar *
-makeRangeVar(char *schemaname, char *relname)
+makeRangeVar(char *schemaname, char *relname, int location)
{
RangeVar *r = makeNode(RangeVar);
r->inhOpt = INH_DEFAULT;
r->istemp = false;
r->alias = NULL;
+ r->location = location;
return r;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.31 2008/08/28 23:09:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.32 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
return -1;
switch (nodeTag(expr))
{
+ case T_RangeVar:
+ loc = ((RangeVar *) expr)->location;
+ break;
case T_Var:
loc = ((Var *) expr)->location;
break;
/* just use argument's location */
loc = exprLocation((Node *) ((TargetEntry *) expr)->expr);
break;
+ case T_IntoClause:
+ /* use the contained RangeVar's location --- close enough */
+ loc = exprLocation((Node *) ((IntoClause *) expr)->rel);
+ break;
case T_List:
{
/* report location of first list member that has a location */
loc = leftmostLoc(loc, tc->location);
}
break;
+ case T_SortBy:
+ /* just use argument's location (ignore operator, if any) */
+ loc = exprLocation(((SortBy *) expr)->node);
+ break;
case T_TypeName:
loc = ((TypeName *) expr)->location;
break;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.337 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.338 2008/09/01 20:42:44 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
WRITE_ENUM_FIELD(inhOpt, InhOption);
WRITE_BOOL_FIELD(istemp);
WRITE_NODE_FIELD(alias);
+ WRITE_LOCATION_FIELD(location);
}
static void
{
WRITE_NODE_TYPE("NOTIFY");
- WRITE_NODE_FIELD(relation);
+ WRITE_STRING_FIELD(conditionname);
}
static void
{
WRITE_NODE_TYPE("SORTBY");
+ WRITE_NODE_FIELD(node);
WRITE_ENUM_FIELD(sortby_dir, SortByDir);
WRITE_ENUM_FIELD(sortby_nulls, SortByNulls);
WRITE_NODE_FIELD(useOp);
- WRITE_NODE_FIELD(node);
+ WRITE_LOCATION_FIELD(location);
}
static void
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.213 2008/08/28 23:09:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.214 2008/09/01 20:42:44 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
{
READ_LOCALS(NotifyStmt);
- READ_NODE_FIELD(relation);
+ READ_STRING_FIELD(conditionname);
READ_DONE();
}
READ_ENUM_FIELD(inhOpt, InhOption);
READ_BOOL_FIELD(istemp);
READ_NODE_FIELD(alias);
+ READ_LOCATION_FIELD(location);
READ_DONE();
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.150 2008/08/25 22:42:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.151 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
break;
case RTE_FUNCTION:
- expandRTE(rte, varno, 0, true /* include dropped */ ,
+ expandRTE(rte, varno, 0, -1, true /* include dropped */ ,
NULL, &colvars);
foreach(l, colvars)
{
break;
case RTE_VALUES:
- expandRTE(rte, varno, 0, false /* dropped not applicable */ ,
+ expandRTE(rte, varno, 0, -1, false /* dropped not applicable */ ,
NULL, &colvars);
foreach(l, colvars)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.78 2008/08/28 23:09:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.79 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
typedef struct
{
- int varno;
- int varattno;
+ int var_location;
int sublevels_up;
-} contain_var_reference_context;
+} locate_var_of_level_context;
+
+typedef struct
+{
+ int var_location;
+ int relid;
+ int sublevels_up;
+} locate_var_of_relation_context;
typedef struct
{
static bool pull_varnos_walker(Node *node,
pull_varnos_context *context);
static bool pull_varattnos_walker(Node *node, Bitmapset **varattnos);
-static bool contain_var_reference_walker(Node *node,
- contain_var_reference_context *context);
static bool contain_var_clause_walker(Node *node, void *context);
static bool contain_vars_of_level_walker(Node *node, int *sublevels_up);
-static bool contain_vars_above_level_walker(Node *node, int *sublevels_up);
+static bool locate_var_of_level_walker(Node *node,
+ locate_var_of_level_context *context);
+static bool locate_var_of_relation_walker(Node *node,
+ locate_var_of_relation_context *context);
static bool find_minimum_var_level_walker(Node *node,
find_minimum_var_level_context *context);
static bool pull_var_clause_walker(Node *node,
(void *) context);
}
+
/*
* pull_varattnos
* Find all the distinct attribute numbers present in an expression tree,
}
-/*
- * contain_var_reference
- *
- * Detect whether a parsetree contains any references to a specified
- * attribute of a specified rtable entry.
- *
- * NOTE: this is used on not-yet-planned expressions. It may therefore find
- * bare SubLinks, and if so it needs to recurse into them to look for uplevel
- * references to the desired rtable entry! But when we find a completed
- * SubPlan, we only need to look at the parameters passed to the subplan.
- */
-bool
-contain_var_reference(Node *node, int varno, int varattno, int levelsup)
-{
- contain_var_reference_context context;
-
- context.varno = varno;
- context.varattno = varattno;
- context.sublevels_up = levelsup;
-
- /*
- * Must be prepared to start with a Query or a bare expression tree; if
- * it's a Query, we don't want to increment sublevels_up.
- */
- return query_or_expression_tree_walker(node,
- contain_var_reference_walker,
- (void *) &context,
- 0);
-}
-
-static bool
-contain_var_reference_walker(Node *node,
- contain_var_reference_context *context)
-{
- if (node == NULL)
- return false;
- if (IsA(node, Var))
- {
- Var *var = (Var *) node;
-
- if (var->varno == context->varno &&
- var->varattno == context->varattno &&
- var->varlevelsup == context->sublevels_up)
- return true;
- return false;
- }
- if (IsA(node, Query))
- {
- /* Recurse into RTE subquery or not-yet-planned sublink subquery */
- bool result;
-
- context->sublevels_up++;
- result = query_tree_walker((Query *) node,
- contain_var_reference_walker,
- (void *) context, 0);
- context->sublevels_up--;
- return result;
- }
- return expression_tree_walker(node, contain_var_reference_walker,
- (void *) context);
-}
-
-
/*
* contain_var_clause
* Recursively scan a clause to discover whether it contains any Var nodes
return expression_tree_walker(node, contain_var_clause_walker, context);
}
+
/*
* contain_vars_of_level
* Recursively scan a clause to discover whether it contains any Var nodes
(void *) sublevels_up);
}
+
/*
- * contain_vars_above_level
- * Recursively scan a clause to discover whether it contains any Var nodes
- * above the specified query level. (For example, pass zero to detect
- * all nonlocal Vars.)
+ * locate_var_of_level
+ * Find the parse location of any Var of the specified query level.
*
- * Returns true if any such Var found.
+ * Returns -1 if no such Var is in the querytree, or if they all have
+ * unknown parse location. (The former case is probably caller error,
+ * but we don't bother to distinguish it from the latter case.)
*
* Will recurse into sublinks. Also, may be invoked directly on a Query.
+ *
+ * Note: it might seem appropriate to merge this functionality into
+ * contain_vars_of_level, but that would complicate that function's API.
+ * Currently, the only uses of this function are for error reporting,
+ * and so shaving cycles probably isn't very important.
*/
-bool
-contain_vars_above_level(Node *node, int levelsup)
+int
+locate_var_of_level(Node *node, int levelsup)
{
- int sublevels_up = levelsup;
+ locate_var_of_level_context context;
- return query_or_expression_tree_walker(node,
- contain_vars_above_level_walker,
- (void *) &sublevels_up,
+ context.var_location = -1; /* in case we find nothing */
+ context.sublevels_up = levelsup;
+
+ (void) query_or_expression_tree_walker(node,
+ locate_var_of_level_walker,
+ (void *) &context,
0);
+
+ return context.var_location;
}
static bool
-contain_vars_above_level_walker(Node *node, int *sublevels_up)
+locate_var_of_level_walker(Node *node,
+ locate_var_of_level_context *context)
{
if (node == NULL)
return false;
if (IsA(node, Var))
{
- if (((Var *) node)->varlevelsup > *sublevels_up)
+ Var *var = (Var *) node;
+
+ if (var->varlevelsup == context->sublevels_up &&
+ var->location >= 0)
+ {
+ context->var_location = var->location;
return true; /* abort tree traversal and return true */
+ }
+ return false;
+ }
+ if (IsA(node, CurrentOfExpr))
+ {
+ /* since CurrentOfExpr doesn't carry location, nothing we can do */
+ return false;
}
if (IsA(node, Query))
{
/* Recurse into subselects */
bool result;
- (*sublevels_up)++;
+ context->sublevels_up++;
result = query_tree_walker((Query *) node,
- contain_vars_above_level_walker,
- (void *) sublevels_up,
+ locate_var_of_level_walker,
+ (void *) context,
0);
- (*sublevels_up)--;
+ context->sublevels_up--;
return result;
}
return expression_tree_walker(node,
- contain_vars_above_level_walker,
- (void *) sublevels_up);
+ locate_var_of_level_walker,
+ (void *) context);
+}
+
+
+/*
+ * locate_var_of_relation
+ * Find the parse location of any Var of the specified relation.
+ *
+ * Returns -1 if no such Var is in the querytree, or if they all have
+ * unknown parse location.
+ *
+ * Will recurse into sublinks. Also, may be invoked directly on a Query.
+ */
+int
+locate_var_of_relation(Node *node, int relid, int levelsup)
+{
+ locate_var_of_relation_context context;
+
+ context.var_location = -1; /* in case we find nothing */
+ context.relid = relid;
+ context.sublevels_up = levelsup;
+
+ (void) query_or_expression_tree_walker(node,
+ locate_var_of_relation_walker,
+ (void *) &context,
+ 0);
+
+ return context.var_location;
+}
+
+static bool
+locate_var_of_relation_walker(Node *node,
+ locate_var_of_relation_context *context)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Var))
+ {
+ Var *var = (Var *) node;
+
+ if (var->varno == context->relid &&
+ var->varlevelsup == context->sublevels_up &&
+ var->location >= 0)
+ {
+ context->var_location = var->location;
+ return true; /* abort tree traversal and return true */
+ }
+ return false;
+ }
+ if (IsA(node, CurrentOfExpr))
+ {
+ /* since CurrentOfExpr doesn't carry location, nothing we can do */
+ return false;
+ }
+ if (IsA(node, Query))
+ {
+ /* Recurse into subselects */
+ bool result;
+
+ context->sublevels_up++;
+ result = query_tree_walker((Query *) node,
+ locate_var_of_relation_walker,
+ (void *) context,
+ 0);
+ context->sublevels_up--;
+ return result;
+ }
+ return expression_tree_walker(node,
+ locate_var_of_relation_walker,
+ (void *) context);
}
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.378 2008/08/28 23:09:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.379 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parsetree.h"
+#include "rewrite/rewriteManip.h"
#include "utils/rel.h"
-typedef struct
-{
- Oid *paramTypes;
- int numParams;
-} check_parameter_resolution_context;
-
-
static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
static List *transformInsertRow(ParseState *pstate, List *exprlist,
DeclareCursorStmt *stmt);
static Query *transformExplainStmt(ParseState *pstate,
ExplainStmt *stmt);
-static void transformLockingClause(Query *qry, LockingClause *lc);
-static bool check_parameter_resolution_walker(Node *node,
- check_parameter_resolution_context *context);
+static void transformLockingClause(ParseState *pstate,
+ Query *qry, LockingClause *lc);
+static bool check_parameter_resolution_walker(Node *node, ParseState *pstate);
/*
query = transformStmt(pstate, parseTree);
+ /* make sure all is well with parameter types */
+ if (pstate->p_numparams > 0)
+ check_parameter_resolution_walker((Node *) query, pstate);
+
*paramTypes = pstate->p_paramtypes;
*numParams = pstate->p_numparams;
free_parsestate(pstate);
- /* make sure all is well with parameter types */
- if (*numParams > 0)
- {
- check_parameter_resolution_context context;
-
- context.paramTypes = *paramTypes;
- context.numParams = *numParams;
- check_parameter_resolution_walker((Node *) query, &context);
- }
-
return query;
}
free_parsestate(sub_pstate);
/* The grammar should have produced a SELECT, but it might have INTO */
- Assert(IsA(selectQuery, Query));
- Assert(selectQuery->commandType == CMD_SELECT);
- Assert(selectQuery->utilityStmt == NULL);
+ if (!IsA(selectQuery, Query) ||
+ selectQuery->commandType != CMD_SELECT ||
+ selectQuery->utilityStmt != NULL)
+ elog(ERROR, "unexpected non-SELECT command in INSERT ... SELECT");
if (selectQuery->intoClause)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("INSERT ... SELECT cannot specify INTO")));
+ errmsg("INSERT ... SELECT cannot specify INTO"),
+ parser_errposition(pstate,
+ exprLocation((Node *) selectQuery->intoClause))));
/*
* Make the source be a subquery in the INSERT's rangetable, and add
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("VALUES lists must all be the same length")));
+ errmsg("VALUES lists must all be the same length"),
+ parser_errposition(pstate,
+ exprLocation((Node *) sublist))));
}
/* Prepare row for assignment to target table */
if (pstate->p_joinlist != NIL)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("VALUES must not contain table references")));
+ errmsg("VALUES must not contain table references"),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) exprsLists, 0))));
/*
* Another thing we can't currently support is NEW/OLD references in
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("VALUES must not contain OLD or NEW references"),
- errhint("Use SELECT ... UNION ALL ... instead.")));
+ errhint("Use SELECT ... UNION ALL ... instead."),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) exprsLists, 0))));
/*
* Generate the VALUES RTE
/*
* Generate list of Vars referencing the RTE
*/
- expandRTE(rte, rtr->rtindex, 0, false, NULL, &exprList);
+ expandRTE(rte, rtr->rtindex, 0, -1, false, NULL, &exprList);
}
else
{
if (pstate->p_hasAggs)
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("cannot use aggregate function in VALUES")));
+ errmsg("cannot use aggregate function in VALUES"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) qry, 0))));
return qry;
}
if (list_length(exprlist) > list_length(icolumns))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("INSERT has more expressions than target columns")));
+ errmsg("INSERT has more expressions than target columns"),
+ parser_errposition(pstate,
+ exprLocation(list_nth(exprlist,
+ list_length(icolumns))))));
if (stmtcols != NIL &&
list_length(exprlist) < list_length(icolumns))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("INSERT has more target columns than expressions")));
+ errmsg("INSERT has more target columns than expressions"),
+ parser_errposition(pstate,
+ exprLocation(list_nth(icolumns,
+ list_length(exprlist))))));
/*
* Prepare columns for assignment to target table.
foreach(l, stmt->lockingClause)
{
- transformLockingClause(qry, (LockingClause *) lfirst(l));
+ transformLockingClause(pstate, qry, (LockingClause *) lfirst(l));
}
return qry;
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("VALUES lists must all be the same length")));
+ errmsg("VALUES lists must all be the same length"),
+ parser_errposition(pstate,
+ exprLocation((Node *) sublist))));
}
exprsLists = lappend(exprsLists, sublist);
* Generate a targetlist as though expanding "*"
*/
Assert(pstate->p_next_resno == 1);
- qry->targetList = expandRelAttrs(pstate, rte, rtr->rtindex, 0);
+ qry->targetList = expandRelAttrs(pstate, rte, rtr->rtindex, 0, -1);
/*
* The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE to a
if (list_length(pstate->p_joinlist) != 1)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("VALUES must not contain table references")));
+ errmsg("VALUES must not contain table references"),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) newExprsLists, 0))));
/*
* Another thing we can't currently support is NEW/OLD references in rules
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("VALUES must not contain OLD or NEW references"),
- errhint("Use SELECT ... UNION ALL ... instead.")));
+ errhint("Use SELECT ... UNION ALL ... instead."),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) newExprsLists, 0))));
qry->rtable = pstate->p_rtable;
qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
if (pstate->p_hasAggs)
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("cannot use aggregate function in VALUES")));
+ errmsg("cannot use aggregate function in VALUES"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) newExprsLists, 0))));
return qry;
}
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("invalid UNION/INTERSECT/EXCEPT ORDER BY clause"),
errdetail("Only result column names can be used, not expressions or functions."),
- errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause.")));
+ errhint("Add the expression/function to every SELECT, or move the UNION into a FROM clause."),
+ parser_errposition(pstate,
+ exprLocation(list_nth(qry->targetList, tllen)))));
qry->limitOffset = transformLimitClause(pstate, limitOffset,
"OFFSET");
foreach(l, lockingClause)
{
- transformLockingClause(qry, (LockingClause *) lfirst(l));
+ transformLockingClause(pstate, qry, (LockingClause *) lfirst(l));
}
return qry;
* In addition to returning the transformed node, we return a list of
* expression nodes showing the type, typmod, and location (for error messages)
* of each output column of the set-op node. This is used only during the
- * internal recursion of this function. We use SetToDefault nodes for
- * this purpose, since they carry exactly the fields needed, but any other
- * expression node type would do as well.
+ * internal recursion of this function. At the upper levels we use
+ * SetToDefault nodes for this purpose, since they carry exactly the fields
+ * needed, but any other expression node type would do as well.
*/
static Node *
transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
if (stmt->intoClause)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT")));
+ errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"),
+ parser_errposition(pstate,
+ exprLocation((Node *) stmt->intoClause))));
+
/* We don't support FOR UPDATE/SHARE with set ops at the moment. */
if (stmt->lockingClause)
ereport(ERROR,
if (contain_vars_of_level((Node *) selectQuery, 1))
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level")));
+ errmsg("UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level"),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) selectQuery, 1))));
}
/*
- * Extract information about the result columns.
+ * Extract a list of the result expressions for upper-level checking.
*/
*colInfo = NIL;
foreach(tl, selectQuery->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
- SetToDefault *cinfo;
- if (tle->resjunk)
- continue;
- cinfo = makeNode(SetToDefault);
- cinfo->typeId = exprType((Node *) tle->expr);
- cinfo->typeMod = exprTypmod((Node *) tle->expr);
- cinfo->location = exprLocation((Node *) tle->expr);
- *colInfo = lappend(*colInfo, cinfo);
+ if (!tle->resjunk)
+ *colInfo = lappend(*colInfo, tle->expr);
}
/*
op->groupClauses = NIL;
forboth(lci, lcolinfo, rci, rcolinfo)
{
- SetToDefault *lcolinfo = (SetToDefault *) lfirst(lci);
- SetToDefault *rcolinfo = (SetToDefault *) lfirst(rci);
- Oid lcoltype = lcolinfo->typeId;
- Oid rcoltype = rcolinfo->typeId;
- int32 lcoltypmod = lcolinfo->typeMod;
- int32 rcoltypmod = rcolinfo->typeMod;
+ Node *lcolinfo = (Node *) lfirst(lci);
+ Node *rcolinfo = (Node *) lfirst(rci);
+ Oid lcoltype = exprType(lcolinfo);
+ Oid rcoltype = exprType(rcolinfo);
+ int32 lcoltypmod = exprTypmod(lcolinfo);
+ int32 rcoltypmod = exprTypmod(rcolinfo);
Node *bestexpr;
SetToDefault *rescolinfo;
Oid rescoltype;
rescoltypmod = -1;
/* verify the coercions are actually possible */
- if (lcoltype != UNKNOWNOID)
- (void) coerce_to_common_type(pstate, (Node *) lcolinfo,
- rescoltype, context);
- if (rcoltype != UNKNOWNOID)
- (void) coerce_to_common_type(pstate, (Node *) rcolinfo,
- rescoltype, context);
+ (void) coerce_to_common_type(pstate, lcolinfo,
+ rescoltype, context);
+ (void) coerce_to_common_type(pstate, rcolinfo,
+ rescoltype, context);
/* emit results */
rescolinfo = makeNode(SetToDefault);
rescolinfo->typeId = rescoltype;
rescolinfo->typeMod = rescoltypmod;
- rescolinfo->location = ((SetToDefault *) bestexpr)->location;
+ rescolinfo->location = exprLocation(bestexpr);
*colInfo = lappend(*colInfo, rescolinfo);
op->colTypes = lappend_oid(op->colTypes, rescoltype);
SortGroupClause *grpcl = makeNode(SortGroupClause);
Oid sortop;
Oid eqop;
+ ParseCallbackState pcbstate;
+
+ setup_parser_errposition_callback(&pcbstate, pstate,
+ rescolinfo->location);
/* determine the eqop and optional sortop */
get_sort_group_operators(rescoltype,
false, true, false,
&sortop, &eqop, NULL);
+ cancel_parser_errposition_callback(&pcbstate);
+
/* we don't have a tlist yet, so can't assign sortgrouprefs */
grpcl->tleSortGroupRef = 0;
grpcl->eqop = eqop;
if (pstate->p_hasAggs)
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("cannot use aggregate function in UPDATE")));
+ errmsg("cannot use aggregate function in UPDATE"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) qry, 0))));
/*
* Now we are done with SELECT-like processing, and can get on with
if (pstate->p_hasAggs)
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("cannot use aggregate function in RETURNING")));
+ errmsg("cannot use aggregate function in RETURNING"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) rlist, 0))));
/* no new relation references please */
if (list_length(pstate->p_rtable) != length_rtable)
+ {
+ int vlocation = -1;
+ int relid;
+
+ /* try to locate such a reference to point to */
+ for (relid = length_rtable + 1; relid <= list_length(pstate->p_rtable); relid++)
+ {
+ vlocation = locate_var_of_relation((Node *) rlist, relid, 0);
+ if (vlocation >= 0)
+ break;
+ }
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("RETURNING cannot contain references to other relations")));
+ errmsg("RETURNING cannot contain references to other relations"),
+ parser_errposition(pstate, vlocation)));
+ }
/* mark column origins */
markTargetListOrigins(pstate, rlist);
result = transformStmt(pstate, stmt->query);
+ /* Grammar should not have allowed anything but SELECT */
if (!IsA(result, Query) ||
result->commandType != CMD_SELECT ||
result->utilityStmt != NULL)
- elog(ERROR, "unexpected non-SELECT command in cursor statement");
+ elog(ERROR, "unexpected non-SELECT command in DECLARE CURSOR");
/* But we must explicitly disallow DECLARE CURSOR ... SELECT INTO */
if (result->intoClause)
ereport(ERROR,
(errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
- errmsg("DECLARE CURSOR cannot specify INTO")));
+ errmsg("DECLARE CURSOR cannot specify INTO"),
+ parser_errposition(pstate,
+ exprLocation((Node *) result->intoClause))));
/* FOR UPDATE and WITH HOLD are not compatible */
if (result->rowMarks != NIL && (stmt->options & CURSOR_OPT_HOLD))
* This basically involves replacing names by integer relids.
*
* NB: if you need to change this, see also markQueryForLocking()
- * in rewriteHandler.c.
+ * in rewriteHandler.c, and isLockedRel() in parse_relation.c.
*/
static void
-transformLockingClause(Query *qry, LockingClause *lc)
+transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc)
{
List *lockedRels = lc->lockedRels;
ListCell *l;
* FOR UPDATE/SHARE of subquery is propagated to all of
* subquery's rels
*/
- transformLockingClause(rte->subquery, allrels);
+ transformLockingClause(pstate, rte->subquery, allrels);
break;
default:
/* ignore JOIN, SPECIAL, FUNCTION RTEs */
/* just the named tables */
foreach(l, lockedRels)
{
- char *relname = strVal(lfirst(l));
+ RangeVar *thisrel = (RangeVar *) lfirst(l);
+
+ /* For simplicity we insist on unqualified alias names here */
+ if (thisrel->catalogname || thisrel->schemaname)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("SELECT FOR UPDATE/SHARE must specify unqualified relation names"),
+ parser_errposition(pstate, thisrel->location)));
i = 0;
foreach(rt, qry->rtable)
RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
++i;
- if (strcmp(rte->eref->aliasname, relname) == 0)
+ if (strcmp(rte->eref->aliasname, thisrel->relname) == 0)
{
switch (rte->rtekind)
{
* FOR UPDATE/SHARE of subquery is propagated to
* all of subquery's rels
*/
- transformLockingClause(rte->subquery, allrels);
+ transformLockingClause(pstate, rte->subquery, allrels);
break;
case RTE_JOIN:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join")));
+ errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a join"),
+ parser_errposition(pstate, thisrel->location)));
break;
case RTE_SPECIAL:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD")));
+ errmsg("SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD"),
+ parser_errposition(pstate, thisrel->location)));
break;
case RTE_FUNCTION:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a function")));
+ errmsg("SELECT FOR UPDATE/SHARE cannot be applied to a function"),
+ parser_errposition(pstate, thisrel->location)));
break;
case RTE_VALUES:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES")));
+ errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES"),
+ parser_errposition(pstate, thisrel->location)));
break;
default:
elog(ERROR, "unrecognized RTE type: %d",
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s\" in FOR UPDATE/SHARE clause not found in FROM clause",
- relname)));
+ thisrel->relname),
+ parser_errposition(pstate, thisrel->location)));
}
}
}
* and yet other instances seen later might have gotten coerced.
*/
static bool
-check_parameter_resolution_walker(Node *node,
- check_parameter_resolution_context *context)
+check_parameter_resolution_walker(Node *node, ParseState *pstate)
{
if (node == NULL)
return false;
int paramno = param->paramid;
if (paramno <= 0 || /* shouldn't happen, but... */
- paramno > context->numParams)
+ paramno > pstate->p_numparams)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
- errmsg("there is no parameter $%d", paramno)));
+ errmsg("there is no parameter $%d", paramno),
+ parser_errposition(pstate, param->location)));
- if (param->paramtype != context->paramTypes[paramno - 1])
+ if (param->paramtype != pstate->p_paramtypes[paramno - 1])
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_PARAMETER),
errmsg("could not determine data type of parameter $%d",
- paramno)));
+ paramno),
+ parser_errposition(pstate, param->location)));
}
return false;
}
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
return query_tree_walker((Query *) node,
check_parameter_resolution_walker,
- (void *) context, 0);
+ (void *) pstate, 0);
}
return expression_tree_walker(node, check_parameter_resolution_walker,
- (void *) context);
+ (void *) pstate);
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.620 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.621 2008/09/01 20:42:44 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
#include "catalog/namespace.h"
#include "commands/defrem.h"
#include "nodes/makefuncs.h"
+#include "nodes/nodeFuncs.h"
#include "parser/gramparse.h"
#include "storage/lmgr.h"
#include "utils/date.h"
if (($3 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
+ errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
+ scanner_errposition(@3)));
t->typmods = list_make1(makeIntConst($3, @3));
}
$$ = makeStringConstCast($2, @2, t);
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("time zone interval must be HOUR or HOUR TO MINUTE")));
+ errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
+ scanner_errposition(@6)));
t->typmods = list_make2(makeIntConst($6, @6),
makeIntConst($3, @3));
$$ = makeStringConstCast($5, @5, t);
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("MATCH PARTIAL not yet implemented")));
+ errmsg("MATCH PARTIAL not yet implemented"),
+ scanner_errposition(@1)));
$$ = FKCONSTR_MATCH_PARTIAL;
}
| MATCH SIMPLE
if (n->intoClause != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("CREATE TABLE AS cannot specify INTO")));
+ errmsg("CREATE TABLE AS cannot specify INTO"),
+ scanner_errposition(exprLocation((Node *) n->intoClause))));
$4->rel->istemp = $2;
n->intoClause = $4;
$$ = $6;
if ($1 == 0 && $2 != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE")));
+ errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
+ scanner_errposition(@1)));
$$ = $1 | $2;
}
| ConstraintTimeSpec
if ($2 == 0 && $1 != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE")));
+ errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
+ scanner_errposition(@1)));
$$ = $1 | $2;
}
| /*EMPTY*/
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
- NameListToString($3))));
+ NameListToString($3)),
+ scanner_errposition(@3)));
break;
}
+ r->location = @3;
n->typevar = r;
n->coldeflist = $6;
$$ = (Node *)n;
n->number = $2;
$$ = (Node *) n;
}
- | OPERATOR Iconst any_operator '(' oper_argtypes ')' opt_recheck
+ | OPERATOR Iconst any_operator oper_argtypes opt_recheck
{
CreateOpClassItem *n = makeNode(CreateOpClassItem);
n->itemtype = OPCLASS_ITEM_OPERATOR;
n->name = $3;
- n->args = $5;
+ n->args = $4;
n->number = $2;
$$ = (Node *) n;
}
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RECHECK is no longer supported"),
- errhint("Update your data type.")));
+ errhint("Update your data type."),
+ scanner_errposition(@1)));
$$ = TRUE;
}
| /*EMPTY*/ { $$ = FALSE; }
n->comment = $7;
$$ = (Node *) n;
}
- | COMMENT ON OPERATOR any_operator '(' oper_argtypes ')'
- IS comment_text
+ | COMMENT ON OPERATOR any_operator oper_argtypes IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_OPERATOR;
n->objname = $4;
- n->objargs = $6;
- n->comment = $9;
+ n->objargs = $5;
+ n->comment = $7;
$$ = (Node *) n;
}
| COMMENT ON CONSTRAINT name ON any_name IS comment_text
;
opt_asc_desc: ASC { $$ = SORTBY_ASC; }
- | DESC { $$ = SORTBY_DESC; }
- | /*EMPTY*/ { $$ = SORTBY_DEFAULT; }
+ | DESC { $$ = SORTBY_DESC; }
+ | /*EMPTY*/ { $$ = SORTBY_DEFAULT; }
;
opt_nulls_order: NULLS_FIRST { $$ = SORTBY_NULLS_FIRST; }
;
RemoveOperStmt:
- DROP OPERATOR any_operator '(' oper_argtypes ')' opt_drop_behavior
+ DROP OPERATOR any_operator oper_argtypes opt_drop_behavior
{
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
n->kind = OBJECT_OPERATOR;
n->name = $3;
- n->args = $5;
- n->behavior = $7;
+ n->args = $4;
+ n->behavior = $5;
n->missing_ok = false;
$$ = (Node *)n;
}
- | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
+ | DROP OPERATOR IF_P EXISTS any_operator oper_argtypes opt_drop_behavior
{
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
n->kind = OBJECT_OPERATOR;
n->name = $5;
- n->args = $7;
- n->behavior = $9;
+ n->args = $6;
+ n->behavior = $7;
n->missing_ok = true;
$$ = (Node *)n;
}
;
oper_argtypes:
- Typename
+ '(' Typename ')'
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing argument"),
- errhint("Use NONE to denote the missing argument of a unary operator.")));
+ errhint("Use NONE to denote the missing argument of a unary operator."),
+ scanner_errposition(@3)));
}
- | Typename ',' Typename
- { $$ = list_make2($1, $3); }
- | NONE ',' Typename /* left unary */
- { $$ = list_make2(NULL, $3); }
- | Typename ',' NONE /* right unary */
- { $$ = list_make2($1, NULL); }
+ | '(' Typename ',' Typename ')'
+ { $$ = list_make2($2, $4); }
+ | '(' NONE ',' Typename ')' /* left unary */
+ { $$ = list_make2(NULL, $4); }
+ | '(' Typename ',' NONE ')' /* right unary */
+ { $$ = list_make2($2, NULL); }
;
any_operator:
n->newowner = $7;
$$ = (Node *)n;
}
- | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
+ | ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPERATOR;
n->object = $3;
- n->objarg = $5;
- n->newowner = $9;
+ n->objarg = $4;
+ n->newowner = $7;
$$ = (Node *)n;
}
| ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
/*****************************************************************************
*
* QUERY:
- * NOTIFY <qualified_name> can appear both in rule bodies and
+ * NOTIFY <identifier> can appear both in rule bodies and
* as a query-level command
*
*****************************************************************************/
NotifyStmt: NOTIFY ColId
{
NotifyStmt *n = makeNode(NotifyStmt);
- n->relation = makeNode(RangeVar);
- n->relation->relname = $2;
- n->relation->schemaname = NULL;
+ n->conditionname = $2;
$$ = (Node *)n;
}
;
ListenStmt: LISTEN ColId
{
ListenStmt *n = makeNode(ListenStmt);
- n->relation = makeNode(RangeVar);
- n->relation->relname = $2;
- n->relation->schemaname = NULL;
+ n->conditionname = $2;
$$ = (Node *)n;
}
;
UNLISTEN ColId
{
UnlistenStmt *n = makeNode(UnlistenStmt);
- n->relation = makeNode(RangeVar);
- n->relation->relname = $2;
- n->relation->schemaname = NULL;
+ n->conditionname = $2;
$$ = (Node *)n;
}
| UNLISTEN '*'
{
UnlistenStmt *n = makeNode(UnlistenStmt);
- n->relation = NULL;
+ n->conditionname = NULL;
$$ = (Node *)n;
}
;
if (list_length($2) != list_length($5))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("number of columns does not match number of values")));
+ errmsg("number of columns does not match number of values"),
+ scanner_errposition(@1)));
forboth(col_cell, $2, val_cell, $5)
{
ResTarget *res_col = (ResTarget *) lfirst(col_cell);
$$->sortby_dir = SORTBY_USING;
$$->sortby_nulls = $4;
$$->useOp = $3;
+ $$->location = @3;
}
| a_expr opt_asc_desc opt_nulls_order
{
$$->sortby_dir = $2;
$$->sortby_nulls = $3;
$$->useOp = NIL;
+ $$->location = -1; /* no operator */
}
;
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("LIMIT #,# syntax is not supported"),
- errhint("Use separate LIMIT and OFFSET clauses.")));
+ errhint("Use separate LIMIT and OFFSET clauses."),
+ scanner_errposition(@1)));
}
;
;
locked_rels_list:
- OF name_list { $$ = $2; }
+ OF qualified_name_list { $$ = $2; }
| /* EMPTY */ { $$ = NIL; }
;
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("VALUES in FROM must have an alias"),
- errhint("For example, FROM (VALUES ...) [AS] foo.")));
+ errhint("For example, FROM (VALUES ...) [AS] foo."),
+ scanner_errposition(@1)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("subquery in FROM must have an alias"),
- errhint("For example, FROM (SELECT ...) [AS] foo.")));
+ errhint("For example, FROM (SELECT ...) [AS] foo."),
+ scanner_errposition(@1)));
$$ = NULL;
}
| select_with_parens alias_clause
if ($2 < 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("precision for type float must be at least 1 bit")));
+ errmsg("precision for type float must be at least 1 bit"),
+ scanner_errposition(@2)));
else if ($2 <= 24)
$$ = SystemTypeName("float4");
else if ($2 <= 53)
else
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("precision for type float must be less than 54 bits")));
+ errmsg("precision for type float must be less than 54 bits"),
+ scanner_errposition(@2)));
}
| /*EMPTY*/
{
*/
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("UNIQUE predicate is not yet implemented")));
+ errmsg("UNIQUE predicate is not yet implemented"),
+ scanner_errposition(@1)));
}
| a_expr IS DOCUMENT_P %prec IS
{
$$->catalogname = NULL;
$$->schemaname = NULL;
$$->relname = $1;
+ $$->location = @1;
}
| relation_name indirection
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
- NameListToString(lcons(makeString($1), $2)))));
+ NameListToString(lcons(makeString($1), $2))),
+ scanner_errposition(@1)));
break;
}
+ $$->location = @1;
}
;
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("OLD used in query that is not in a rule")));
+ errmsg("OLD used in query that is not in a rule"),
+ scanner_errposition(@1)));
}
| NEW
{
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("NEW used in query that is not in a rule")));
+ errmsg("NEW used in query that is not in a rule"),
+ scanner_errposition(@1)));
}
;
else if (list_length(largs) != 2)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("wrong number of parameters on left side of OVERLAPS expression")));
+ errmsg("wrong number of parameters on left side of OVERLAPS expression"),
+ scanner_errposition(location)));
if (list_length(rargs) == 1)
rargs = lappend(rargs, rargs);
else if (list_length(rargs) != 2)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("wrong number of parameters on right side of OVERLAPS expression")));
+ errmsg("wrong number of parameters on right side of OVERLAPS expression"),
+ scanner_errposition(location)));
n->args = list_concat(largs, rargs);
n->agg_star = FALSE;
n->agg_distinct = FALSE;
if (stmt->sortClause)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("multiple ORDER BY clauses not allowed")));
+ errmsg("multiple ORDER BY clauses not allowed"),
+ scanner_errposition(exprLocation((Node *) sortClause))));
stmt->sortClause = sortClause;
}
/* We can handle multiple locking clauses, though */
if (stmt->limitOffset)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("multiple OFFSET clauses not allowed")));
+ errmsg("multiple OFFSET clauses not allowed"),
+ scanner_errposition(exprLocation(limitOffset))));
stmt->limitOffset = limitOffset;
}
if (limitCount)
if (stmt->limitCount)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("multiple LIMIT clauses not allowed")));
+ errmsg("multiple LIMIT clauses not allowed"),
+ scanner_errposition(exprLocation(limitCount))));
stmt->limitCount = limitCount;
}
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.82 2008/08/28 23:09:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.83 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (checkExprHasAggs((Node *) agg->args))
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("aggregate function calls cannot be nested")));
+ errmsg("aggregate function calls cannot be nested"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) agg->args, 0))));
}
if (min_varlevel < 0)
if (checkExprHasAggs(qry->jointree->quals))
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("aggregates not allowed in WHERE clause")));
+ errmsg("aggregates not allowed in WHERE clause"),
+ parser_errposition(pstate,
+ locate_agg_of_level(qry->jointree->quals, 0))));
if (checkExprHasAggs((Node *) qry->jointree->fromlist))
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("aggregates not allowed in JOIN conditions")));
+ errmsg("aggregates not allowed in JOIN conditions"),
+ parser_errposition(pstate,
+ locate_agg_of_level((Node *) qry->jointree->fromlist, 0))));
/*
* No aggregates allowed in GROUP BY clauses, either.
if (checkExprHasAggs(expr))
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("aggregates not allowed in GROUP BY clause")));
+ errmsg("aggregates not allowed in GROUP BY clause"),
+ parser_errposition(pstate,
+ locate_agg_of_level(expr, 0))));
groupClauses = lcons(expr, groupClauses);
}
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
errmsg("column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function",
- rte->eref->aliasname, attname)));
+ rte->eref->aliasname, attname),
+ parser_errposition(context->pstate, var->location)));
else
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
errmsg("subquery uses ungrouped column \"%s.%s\" from outer query",
- rte->eref->aliasname, attname)));
-
+ rte->eref->aliasname, attname),
+ parser_errposition(context->pstate, var->location)));
}
if (IsA(node, Query))
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.178 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.179 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Var *l_colvar, Var *r_colvar);
static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
List **tlist, int clause);
+static int get_matching_location(int sortgroupref,
+ List *sortgrouprefs, List *exprs);
static List *addTargetToSortList(ParseState *pstate, TargetEntry *tle,
- List *sortlist, List *targetlist,
- SortByDir sortby_dir, SortByNulls sortby_nulls,
- List *sortby_opname, bool resolveUnknown);
+ List *sortlist, List *targetlist, SortBy *sortby,
+ bool resolveUnknown);
static List *addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
- List *grouplist, List *targetlist,
+ List *grouplist, List *targetlist, int location,
bool resolveUnknown);
* free_parsestate() will eventually do the corresponding heap_close(),
* but *not* release the lock.
*/
- pstate->p_target_relation = heap_openrv(relation, RowExclusiveLock);
+ pstate->p_target_relation = parserOpenTable(pstate, relation,
+ RowExclusiveLock);
/*
* Now build an RTE.
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("JOIN/ON clause refers to \"%s\", which is not part of JOIN",
- rt_fetch(varno, pstate->p_rtable)->eref->aliasname)));
+ rt_fetch(varno, pstate->p_rtable)->eref->aliasname),
+ parser_errposition(pstate,
+ locate_var_of_relation(result, varno, 0))));
}
bms_free(clause_varnos);
/*
* We require user to supply an alias for a subselect, per SQL92. To relax
* this, we'd have to be prepared to gin up a unique alias for an
- * unlabeled subselect.
+ * unlabeled subselect. (This is just elog, not ereport, because the
+ * grammar should have enforced it already.)
*/
if (r->alias == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("subquery in FROM must have an alias")));
+ elog(ERROR, "subquery in FROM must have an alias");
/*
* Analyze and transform the subquery.
* Check that we got something reasonable. Many of these conditions are
* impossible given restrictions of the grammar, but check 'em anyway.
*/
- if (query->commandType != CMD_SELECT ||
+ if (!IsA(query, Query) ||
+ query->commandType != CMD_SELECT ||
query->utilityStmt != NULL)
- elog(ERROR, "expected SELECT query from subquery in FROM");
- if (query->intoClause != NULL)
+ elog(ERROR, "unexpected non-SELECT command in subquery in FROM");
+ if (query->intoClause)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("subquery in FROM cannot have SELECT INTO")));
+ errmsg("subquery in FROM cannot have SELECT INTO"),
+ parser_errposition(pstate,
+ exprLocation((Node *) query->intoClause))));
/*
* The subquery cannot make use of any variables from FROM items created
if (contain_vars_of_level((Node *) query, 1))
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("subquery in FROM cannot refer to other relations of same query level")));
+ errmsg("subquery in FROM cannot refer to other relations of same query level"),
+ parser_errposition(pstate,
+ locate_var_of_level((Node *) query, 1))));
}
/*
if (contain_vars_of_level(funcexpr, 0))
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("function expression in FROM cannot refer to other relations of same query level")));
+ errmsg("function expression in FROM cannot refer to other relations of same query level"),
+ parser_errposition(pstate,
+ locate_var_of_level(funcexpr, 0))));
}
/*
if (checkExprHasAggs(funcexpr))
ereport(ERROR,
(errcode(ERRCODE_GROUPING_ERROR),
- errmsg("cannot use aggregate function in function expression in FROM")));
+ errmsg("cannot use aggregate function in function expression in FROM"),
+ parser_errposition(pstate,
+ locate_agg_of_level(funcexpr, 0))));
}
/*
*
* Note: expandRTE returns new lists, safe for me to modify
*/
- expandRTE(l_rte, l_rtindex, 0, false,
+ expandRTE(l_rte, l_rtindex, 0, -1, false,
&l_colnames, &l_colvars);
- expandRTE(r_rte, r_rtindex, 0, false,
+ expandRTE(r_rte, r_rtindex, 0, -1, false,
&r_colnames, &r_colvars);
/*
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
/* translator: %s is name of a SQL construct, eg LIMIT */
errmsg("argument of %s must not contain variables",
- constructName)));
+ constructName),
+ parser_errposition(pstate,
+ locate_var_of_level(qual, 0))));
}
if (checkExprHasAggs(qual))
{
(errcode(ERRCODE_GROUPING_ERROR),
/* translator: %s is name of a SQL construct, eg LIMIT */
errmsg("argument of %s must not contain aggregates",
- constructName)));
+ constructName),
+ parser_errposition(pstate,
+ locate_agg_of_level(qual, 0))));
}
return qual;
if (!found)
result = addTargetToGroupList(pstate, tle,
result, *targetlist,
+ exprLocation(gexpr),
true);
}
targetlist, ORDER_CLAUSE);
sortlist = addTargetToSortList(pstate, tle,
- sortlist, *targetlist,
- sortby->sortby_dir,
- sortby->sortby_nulls,
- sortby->useOp,
+ sortlist, *targetlist, sortby,
resolveUnknown);
}
if (tle->resjunk)
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list")));
+ errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list"),
+ parser_errposition(pstate,
+ exprLocation((Node *) tle->expr))));
result = lappend(result, copyObject(scl));
}
continue; /* ignore junk */
result = addTargetToGroupList(pstate, tle,
result, *targetlist,
+ exprLocation((Node *) tle->expr),
true);
}
List **targetlist, List *sortClause)
{
List *result = NIL;
- ListCell *slitem;
- ListCell *dlitem;
- Bitmapset *refnos = NULL;
- int sortgroupref;
+ List *sortgrouprefs = NIL;
bool skipped_sortitem;
+ ListCell *lc;
+ ListCell *lc2;
/*
* Add all the DISTINCT ON expressions to the tlist (if not already
* present, they are added as resjunk items). Assign sortgroupref
- * numbers to them, and form a bitmapset of these numbers. (A
- * bitmapset is convenient here because we don't care about order
- * and we can discard duplicates.)
+ * numbers to them, and make a list of these numbers. (NB: we rely
+ * below on the sortgrouprefs list being one-for-one with the original
+ * distinctlist. Also notice that we could have duplicate DISTINCT ON
+ * expressions and hence duplicate entries in sortgrouprefs.)
*/
- foreach(dlitem, distinctlist)
+ foreach(lc, distinctlist)
{
- Node *dexpr = (Node *) lfirst(dlitem);
+ Node *dexpr = (Node *) lfirst(lc);
+ int sortgroupref;
TargetEntry *tle;
tle = findTargetlistEntry(pstate, dexpr,
targetlist, DISTINCT_ON_CLAUSE);
sortgroupref = assignSortGroupRef(tle, *targetlist);
- refnos = bms_add_member(refnos, sortgroupref);
+ sortgrouprefs = lappend_int(sortgrouprefs, sortgroupref);
}
/*
* skipped an ORDER BY item that wasn't in DISTINCT ON.
*/
skipped_sortitem = false;
- foreach(slitem, sortClause)
+ foreach(lc, sortClause)
{
- SortGroupClause *scl = (SortGroupClause *) lfirst(slitem);
+ SortGroupClause *scl = (SortGroupClause *) lfirst(lc);
- if (bms_is_member(scl->tleSortGroupRef, refnos))
+ if (list_member_int(sortgrouprefs, scl->tleSortGroupRef))
{
if (skipped_sortitem)
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions")));
+ errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
+ parser_errposition(pstate,
+ get_matching_location(scl->tleSortGroupRef,
+ sortgrouprefs,
+ distinctlist))));
else
result = lappend(result, copyObject(scl));
}
* better to throw an error or warning here. But historically we've
* allowed it, so keep doing so.)
*/
- while ((sortgroupref = bms_first_member(refnos)) >= 0)
+ forboth(lc, distinctlist, lc2, sortgrouprefs)
{
+ Node *dexpr = (Node *) lfirst(lc);
+ int sortgroupref = lfirst_int(lc2);
TargetEntry *tle = get_sortgroupref_tle(sortgroupref, *targetlist);
if (targetIsInSortList(tle, InvalidOid, result))
if (skipped_sortitem)
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
- errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions")));
+ errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
+ parser_errposition(pstate, exprLocation(dexpr))));
result = addTargetToGroupList(pstate, tle,
result, *targetlist,
+ exprLocation(dexpr),
true);
}
return result;
}
+/*
+ * get_matching_location
+ * Get the exprLocation of the exprs member corresponding to the
+ * (first) member of sortgrouprefs that equals sortgroupref.
+ *
+ * This is used so that we can point at a troublesome DISTINCT ON entry.
+ * (Note that we need to use the original untransformed DISTINCT ON list
+ * item, as whatever TLE it corresponds to will very possibly have a
+ * parse location pointing to some matching entry in the SELECT list
+ * or ORDER BY list.)
+ */
+static int
+get_matching_location(int sortgroupref, List *sortgrouprefs, List *exprs)
+{
+ ListCell *lcs;
+ ListCell *lce;
+
+ forboth(lcs, sortgrouprefs, lce, exprs)
+ {
+ if (lfirst_int(lcs) == sortgroupref)
+ return exprLocation((Node *) lfirst(lce));
+ }
+ /* if no match, caller blew it */
+ elog(ERROR, "get_matching_location: no matching sortgroupref");
+ return -1; /* keep compiler quiet */
+}
+
/*
* addTargetToSortList
* If the given targetlist entry isn't already in the SortGroupClause
*/
static List *
addTargetToSortList(ParseState *pstate, TargetEntry *tle,
- List *sortlist, List *targetlist,
- SortByDir sortby_dir, SortByNulls sortby_nulls,
- List *sortby_opname, bool resolveUnknown)
+ List *sortlist, List *targetlist, SortBy *sortby,
+ bool resolveUnknown)
{
Oid restype = exprType((Node *) tle->expr);
Oid sortop;
Oid eqop;
bool reverse;
+ int location;
+ ParseCallbackState pcbstate;
/* if tlist item is an UNKNOWN literal, change it to TEXT */
if (restype == UNKNOWNOID && resolveUnknown)
restype = TEXTOID;
}
+ /*
+ * Rather than clutter the API of get_sort_group_operators and the other
+ * functions we're about to use, make use of error context callback to
+ * mark any error reports with a parse position. We point to the operator
+ * location if present, else to the expression being sorted. (NB: use
+ * the original untransformed expression here; the TLE entry might well
+ * point at a duplicate expression in the regular SELECT list.)
+ */
+ location = sortby->location;
+ if (location < 0)
+ location = exprLocation(sortby->node);
+ setup_parser_errposition_callback(&pcbstate, pstate, location);
+
/* determine the sortop, eqop, and directionality */
- switch (sortby_dir)
+ switch (sortby->sortby_dir)
{
case SORTBY_DEFAULT:
case SORTBY_ASC:
reverse = true;
break;
case SORTBY_USING:
- Assert(sortby_opname != NIL);
- sortop = compatible_oper_opid(sortby_opname,
+ Assert(sortby->useOp != NIL);
+ sortop = compatible_oper_opid(sortby->useOp,
restype,
restype,
false);
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("operator %s is not a valid ordering operator",
- strVal(llast(sortby_opname))),
+ strVal(llast(sortby->useOp))),
errhint("Ordering operators must be \"<\" or \">\" members of btree operator families.")));
break;
default:
- elog(ERROR, "unrecognized sortby_dir: %d", sortby_dir);
+ elog(ERROR, "unrecognized sortby_dir: %d", sortby->sortby_dir);
sortop = InvalidOid; /* keep compiler quiet */
eqop = InvalidOid;
reverse = false;
break;
}
+ cancel_parser_errposition_callback(&pcbstate);
+
/* avoid making duplicate sortlist entries */
if (!targetIsInSortList(tle, sortop, sortlist))
{
sortcl->eqop = eqop;
sortcl->sortop = sortop;
- switch (sortby_nulls)
+ switch (sortby->sortby_nulls)
{
case SORTBY_NULLS_DEFAULT:
/* NULLS FIRST is default for DESC; other way for ASC */
sortcl->nulls_first = false;
break;
default:
- elog(ERROR, "unrecognized sortby_nulls: %d", sortby_nulls);
+ elog(ERROR, "unrecognized sortby_nulls: %d",
+ sortby->sortby_nulls);
break;
}
* the TLE is considered "already in the list" if it appears there with any
* sorting semantics.
*
+ * location is the parse location to be fingered in event of trouble. Note
+ * that we can't rely on exprLocation(tle->expr), because that might point
+ * to a SELECT item that matches the GROUP BY item; it'd be pretty confusing
+ * to report such a location.
+ *
* If resolveUnknown is TRUE, convert TLEs of type UNKNOWN to TEXT. If not,
* do nothing (which implies the search for an equality operator will fail).
* pstate should be provided if resolveUnknown is TRUE, but can be NULL
*/
static List *
addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
- List *grouplist, List *targetlist,
+ List *grouplist, List *targetlist, int location,
bool resolveUnknown)
{
Oid restype = exprType((Node *) tle->expr);
if (!targetIsInSortList(tle, InvalidOid, grouplist))
{
SortGroupClause *grpcl = makeNode(SortGroupClause);
+ ParseCallbackState pcbstate;
+
+ setup_parser_errposition_callback(&pcbstate, pstate, location);
/* determine the eqop and optional sortop */
get_sort_group_operators(restype,
false, true, false,
&sortop, &eqop, NULL);
+ cancel_parser_errposition_callback(&pcbstate);
+
grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
grpcl->eqop = eqop;
grpcl->sortop = sortop;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.165 2008/08/28 23:09:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.166 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Oid baseTypeId;
int32 baseTypeMod;
Type targetType;
+ ParseCallbackState pcbstate;
/*
* If the target type is a domain, we want to call its base type's
else
newcon->location = location;
+ /*
+ * Set up to point at the constant's text if the input routine
+ * throws an error.
+ */
+ setup_parser_errposition_callback(&pcbstate, pstate, con->location);
+
/*
* We pass typmod -1 to the input routine, primarily because existing
* input routines follow implicit-coercion semantics for length
else
newcon->constvalue = stringTypeDatum(targetType, NULL, -1);
+ cancel_parser_errposition_callback(&pcbstate);
+
result = (Node *) newcon;
/* If target is a domain, apply constraints. */
paramno > toppstate->p_numparams)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
- errmsg("there is no parameter $%d", paramno)));
+ errmsg("there is no parameter $%d", paramno),
+ parser_errposition(pstate, param->location)));
if (toppstate->p_paramtypes[paramno - 1] == UNKNOWNOID)
{
paramno),
errdetail("%s versus %s",
format_type_be(toppstate->p_paramtypes[paramno - 1]),
- format_type_be(targetTypeId))));
+ format_type_be(targetTypeId)),
+ parser_errposition(pstate, param->location)));
}
param->paramtype = targetTypeId;
{
int rtindex = ((Var *) node)->varno;
int sublevels_up = ((Var *) node)->varlevelsup;
+ int vlocation = ((Var *) node)->location;
RangeTblEntry *rte;
rte = GetRTEByRangeTablePosn(pstate, rtindex, sublevels_up);
- expandRTE(rte, rtindex, sublevels_up, false,
+ expandRTE(rte, rtindex, sublevels_up, vlocation, false,
NULL, &args);
}
else
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.233 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.234 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
A_Const *con = (A_Const *) expr;
Value *val = &con->val;
- result = (Node *) make_const(val, con->location);
+ result = (Node *) make_const(pstate, val, con->location);
break;
}
* "rel.*".
*/
if (refnameRangeTblEntry(pstate, NULL, name1,
+ cref->location,
&levels_up) != NULL)
node = transformWholeRowRef(pstate, NULL, name1,
cref->location);
* return a pointer to it.
*/
static Oid *
-find_param_type(ParseState *pstate, int paramno)
+find_param_type(ParseState *pstate, int paramno, int location)
{
Oid *result;
if (paramno <= 0) /* probably can't happen? */
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
- errmsg("there is no parameter $%d", paramno)));
+ errmsg("there is no parameter $%d", paramno),
+ parser_errposition(pstate, location)));
if (paramno > pstate->p_numparams)
{
if (!pstate->p_variableparams)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_PARAMETER),
- errmsg("there is no parameter $%d",
- paramno)));
+ errmsg("there is no parameter $%d", paramno),
+ parser_errposition(pstate, location)));
/* Okay to enlarge param array */
if (pstate->p_paramtypes)
pstate->p_paramtypes = (Oid *) repalloc(pstate->p_paramtypes,
transformParamRef(ParseState *pstate, ParamRef *pref)
{
int paramno = pref->number;
- Oid *pptype = find_param_type(pstate, paramno);
+ Oid *pptype = find_param_type(pstate, paramno, pref->location);
Param *param;
param = makeNode(Param);
pstate->p_hasSubLinks = true;
qtree = parse_sub_analyze(sublink->subselect, pstate);
- if (qtree->commandType != CMD_SELECT ||
- qtree->utilityStmt != NULL ||
- qtree->intoClause != NULL)
- elog(ERROR, "bad query in sub-select");
+
+ /*
+ * Check that we got something reasonable. Many of these conditions are
+ * impossible given restrictions of the grammar, but check 'em anyway.
+ */
+ if (!IsA(qtree, Query) ||
+ qtree->commandType != CMD_SELECT ||
+ qtree->utilityStmt != NULL)
+ elog(ERROR, "unexpected non-SELECT command in SubLink");
+ if (qtree->intoClause)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("subquery cannot have SELECT INTO"),
+ parser_errposition(pstate,
+ exprLocation((Node *) qtree->intoClause))));
+
sublink->subselect = (Node *) qtree;
if (sublink->subLinkType == EXISTS_SUBLINK)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find element type for data type %s",
- format_type_be(array_type))));
+ format_type_be(array_type)),
+ parser_errposition(pstate, a->location)));
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for data type %s",
- format_type_be(element_type))));
+ format_type_be(element_type)),
+ parser_errposition(pstate, a->location)));
}
coerce_hard = false;
}
/* If a parameter is used, it must be of type REFCURSOR */
if (cexpr->cursor_name == NULL)
{
- Oid *pptype = find_param_type(pstate, cexpr->cursor_param);
+ Oid *pptype = find_param_type(pstate, cexpr->cursor_param, -1);
if (pstate->p_variableparams && *pptype == UNKNOWNOID)
{
/* Look up the referenced RTE, creating it if needed */
- rte = refnameRangeTblEntry(pstate, schemaname, relname,
+ rte = refnameRangeTblEntry(pstate, schemaname, relname, location,
&sublevels_up);
if (rte == NULL)
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname),
- location);
+ rte = addImplicitRTE(pstate,
+ makeRangeVar(schemaname, relname, location));
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.206 2008/08/28 23:09:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.207 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for data type %s",
- format_type_be(newa->element_typeid))));
+ format_type_be(newa->element_typeid)),
+ parser_errposition(pstate, exprLocation((Node *) vargs))));
newa->multidims = false;
newa->location = exprLocation((Node *) vargs);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.102 2008/08/28 23:09:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.103 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/varbit.h"
+static void pcb_error_callback(void *arg);
+
+
/*
* make_parsestate
* Allocate and initialize a new ParseState.
}
+/*
+ * setup_parser_errposition_callback
+ * Arrange for non-parser errors to report an error position
+ *
+ * Sometimes the parser calls functions that aren't part of the parser
+ * subsystem and can't reasonably be passed a ParseState; yet we would
+ * like any errors thrown in those functions to be tagged with a parse
+ * error location. Use this function to set up an error context stack
+ * entry that will accomplish that. Usage pattern:
+ *
+ * declare a local variable "ParseCallbackState pcbstate"
+ * ...
+ * setup_parser_errposition_callback(&pcbstate, pstate, location);
+ * call function that might throw error;
+ * cancel_parser_errposition_callback(&pcbstate);
+ */
+void
+setup_parser_errposition_callback(ParseCallbackState *pcbstate,
+ ParseState *pstate, int location)
+{
+ /* Setup error traceback support for ereport() */
+ pcbstate->pstate = pstate;
+ pcbstate->location = location;
+ pcbstate->errcontext.callback = pcb_error_callback;
+ pcbstate->errcontext.arg = (void *) pcbstate;
+ pcbstate->errcontext.previous = error_context_stack;
+ error_context_stack = &pcbstate->errcontext;
+}
+
+/*
+ * Cancel a previously-set-up errposition callback.
+ */
+void
+cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
+{
+ /* Pop the error context stack */
+ error_context_stack = pcbstate->errcontext.previous;
+}
+
+/*
+ * Error context callback for inserting parser error location.
+ *
+ * Note that this will be called for *any* error occurring while the
+ * callback is installed. We avoid inserting an irrelevant error location
+ * if the error is a query cancel --- are there any other important cases?
+ */
+static void
+pcb_error_callback(void *arg)
+{
+ ParseCallbackState *pcbstate = (ParseCallbackState *) arg;
+
+ if (geterrcode() != ERRCODE_QUERY_CANCELED)
+ (void) parser_errposition(pcbstate->pstate, pcbstate->location);
+}
+
+
/*
* make_var
* Build a Var node for an attribute identified by RTE and attrno
* too many examples that fail if we try.
*/
Const *
-make_const(Value *value, int location)
+make_const(ParseState *pstate, Value *value, int location)
{
+ Const *con;
Datum val;
int64 val64;
Oid typeid;
int typelen;
bool typebyval;
- Const *con;
+ ParseCallbackState pcbstate;
switch (nodeTag(value))
{
}
else
{
+ /* arrange to report location if numeric_in() fails */
+ setup_parser_errposition_callback(&pcbstate, pstate, location);
val = DirectFunctionCall3(numeric_in,
CStringGetDatum(strVal(value)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
+ cancel_parser_errposition_callback(&pcbstate);
typeid = NUMERICOID;
typelen = -1; /* variable len */
break;
case T_BitString:
+ /* arrange to report location if bit_in() fails */
+ setup_parser_errposition_callback(&pcbstate, pstate, location);
val = DirectFunctionCall3(bit_in,
CStringGetDatum(strVal(value)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
+ cancel_parser_errposition_callback(&pcbstate);
typeid = BITOID;
typelen = -1;
typebyval = false;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.134 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.135 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
bool add_missing_from;
static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate,
- const char *refname);
-static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid);
+ const char *refname, int location);
+static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid,
+ int location);
static bool isLockedRel(ParseState *pstate, char *refname);
static void expandRelation(Oid relid, Alias *eref,
int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars);
static void expandTupleDesc(TupleDesc tupdesc, Alias *eref,
int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars);
static int specialAttNum(const char *attname);
-static void warnAutoRange(ParseState *pstate, RangeVar *relation,
- int location);
+static void warnAutoRange(ParseState *pstate, RangeVar *relation);
/*
refnameRangeTblEntry(ParseState *pstate,
const char *schemaname,
const char *refname,
+ int location,
int *sublevels_up)
{
Oid relId = InvalidOid;
RangeTblEntry *result;
if (OidIsValid(relId))
- result = scanNameSpaceForRelid(pstate, relId);
+ result = scanNameSpaceForRelid(pstate, relId, location);
else
- result = scanNameSpaceForRefname(pstate, refname);
+ result = scanNameSpaceForRefname(pstate, refname, location);
if (result)
return result;
* if no match. Raise error if multiple matches.
*/
static RangeTblEntry *
-scanNameSpaceForRefname(ParseState *pstate, const char *refname)
+scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)
{
RangeTblEntry *result = NULL;
ListCell *l;
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_ALIAS),
errmsg("table reference \"%s\" is ambiguous",
- refname)));
+ refname),
+ parser_errposition(pstate, location)));
result = rte;
}
}
* acts the way it does.
*/
static RangeTblEntry *
-scanNameSpaceForRelid(ParseState *pstate, Oid relid)
+scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
{
RangeTblEntry *result = NULL;
ListCell *l;
ereport(ERROR,
(errcode(ERRCODE_AMBIGUOUS_ALIAS),
errmsg("table reference %u is ambiguous",
- relid)));
+ relid),
+ parser_errposition(pstate, location)));
result = rte;
}
}
RangeTblEntry *rte;
int sublevels_up;
- rte = refnameRangeTblEntry(pstate, schemaname, refname, &sublevels_up);
+ rte = refnameRangeTblEntry(pstate, schemaname, refname, location,
+ &sublevels_up);
if (rte == NULL)
{
if (!implicitRTEOK)
return NULL;
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname, refname),
- location);
+ rte = addImplicitRTE(pstate,
+ makeRangeVar(schemaname, refname, location));
}
return scanRTEForColumn(pstate, rte, colname, location);
eref->colnames = list_make1(makeString(eref->aliasname));
}
+/*
+ * Open a table during parse analysis
+ *
+ * This is essentially just the same as heap_openrv(), except that it
+ * arranges to include the RangeVar's parse location in any resulting error.
+ *
+ * Note: properly, lockmode should be declared LOCKMODE not int, but that
+ * would require importing storage/lock.h into parse_relation.h. Since
+ * LOCKMODE is typedef'd as int anyway, that seems like overkill.
+ */
+Relation
+parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode)
+{
+ Relation rel;
+ ParseCallbackState pcbstate;
+
+ setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
+ rel = heap_openrv(relation, lockmode);
+ cancel_parser_errposition_callback(&pcbstate);
+ return rel;
+}
+
/*
* Add an entry for a relation to the pstate's range table (p_rtable).
*
* depending on whether we're doing SELECT FOR UPDATE/SHARE.
*/
lockmode = isLockedRel(pstate, refname) ? RowShareLock : AccessShareLock;
- rel = heap_openrv(relation, lockmode);
+ rel = parserOpenTable(pstate, relation, lockmode);
rte->relid = RelationGetRelid(rel);
/*
if (functypclass != TYPEFUNC_RECORD)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("a column definition list is only allowed for functions returning \"record\"")));
+ errmsg("a column definition list is only allowed for functions returning \"record\""),
+ parser_errposition(pstate, exprLocation(funcexpr))));
}
else
{
if (functypclass == TYPEFUNC_RECORD)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("a column definition list is required for functions returning \"record\"")));
+ errmsg("a column definition list is required for functions returning \"record\""),
+ parser_errposition(pstate, exprLocation(funcexpr))));
}
if (functypclass == TYPEFUNC_COMPOSITE)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("column \"%s\" cannot be declared SETOF",
- attrname)));
+ attrname),
+ parser_errposition(pstate, n->typename->location)));
attrtype = typenameTypeId(pstate, n->typename, &attrtypmod);
eref->colnames = lappend(eref->colnames, makeString(attrname));
rte->funccoltypes = lappend_oid(rte->funccoltypes, attrtype);
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("function \"%s\" in FROM has unsupported return type %s",
- funcname, format_type_be(funcrettype))));
+ funcname, format_type_be(funcrettype)),
+ parser_errposition(pstate, exprLocation(funcexpr))));
/*----------
* Flags:
foreach(l2, lc->lockedRels)
{
- char *rname = strVal(lfirst(l2));
+ RangeVar *thisrel = (RangeVar *) lfirst(l2);
- if (strcmp(refname, rname) == 0)
+ if (strcmp(refname, thisrel->relname) == 0)
return true;
}
}
* a conflicting name.
*/
RangeTblEntry *
-addImplicitRTE(ParseState *pstate, RangeVar *relation, int location)
+addImplicitRTE(ParseState *pstate, RangeVar *relation)
{
RangeTblEntry *rte;
/* issue warning or error as needed */
- warnAutoRange(pstate, relation, location);
+ warnAutoRange(pstate, relation);
/*
* Note that we set inFromCl true, so that the RTE will be listed
* results. If include_dropped is TRUE then empty strings and NULL constants
* (not Vars!) are returned for dropped columns.
*
- * rtindex and sublevels_up are the varno and varlevelsup values to use
- * in the created Vars. Ordinarily rtindex should match the actual position
- * of the RTE in its rangetable.
+ * rtindex, sublevels_up, and location are the varno, varlevelsup, and location
+ * values to use in the created Vars. Ordinarily rtindex should match the
+ * actual position of the RTE in its rangetable.
*
* The output lists go into *colnames and *colvars.
* If only one of the two kinds of output list is needed, pass NULL for the
*/
void
expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars)
{
int varattno;
{
case RTE_RELATION:
/* Ordinary relation RTE */
- expandRelation(rte->relid, rte->eref, rtindex, sublevels_up,
+ expandRelation(rte->relid, rte->eref,
+ rtindex, sublevels_up, location,
include_dropped, colnames, colvars);
break;
case RTE_SUBQUERY:
exprType((Node *) te->expr),
exprTypmod((Node *) te->expr),
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
{
/* Composite data type, e.g. a table's row type */
Assert(tupdesc);
- expandTupleDesc(tupdesc, rte->eref, rtindex, sublevels_up,
+ expandTupleDesc(tupdesc, rte->eref,
+ rtindex, sublevels_up, location,
include_dropped, colnames, colvars);
}
else if (functypclass == TYPEFUNC_SCALAR)
varnode = makeVar(rtindex, 1,
funcrettype, -1,
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
attrtype,
attrtypmod,
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
}
exprType(col),
exprTypmod(col),
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
}
exprType(avar),
exprTypmod(avar),
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
*/
static void
expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars)
{
Relation rel;
/* Get the tupledesc and turn it over to expandTupleDesc */
rel = relation_open(relid, AccessShareLock);
- expandTupleDesc(rel->rd_att, eref, rtindex, sublevels_up, include_dropped,
+ expandTupleDesc(rel->rd_att, eref, rtindex, sublevels_up,
+ location, include_dropped,
colnames, colvars);
relation_close(rel, AccessShareLock);
}
static void
expandTupleDesc(TupleDesc tupdesc, Alias *eref,
int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars)
{
int maxattrs = tupdesc->natts;
varnode = makeVar(rtindex, attr->attnum,
attr->atttypid, attr->atttypmod,
sublevels_up);
+ varnode->location = location;
*colvars = lappend(*colvars, varnode);
}
/*
* expandRelAttrs -
* Workhorse for "*" expansion: produce a list of targetentries
- * for the attributes of the rte
+ * for the attributes of the RTE
*
* As with expandRTE, rtindex/sublevels_up determine the varno/varlevelsup
- * fields of the Vars produced. pstate->p_next_resno determines the resnos
- * assigned to the TLEs.
+ * fields of the Vars produced, and location sets their location.
+ * pstate->p_next_resno determines the resnos assigned to the TLEs.
*/
List *
expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
- int rtindex, int sublevels_up)
+ int rtindex, int sublevels_up, int location)
{
List *names,
*vars;
*var;
List *te_list = NIL;
- expandRTE(rte, rtindex, sublevels_up, false,
+ expandRTE(rte, rtindex, sublevels_up, location, false,
&names, &vars);
forboth(name, names, var, vars)
te_list = lappend(te_list, te);
}
- Assert(name == NULL && var == NULL); /* lists not the same length? */
+ Assert(name == NULL && var == NULL); /* lists not the same length? */
return te_list;
}
* a warning.
*/
static void
-warnAutoRange(ParseState *pstate, RangeVar *relation, int location)
+warnAutoRange(ParseState *pstate, RangeVar *relation)
{
RangeTblEntry *rte;
int sublevels_up;
if (rte && rte->alias &&
strcmp(rte->eref->aliasname, relation->relname) != 0 &&
refnameRangeTblEntry(pstate, NULL, rte->eref->aliasname,
+ relation->location,
&sublevels_up) == rte)
badAlias = rte->eref->aliasname;
badAlias) :
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
rte->eref->aliasname)),
- parser_errposition(pstate, location)));
+ parser_errposition(pstate, relation->location)));
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
relation->relname) :
errmsg("missing FROM-clause entry for table \"%s\"",
relation->relname)),
- parser_errposition(pstate, location)));
+ parser_errposition(pstate, relation->location)));
}
else
{
(rte ?
errhint("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
rte->eref->aliasname) : 0)),
- parser_errposition(pstate, location)));
+ parser_errposition(pstate, relation->location)));
}
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.163 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.164 2008/09/01 20:42:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int location);
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
bool targetlist);
-static List *ExpandAllTables(ParseState *pstate);
+static List *ExpandAllTables(ParseState *pstate, int location);
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
bool targetlist);
static int FigureColnameInternal(Node *node, char **name);
* need not handle the targetlist==false case here.
*/
Assert(targetlist);
- return ExpandAllTables(pstate);
+ return ExpandAllTables(pstate, cref->location);
}
else
{
break;
}
- rte = refnameRangeTblEntry(pstate, schemaname, relname,
+ rte = refnameRangeTblEntry(pstate, schemaname, relname, cref->location,
&sublevels_up);
if (rte == NULL)
- rte = addImplicitRTE(pstate, makeRangeVar(schemaname, relname),
- cref->location);
+ rte = addImplicitRTE(pstate,
+ makeRangeVar(schemaname, relname,
+ cref->location));
/* Require read access --- see comments in setTargetTable() */
rte->requiredPerms |= ACL_SELECT;
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
if (targetlist)
- return expandRelAttrs(pstate, rte, rtindex, sublevels_up);
+ return expandRelAttrs(pstate, rte, rtindex, sublevels_up,
+ cref->location);
else
{
List *vars;
- expandRTE(rte, rtindex, sublevels_up, false,
+ expandRTE(rte, rtindex, sublevels_up, cref->location, false,
NULL, &vars);
return vars;
}
* etc.
*/
static List *
-ExpandAllTables(ParseState *pstate)
+ExpandAllTables(ParseState *pstate, int location)
{
List *target = NIL;
ListCell *l;
if (!pstate->p_varnamespace)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("SELECT * with no tables specified is not valid")));
+ errmsg("SELECT * with no tables specified is not valid"),
+ parser_errposition(pstate, location)));
foreach(l, pstate->p_varnamespace)
{
rte->requiredPerms |= ACL_SELECT;
target = list_concat(target,
- expandRelAttrs(pstate, rte, rtindex, 0));
+ expandRelAttrs(pstate, rte, rtindex, 0,
+ location));
}
return target;
((Var *) expr)->varattno == InvalidAttrNumber)
{
Var *var = (Var *) expr;
+ Var *newvar;
+
+ newvar = makeVar(var->varno,
+ i + 1,
+ att->atttypid,
+ att->atttypmod,
+ var->varlevelsup);
+ newvar->location = var->location;
- fieldnode = (Node *) makeVar(var->varno,
- i + 1,
- att->atttypid,
- att->atttypmod,
- var->varlevelsup);
+ fieldnode = (Node *) newvar;
}
else
{
*lvar;
int i;
- expandRTE(rte, var->varno, 0, false,
+ expandRTE(rte, var->varno, 0, var->location, false,
&names, &vars);
tupleDesc = CreateTemplateTupleDesc(list_length(vars), false);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.98 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.99 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
else if (typename->pct_type)
{
/* Handle %TYPE reference to type of an existing field */
- RangeVar *rel = makeRangeVar(NULL, NULL);
+ RangeVar *rel = makeRangeVar(NULL, NULL, typename->location);
char *field = NULL;
Oid relid;
AttrNumber attnum;
/* this construct should never have an array indicator */
Assert(typename->arrayBounds == NIL);
- /* emit nuisance notice */
+ /* emit nuisance notice (intentionally not errposition'd) */
ereport(NOTICE,
(errmsg("type reference %s converted to %s",
TypeNameToString(typename),
int n;
ListCell *l;
ArrayType *arrtypmod;
+ ParseCallbackState pcbstate;
/* Return prespecified typmod if no typmod expressions */
if (typename->typmods == NIL)
arrtypmod = construct_array(datums, n, CSTRINGOID,
-2, false, 'c');
+ /* arrange to report location if type's typmodin function fails */
+ setup_parser_errposition_callback(&pcbstate, pstate, typename->location);
+
result = DatumGetInt32(OidFunctionCall1(typmodin,
PointerGetDatum(arrtypmod)));
+ cancel_parser_errposition_callback(&pcbstate);
+
pfree(datums);
pfree(arrtypmod);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.16 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.17 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* TABLE.
*/
seqstmt = makeNode(CreateSeqStmt);
- seqstmt->sequence = makeRangeVar(snamespace, sname);
+ seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
seqstmt->options = NIL;
cxt->blist = lappend(cxt->blist, seqstmt);
* done after this CREATE/ALTER TABLE.
*/
altseqstmt = makeNode(AlterSeqStmt);
- altseqstmt->sequence = makeRangeVar(snamespace, sname);
+ altseqstmt->sequence = makeRangeVar(snamespace, sname, -1);
attnamelist = list_make3(makeString(snamespace),
makeString(cxt->relation->relname),
makeString(column->colname));
bool including_indexes = false;
ListCell *elem;
- relation = heap_openrv(inhRelation->relation, AccessShareLock);
+ relation = parserOpenTable(pstate, inhRelation->relation, AccessShareLock);
if (relation->rd_rel->relkind != RELKIND_RELATION)
ereport(ERROR,
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.145 2008/08/29 13:02:32 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.146 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void addlitchar(unsigned char ychar);
static char *litbufdup(void);
-static int lexer_errposition(void);
+#define lexer_errposition() scanner_errposition(yylloc)
+
static void check_escape_warning(void);
static void check_string_escape_warning(unsigned char ychar);
%%
/*
- * lexer_errposition
- * Report a lexical-analysis-time cursor position, if possible.
+ * scanner_errposition
+ * Report a lexer or grammar error cursor position, if possible.
*
* This is expected to be used within an ereport() call. The return value
* is a dummy (always 0, in fact).
*
- * Note that this can only be used for messages from the lexer itself,
- * since it depends on scanbuf to still be valid.
+ * Note that this can only be used for messages emitted during raw parsing
+ * (essentially, scan.l and gram.y), since it requires scanbuf to still be
+ * valid.
*/
-static int
-lexer_errposition(void)
+int
+scanner_errposition(int location)
{
int pos;
+ Assert(scanbuf != NULL); /* else called from wrong place */
+ if (location < 0)
+ return 0; /* no-op if location is unknown */
+
/* Convert byte offset to character number */
- pos = pg_mbstrlen_with_len(scanbuf, yylloc) + 1;
+ pos = pg_mbstrlen_with_len(scanbuf, location) + 1;
/* And pass it to the ereport mechanism */
return errposition(pos);
}
{
yy_delete_buffer(scanbufhandle);
pfree(scanbuf);
+ scanbuf = NULL;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.112 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.113 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int sublevels_up;
} contain_aggs_of_level_context;
+typedef struct
+{
+ int agg_location;
+ int sublevels_up;
+} locate_agg_of_level_context;
+
static bool contain_aggs_of_level_walker(Node *node,
contain_aggs_of_level_context *context);
+static bool locate_agg_of_level_walker(Node *node,
+ locate_agg_of_level_context *context);
static bool checkExprHasSubLink_walker(Node *node, void *context);
static Relids offset_relid_set(Relids relids, int offset);
static Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid);
/*
* checkExprHasAggs -
- * Check if an expression contains an aggregate function call.
+ * Check if an expression contains an aggregate function call of the
+ * current query level.
*/
bool
checkExprHasAggs(Node *node)
(void *) context);
}
+/*
+ * locate_agg_of_level -
+ * Find the parse location of any aggregate of the specified query level.
+ *
+ * Returns -1 if no such agg is in the querytree, or if they all have
+ * unknown parse location. (The former case is probably caller error,
+ * but we don't bother to distinguish it from the latter case.)
+ *
+ * Note: it might seem appropriate to merge this functionality into
+ * contain_aggs_of_level, but that would complicate that function's API.
+ * Currently, the only uses of this function are for error reporting,
+ * and so shaving cycles probably isn't very important.
+ */
+int
+locate_agg_of_level(Node *node, int levelsup)
+{
+ locate_agg_of_level_context context;
+
+ context.agg_location = -1; /* in case we find nothing */
+ context.sublevels_up = levelsup;
+
+ /*
+ * Must be prepared to start with a Query or a bare expression tree; if
+ * it's a Query, we don't want to increment sublevels_up.
+ */
+ (void) query_or_expression_tree_walker(node,
+ locate_agg_of_level_walker,
+ (void *) &context,
+ 0);
+
+ return context.agg_location;
+}
+
+static bool
+locate_agg_of_level_walker(Node *node,
+ locate_agg_of_level_context *context)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Aggref))
+ {
+ if (((Aggref *) node)->agglevelsup == context->sublevels_up &&
+ ((Aggref *) node)->location >= 0)
+ {
+ context->agg_location = ((Aggref *) node)->location;
+ return true; /* abort the tree traversal and return true */
+ }
+ /* else fall through to examine argument */
+ }
+ if (IsA(node, Query))
+ {
+ /* Recurse into subselects */
+ bool result;
+
+ context->sublevels_up++;
+ result = query_tree_walker((Query *) node,
+ locate_agg_of_level_walker,
+ (void *) context, 0);
+ context->sublevels_up--;
+ return result;
+ }
+ return expression_tree_walker(node, locate_agg_of_level_walker,
+ (void *) context);
+}
+
/*
* checkExprHasSubLink -
* Check if an expression contains a SubLink.
* this is a JOIN), then omit dropped columns.
*/
expandRTE(context->target_rte,
- this_varno, this_varlevelsup,
+ this_varno, this_varlevelsup, var->location,
(var->vartype != RECORDOID),
NULL, &fields);
/* Adjust the generated per-field Vars... */
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.297 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.298 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
NotifyStmt *stmt = (NotifyStmt *) parsetree;
- Async_Notify(stmt->relation->relname);
+ Async_Notify(stmt->conditionname);
}
break;
{
ListenStmt *stmt = (ListenStmt *) parsetree;
- Async_Listen(stmt->relation->relname);
+ Async_Listen(stmt->conditionname);
}
break;
{
UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
- if (stmt->relation)
- Async_Unlisten(stmt->relation->relname);
+ if (stmt->conditionname)
+ Async_Unlisten(stmt->conditionname);
else
Async_UnlistenAll();
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.281 2008/08/25 22:42:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.282 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
appendContextKeyword(context, "",
0, PRETTYINDENT_STD, 1);
appendStringInfo(buf, "NOTIFY %s",
- quote_qualified_identifier(stmt->relation->schemaname,
- stmt->relation->relname));
+ quote_identifier(stmt->conditionname));
}
else
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.205 2008/07/09 15:56:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.206 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
return 0; /* return value does not matter */
}
+/*
+ * geterrcode --- return the currently set SQLSTATE error code
+ *
+ * This is only intended for use in error callback subroutines, since there
+ * is no other place outside elog.c where the concept is meaningful.
+ */
+int
+geterrcode(void)
+{
+ ErrorData *edata = &errordata[errordata_stack_depth];
+
+ /* we don't bother incrementing recursion_depth */
+ CHECK_STACK_DEPTH();
+
+ return edata->sqlerrcode;
+}
+
/*
* geterrposition --- return the currently set error position (0 if none)
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.481 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.482 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200808281
+#define CATALOG_VERSION_NO 200808311
#endif
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.62 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.63 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod,
CoercionForm rformat);
-extern RangeVar *makeRangeVar(char *schemaname, char *relname);
+extern RangeVar *makeRangeVar(char *schemaname, char *relname, int location);
extern TypeName *makeTypeName(char *typnam);
extern TypeName *makeTypeNameFromNameList(List *names);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.373 2008/08/30 01:39:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.374 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
typedef struct SortBy
{
NodeTag type;
- SortByDir sortby_dir; /* ASC/DESC/USING */
+ Node *node; /* expression to sort on */
+ SortByDir sortby_dir; /* ASC/DESC/USING/default */
SortByNulls sortby_nulls; /* NULLS FIRST/LAST */
List *useOp; /* name of op to use, if SORTBY_USING */
- Node *node; /* expression to sort on */
+ int location; /* operator location, or -1 if none/unknown */
} SortBy;
/*
* LockingClause - raw representation of FOR UPDATE/SHARE options
*
* Note: lockedRels == NIL means "all relations in query". Otherwise it
- * is a list of String nodes giving relation eref names.
+ * is a list of RangeVar nodes. (We use RangeVar mainly because it carries
+ * a location field --- currently, parse analysis insists on unqualified
+ * names in LockingClause.)
*/
typedef struct LockingClause
{
typedef struct NotifyStmt
{
NodeTag type;
- RangeVar *relation; /* qualified name to notify */
+ char *conditionname; /* condition name to notify */
} NotifyStmt;
/* ----------------------
typedef struct ListenStmt
{
NodeTag type;
- RangeVar *relation; /* name to listen on */
+ char *conditionname; /* condition name to listen on */
} ListenStmt;
/* ----------------------
typedef struct UnlistenStmt
{
NodeTag type;
- RangeVar *relation; /* name to unlisten on, or NULL for all */
+ char *conditionname; /* name to unlisten on, or NULL for all */
} UnlistenStmt;
/* ----------------------
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.140 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.141 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* on children? */
bool istemp; /* is this a temp relation/sequence? */
Alias *alias; /* table alias & optional column aliases */
+ int location; /* token location, or -1 if unknown */
} RangeVar;
/*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/var.h,v 1.37 2008/01/01 19:45:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/var.h,v 1.38 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern Relids pull_varnos(Node *node);
extern void pull_varattnos(Node *node, Bitmapset **varattnos);
-extern bool contain_var_reference(Node *node, int varno, int varattno,
- int levelsup);
extern bool contain_var_clause(Node *node);
extern bool contain_vars_of_level(Node *node, int levelsup);
-extern bool contain_vars_above_level(Node *node, int levelsup);
+extern int locate_var_of_level(Node *node, int levelsup);
+extern int locate_var_of_relation(Node *node, int relid, int levelsup);
extern int find_minimum_var_level(Node *node);
extern List *pull_var_clause(Node *node, bool includeUpperVars);
extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.41 2008/04/04 11:47:19 mha Exp $
+ * $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.42 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void scanner_init(const char *str);
extern void scanner_finish(void);
extern int base_yylex(void);
+extern int scanner_errposition(int location);
extern void base_yyerror(const char *message);
/* from gram.y */
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.55 2008/08/28 23:09:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_node.h,v 1.56 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
RangeTblEntry *p_target_rangetblentry;
} ParseState;
+/* Support for parser_errposition_callback function */
+typedef struct ParseCallbackState
+{
+ ParseState *pstate;
+ int location;
+ ErrorContextCallback errcontext;
+} ParseCallbackState;
+
+
extern ParseState *make_parsestate(ParseState *parentParseState);
extern void free_parsestate(ParseState *pstate);
extern int parser_errposition(ParseState *pstate, int location);
+extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate,
+ ParseState *pstate, int location);
+extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate);
+
extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno,
int location);
extern Oid transformArrayType(Oid arrayType);
int32 elementTypMod,
List *indirection,
Node *assignFrom);
-extern Const *make_const(Value *value, int location);
+extern Const *make_const(ParseState *pstate, Value *value, int location);
#endif /* PARSE_NODE_H */
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.57 2008/01/01 19:45:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_relation.h,v 1.58 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern RangeTblEntry *refnameRangeTblEntry(ParseState *pstate,
const char *schemaname,
const char *refname,
+ int location,
int *sublevels_up);
extern void checkNameSpaceConflicts(ParseState *pstate, List *namespace1,
List *namespace2);
char *colname,
bool implicitRTEOK,
int location);
+extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation,
+ int lockmode);
extern RangeTblEntry *addRangeTableEntry(ParseState *pstate,
RangeVar *relation,
Alias *alias,
extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte,
bool addToJoinList,
bool addToRelNameSpace, bool addToVarNameSpace);
-extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation,
- int location);
+extern RangeTblEntry *addImplicitRTE(ParseState *pstate, RangeVar *relation);
extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
- bool include_dropped,
+ int location, bool include_dropped,
List **colnames, List **colvars);
extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte,
- int rtindex, int sublevels_up);
+ int rtindex, int sublevels_up, int location);
extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK);
extern Name attnumAttName(Relation rd, int attid);
extern Oid attnumTypeId(Relation rd, int attid);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.46 2008/08/22 00:16:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/rewrite/rewriteManip.h,v 1.47 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void AddInvertedQual(Query *parsetree, Node *qual);
extern bool contain_aggs_of_level(Node *node, int levelsup);
+extern int locate_agg_of_level(Node *node, int levelsup);
extern bool checkExprHasAggs(Node *node);
extern bool checkExprHasSubLink(Node *node);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.93 2008/04/16 23:59:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.94 2008/09/01 20:42:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern int internalerrposition(int cursorpos);
extern int internalerrquery(const char *query);
+extern int geterrcode(void);
extern int geterrposition(void);
extern int getinternalerrposition(void);
SELECT * FROM perl_record();
ERROR: a column definition list is required for functions returning "record"
+LINE 1: SELECT * FROM perl_record();
+ ^
SELECT * FROM perl_record() AS (f1 integer, f2 text, f3 text);
f1 | f2 | f3
----+----+----
ERROR: function returning record called in context that cannot accept type record
SELECT * FROM perl_record();
ERROR: a column definition list is required for functions returning "record"
+LINE 1: SELECT * FROM perl_record();
+ ^
SELECT * FROM perl_record() AS (f1 integer, f2 text, f3 text);
f1 | f2 | f3
----+-------+-------
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
+LINE 1: SELECT * FROM perl_record_set();
+ ^
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
f1 | f2 | f3
----+----+----
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
+LINE 1: SELECT * FROM perl_record_set();
+ ^
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
ERROR: setof-composite-returning Perl function must call return_next with reference to hash
CREATE OR REPLACE FUNCTION perl_record_set() RETURNS SETOF record AS $$
ERROR: set-valued function called in context that cannot accept a set
SELECT * FROM perl_record_set();
ERROR: a column definition list is required for functions returning "record"
+LINE 1: SELECT * FROM perl_record_set();
+ ^
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
f1 | f2 | f3
----+-------+------------
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.129 2008/08/29 13:02:33 petere Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.130 2008/09/01 20:42:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
word[i] = '%';
pfree(cp[3]);
- relvar = makeRangeVar(cp[0], cp[1]);
+ relvar = makeRangeVar(cp[0], cp[1], -1);
classOid = RangeVarGetRelid(relvar, true);
if (!OidIsValid(classOid))
goto done;
word[i] = '%';
/* Lookup the relation */
- relvar = makeRangeVar(cp[0], cp[1]);
+ relvar = makeRangeVar(cp[0], cp[1], -1);
classOid = RangeVarGetRelid(relvar, true);
if (!OidIsValid(classOid))
ereport(ERROR,
-- what happens if we specify slightly misformatted abstime?
INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00');
ERROR: date/time field value out of range: "Feb 35, 1946 10:00:00"
+LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00'...
+ ^
HINT: Perhaps you need a different "datestyle" setting.
INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10');
ERROR: date/time field value out of range: "Feb 28, 1984 25:08:10"
+LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10'...
+ ^
-- badly formatted abstimes: these should result in invalid abstimes
INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format');
ERROR: invalid input syntax for type abstime: "bad date format"
+LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format');
+ ^
INSERT INTO ABSTIME_TBL (f1) VALUES ('Jun 10, 1843');
-- test abstime operators
SELECT '' AS eight, * FROM ABSTIME_TBL;
having exists (select 1 from onek b
where sum(distinct a.four + b.four) = b.four);
ERROR: aggregates not allowed in WHERE clause
+LINE 4: where sum(distinct a.four + b.four) = b.four)...
+ ^
--
-- test for bitwise integer aggregates
--
ALTER TABLE tmp RENAME TO tmp_new2;
SELECT * FROM tmp; -- should fail
ERROR: relation "tmp" does not exist
+LINE 1: SELECT * FROM tmp;
+ ^
SELECT * FROM tmp_new;
tmptable
----------
-- INSERTs
insert into atacc1 values (10, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
+LINE 1: insert into atacc1 values (10, 11, 12, 13);
+ ^
insert into atacc1 values (default, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
+LINE 1: insert into atacc1 values (default, 11, 12, 13);
+ ^
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
ERROR: column "a" of relation "atacc1" does not exist
-- none of the following should be accepted
select '{{1,{2}},{2,3}}'::text[];
ERROR: malformed array literal: "{{1,{2}},{2,3}}"
+LINE 1: select '{{1,{2}},{2,3}}'::text[];
+ ^
select '{{},{}}'::text[];
ERROR: malformed array literal: "{{},{}}"
+LINE 1: select '{{},{}}'::text[];
+ ^
select E'{{1,2},\\{2,3}}'::text[];
ERROR: malformed array literal: "{{1,2},\{2,3}}"
+LINE 1: select E'{{1,2},\\{2,3}}'::text[];
+ ^
select '{{"1 2" x},{3}}'::text[];
ERROR: malformed array literal: "{{"1 2" x},{3}}"
+LINE 1: select '{{"1 2" x},{3}}'::text[];
+ ^
select '{}}'::text[];
ERROR: malformed array literal: "{}}"
+LINE 1: select '{}}'::text[];
+ ^
select '{ }}'::text[];
ERROR: malformed array literal: "{ }}"
+LINE 1: select '{ }}'::text[];
+ ^
select array[];
ERROR: cannot determine type of empty array
LINE 1: select array[];
INSERT INTO BOOLTBL2 (f1)
VALUES (bool 'XXX');
ERROR: invalid input syntax for type boolean: "XXX"
+LINE 2: VALUES (bool 'XXX');
+ ^
-- BOOLTBL2 should be full of false's at this point
SELECT '' AS f_4, BOOLTBL2.* FROM BOOLTBL2;
f_4 | f1
-- badly formatted box inputs
INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
ERROR: invalid input syntax for type box: "(2.3, 4.5)"
+LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
+ ^
INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
ERROR: invalid input syntax for type box: "asdfasdf(ad"
+LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
+ ^
SELECT '' AS four, * FROM BOX_TBL;
four | f1
------+---------------------
-- bad values
INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>');
ERROR: invalid input syntax for type circle: "<(-100,0),-100>"
+LINE 1: INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>');
+ ^
INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5');
ERROR: invalid input syntax for type circle: "1abc,3,5"
+LINE 1: INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5');
+ ^
INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)');
ERROR: invalid input syntax for type circle: "(3,(1,2),3)"
+LINE 1: INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)');
+ ^
SELECT * FROM CIRCLE_TBL;
f1
----------------
-- (we have borrowed numeric's typmod functions)
CREATE TEMP TABLE mytab (foo widget(42,13,7)); -- should fail
ERROR: invalid NUMERIC type modifier
+LINE 1: CREATE TEMP TABLE mytab (foo widget(42,13,7));
+ ^
CREATE TEMP TABLE mytab (foo widget(42,13));
SELECT format_type(atttypid,atttypmod) FROM pg_attribute
WHERE attrelid = 'mytab'::regclass AND attnum > 0;
INSERT INTO DATE_TBL VALUES ('1997-02-28');
INSERT INTO DATE_TBL VALUES ('1997-02-29');
ERROR: date/time field value out of range: "1997-02-29"
+LINE 1: INSERT INTO DATE_TBL VALUES ('1997-02-29');
+ ^
INSERT INTO DATE_TBL VALUES ('1997-03-01');
INSERT INTO DATE_TBL VALUES ('1997-03-02');
INSERT INTO DATE_TBL VALUES ('2000-04-01');
SELECT date '1/8/1999';
ERROR: date/time field value out of range: "1/8/1999"
+LINE 1: SELECT date '1/8/1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1/18/1999';
ERROR: date/time field value out of range: "1/18/1999"
+LINE 1: SELECT date '1/18/1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '18/1/1999';
ERROR: date/time field value out of range: "18/1/1999"
+LINE 1: SELECT date '18/1/1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01/02/03';
date
SELECT date 'January 8, 99 BC';
ERROR: date/time field value out of range: "January 8, 99 BC"
+LINE 1: SELECT date 'January 8, 99 BC';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '99-Jan-08';
date
SELECT date '08-Jan-99';
ERROR: date/time field value out of range: "08-Jan-99"
+LINE 1: SELECT date '08-Jan-99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '08-Jan-1999';
date
SELECT date 'Jan-08-99';
ERROR: date/time field value out of range: "Jan-08-99"
+LINE 1: SELECT date 'Jan-08-99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date 'Jan-08-1999';
date
SELECT date '99-08-Jan';
ERROR: invalid input syntax for type date: "99-08-Jan"
+LINE 1: SELECT date '99-08-Jan';
+ ^
SELECT date '1999-08-Jan';
ERROR: invalid input syntax for type date: "1999-08-Jan"
+LINE 1: SELECT date '1999-08-Jan';
+ ^
SELECT date '99 Jan 08';
date
------------
SELECT date '08 Jan 99';
ERROR: date/time field value out of range: "08 Jan 99"
+LINE 1: SELECT date '08 Jan 99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '08 Jan 1999';
date
SELECT date 'Jan 08 99';
ERROR: date/time field value out of range: "Jan 08 99"
+LINE 1: SELECT date 'Jan 08 99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date 'Jan 08 1999';
date
SELECT date '08-01-99';
ERROR: date/time field value out of range: "08-01-99"
+LINE 1: SELECT date '08-01-99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '08-01-1999';
ERROR: date/time field value out of range: "08-01-1999"
+LINE 1: SELECT date '08-01-1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01-08-99';
ERROR: date/time field value out of range: "01-08-99"
+LINE 1: SELECT date '01-08-99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01-08-1999';
ERROR: date/time field value out of range: "01-08-1999"
+LINE 1: SELECT date '01-08-1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '99-08-01';
date
SELECT date '08 01 99';
ERROR: date/time field value out of range: "08 01 99"
+LINE 1: SELECT date '08 01 99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '08 01 1999';
ERROR: date/time field value out of range: "08 01 1999"
+LINE 1: SELECT date '08 01 1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01 08 99';
ERROR: date/time field value out of range: "01 08 99"
+LINE 1: SELECT date '01 08 99';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01 08 1999';
ERROR: date/time field value out of range: "01 08 1999"
+LINE 1: SELECT date '01 08 1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '99 08 01';
date
SELECT date '1/18/1999';
ERROR: date/time field value out of range: "1/18/1999"
+LINE 1: SELECT date '1/18/1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '18/1/1999';
date
SELECT date '99-Jan-08';
ERROR: date/time field value out of range: "99-Jan-08"
+LINE 1: SELECT date '99-Jan-08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-Jan-08';
date
SELECT date '99-08-Jan';
ERROR: invalid input syntax for type date: "99-08-Jan"
+LINE 1: SELECT date '99-08-Jan';
+ ^
SELECT date '1999-08-Jan';
ERROR: invalid input syntax for type date: "1999-08-Jan"
+LINE 1: SELECT date '1999-08-Jan';
+ ^
SELECT date '99 Jan 08';
ERROR: date/time field value out of range: "99 Jan 08"
+LINE 1: SELECT date '99 Jan 08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999 Jan 08';
date
SELECT date '99 08 Jan';
ERROR: invalid input syntax for type date: "99 08 Jan"
+LINE 1: SELECT date '99 08 Jan';
+ ^
SELECT date '1999 08 Jan';
date
------------
SELECT date '99-01-08';
ERROR: date/time field value out of range: "99-01-08"
+LINE 1: SELECT date '99-01-08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-01-08';
date
SELECT date '99-08-01';
ERROR: date/time field value out of range: "99-08-01"
+LINE 1: SELECT date '99-08-01';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-08-01';
date
SELECT date '99 01 08';
ERROR: date/time field value out of range: "99 01 08"
+LINE 1: SELECT date '99 01 08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999 01 08';
date
SELECT date '99 08 01';
ERROR: date/time field value out of range: "99 08 01"
+LINE 1: SELECT date '99 08 01';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999 08 01';
date
SELECT date '18/1/1999';
ERROR: date/time field value out of range: "18/1/1999"
+LINE 1: SELECT date '18/1/1999';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '01/02/03';
date
SELECT date '99-Jan-08';
ERROR: date/time field value out of range: "99-Jan-08"
+LINE 1: SELECT date '99-Jan-08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-Jan-08';
date
SELECT date '99-08-Jan';
ERROR: invalid input syntax for type date: "99-08-Jan"
+LINE 1: SELECT date '99-08-Jan';
+ ^
SELECT date '1999-08-Jan';
ERROR: invalid input syntax for type date: "1999-08-Jan"
+LINE 1: SELECT date '1999-08-Jan';
+ ^
SELECT date '99 Jan 08';
ERROR: invalid input syntax for type date: "99 Jan 08"
+LINE 1: SELECT date '99 Jan 08';
+ ^
SELECT date '1999 Jan 08';
date
------------
SELECT date '99 08 Jan';
ERROR: invalid input syntax for type date: "99 08 Jan"
+LINE 1: SELECT date '99 08 Jan';
+ ^
SELECT date '1999 08 Jan';
date
------------
SELECT date '99-01-08';
ERROR: date/time field value out of range: "99-01-08"
+LINE 1: SELECT date '99-01-08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-01-08';
date
SELECT date '99-08-01';
ERROR: date/time field value out of range: "99-08-01"
+LINE 1: SELECT date '99-08-01';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999-08-01';
date
SELECT date '99 01 08';
ERROR: date/time field value out of range: "99 01 08"
+LINE 1: SELECT date '99 01 08';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999 01 08';
date
SELECT date '99 08 01';
ERROR: date/time field value out of range: "99 08 01"
+LINE 1: SELECT date '99 08 01';
+ ^
HINT: Perhaps you need a different "datestyle" setting.
SELECT date '1999 08 01';
date
SELECT 'mauve'::rainbow;
ERROR: invalid input value for enum rainbow: "mauve"
+LINE 1: SELECT 'mauve'::rainbow;
+ ^
--
-- Basic table creation, row selection
--
-- no such relation
select * from nonesuch;
ERROR: relation "nonesuch" does not exist
+LINE 1: select * from nonesuch;
+ ^
-- missing target list
select from pg_database;
ERROR: syntax error at or near "from"
-- no such relation
delete from nonesuch;
ERROR: relation "nonesuch" does not exist
+LINE 1: delete from nonesuch;
+ ^
--
-- DROP
-- no such operator
drop operator === (int4);
ERROR: missing argument
+LINE 1: drop operator === (int4);
+ ^
HINT: Use NONE to denote the missing argument of a unary operator.
-- no such operator by that name
drop operator === (int4, int4);
-- no such type1
drop operator = (nonesuch);
ERROR: missing argument
+LINE 1: drop operator = (nonesuch);
+ ^
HINT: Use NONE to denote the missing argument of a unary operator.
-- no such type1
drop operator = ( , int4);
-- test for over and under flow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
ERROR: value out of range: overflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
ERROR: value out of range: overflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
ERROR: value out of range: underflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
ERROR: value out of range: underflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
+ ^
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type real: " "
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type real: "xyz"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type real: "5.0.0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type real: "5 . 0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type real: "5. 0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
ERROR: invalid input syntax for type real: " - 3.0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type real: "123 5"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float4;
float4
-- bad special inputs
SELECT 'N A N'::float4;
ERROR: invalid input syntax for type real: "N A N"
+LINE 1: SELECT 'N A N'::float4;
+ ^
SELECT 'NaN x'::float4;
ERROR: invalid input syntax for type real: "NaN x"
+LINE 1: SELECT 'NaN x'::float4;
+ ^
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float4;
+ ^
SELECT 'Infinity'::float4 + 100.0;
?column?
----------
-- test for over and under flow
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
ERROR: value out of range: overflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
ERROR: value out of range: overflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
ERROR: value out of range: underflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
ERROR: value out of range: underflow
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70');
+ ^
-- bad input
INSERT INTO FLOAT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type real: ""
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type real: " "
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type real: "xyz"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type real: "5.0.0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type real: "5 . 0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type real: "5. 0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
ERROR: invalid input syntax for type real: " - 3.0"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0');
+ ^
INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type real: "123 5"
+LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float4;
float4
-- bad special inputs
SELECT 'N A N'::float4;
ERROR: invalid input syntax for type real: "N A N"
+LINE 1: SELECT 'N A N'::float4;
+ ^
SELECT 'NaN x'::float4;
ERROR: invalid input syntax for type real: "NaN x"
+LINE 1: SELECT 'NaN x'::float4;
+ ^
SELECT ' INFINITY x'::float4;
ERROR: invalid input syntax for type real: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float4;
+ ^
SELECT 'Infinity'::float4 + 100.0;
?column?
----------
-- test for underflow and overflow handling
SELECT '10e400'::float8;
ERROR: "10e400" is out of range for type double precision
+LINE 1: SELECT '10e400'::float8;
+ ^
SELECT '-10e400'::float8;
ERROR: "-10e400" is out of range for type double precision
+LINE 1: SELECT '-10e400'::float8;
+ ^
SELECT '10e-400'::float8;
ERROR: "10e-400" is out of range for type double precision
+LINE 1: SELECT '10e-400'::float8;
+ ^
SELECT '-10e-400'::float8;
ERROR: "-10e-400" is out of range for type double precision
+LINE 1: SELECT '-10e-400'::float8;
+ ^
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type double precision: " "
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type double precision: "xyz"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type double precision: "5.0.0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type double precision: "5 . 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type double precision: "5. 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
ERROR: invalid input syntax for type double precision: " - 3"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type double precision: "123 5"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float8;
float8
-- bad special inputs
SELECT 'N A N'::float8;
ERROR: invalid input syntax for type double precision: "N A N"
+LINE 1: SELECT 'N A N'::float8;
+ ^
SELECT 'NaN x'::float8;
ERROR: invalid input syntax for type double precision: "NaN x"
+LINE 1: SELECT 'NaN x'::float8;
+ ^
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float8;
+ ^
SELECT 'Infinity'::float8 + 100.0;
?column?
----------
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
ERROR: "-10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
ERROR: "10e-400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
ERROR: "-10e-400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
+ ^
-- maintain external table consistency across platforms
-- delete all values and reinsert well-behaved ones
DELETE FROM FLOAT8_TBL;
-- test for underflow and overflow handling
SELECT '10e400'::float8;
ERROR: "10e400" is out of range for type double precision
+LINE 1: SELECT '10e400'::float8;
+ ^
SELECT '-10e400'::float8;
ERROR: "-10e400" is out of range for type double precision
+LINE 1: SELECT '-10e400'::float8;
+ ^
SELECT '10e-400'::float8;
float8
--------
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type double precision: " "
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type double precision: "xyz"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type double precision: "5.0.0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type double precision: "5 . 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type double precision: "5. 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
ERROR: invalid input syntax for type double precision: " - 3"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type double precision: "123 5"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float8;
float8
-- bad special inputs
SELECT 'N A N'::float8;
ERROR: invalid input syntax for type double precision: "N A N"
+LINE 1: SELECT 'N A N'::float8;
+ ^
SELECT 'NaN x'::float8;
ERROR: invalid input syntax for type double precision: "NaN x"
+LINE 1: SELECT 'NaN x'::float8;
+ ^
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float8;
+ ^
SELECT 'Infinity'::float8 + 100.0;
?column?
----------
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
ERROR: "-10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
-- maintain external table consistency across platforms
-- test for underflow and overflow handling
SELECT '10e400'::float8;
ERROR: "10e400" is out of range for type double precision
+LINE 1: SELECT '10e400'::float8;
+ ^
SELECT '-10e400'::float8;
ERROR: "-10e400" is out of range for type double precision
+LINE 1: SELECT '-10e400'::float8;
+ ^
SELECT '10e-400'::float8;
float8
--------
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type double precision: " "
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type double precision: "xyz"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type double precision: "5.0.0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type double precision: "5 . 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type double precision: "5. 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
ERROR: invalid input syntax for type double precision: " - 3"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type double precision: "123 5"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float8;
float8
-- bad special inputs
SELECT 'N A N'::float8;
ERROR: invalid input syntax for type double precision: "N A N"
+LINE 1: SELECT 'N A N'::float8;
+ ^
SELECT 'NaN x'::float8;
ERROR: invalid input syntax for type double precision: "NaN x"
+LINE 1: SELECT 'NaN x'::float8;
+ ^
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float8;
+ ^
SELECT 'Infinity'::float8 + 100.0;
?column?
----------
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
ERROR: "-10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
-- maintain external table consistency across platforms
-- test for underflow and overflow handling
SELECT '10e400'::float8;
ERROR: "10e400" is out of range for type double precision
+LINE 1: SELECT '10e400'::float8;
+ ^
SELECT '-10e400'::float8;
ERROR: "-10e400" is out of range for type double precision
+LINE 1: SELECT '-10e400'::float8;
+ ^
SELECT '10e-400'::float8;
ERROR: "10e-400" is out of range for type double precision
+LINE 1: SELECT '10e-400'::float8;
+ ^
SELECT '-10e-400'::float8;
ERROR: "-10e-400" is out of range for type double precision
+LINE 1: SELECT '-10e-400'::float8;
+ ^
-- bad input
INSERT INTO FLOAT8_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type double precision: ""
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type double precision: " "
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' ');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
ERROR: invalid input syntax for type double precision: "xyz"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
ERROR: invalid input syntax for type double precision: "5.0.0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
ERROR: invalid input syntax for type double precision: "5 . 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
ERROR: invalid input syntax for type double precision: "5. 0"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
ERROR: invalid input syntax for type double precision: " - 3"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for type double precision: "123 5"
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5');
+ ^
-- special inputs
SELECT 'NaN'::float8;
float8
-- bad special inputs
SELECT 'N A N'::float8;
ERROR: invalid input syntax for type double precision: "N A N"
+LINE 1: SELECT 'N A N'::float8;
+ ^
SELECT 'NaN x'::float8;
ERROR: invalid input syntax for type double precision: "NaN x"
+LINE 1: SELECT 'NaN x'::float8;
+ ^
SELECT ' INFINITY x'::float8;
ERROR: invalid input syntax for type double precision: " INFINITY x"
+LINE 1: SELECT ' INFINITY x'::float8;
+ ^
SELECT 'Infinity'::float8 + 100.0;
?column?
----------
-- test for over- and underflow
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
ERROR: "10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
ERROR: "-10e400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
ERROR: "10e-400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400');
+ ^
INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
ERROR: "-10e-400" is out of range for type double precision
+LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400');
+ ^
-- maintain external table consistency across platforms
-- delete all values and reinsert well-behaved ones
DELETE FROM FLOAT8_TBL;
-- should fail in mdy mode:
SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
ERROR: date/time field value out of range: "27/12/2001 04:05:06.789-08"
+LINE 1: SELECT timestamp with time zone '27/12/2001 04:05:06.789-08'...
+ ^
HINT: Perhaps you need a different "datestyle" setting.
set datestyle to dmy;
SELECT timestamp with time zone '27/12/2001 04:05:06.789-08';
SELECT CAST(time with time zone '01:02-08' AS interval) AS "+00:01";
ERROR: cannot cast type time with time zone to interval
LINE 1: SELECT CAST(time with time zone '01:02-08' AS interval) AS "...
- ^
+ ^
SELECT CAST(interval '02:03' AS time with time zone) AS "02:03:00-08";
ERROR: cannot cast type interval to time with time zone
LINE 1: SELECT CAST(interval '02:03' AS time with time zone) AS "02:...
- ^
+ ^
SELECT time with time zone '01:30-08' - interval '02:01' AS "23:29:00-08";
23:29:00-08
-------------
-- check that CIDR rejects invalid input:
INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/30', '192.168.1.226');
ERROR: invalid cidr value: "192.168.1.2/30"
+LINE 1: INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/30', '192.1...
+ ^
DETAIL: Value has bits set to right of mask.
INSERT INTO INET_TBL (c, i) VALUES ('1234::1234::1234', '::1.2.3.4');
ERROR: invalid input syntax for type cidr: "1234::1234::1234"
+LINE 1: INSERT INTO INET_TBL (c, i) VALUES ('1234::1234::1234', '::1...
+ ^
-- check that CIDR rejects invalid input when converting from text:
INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/30'), '192.168.1.226');
ERROR: invalid cidr value: "192.168.1.2/30"
+LINE 1: INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/30'), ...
+ ^
DETAIL: Value has bits set to right of mask.
INSERT INTO INET_TBL (c, i) VALUES (cidr('ffff:ffff:ffff:ffff::/24'), '::192.168.1.226');
ERROR: invalid cidr value: "ffff:ffff:ffff:ffff::/24"
+LINE 1: INSERT INTO INET_TBL (c, i) VALUES (cidr('ffff:ffff:ffff:fff...
+ ^
DETAIL: Value has bits set to right of mask.
SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL;
ten | cidr | inet
--
insert into inserttest (col1, col2, col3) values (DEFAULT, DEFAULT);
ERROR: INSERT has more target columns than expressions
+LINE 1: insert into inserttest (col1, col2, col3) values (DEFAULT, D...
+ ^
insert into inserttest (col1, col2, col3) values (1, 2);
ERROR: INSERT has more target columns than expressions
+LINE 1: insert into inserttest (col1, col2, col3) values (1, 2);
+ ^
insert into inserttest (col1) values (1, 2);
ERROR: INSERT has more expressions than target columns
+LINE 1: insert into inserttest (col1) values (1, 2);
+ ^
insert into inserttest (col1) values (DEFAULT, DEFAULT);
ERROR: INSERT has more expressions than target columns
+LINE 1: insert into inserttest (col1) values (DEFAULT, DEFAULT);
+ ^
select * from inserttest;
col1 | col2 | col3
------+------+---------
INSERT INTO INT2_TBL(f1) VALUES (' -1234');
INSERT INTO INT2_TBL(f1) VALUES ('34.5');
ERROR: invalid input syntax for integer: "34.5"
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('34.5');
+ ^
-- largest and smallest values
INSERT INTO INT2_TBL(f1) VALUES ('32767');
INSERT INTO INT2_TBL(f1) VALUES ('-32767');
-- bad input values -- should give errors
INSERT INTO INT2_TBL(f1) VALUES ('100000');
ERROR: value "100000" is out of range for type smallint
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('100000');
+ ^
INSERT INTO INT2_TBL(f1) VALUES ('asdf');
ERROR: invalid input syntax for integer: "asdf"
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('asdf');
+ ^
INSERT INTO INT2_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for integer: " "
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES (' ');
+ ^
INSERT INTO INT2_TBL(f1) VALUES ('- 1234');
ERROR: invalid input syntax for integer: "- 1234"
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('- 1234');
+ ^
INSERT INTO INT2_TBL(f1) VALUES ('4 444');
ERROR: invalid input syntax for integer: "4 444"
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('4 444');
+ ^
INSERT INTO INT2_TBL(f1) VALUES ('123 dt');
ERROR: invalid input syntax for integer: "123 dt"
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('123 dt');
+ ^
INSERT INTO INT2_TBL(f1) VALUES ('');
ERROR: invalid input syntax for integer: ""
+LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('');
+ ^
SELECT '' AS five, * FROM INT2_TBL;
five | f1
------+--------
INSERT INTO INT4_TBL(f1) VALUES (' -123456');
INSERT INTO INT4_TBL(f1) VALUES ('34.5');
ERROR: invalid input syntax for integer: "34.5"
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('34.5');
+ ^
-- largest and smallest values
INSERT INTO INT4_TBL(f1) VALUES ('2147483647');
INSERT INTO INT4_TBL(f1) VALUES ('-2147483647');
-- bad input values -- should give errors
INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
ERROR: value "1000000000000" is out of range for type integer
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('1000000000000');
+ ^
INSERT INTO INT4_TBL(f1) VALUES ('asdf');
ERROR: invalid input syntax for integer: "asdf"
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('asdf');
+ ^
INSERT INTO INT4_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for integer: " "
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' ');
+ ^
INSERT INTO INT4_TBL(f1) VALUES (' asdf ');
ERROR: invalid input syntax for integer: " asdf "
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' asdf ');
+ ^
INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
ERROR: invalid input syntax for integer: "- 1234"
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('- 1234');
+ ^
INSERT INTO INT4_TBL(f1) VALUES ('123 5');
ERROR: invalid input syntax for integer: "123 5"
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('123 5');
+ ^
INSERT INTO INT4_TBL(f1) VALUES ('');
ERROR: invalid input syntax for integer: ""
+LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('');
+ ^
SELECT '' AS five, * FROM INT4_TBL;
five | f1
------+-------------
-- bad inputs
INSERT INTO INT8_TBL(q1) VALUES (' ');
ERROR: invalid input syntax for integer: " "
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' ');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('xxx');
ERROR: invalid input syntax for integer: "xxx"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('xxx');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
ERROR: value "3908203590239580293850293850329485" is out of range for type bigint
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('39082035902395802938502938...
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
ERROR: value "-1204982019841029840928340329840934" is out of range for type bigint
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340...
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('- 123');
ERROR: invalid input syntax for integer: "- 123"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('- 123');
+ ^
INSERT INTO INT8_TBL(q1) VALUES (' 345 5');
ERROR: invalid input syntax for integer: " 345 5"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' 345 5');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('');
ERROR: invalid input syntax for integer: ""
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('');
+ ^
SELECT * FROM INT8_TBL;
q1 | q2
------------------+-------------------
select '-9223372036854775809'::int8;
ERROR: value "-9223372036854775809" is out of range for type bigint
+LINE 1: select '-9223372036854775809'::int8;
+ ^
select '9223372036854775807'::int8;
int8
---------------------
select '9223372036854775808'::int8;
ERROR: value "9223372036854775808" is out of range for type bigint
+LINE 1: select '9223372036854775808'::int8;
+ ^
-- bad inputs
INSERT INTO INT8_TBL(q1) VALUES (' ');
ERROR: invalid input syntax for integer: " "
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' ');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('xxx');
ERROR: invalid input syntax for integer: "xxx"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('xxx');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
ERROR: value "3908203590239580293850293850329485" is out of range for type bigint
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('39082035902395802938502938...
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
ERROR: value "-1204982019841029840928340329840934" is out of range for type bigint
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340...
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('- 123');
ERROR: invalid input syntax for integer: "- 123"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('- 123');
+ ^
INSERT INTO INT8_TBL(q1) VALUES (' 345 5');
ERROR: invalid input syntax for integer: " 345 5"
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' 345 5');
+ ^
INSERT INTO INT8_TBL(q1) VALUES ('');
ERROR: invalid input syntax for integer: ""
+LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('');
+ ^
SELECT * FROM INT8_TBL;
q1 | q2
------------------+-------------------
select '-9223372036854775809'::int8;
ERROR: value "-9223372036854775809" is out of range for type bigint
+LINE 1: select '-9223372036854775809'::int8;
+ ^
select '9223372036854775807'::int8;
int8
---------------------
select '9223372036854775808'::int8;
ERROR: value "9223372036854775808" is out of range for type bigint
+LINE 1: select '9223372036854775808'::int8;
+ ^
-- badly formatted interval
INSERT INTO INTERVAL_TBL (f1) VALUES ('badly formatted interval');
ERROR: invalid input syntax for type interval: "badly formatted interval"
+LINE 1: INSERT INTO INTERVAL_TBL (f1) VALUES ('badly formatted inter...
+ ^
INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago');
ERROR: invalid input syntax for type interval: "@ 30 eons ago"
+LINE 1: INSERT INTO INTERVAL_TBL (f1) VALUES ('@ 30 eons ago');
+ ^
-- test interval operators
SELECT '' AS ten, * FROM INTERVAL_TBL;
ten | f1
SELECT '1 second 2 seconds'::interval; -- error
ERROR: invalid input syntax for type interval: "1 second 2 seconds"
+LINE 1: SELECT '1 second 2 seconds'::interval;
+ ^
SELECT '10 milliseconds 20 milliseconds'::interval; -- error
ERROR: invalid input syntax for type interval: "10 milliseconds 20 milliseconds"
+LINE 1: SELECT '10 milliseconds 20 milliseconds'::interval;
+ ^
SELECT '5.5 seconds 3 milliseconds'::interval; -- error
ERROR: invalid input syntax for type interval: "5.5 seconds 3 milliseconds"
+LINE 1: SELECT '5.5 seconds 3 milliseconds'::interval;
+ ^
SELECT '1:20:05 5 microseconds'::interval; -- error
ERROR: invalid input syntax for type interval: "1:20:05 5 microseconds"
+LINE 1: SELECT '1:20:05 5 microseconds'::interval;
+ ^
-- bad values for parser testing
INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)');
ERROR: invalid input syntax for type lseg: "(3asdf,2 ,3,4r2)"
+LINE 1: INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)');
+ ^
INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4');
ERROR: invalid input syntax for type lseg: "[1,2,3, 4"
+LINE 1: INSERT INTO LSEG_TBL VALUES ('[1,2,3, 4');
+ ^
INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]');
ERROR: invalid input syntax for type lseg: "[(,2),(3,4)]"
+LINE 1: INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]');
+ ^
INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)');
ERROR: invalid input syntax for type lseg: "[(1,2),(3,4)"
+LINE 1: INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)');
+ ^
select * from LSEG_TBL;
s
-------------------------------
INSERT INTO num_input_test(n1) VALUES ('-555.50');
INSERT INTO num_input_test(n1) VALUES ('NaN ');
ERROR: invalid input syntax for type numeric: "NaN "
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('NaN ');
+ ^
INSERT INTO num_input_test(n1) VALUES (' nan');
ERROR: invalid input syntax for type numeric: " nan"
+LINE 1: INSERT INTO num_input_test(n1) VALUES (' nan');
+ ^
-- bad inputs
INSERT INTO num_input_test(n1) VALUES (' ');
ERROR: invalid input syntax for type numeric: " "
+LINE 1: INSERT INTO num_input_test(n1) VALUES (' ');
+ ^
INSERT INTO num_input_test(n1) VALUES (' 1234 %');
ERROR: invalid input syntax for type numeric: " 1234 %"
+LINE 1: INSERT INTO num_input_test(n1) VALUES (' 1234 %');
+ ^
INSERT INTO num_input_test(n1) VALUES ('xyz');
ERROR: invalid input syntax for type numeric: "xyz"
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('xyz');
+ ^
INSERT INTO num_input_test(n1) VALUES ('- 1234');
ERROR: invalid input syntax for type numeric: "- 1234"
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('- 1234');
+ ^
INSERT INTO num_input_test(n1) VALUES ('5 . 0');
ERROR: invalid input syntax for type numeric: "5 . 0"
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('5 . 0');
+ ^
INSERT INTO num_input_test(n1) VALUES ('5. 0 ');
ERROR: invalid input syntax for type numeric: "5. 0 "
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('5. 0 ');
+ ^
INSERT INTO num_input_test(n1) VALUES ('');
ERROR: invalid input syntax for type numeric: ""
+LINE 1: INSERT INTO num_input_test(n1) VALUES ('');
+ ^
INSERT INTO num_input_test(n1) VALUES (' N aN ');
ERROR: invalid input syntax for type numeric: " N aN "
+LINE 1: INSERT INTO num_input_test(n1) VALUES (' N aN ');
+ ^
SELECT * FROM num_input_test;
n1
---------
-- bad inputs
INSERT INTO OID_TBL(f1) VALUES ('');
ERROR: invalid input syntax for type oid: ""
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('');
+ ^
INSERT INTO OID_TBL(f1) VALUES (' ');
ERROR: invalid input syntax for type oid: " "
+LINE 1: INSERT INTO OID_TBL(f1) VALUES (' ');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
ERROR: invalid input syntax for type oid: "asdfasd"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('asdfasd');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
ERROR: invalid input syntax for type oid: "99asdfasd"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('99asdfasd');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('5 d');
ERROR: invalid input syntax for type oid: "5 d"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('5 d');
+ ^
INSERT INTO OID_TBL(f1) VALUES (' 5d');
ERROR: invalid input syntax for type oid: " 5d"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES (' 5d');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('5 5');
ERROR: invalid input syntax for type oid: "5 5"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('5 5');
+ ^
INSERT INTO OID_TBL(f1) VALUES (' - 500');
ERROR: invalid input syntax for type oid: " - 500"
+LINE 1: INSERT INTO OID_TBL(f1) VALUES (' - 500');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935');
ERROR: value "32958209582039852935" is out of range for type oid
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('32958209582039852935');
+ ^
INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385');
ERROR: value "-23582358720398502385" is out of range for type oid
+LINE 1: INSERT INTO OID_TBL(f1) VALUES ('-23582358720398502385');
+ ^
SELECT '' AS six, * FROM OID_TBL;
six | f1
-----+------------
-- bad values for parser testing
INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]');
ERROR: invalid input syntax for type path: "[(,2),(3,4)]"
+LINE 1: INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]');
+ ^
INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)');
ERROR: invalid input syntax for type path: "[(1,2),(3,4)"
+LINE 1: INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)');
+ ^
SELECT f1 FROM PATH_TBL;
f1
---------------------------
-- bad format points
INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf');
ERROR: invalid input syntax for type point: "asdfasdf"
+LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf');
+ ^
INSERT INTO POINT_TBL(f1) VALUES ('10.0,10.0');
INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)');
ERROR: invalid input syntax for type point: "(10.0 10.0)"
+LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)');
+ ^
INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0');
ERROR: invalid input syntax for type point: "(10.0,10.0"
+LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0');
+ ^
SELECT '' AS six, * FROM POINT_TBL;
six | f1
-----+------------
-- bad polygon input strings
INSERT INTO POLYGON_TBL(f1) VALUES ('0.0');
ERROR: invalid input syntax for type polygon: "0.0"
+LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('0.0');
+ ^
INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0 0.0');
ERROR: invalid input syntax for type polygon: "(0.0 0.0"
+LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0 0.0');
+ ^
INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2)');
ERROR: invalid input syntax for type polygon: "(0,1,2)"
+LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2)');
+ ^
INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2,3');
ERROR: invalid input syntax for type polygon: "(0,1,2,3"
+LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('(0,1,2,3');
+ ^
INSERT INTO POLYGON_TBL(f1) VALUES ('asdf');
ERROR: invalid input syntax for type polygon: "asdf"
+LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('asdf');
+ ^
SELECT '' AS four, * FROM POLYGON_TBL;
four | f1
------+---------------------
-- Table doesn't exist, the creation hasn't been committed yet
SELECT * FROM pxtest2;
ERROR: relation "pxtest2" does not exist
+LINE 1: SELECT * FROM pxtest2;
+ ^
-- There should be two prepared transactions
SELECT gid FROM pg_prepared_xacts;
gid
COMMIT PREPARED 'regress-two';
SELECT * FROM pxtest3;
ERROR: relation "pxtest3" does not exist
+LINE 1: SELECT * FROM pxtest3;
+ ^
-- There should be no prepared transactions
SELECT gid FROM pg_prepared_xacts;
gid
-- supposed to fail with ERROR
select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
ERROR: function expression in FROM cannot refer to other relations of same query level
+LINE 1: select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
+ ^
-- function in subselect
select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
fooid | f2
-- badly formatted reltimes
INSERT INTO RELTIME_TBL (f1) VALUES ('badly formatted reltime');
ERROR: invalid input syntax for type reltime: "badly formatted reltime"
+LINE 1: INSERT INTO RELTIME_TBL (f1) VALUES ('badly formatted reltim...
+ ^
INSERT INTO RELTIME_TBL (f1) VALUES ('@ 30 eons ago');
ERROR: invalid input syntax for type reltime: "@ 30 eons ago"
+LINE 1: INSERT INTO RELTIME_TBL (f1) VALUES ('@ 30 eons ago');
+ ^
-- test reltime operators
SELECT '' AS six, * FROM RELTIME_TBL;
six | f1
select '(Joe)'::fullname; -- bad
ERROR: malformed record literal: "(Joe)"
+LINE 1: select '(Joe)'::fullname;
+ ^
DETAIL: Too few columns.
select '(Joe,,)'::fullname; -- bad
ERROR: malformed record literal: "(Joe,,)"
+LINE 1: select '(Joe,,)'::fullname;
+ ^
DETAIL: Too many columns.
create temp table quadtable(f1 int, q quad);
insert into quadtable values (1, ((3.3,4.4),(5.5,6.6)));
FROM tmp
ORDER BY string4 using <, two using <, ten using <;
ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
+LINE 1: SELECT DISTINCT ON (string4, ten) string4, two, ten
+ ^
SELECT DISTINCT ON (string4, ten) string4, ten, two
FROM tmp
ORDER BY string4 using <, ten using >, two using <;
-- errors: ungrouped column references
SELECT a FROM test_having HAVING min(a) < max(a);
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT a FROM test_having HAVING min(a) < max(a);
+ ^
SELECT 1 AS one FROM test_having HAVING a > 1;
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT 1 AS one FROM test_having HAVING a > 1;
+ ^
-- the really degenerate case: need not scan table at all
SELECT 1 AS one FROM test_having HAVING 1 > 2;
one
-- errors: ungrouped column references
SELECT a FROM test_having HAVING min(a) < max(a);
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT a FROM test_having HAVING min(a) < max(a);
+ ^
SELECT 1 AS one FROM test_having HAVING a > 1;
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT 1 AS one FROM test_having HAVING a > 1;
+ ^
-- the really degenerate case: need not scan table at all
SELECT 1 AS one FROM test_having HAVING 1 > 2;
one
-- errors: ungrouped column references
SELECT a FROM test_having HAVING min(a) < max(a);
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT a FROM test_having HAVING min(a) < max(a);
+ ^
SELECT 1 AS one FROM test_having HAVING a > 1;
ERROR: column "test_having.a" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: SELECT 1 AS one FROM test_having HAVING a > 1;
+ ^
-- the really degenerate case: need not scan table at all
SELECT 1 AS one FROM test_having HAVING 1 > 2;
one
-- failure expected
SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b;
count
-- failure expected
SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
count
-- failure expected
SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b;
count
-- failure expected
SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
count
-- failure expected
SELECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(*) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(*) FROM test_missing_target GROUP BY b ORDER BY b;
count
-- failure expected
SELECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
ERROR: column "test_missing_target.b" must appear in the GROUP BY clause or be used in an aggregate function
+LINE 1: ...ECT count(a) FROM test_missing_target GROUP BY a ORDER BY b;
+ ^
-- w/o existing GROUP BY target and w/o existing same ORDER BY target
SELECT count(b) FROM test_missing_target GROUP BY b/2 ORDER BY b/2;
count
\c
SELECT * FROM temptest;
ERROR: relation "temptest" does not exist
+LINE 1: SELECT * FROM temptest;
+ ^
-- Test ON COMMIT DELETE ROWS
CREATE TEMP TABLE temptest(col int) ON COMMIT DELETE ROWS;
BEGIN;
COMMIT;
SELECT * FROM temptest;
ERROR: relation "temptest" does not exist
+LINE 1: SELECT * FROM temptest;
+ ^
BEGIN;
CREATE TEMP TABLE temptest(col) ON COMMIT DROP AS SELECT 1;
SELECT * FROM temptest;
COMMIT;
SELECT * FROM temptest;
ERROR: relation "temptest" does not exist
+LINE 1: SELECT * FROM temptest;
+ ^
-- ON COMMIT is only allowed for TEMP
CREATE TABLE temptest(col int) ON COMMIT DELETE ROWS;
ERROR: ON COMMIT can only be used on temporary tables
-- this should fail (the timezone offset is not known)
INSERT INTO TIME_TBL VALUES ('15:36:39 America/New_York');
ERROR: invalid input syntax for type time: "15:36:39 America/New_York"
+LINE 1: INSERT INTO TIME_TBL VALUES ('15:36:39 America/New_York');
+ ^
SELECT f1 AS "Time" FROM TIME_TBL;
Time
-------------
-- Obsolete special values
INSERT INTO TIMESTAMP_TBL VALUES ('invalid');
ERROR: date/time value "invalid" is no longer supported
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('invalid');
+ ^
INSERT INTO TIMESTAMP_TBL VALUES ('current');
ERROR: date/time value "current" is no longer supported
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('current');
+ ^
-- Postgres v6.0 standard output format
INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST');
INSERT INTO TIMESTAMP_TBL VALUES ('Invalid Abstime');
ERROR: date/time value "Invalid Abstime" is no longer supported
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('Invalid Abstime');
+ ^
INSERT INTO TIMESTAMP_TBL VALUES ('Undefined Abstime');
ERROR: date/time value "Undefined Abstime" is no longer supported
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('Undefined Abstime');
+ ^
-- Variations on Postgres v6.1 standard output format
INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST');
INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST');
-- this fails (even though TZ is a no-op, we still look it up)
INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/Does_not_exist');
ERROR: time zone "america/does_not_exist" not recognized
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('19970710 173201 America/D...
+ ^
-- Check date conversion and date arithmetic
INSERT INTO TIMESTAMP_TBL VALUES ('1997-06-10 18:32:01 PDT');
INSERT INTO TIMESTAMP_TBL VALUES ('Feb 10 17:32:01 1997');
INSERT INTO TIMESTAMP_TBL VALUES ('Feb 28 17:32:01 1997');
INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997');
ERROR: date/time field value out of range: "Feb 29 17:32:01 1997"
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('Feb 29 17:32:01 1997');
+ ^
INSERT INTO TIMESTAMP_TBL VALUES ('Mar 01 17:32:01 1997');
INSERT INTO TIMESTAMP_TBL VALUES ('Dec 30 17:32:01 1997');
INSERT INTO TIMESTAMP_TBL VALUES ('Dec 31 17:32:01 1997');
-- Currently unsupported syntax and ranges
INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097');
ERROR: time zone displacement out of range: "Feb 16 17:32:01 -0097"
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 -0097');
+ ^
INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC');
ERROR: timestamp out of range: "Feb 16 17:32:01 5097 BC"
+LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('Feb 16 17:32:01 5097 BC')...
+ ^
SELECT '' AS "64", d1 FROM TIMESTAMP_TBL;
64 | d1
----+-----------------------------
-- Obsolete special values
INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid');
ERROR: date/time value "invalid" is no longer supported
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid');
+ ^
INSERT INTO TIMESTAMPTZ_TBL VALUES ('current');
ERROR: date/time value "current" is no longer supported
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('current');
+ ^
-- Postgres v6.0 standard output format
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Invalid Abstime');
ERROR: date/time value "Invalid Abstime" is no longer supported
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('Invalid Abstime');
+ ^
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Undefined Abstime');
ERROR: date/time value "Undefined Abstime" is no longer supported
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('Undefined Abstime');
+ ^
-- Variations on Postgres v6.1 standard output format
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.000001 1997 PST');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01.999999 1997 PST');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America/Does_not_exist');
ERROR: time zone "america/does_not_exist" not recognized
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('19970710 173201 America...
+ ^
SELECT '19970710 173201' AT TIME ZONE 'America/Does_not_exist';
ERROR: time zone "America/Does_not_exist" not recognized
-- Daylight saving time for timestamps beyond 32-bit time_t range.
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 28 17:32:01 1997');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997');
ERROR: date/time field value out of range: "Feb 29 17:32:01 1997"
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 29 17:32:01 1997');
+ ^
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mar 01 17:32:01 1997');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 30 17:32:01 1997');
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Dec 31 17:32:01 1997');
-- Currently unsupported syntax and ranges
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097');
ERROR: time zone displacement out of range: "Feb 16 17:32:01 -0097"
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 -0097')...
+ ^
INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC');
ERROR: timestamp out of range: "Feb 16 17:32:01 5097 BC"
+LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('Feb 16 17:32:01 5097 BC...
+ ^
-- Alternative field order that we've historically supported (sort of)
-- with regular and POSIXy timezone specs
SELECT 'Wed Jul 11 10:51:14 America/New_York 2001'::timestamptz;
-- this should fail (the timezone offset is not known)
INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York');
ERROR: invalid input syntax for type time with time zone: "15:36:39 America/New_York"
+LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York');
+ ^
SELECT f1 AS "Time TZ" FROM TIMETZ_TBL;
Time TZ
----------------
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["bad time specifications" ""]');
ERROR: invalid input syntax for type abstime: "bad time specifications"
+LINE 2: VALUES ('["bad time specifications" ""]');
+ ^
INSERT INTO TINTERVAL_TBL (f1)
VALUES ('["" "infinity"]');
ERROR: invalid input syntax for type abstime: ""
+LINE 2: VALUES ('["" "infinity"]');
+ ^
-- test tinterval operators
SELECT '' AS five, * FROM TINTERVAL_TBL;
five | f1
SELECT * FROM bar; -- shouldn't exist
ERROR: relation "bar" does not exist
+LINE 1: SELECT * FROM bar;
+ ^
SELECT * FROM barbaz; -- should be empty
a
---
SAVEPOINT one;
INSERT into bar VALUES (1);
ERROR: relation "bar" does not exist
+LINE 1: INSERT into bar VALUES (1);
+ ^
ROLLBACK TO one;
RELEASE SAVEPOINT one;
SAVEPOINT two;
DROP TABLE truncate_a;
SELECT nextval('truncate_a_id1'); -- fail, seq should have been dropped
ERROR: relation "truncate_a_id1" does not exist
+LINE 1: SELECT nextval('truncate_a_id1');
+ ^
-- errors
select '31:12:'::txid_snapshot;
ERROR: invalid input for txid_snapshot: "31:12:"
+LINE 1: select '31:12:'::txid_snapshot;
+ ^
select '0:1:'::txid_snapshot;
ERROR: invalid input for txid_snapshot: "0:1:"
+LINE 1: select '0:1:'::txid_snapshot;
+ ^
select '12:13:0'::txid_snapshot;
ERROR: invalid input for txid_snapshot: "12:13:0"
+LINE 1: select '12:13:0'::txid_snapshot;
+ ^
select '12:16:14,13'::txid_snapshot;
ERROR: invalid input for txid_snapshot: "12:16:14,13"
+LINE 1: select '12:16:14,13'::txid_snapshot;
+ ^
select '12:16:14,14'::txid_snapshot;
ERROR: invalid input for txid_snapshot: "12:16:14,14"
+LINE 1: select '12:16:14,14'::txid_snapshot;
+ ^
create temp table snapshot_test (
nr integer,
snap txid_snapshot
SELECT txid_snapshot '1:9223372036854775808:3';
ERROR: invalid input for txid_snapshot: "1:9223372036854775808:3"
+LINE 1: SELECT txid_snapshot '1:9223372036854775808:3';
+ ^
-- too long
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111F');
ERROR: invalid input syntax for uuid: "11111111-1111-1111-1111-111111111111F"
+LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-111...
+ ^
-- too short
INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-1111-11111111111}');
ERROR: invalid input syntax for uuid: "{11111111-1111-1111-1111-11111111111}"
+LINE 1: INSERT INTO guid1(guid_field) VALUES('{11111111-1111-1111-11...
+ ^
-- valid data but invalid format
INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-1111-111111111111');
ERROR: invalid input syntax for uuid: "111-11111-1111-1111-1111-111111111111"
+LINE 1: INSERT INTO guid1(guid_field) VALUES('111-11111-1111-1111-11...
+ ^
INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222 ');
ERROR: invalid input syntax for uuid: "{22222222-2222-2222-2222-222222222222 "
+LINE 1: INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-22...
+ ^
-- invalid data
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G111-111111111111');
ERROR: invalid input syntax for uuid: "11111111-1111-1111-G111-111111111111"
+LINE 1: INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-G11...
+ ^
INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
ERROR: invalid input syntax for uuid: "11+11111-1111-1111-1111-111111111111"
+LINE 1: INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-111...
+ ^
--inserting three input formats
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
INSERT INTO xmltest VALUES (2, '<value>two</value>');
INSERT INTO xmltest VALUES (3, '<wrong');
ERROR: invalid XML content
+LINE 1: INSERT INTO xmltest VALUES (3, '<wrong');
+ ^
DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag wrong line 1
<wrong
^
^
SELECT xmlconcat('bad', '<syntax');
ERROR: invalid XML content
+LINE 1: SELECT xmlconcat('bad', '<syntax');
+ ^
DETAIL: Entity: line 1: parser error : Couldn't find end of Start Tag syntax line 1
<syntax
^
SELECT '<>' IS NOT DOCUMENT;
ERROR: invalid XML content
+LINE 1: SELECT '<>' IS NOT DOCUMENT;
+ ^
DETAIL: Entity: line 1: parser error : StartTag: invalid element name
<>
^
EXECUTE foo ('bad');
ERROR: invalid XML document
+LINE 1: EXECUTE foo ('bad');
+ ^
DETAIL: Entity: line 1: parser error : Start tag expected, '<' not found
bad
^
);
INSERT INTO xmltest VALUES (1, '<value>one</value>');
ERROR: unsupported XML feature
+LINE 1: INSERT INTO xmltest VALUES (1, '<value>one</value>');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
INSERT INTO xmltest VALUES (2, '<value>two</value>');
ERROR: unsupported XML feature
+LINE 1: INSERT INTO xmltest VALUES (2, '<value>two</value>');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
INSERT INTO xmltest VALUES (3, '<wrong');
ERROR: unsupported XML feature
+LINE 1: INSERT INTO xmltest VALUES (3, '<wrong');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT * FROM xmltest;
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlconcat('hello', 'you');
ERROR: unsupported XML feature
+LINE 1: SELECT xmlconcat('hello', 'you');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlconcat(1, 2);
^
SELECT xmlconcat('bad', '<syntax');
ERROR: unsupported XML feature
+LINE 1: SELECT xmlconcat('bad', '<syntax');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
ERROR: unsupported XML feature
+LINE 1: SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1" standa...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1" standalone="no"?><bar/>');
ERROR: unsupported XML feature
+LINE 1: SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlelement(name element,
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot(xml '<foo/>', version no value, standalone no...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot(xml '<foo/>', version '2.0');
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot(xml '<foo/>', version '2.0');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot(xml '<foo/>', version no value, standalone ye...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot(xml '<?xml version="1.1"?><foo/>', version no value, standalone yes);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot(xml '<?xml version="1.1"?><foo/>', version no...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value, standalone no value);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>', version no value);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlroot('<?xml version="1.1" standalone="yes"?><foo/>...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlroot (
SELECT xmlserialize(content 'good' as char(10));
ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(content 'good' as char(10));
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlserialize(document 'bad' as text);
ERROR: unsupported XML feature
+LINE 1: SELECT xmlserialize(document 'bad' as text);
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xml '<foo>bar</foo>' IS DOCUMENT;
ERROR: unsupported XML feature
+LINE 1: SELECT xml '<foo>bar</foo>' IS DOCUMENT;
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
ERROR: unsupported XML feature
+LINE 1: SELECT xml '<foo>bar</foo><bar>foo</bar>' IS DOCUMENT;
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xml '<abc/>' IS NOT DOCUMENT;
ERROR: unsupported XML feature
+LINE 1: SELECT xml '<abc/>' IS NOT DOCUMENT;
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xml 'abc' IS NOT DOCUMENT;
ERROR: unsupported XML feature
+LINE 1: SELECT xml 'abc' IS NOT DOCUMENT;
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT '<>' IS NOT DOCUMENT;
ERROR: unsupported XML feature
+LINE 1: SELECT '<>' IS NOT DOCUMENT;
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlagg(data) FROM xmltest;
HINT: You need to rebuild PostgreSQL using --with-libxml.
PREPARE foo (xml) AS SELECT xmlconcat('<foo/>', $1);
ERROR: unsupported XML feature
+LINE 1: PREPARE foo (xml) AS SELECT xmlconcat('<foo/>', $1);
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SET XML OPTION DOCUMENT;
CREATE VIEW xmlview1 AS SELECT xmlcomment('test');
CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you');
ERROR: unsupported XML feature
+LINE 1: CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
CREATE VIEW xmlview3 AS SELECT xmlelement(name element, xmlattributes (1 as ":one:", 'deuce' as two), 'content&');
HINT: You need to rebuild PostgreSQL using --with-libxml.
CREATE VIEW xmlview7 AS SELECT xmlroot(xml '<foo/>', version no value, standalone yes);
ERROR: unsupported XML feature
+LINE 1: CREATE VIEW xmlview7 AS SELECT xmlroot(xml '<foo/>', version...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
CREATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as char(10));
ERROR: unsupported XML feature
+LINE 1: ...EATE VIEW xmlview8 AS SELECT xmlserialize(content 'good' as ...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
CREATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as text);
ERROR: unsupported XML feature
+LINE 1: ...EATE VIEW xmlview9 AS SELECT xmlserialize(content 'good' as ...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT table_name, view_definition FROM information_schema.views
SELECT xpath('', '<!-- error -->');
ERROR: unsupported XML feature
+LINE 1: SELECT xpath('', '<!-- error -->');
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
ERROR: unsupported XML feature
+LINE 1: SELECT xpath('//text()', '<local:data xmlns:local="http://12...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
ERROR: unsupported XML feature
+LINE 1: SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="ht...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
ERROR: unsupported XML feature
+LINE 1: SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'...
+ ^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
AS 'SELECT $2;';
ERROR: there is no parameter $2
-CONTEXT: SQL function "test1"
+LINE 2: AS 'SELECT $2;';
+ ^
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
AS 'a', 'b';
ERROR: only one AS item needed for language "sql"