SELECT '[]'::JSON;
SELECT '['::JSON;
SELECT '[1,2,3]'::JSON;
SELECT '[1,2,3]'::JSON::TEXT;
SELECT '[1,2,3  ]'::JSON;
SELECT '[1,2,3  ,4]'::JSON;
SELECT '[1,2,3  ,4.0]'::JSON;
SELECT '[1,2,3  ,4]'::JSON;
SELECT 'true'::JSON;
SELECT 'true'::TEXT::JSON;
SELECT 'false'::JSON;
SELECT 'null'::JSON;
SELECT '1.1'::JSON;
SELECT '"string"'::JSON;
SELECT '{"key1":"value1", "key2":"value2"}'::JSON;
SELECT '{"key1":"value1", "key2":"value2"}'::JSON;
SELECT 15::JSON;

SELECT json_get_type('[]');
SELECT json_get_type('{}');
SELECT json_get_type('true');
SELECT json_get_type('false');
SELECT json_get_type('null');

CREATE TABLE testjson (j JSON);
INSERT INTO testjson VALUES ('[1,2,3,4]');
INSERT INTO testjson VALUES ('{"key":"value"}');
INSERT INTO testjson VALUES ('{"key":"value"');
INSERT INTO testjson VALUES ('');
INSERT INTO testjson VALUES ('""');
INSERT INTO testjson VALUES ('true');
INSERT INTO testjson VALUES ('false');
INSERT INTO testjson VALUES ('null');
INSERT INTO testjson VALUES ('[]');
INSERT INTO testjson VALUES ('{}');

SELECT * FROM testjson;

SELECT json_get_type(j) FROM testjson;


-- to_json: null
SELECT to_json(NULL);
SELECT to_json(NULL::INT);
SELECT to_json(NULL::INT[]);
SELECT to_json(NULL::VOID);
SELECT to_json(NULL::MONEY);
SELECT to_json('null'::text); -- should yield '"null"', not 'null'
SELECT json_get_type(to_json(NULL));
SELECT json_get_type(to_json(NULL::INT));
SELECT json_get_type(to_json(NULL::VOID));
SELECT json_get_type(to_json(NULL::MONEY));

-- to_json: string
SELECT to_json('');
SELECT json_get_type(to_json(''));
SELECT to_json('string');
SELECT json_get_type(to_json('string'));
SELECT to_json('string'::VARCHAR);
SELECT json_get_type(to_json('string'::VARCHAR));
SELECT to_json('string'::VARCHAR(3));
SELECT json_get_type(to_json('string'::VARCHAR(3)));
SELECT to_json('{1,2,3}'::TEXT);
SELECT json_get_type(to_json('{1,2,3}'::TEXT));
SELECT to_json('"doubly-encoded"'::JSON);
SELECT json_get_type(to_json('"doubly-encoded"'::JSON));
SELECT to_json('"nested quotes"'::TEXT);
SELECT json_get_type(to_json('"nested quotes"'::TEXT));
SELECT to_json('"nested quotes"'::TEXT)::TEXT::JSON;
SELECT json_get_type(to_json('"nested quotes"'::TEXT)::TEXT::JSON);
SELECT to_json('h'::CHAR);
SELECT json_get_type(to_json('h'::CHAR));
SELECT to_json('hello world'::CHAR);
SELECT json_get_type(to_json('hello world'::CHAR));
SELECT to_json('hello world!'::CHAR(11));
SELECT json_get_type(to_json('hello world!'::CHAR(11)));

-- to_json: number
SELECT to_json(12345);
SELECT to_json(12345.678);
SELECT json_get_type(to_json(12345));
SELECT json_get_type(to_json(12345.678));
SELECT to_json(+1.23e100::FLOAT);
SELECT to_json('+1.23e100'::FLOAT);
SELECT to_json(123456789012345678901234567890123456789012345678901234567890.123456789012345678901234567890123456789012345678901234567890);
SELECT json_get_type(to_json(123456789012345678901234567890123456789012345678901234567890.123456789012345678901234567890123456789012345678901234567890));
SELECT to_json('100'::MONEY);

-- to_json: bool
SELECT to_json(TRUE);
SELECT to_json(FALSE);
SELECT to_json(1=1);
SELECT to_json(1=2);
SELECT json_get_type(to_json(TRUE));
SELECT json_get_type(to_json(FALSE));
SELECT json_get_type(to_json(1=1));
SELECT json_get_type(to_json(1=2));
SELECT to_json(TRUE::TEXT)::TEXT = '"' || TRUE || '"';
SELECT to_json(FALSE::TEXT)::TEXT = '"' || FALSE || '"';

-- to_json: array
SELECT to_json(ARRAY[1,2,3]);
-- more tests are in array_to_json.sql

-- to_json: invalid types
SELECT to_json(row(1,2));
SELECT to_json('127.0.0.1'::INET);


-- from_json: null
SELECT from_json(null);
SELECT from_json(NULL::TEXT);
SELECT from_json(NULL::JSON);

-- from_json: string
SELECT from_json('"valid string"');

-- Use unaligned output so results are consistent between PostgreSQL 8 and 9.
\a
SELECT from_json($$ "hello\nworld" $$);
\a

SELECT from_json($$ "hello\u0000world" $$);

-- from_json: number
SELECT from_json('123');
SELECT from_json('123')::INT;
SELECT from_json('123.456')::INT;
SELECT from_json('123.456')::FLOAT;
SELECT from_json('123e-38');
SELECT from_json('123e-38')::FLOAT;
SELECT from_json('1.23e-38')::FLOAT;
SELECT from_json('1.23e-38');
SELECT from_json('1.23e-38')::NUMERIC;

-- from_json: bool
SELECT from_json('true')::JSON;
SELECT from_json('true');
SELECT from_json('true')::BOOLEAN;
SELECT from_json('true')::BOOLEAN::JSON;
SELECT from_json('true')::BOOLEAN::TEXT::JSON;
SELECT from_json('false')::BOOLEAN::TEXT::JSON;
SELECT from_json('false');
SELECT from_json('f');
SELECT from_json('t');
SELECT from_json('f'::BOOLEAN::TEXT);
SELECT from_json('f'::BOOLEAN::TEXT::JSON);
SELECT from_json('t'::BOOLEAN::TEXT::JSON);

-- from_json: object
SELECT from_json('{"key": "value"}');

-- from_json: array
SELECT from_json('[1,2,3]');

-- from_json: invalid
SELECT from_json('invalid');

CREATE TABLE sample_query_text (json JSON);
INSERT INTO sample_query_text VALUES ($$
"SELECT pg_catalog.quote_ident(c.relname) FROM pg_catalog.pg_class c WHERE c.relkind IN ('i') AND substring(pg_catalog.quote_ident(c.relname),1,0)='' AND pg_catalog.pg_table_is_visible(c.oid) AND c.relnamespace <> (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')\nUNION\nSELECT pg_catalog.quote_ident(n.nspname) || '.' FROM pg_catalog.pg_namespace n WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,0)='' AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,0) = substring('',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) > 1\nUNION\nSELECT pg_catalog.quote_ident(n.nspname) || '.' || pg_catalog.quote_ident(c.relname) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n WHERE c.relnamespace = n.oid AND c.relkind IN ('i') AND substring(pg_catalog.quote_ident(n.nspname) || '.' || pg_catalog.quote_ident(c.relname),1,0)='' AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,0) = substring('',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1) AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,0) = substring('',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1\n UNION SELECT 'ON' UNION SELECT 'CONCURRENTLY'\nLIMIT 1000"
$$);

SELECT md5(from_json(json)) FROM sample_query_text;
