diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 483abb6..2c035b1 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -50,6 +50,8 @@ else
 	@$(missing) bison $< $@
 endif
 
+json_scanner.h: json_scanner.c ;
+
 json_scanner.c: json_scanner.l
 ifdef FLEX
 	$(FLEX) $(FLEXFLAGS) -o'$@' $<
@@ -59,4 +61,6 @@ endif
 
 json_parser.o keywords.o parser.o: json_parser.h
 
+json.c: json_parser.h json_scanner.h
+
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 13e5391..9a3979e 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -20,7 +20,9 @@
 #include "json_parser.h"
 #include "json_scanner.h"
 
-static Json *json_parse(const char *str, int len, bool validateOnly);
+static Json *json_parse(const char *str, int len);
+static bool json_validate(const char *str, int len);
+static Json *json_parse_or_validate(const char *str, int len, bool *validate);
 static void json_free(Json *node);
 static void append_json(StringInfo buf, const Json *node, int indent);
 static void append_indent(StringInfo buf, int indent);
@@ -43,11 +45,12 @@ json_in(PG_FUNCTION_ARGS)
 
 	json = (jsontype *) cstring_to_text(s);
 
-	/*
-	 * Parse the data to check if it is a JSON data.  Assume that
-	 * ERROR occurred if parsing failed.
-	 */
-	json_parse(VARDATA_ANY(json), VARSIZE_ANY_EXHDR(json), true);
+	if (!json_validate(VARDATA_ANY(json), VARSIZE_ANY_EXHDR(json)))
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				 errmsg("invalid input syntax for JSON")));
+	}
 
 	PG_RETURN_JSON_P(json);
 }
@@ -68,7 +71,12 @@ json_recv(PG_FUNCTION_ARGS)
 	int			nbytes;
 
 	str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
-	json_parse(str, nbytes, true);
+	if (!json_validate(str, nbytes))
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
+				 errmsg("invalid input syntax for JSON")));
+	}
 
 	result = (jsontype *) cstring_to_text_with_len(str, nbytes);
 	pfree(str);
@@ -82,12 +90,31 @@ json_send(PG_FUNCTION_ARGS)
 	return textsend(fcinfo);
 }
 
+/* json_validate(text).  Renamed to avoid clashing
+ * with the C function json_validate. */
+PG_FUNCTION_INFO_V1(json_validate_f);
+Datum		json_validate_f(PG_FUNCTION_ARGS);
+Datum
+json_validate_f(PG_FUNCTION_ARGS)
+{
+	jsontype   *t = PG_GETARG_JSON_P(0);
+	bool		ret;
+
+	ret = json_validate(VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t));
+	PG_RETURN_BOOL(ret);
+}
+
 Datum
 text_to_json(PG_FUNCTION_ARGS)
 {
 	text	   *t = PG_GETARG_TEXT_PP(0);
 
-	json_parse(VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t), true);
+	if (!json_validate(VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t)))
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				 errmsg("invalid input syntax for JSON")));
+	}
 
 	PG_RETURN_JSON_P((jsontype *) t);
 }
@@ -106,7 +133,7 @@ json_pretty(PG_FUNCTION_ARGS)
 	Json		   *node;
 	StringInfoData	buf;
 
-	node = json_parse(VARDATA_ANY(json), VARSIZE_ANY_EXHDR(json), false);
+	node = json_parse(VARDATA_ANY(json), VARSIZE_ANY_EXHDR(json));
 	initStringInfo(&buf);
 	append_json(&buf, node, 0);
 	json_free(node);
@@ -115,17 +142,42 @@ json_pretty(PG_FUNCTION_ARGS)
 }
 
 /*
- * json_parse -- parse and validate the JSON text.
+ * json_parse -- parse a JSON text.
+ *
+ * Returns NULL if the input is not valid JSON.
+ */
+static Json *
+json_parse(const char *str, int len)
+{
+	return json_parse_or_validate(str, len, NULL);
+}
+
+/*
+ * json_validate -- validate a JSON text.
+ */
+static bool
+json_validate(const char *str, int len)
+{
+	bool valid;
+	json_parse_or_validate(str, len, &valid);
+	return valid;
+}
+
+/*
+ * Helper for json_parse and json_validate.
  *
- * Only validates the input when validateOnly is true, or returns JSON
- * tree on false.
+ * If validate is NULL, this function returns a parse tree
+ *      (or NULL if the JSON was invalid).
+ * If validate is not NULL, this function passes a boolean through
+ *      *validate to indicate whether the JSON was valid.
  */
 static Json *
-json_parse(const char *str, int len, bool validateOnly)
+json_parse_or_validate(const char *str, int len, bool *validate)
 {
 	yyscan_t		scanner;
 	char		   *scanbuf;
 	JsonParser		parser;
+	int				rc;
 
 	scanbuf = (char *) palloc(len + 2);
 	memcpy(scanbuf, str, len);
@@ -133,8 +185,8 @@ json_parse(const char *str, int len, bool validateOnly)
 
 	/* initialize parser and scanner */
 	memset(&parser, 0, sizeof(parser));
-	parser.validateOnly = validateOnly;
-	if (!validateOnly)
+	parser.validateOnly = !!validate;
+	if (!validate)
 		initStringInfo(&parser.buf);
 
 	json_yylex_init(&scanner);
@@ -142,7 +194,7 @@ json_parse(const char *str, int len, bool validateOnly)
 	json_yy_scan_buffer(scanbuf, len + 2, scanner);
 
 	/* parse the JSON text */
-	json_yyparse(scanner);
+	rc = json_yyparse(scanner);
 
 	/* cleanup */
 	json_yylex_destroy(scanner);
@@ -150,6 +202,9 @@ json_parse(const char *str, int len, bool validateOnly)
 	if (parser.buf.data)
 		pfree(parser.buf.data);
 
+	if (validate)
+		*validate = (rc == 0);
+
 	return parser.json;
 }
 
@@ -279,9 +334,7 @@ append_indent(StringInfo buf, int indent)
 void
 json_yyerror(yyscan_t scanner, const char *error)
 {
-	ereport(ERROR,
-			(errcode(ERRCODE_SYNTAX_ERROR),
-			 errmsg("syntax error in json: %s", error)));
+	
 }
 
 void *
diff --git a/src/backend/utils/adt/json_scanner.l b/src/backend/utils/adt/json_scanner.l
index f4ed64f..acc0c6d 100644
--- a/src/backend/utils/adt/json_scanner.l
+++ b/src/backend/utils/adt/json_scanner.l
@@ -52,7 +52,7 @@ true		{ return T_JSON_TRUE; }
 false		{ return T_JSON_FALSE; }
 
 	/* Number */
-0|-?([1-9][0-9]*(\.[0-9]+)?|0\.[0-9]+)([Ee][+-]?[0-9]+)?	{
+-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee][+-]?[0-9]+)?	{
 		JsonParser *parser = getParser();
 		if (!parser->validateOnly)
 			yylval->number = pstrdup(yytext);
@@ -66,7 +66,7 @@ false		{ return T_JSON_FALSE; }
 		if (!parser->validateOnly)
 			appendStringInfoString(&parser->buf, yytext);
 	}
-<str>([^\"\\[:cntrl:]]+|\\u[0-9A-Fa-f]{4}|\\[\"\\/bfnrt]) {
+<str>([^\"\\\x00-\x1F]+|\\u[0-9A-Fa-f]{4}|\\[\"\\/bfnrt]) {
 		JsonParser *parser = getParser();
 		if (!parser->validateOnly)
 			appendStringInfoString(&parser->buf, yytext);
@@ -82,7 +82,9 @@ false		{ return T_JSON_FALSE; }
 		BEGIN(INITIAL);
 		return T_JSON_STRING;
 	}
-<str>.|\n	{ return T_JSON_INVALID; }	/* unterminated string */
+		/* unterminated string */
+<str>.|\n		{ return T_JSON_INVALID; }
+<str><<EOF>>	{ return T_JSON_INVALID; }
 
 	/* Invalid */
 . return T_JSON_INVALID;
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index b3d3da5..ae49f53 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -4472,6 +4472,7 @@ DATA(insert OID = 3831 (  text				PGNSP PGUID 12 1 0 0 f f f t f i 1 0 25 "321"
 DESCR("serialize a JSON value to a character string");
 DATA(insert OID = 3832 (  json_pretty		PGNSP PGUID 12 1 0 0 f f f t f i 1 0 25 "321" _null_ _null_ _null_ _null_ json_pretty _null_ _null_ _null_ ));
 DESCR("convert a JSON to a human readable text");
+DATA(insert OID = 3833 (  json_validate		PGNSP PGUID 12 1 0 0 f f f t f i 1 0 16	 "25"		  _null_ _null_ _null_					_null_ json_validate_f _null_ _null_ _null_ ));
 
 /* uuid */
 DATA(insert OID = 2952 (  uuid_in		   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 2950 "2275" _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ ));
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index 1237714..6bf7a9f 100644
--- a/src/test/regress/expected/json.out
+++ b/src/test/regress/expected/json.out
@@ -1,3 +1,365 @@
+-- Get our json_test_strings table.
+SET client_min_messages = warning;
+\set ECHO none
+RESET client_min_messages;
+-- Trivial cast-to-JSON tests
+SELECT '[]'::JSON;
+ json 
+------
+ []
+(1 row)
+
+SELECT '['::JSON;
+ERROR:  invalid input syntax for JSON
+LINE 1: SELECT '['::JSON;
+               ^
+SELECT '[1,2,3]'::JSON;
+  json   
+---------
+ [1,2,3]
+(1 row)
+
+SELECT '[1,2,3]'::JSON::TEXT;
+  text   
+---------
+ [1,2,3]
+(1 row)
+
+SELECT '[1,2,3  ]'::JSON;
+   json    
+-----------
+ [1,2,3  ]
+(1 row)
+
+SELECT '[1,2,3  ,4]'::JSON;
+    json     
+-------------
+ [1,2,3  ,4]
+(1 row)
+
+SELECT '[1,2,3  ,4.0]'::JSON;
+     json      
+---------------
+ [1,2,3  ,4.0]
+(1 row)
+
+SELECT '[1,2,3  ,4]'::JSON;
+    json     
+-------------
+ [1,2,3  ,4]
+(1 row)
+
+SELECT 'true'::JSON;
+ json 
+------
+ true
+(1 row)
+
+SELECT 'true'::TEXT::JSON;
+ json 
+------
+ true
+(1 row)
+
+SELECT 'false'::JSON;
+ json  
+-------
+ false
+(1 row)
+
+SELECT 'null'::JSON;
+ json 
+------
+ null
+(1 row)
+
+SELECT '1.1'::JSON;
+ json 
+------
+ 1.1
+(1 row)
+
+SELECT '"string"'::JSON;
+   json   
+----------
+ "string"
+(1 row)
+
+SELECT '{"key1":"value1", "key2":"value2"}'::JSON;
+                json                
+------------------------------------
+ {"key1":"value1", "key2":"value2"}
+(1 row)
+
+SELECT '{"key1":"value1", "key2":"value2"}'::JSON;
+                json                
+------------------------------------
+ {"key1":"value1", "key2":"value2"}
+(1 row)
+
+SELECT 15::JSON;
+ERROR:  cannot cast type integer to json
+LINE 1: SELECT 15::JSON;
+                 ^
+-- Make sure all the right strings validate
+SELECT string, json_validate(string) FROM json_test_strings;
+                          string                          | json_validate 
+----------------------------------------------------------+---------------
+                                                          | f
+                                                          | f
+ "                                                        | f
+ [,]                                                      | f
+ [)                                                       | f
+ []]                                                      | f
+ [}                                                       | f
+ {,}                                                      | f
+ {]                                                       | f
+ ["1":2]                                                  | f
+ [1,2,]                                                   | f
+ [1:2}                                                    | f
+ {"1":2,}                                                 | f
+ {1:2}                                                    | f
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"], [7 ]}]}          | f
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"], [7]}]}           | f
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]      | f
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]]     | f
+ {"1":2, "3":4                                            | f
+ "1\u2"                                                   | f
+ [,2]                                                     | f
+ "3                                                       | f
+ "3" "4"                                                  | f
+ [3[4]                                                    | f
+ [3[4]]                                                   | f
+ [3, [4, [5], 6] 7, 8 9]                                  | f
+ [3, [4, [5], 6] 7, 8, 9]                                 | f
+ [3, [4, [5], 6], 7, 8 9]                                 | f
+ {"hello":true, "bye":false, null}                        | f
+ {"hello":true, "bye":false, null:null}                   | f
+ "hi                                                      | f
+ "hi"""                                                   | f
+ {"hi": "bye"]                                            | f
+ "\uD800\uD800"                                           | t
+ "\uD800\uDBFF"                                           | t
+ "\UD834\UDD1E"                                           | f
+ "\uDB00"                                                 | t
+ "\uDB00\uDBFF"                                           | t
+ "\uFFFE"                                                 | t
+ "\uFFFF"                                                 | t
+ .                                                        | f
+ ""                                                       | t
+ []                                                       | t
+ {}                                                       | t
+ +.                                                       | f
+ 0.5                                                      | t
+ 0.e1                                                     | f
+ {"1":{}}                                                 | t
+ {"1":2}                                                  | t
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"]}]}                | t
+ {"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]}     | t
+ 1234                                                     | t
+ -1234                                                    | t
+ {"1":2, "3":4}                                           | t
+ +1234                                                    | f
+ ++1234                                                   | f
+ 123.456e14234                                            | t
+ 123.456e-14234                                           | t
+ 123.456e+14234                                           | t
+ 123.e-14234                                              | f
+ "1\u2000"                                                | t
+ "1\u20001"                                               | t
+ 2                                                        | t
+ .246e-14234                                              | f
+ .2e-14234                                                | f
+ 3                                                        | t
+ .3                                                       | f
+ "3"                                                      | t
+ [3]                                                      | t
+ +3.                                                      | f
+ 3.2e+1                                                   | t
+ [3, [4]]                                                 | t
+ [3, [4, [5]]]                                            | t
+ [3, [4, [5], 6]]                                         | t
+ [3, [4, [5], 6], 7]                                      | t
+ [3, [4, [5], 6], 7, 8]                                   | t
+ [3, [4, [5], 6], 7, 8, 9]                                | t
+ +3.5                                                     | f
+ .3e                                                      | f
+ .3e1                                                     | f
+ .3e-1                                                    | f
+ .3e+1                                                    | f
+ 3.e1                                                     | f
+ 3.e+1                                                    | f
+ 3e+1                                                     | t
+ .5                                                       | f
+ +.5                                                      | f
+ .5e+1                                                    | f
+ [ 7]                                                     | t
+ [7 ]                                                     | t
+ [7]                                                      | t
+ .e-14234                                                 | f
+ "hello"                                                  | t
+ ["hello"]                                                | t
+ ["hello", "bye"]                                         | t
+ ["hello", "bye\n"]                                       | t
+ ["hello", "bye\n\r\t"]                                   | t
+ ["hello", "bye\n\r\t\b"]                                 | t
+ ["hello", "bye\n\r\t\b",true]                            | t
+ ["hello", "bye\n\r\t\b",true , false]                    | t
+ ["hello", "bye\n\r\t\b",true , false,    null]           | t
+ ["hello", "bye\n\r\t\v"]                                 | f
+ {"hello":true}                                           | t
+ {"hello":true, "bye":false}                              | t
+ {"hello":true, "bye":false, "foo":["one","two","three"]} | t
+ "hi"                                                     | t
+ ["hi"]                                                   | t
+ ["hi", "bye"]                                            | t
+ {"hi": "bye"}                                            | t
+ ["hi", "bye", 3]                                         | t
+ ["hi", "bye[", 3]                                        | t
+ "\u0007"                                                 | t
+ "\u0008"                                                 | t
+ "\u0009"                                                 | t
+ "\u0010"                                                 | t
+ "\u0020"                                                 | t
+ "\u10000"                                                | t
+ "\u1234"                                                 | t
+ "\u99999"                                                | t
+ "\ud800\udc00"                                           | t
+ "\uD800\uDC00"                                           | t
+ "\uD834\uDD1E"                                           | t
+ "\uDBFF\uDFFF"                                           | t
+ "\uFFFD"                                                 | t
+ "\uFFFF"                                                 | t
+ hello                                                    | f
+ [32, 1]                                                  | t
+ [32,                                                     | f
+ "\uD800\uDC00"                                           | t
+ "\n"                                                     | t
+ "hello"                                                  | t
+ "hello\u0009world"                                       | t
+ "hello"                                                  | t
+ "hello\n"                                                | t
+ "hello"                                                  | t
+ 3                                                        | t
+ 3.                                                       | f
+ .3                                                       | f
+ 0.3                                                      | t
+ 0.3e                                                     | f
+ 0.3e+                                                    | f
+ 0.3e+5                                                   | t
+ 0.3e-5                                                   | t
+ 0.3e5                                                    | t
+ "hello"                                                  | t
+ +3                                                       | f
+ -3                                                       | t
+ -3.                                                      | f
+ -3.1                                                     | t
+ -0                                                       | t
+ -0.                                                      | f
+ -0.0                                                     | t
+ .5                                                       | f
+ 5.                                                       | f
+ 5.e1                                                     | f
+ 0.5                                                      | t
+ .3e1                                                     | f
+ .3e+1                                                    | f
+ .3e-1                                                    | f
+ .3e-1 .5                                                 | f
+ .3e-1.5                                                  | f
+ .3e+1.5                                                  | f
+ .3e+.                                                    | f
+ .3e+.5                                                   | f
+ .3e+1.5                                                  | f
+ 9.3e+1.5                                                 | f
+ 9.e+1.5                                                  | f
+ 9.e+                                                     | f
+ 9.e+1                                                    | f
+ "\""                                                     | t
+ "\"3.5"                                                  | t
+ "\"."                                                    | t
+ "\".".                                                   | f
+ "\"....."                                                | t
+ "\"\"\"\"""                                              | f
+ "newline                                                +| f
+ "                                                        | 
+ ["\"\"\"\"", .5]                                         | f
+ [.5]                                                     | f
+ ["\"\"\"\"", 0.5]                                        | t
+ ["\"\"\"\"", .5]                                         | f
+ ["\"\"\"\"",.5]                                          | f
+ ["\"",.5]                                                | f
+ ["\".5",.5]                                              | f
+ ["\".5",".5\"".5]                                        | f
+ ["\".5",".5\"", .5]                                      | f
+ ["\".5",".5\"",.5]                                       | f
+ ["\".5",".5\"",0.5]                                      | t
+ {"key":/*comment*/"value"}                               | f
+ {"key":/*comment"value"}                                 | f
+ {"key":"value"}/*                                        | f
+ {"key":"value"}/**/                                      | f
+ {"key":"value"}/***/                                     | f
+ {"key":"value"}/**//                                     | f
+ {"key":"value"}/**///                                    | f
+ {"key":"value"}/**///----                                | f
+ {"key":"value"}#                                         | f
+ {"key":"value"}#{                                        | f
+ {"key":"value"}#{}                                       | f
+ {"key":"value"}#,                                        | f
+ {"key":"value"/**/, "k2":"v2"}                           | f
+ "\u0027"                                                 | t
+ "hello\'"                                                | f
+ 'hello\''                                                | f
+ 'hello'                                                  | f
+ 'hell\'o'                                                | f
+ '\'hello'                                                | f
+ '\'hello\''                                              | f
+ \'hello\'                                                | f
+ 'hello\'                                                 | f
+ ['hello\']                                               | f
+ ['hello\'']                                              | f
+ ['hello"']                                               | f
+ ['hello\"']                                              | f
+ ['hello"o']                                              | f
+ ['"']                                                    | f
+ '"'                                                      | f
+ '"hello"'                                                | f
+ '"hello'                                                 | f
+ '"hi"'                                                   | f
+ "\x01"                                                   | f
+ "\x02"                                                   | f
+ "\x03"                                                   | f
+ "\x04"                                                   | f
+ "\x05"                                                   | f
+ "\x06"                                                   | f
+ "\x07"                                                   | f
+ "\x08"                                                   | f
+ "       "                                                | f
+ "                                                       +| f
+ "                                                        | 
+ "\x0B"                                                   | f
+ "\x0C"                                                   | f
+ "\r"                                                     | f
+ "\x0E"                                                   | f
+ "\x0F"                                                   | f
+ "\x10"                                                   | f
+ "\x11"                                                   | f
+ "\x12"                                                   | f
+ "\x13"                                                   | f
+ "\x14"                                                   | f
+ "\x15"                                                   | f
+ "\x16"                                                   | f
+ "\x17"                                                   | f
+ "\x18"                                                   | f
+ "\x19"                                                   | f
+ "\x1A"                                                   | f
+ "\x1B"                                                   | f
+ "\x1C"                                                   | f
+ "\x1D"                                                   | f
+ "\x1E"                                                   | f
+ "\x1F"                                                   | f
+ "\x7F"                                                   | t
+(251 rows)
+
 CREATE TABLE jsontest (
     id int,
     data json
@@ -6,15 +368,15 @@ INSERT INTO jsontest VALUES (1, 'null');
 INSERT INTO jsontest VALUES (2, '{"booleans":[true,false],"null":null}');
 INSERT INTO jsontest VALUES (3, E'[\n123.456,\n"string",\n{"name":"object"}\n]');
 INSERT INTO jsontest VALUES (101, 'wrong');
-ERROR:  syntax error in json: syntax error
+ERROR:  invalid input syntax for JSON
 LINE 1: INSERT INTO jsontest VALUES (101, 'wrong');
                                           ^
 INSERT INTO jsontest VALUES (101, '[wrong');
-ERROR:  syntax error in json: syntax error
+ERROR:  invalid input syntax for JSON
 LINE 1: INSERT INTO jsontest VALUES (101, '[wrong');
                                           ^
 INSERT INTO jsontest VALUES (101, '{"wrong":123}}');
-ERROR:  syntax error in json: syntax error
+ERROR:  invalid input syntax for JSON
 LINE 1: INSERT INTO jsontest VALUES (101, '{"wrong":123}}');
                                           ^
 SELECT *, json_pretty(data) FROM jsontest;
diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql
index 76a1d06..841052d 100644
--- a/src/test/regress/sql/json.sql
+++ b/src/test/regress/sql/json.sql
@@ -1,3 +1,32 @@
+-- Get our json_test_strings table.
+SET client_min_messages = warning;
+\set ECHO none
+\i sql/json_test_strings.sql
+\set ECHO all
+RESET client_min_messages;
+
+-- Trivial cast-to-JSON tests
+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;
+
+-- Make sure all the right strings validate
+SELECT string, json_validate(string) FROM json_test_strings;
+
 CREATE TABLE jsontest (
     id int,
     data json
diff --git a/src/test/regress/sql/json_test_strings.sql b/src/test/regress/sql/json_test_strings.sql
new file mode 100644
index 0000000..909a0da
--- /dev/null
+++ b/src/test/regress/sql/json_test_strings.sql
@@ -0,0 +1,264 @@
+/*
+ * This is not a test.  It is the set of
+ * test strings used by the json.sql test.
+ */
+
+CREATE TABLE json_test_strings (string TEXT);
+INSERT INTO json_test_strings VALUES ($$$$);
+INSERT INTO json_test_strings VALUES ($$  $$);
+INSERT INTO json_test_strings VALUES ($$"$$);
+INSERT INTO json_test_strings VALUES ($$[,]$$);
+INSERT INTO json_test_strings VALUES ($$[)$$);
+INSERT INTO json_test_strings VALUES ($$[]]$$);
+INSERT INTO json_test_strings VALUES ($$[}$$);
+INSERT INTO json_test_strings VALUES ($${,}$$);
+INSERT INTO json_test_strings VALUES ($${]$$);
+INSERT INTO json_test_strings VALUES ($$["1":2]$$);
+INSERT INTO json_test_strings VALUES ($$[1,2,]$$);
+INSERT INTO json_test_strings VALUES ($$[1:2}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2,}$$);
+INSERT INTO json_test_strings VALUES ($${1:2}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"], [7 ]}]}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"], [7]}]}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]]$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "3":4$$);
+INSERT INTO json_test_strings VALUES ($$"1\u2"$$);
+INSERT INTO json_test_strings VALUES ($$[,2]$$);
+INSERT INTO json_test_strings VALUES ($$"3$$);
+INSERT INTO json_test_strings VALUES ($$"3" "4"$$);
+INSERT INTO json_test_strings VALUES ($$[3[4]$$);
+INSERT INTO json_test_strings VALUES ($$[3[4]]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6] 7, 8 9]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6] 7, 8, 9]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6], 7, 8 9]$$);
+INSERT INTO json_test_strings VALUES ($${"hello":true, "bye":false, null}$$);
+INSERT INTO json_test_strings VALUES ($${"hello":true, "bye":false, null:null}$$);
+INSERT INTO json_test_strings VALUES ($$"hi$$);
+INSERT INTO json_test_strings VALUES ($$"hi"""$$);
+INSERT INTO json_test_strings VALUES ($${"hi": "bye"]$$);
+INSERT INTO json_test_strings VALUES ($$"\uD800\uD800"$$);
+INSERT INTO json_test_strings VALUES ($$"\uD800\uDBFF"$$);
+INSERT INTO json_test_strings VALUES ($$"\UD834\UDD1E"$$);
+INSERT INTO json_test_strings VALUES ($$"\uDB00"$$);
+INSERT INTO json_test_strings VALUES ($$"\uDB00\uDBFF"$$);
+INSERT INTO json_test_strings VALUES ($$"\uFFFE"$$);
+INSERT INTO json_test_strings VALUES ($$"\uFFFF"$$);
+INSERT INTO json_test_strings VALUES ($$.$$);
+INSERT INTO json_test_strings VALUES ($$""$$);
+INSERT INTO json_test_strings VALUES ($$[]$$);
+INSERT INTO json_test_strings VALUES ($${}$$);
+INSERT INTO json_test_strings VALUES ($$+.$$);
+INSERT INTO json_test_strings VALUES ($$0.5$$);
+INSERT INTO json_test_strings VALUES ($$0.e1$$);
+INSERT INTO json_test_strings VALUES ($${"1":{}}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"]}]}$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "2.5" : [3, 4, {}, {"5": ["6"], "7" :[8 ]}]}$$);
+INSERT INTO json_test_strings VALUES ($$1234$$);
+INSERT INTO json_test_strings VALUES ($$-1234$$);
+INSERT INTO json_test_strings VALUES ($${"1":2, "3":4}$$);
+INSERT INTO json_test_strings VALUES ($$+1234$$);
+INSERT INTO json_test_strings VALUES ($$++1234$$);
+INSERT INTO json_test_strings VALUES ($$123.456e14234$$);
+INSERT INTO json_test_strings VALUES ($$123.456e-14234$$);
+INSERT INTO json_test_strings VALUES ($$123.456e+14234$$);
+INSERT INTO json_test_strings VALUES ($$123.e-14234$$);
+INSERT INTO json_test_strings VALUES ($$"1\u2000"$$);
+INSERT INTO json_test_strings VALUES ($$"1\u20001"$$);
+INSERT INTO json_test_strings VALUES ($$2$$);
+INSERT INTO json_test_strings VALUES ($$.246e-14234$$);
+INSERT INTO json_test_strings VALUES ($$.2e-14234$$);
+INSERT INTO json_test_strings VALUES ($$3$$);
+INSERT INTO json_test_strings VALUES ($$.3$$);
+INSERT INTO json_test_strings VALUES ($$"3"$$);
+INSERT INTO json_test_strings VALUES ($$[3]$$);
+INSERT INTO json_test_strings VALUES ($$+3.$$);
+INSERT INTO json_test_strings VALUES ($$3.2e+1$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4]]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5]]]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6]]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6], 7]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6], 7, 8]$$);
+INSERT INTO json_test_strings VALUES ($$[3, [4, [5], 6], 7, 8, 9]$$);
+INSERT INTO json_test_strings VALUES ($$+3.5$$);
+INSERT INTO json_test_strings VALUES ($$.3e$$);
+INSERT INTO json_test_strings VALUES ($$.3e1$$);
+INSERT INTO json_test_strings VALUES ($$.3e-1$$);
+INSERT INTO json_test_strings VALUES ($$.3e+1$$);
+INSERT INTO json_test_strings VALUES ($$3.e1$$);
+INSERT INTO json_test_strings VALUES ($$3.e+1$$);
+INSERT INTO json_test_strings VALUES ($$3e+1$$);
+INSERT INTO json_test_strings VALUES ($$.5$$);
+INSERT INTO json_test_strings VALUES ($$+.5$$);
+INSERT INTO json_test_strings VALUES ($$.5e+1$$);
+INSERT INTO json_test_strings VALUES ($$[ 7]$$);
+INSERT INTO json_test_strings VALUES ($$[7 ]$$);
+INSERT INTO json_test_strings VALUES ($$[7]$$);
+INSERT INTO json_test_strings VALUES ($$.e-14234$$);
+INSERT INTO json_test_strings VALUES ($$"hello"$$);
+INSERT INTO json_test_strings VALUES ($$["hello"]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye"]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n"]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t"]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t\b"]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t\b",true]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t\b",true , false]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t\b",true , false,    null]$$);
+INSERT INTO json_test_strings VALUES ($$["hello", "bye\n\r\t\v"]$$);
+INSERT INTO json_test_strings VALUES ($${"hello":true}$$);
+INSERT INTO json_test_strings VALUES ($${"hello":true, "bye":false}$$);
+INSERT INTO json_test_strings VALUES ($${"hello":true, "bye":false, "foo":["one","two","three"]}$$);
+INSERT INTO json_test_strings VALUES ($$"hi"$$);
+INSERT INTO json_test_strings VALUES ($$["hi"]$$);
+INSERT INTO json_test_strings VALUES ($$["hi", "bye"]$$);
+INSERT INTO json_test_strings VALUES ($${"hi": "bye"}$$);
+INSERT INTO json_test_strings VALUES ($$["hi", "bye", 3]$$);
+INSERT INTO json_test_strings VALUES ($$["hi", "bye[", 3]$$);
+INSERT INTO json_test_strings VALUES ($$"\u0007"$$);
+INSERT INTO json_test_strings VALUES ($$"\u0008"$$);
+INSERT INTO json_test_strings VALUES ($$"\u0009"$$);
+INSERT INTO json_test_strings VALUES ($$"\u0010"$$);
+INSERT INTO json_test_strings VALUES ($$"\u0020"$$);
+INSERT INTO json_test_strings VALUES ($$"\u10000"$$);
+INSERT INTO json_test_strings VALUES ($$"\u1234"$$);
+INSERT INTO json_test_strings VALUES ($$"\u99999"$$);
+INSERT INTO json_test_strings VALUES ($$"\ud800\udc00"$$);
+INSERT INTO json_test_strings VALUES ($$"\uD800\uDC00"$$);
+INSERT INTO json_test_strings VALUES ($$"\uD834\uDD1E"$$);
+INSERT INTO json_test_strings VALUES ($$"\uDBFF\uDFFF"$$);
+INSERT INTO json_test_strings VALUES ($$"\uFFFD"$$);
+INSERT INTO json_test_strings VALUES ($$"\uFFFF"$$);
+INSERT INTO json_test_strings VALUES ($$hello$$);
+INSERT INTO json_test_strings VALUES ($$[32, 1]$$);
+INSERT INTO json_test_strings VALUES ($$[32, $$);
+INSERT INTO json_test_strings VALUES ($$"\uD800\uDC00"$$);
+INSERT INTO json_test_strings VALUES ($$"\n"$$);
+INSERT INTO json_test_strings VALUES ($$"hello"$$);
+INSERT INTO json_test_strings VALUES ($$"hello\u0009world"$$);
+INSERT INTO json_test_strings VALUES ($$"hello"$$);
+INSERT INTO json_test_strings VALUES ($$"hello\n"$$);
+INSERT INTO json_test_strings VALUES ($$"hello"$$);
+INSERT INTO json_test_strings VALUES ($$3$$);
+INSERT INTO json_test_strings VALUES ($$3.$$);
+INSERT INTO json_test_strings VALUES ($$.3$$);
+INSERT INTO json_test_strings VALUES ($$0.3$$);
+INSERT INTO json_test_strings VALUES ($$0.3e$$);
+INSERT INTO json_test_strings VALUES ($$0.3e+$$);
+INSERT INTO json_test_strings VALUES ($$0.3e+5$$);
+INSERT INTO json_test_strings VALUES ($$0.3e-5$$);
+INSERT INTO json_test_strings VALUES ($$0.3e5$$);
+INSERT INTO json_test_strings VALUES ($$"hello"$$);
+INSERT INTO json_test_strings VALUES ($$+3$$);
+INSERT INTO json_test_strings VALUES ($$-3$$);
+INSERT INTO json_test_strings VALUES ($$-3.$$);
+INSERT INTO json_test_strings VALUES ($$-3.1$$);
+INSERT INTO json_test_strings VALUES ($$-0$$);
+INSERT INTO json_test_strings VALUES ($$-0.$$);
+INSERT INTO json_test_strings VALUES ($$-0.0$$);
+INSERT INTO json_test_strings VALUES ($$.5$$);
+INSERT INTO json_test_strings VALUES ($$5.$$);
+INSERT INTO json_test_strings VALUES ($$5.e1$$);
+INSERT INTO json_test_strings VALUES ($$0.5$$);
+INSERT INTO json_test_strings VALUES ($$.3e1$$);
+INSERT INTO json_test_strings VALUES ($$.3e+1$$);
+INSERT INTO json_test_strings VALUES ($$.3e-1$$);
+INSERT INTO json_test_strings VALUES ($$.3e-1 .5$$);
+INSERT INTO json_test_strings VALUES ($$.3e-1.5$$);
+INSERT INTO json_test_strings VALUES ($$.3e+1.5$$);
+INSERT INTO json_test_strings VALUES ($$.3e+.$$);
+INSERT INTO json_test_strings VALUES ($$.3e+.5$$);
+INSERT INTO json_test_strings VALUES ($$.3e+1.5$$);
+INSERT INTO json_test_strings VALUES ($$9.3e+1.5$$);
+INSERT INTO json_test_strings VALUES ($$9.e+1.5$$);
+INSERT INTO json_test_strings VALUES ($$9.e+$$);
+INSERT INTO json_test_strings VALUES ($$9.e+1$$);
+INSERT INTO json_test_strings VALUES ($$"\""$$);
+INSERT INTO json_test_strings VALUES ($$"\"3.5"$$);
+INSERT INTO json_test_strings VALUES ($$"\"."$$);
+INSERT INTO json_test_strings VALUES ($$"\".".$$);
+INSERT INTO json_test_strings VALUES ($$"\"....."$$);
+INSERT INTO json_test_strings VALUES ($$"\"\"\"\"""$$);
+INSERT INTO json_test_strings VALUES (E'"newline\n"');
+INSERT INTO json_test_strings VALUES ($$["\"\"\"\"", .5]$$);
+INSERT INTO json_test_strings VALUES ($$[.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\"\"\"\"", 0.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\"\"\"\"", .5]$$);
+INSERT INTO json_test_strings VALUES ($$["\"\"\"\"",.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\"",.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\".5",.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\".5",".5\"".5]$$);
+INSERT INTO json_test_strings VALUES ($$["\".5",".5\"", .5]$$);
+INSERT INTO json_test_strings VALUES ($$["\".5",".5\"",.5]$$);
+INSERT INTO json_test_strings VALUES ($$["\".5",".5\"",0.5]$$);
+INSERT INTO json_test_strings VALUES ($${"key":/*comment*/"value"}$$);
+INSERT INTO json_test_strings VALUES ($${"key":/*comment"value"}$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/*$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/**/$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/***/$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/**//$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/**///$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}/**///----$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}#$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}#{$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}#{}$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"}#,$$);
+INSERT INTO json_test_strings VALUES ($${"key":"value"/**/, "k2":"v2"}$$);
+INSERT INTO json_test_strings VALUES ($$"\u0027"$$);
+INSERT INTO json_test_strings VALUES ($$"hello\'"$$);
+INSERT INTO json_test_strings VALUES ($$'hello\''$$);
+INSERT INTO json_test_strings VALUES ($$'hello'$$);
+INSERT INTO json_test_strings VALUES ($$'hell\'o'$$);
+INSERT INTO json_test_strings VALUES ($$'\'hello'$$);
+INSERT INTO json_test_strings VALUES ($$'\'hello\''$$);
+INSERT INTO json_test_strings VALUES ($$\'hello\'$$);
+INSERT INTO json_test_strings VALUES ($$'hello\'$$);
+INSERT INTO json_test_strings VALUES ($$['hello\']$$);
+INSERT INTO json_test_strings VALUES ($$['hello\'']$$);
+INSERT INTO json_test_strings VALUES ($$['hello"']$$);
+INSERT INTO json_test_strings VALUES ($$['hello\"']$$);
+INSERT INTO json_test_strings VALUES ($$['hello"o']$$);
+INSERT INTO json_test_strings VALUES ($$['"']$$);
+INSERT INTO json_test_strings VALUES ($$'"'$$);
+INSERT INTO json_test_strings VALUES ($$'"hello"'$$);
+INSERT INTO json_test_strings VALUES ($$'"hello'$$);
+INSERT INTO json_test_strings VALUES ($$'"hi"'$$);
+
+-- Control characters not allowed in JSON strings.
+-- Can't test \x00 because it's not even a valid TEXT.
+INSERT INTO json_test_strings VALUES (E'"\x01"');
+INSERT INTO json_test_strings VALUES (E'"\x02"');
+INSERT INTO json_test_strings VALUES (E'"\x03"');
+INSERT INTO json_test_strings VALUES (E'"\x04"');
+INSERT INTO json_test_strings VALUES (E'"\x05"');
+INSERT INTO json_test_strings VALUES (E'"\x06"');
+INSERT INTO json_test_strings VALUES (E'"\x07"');
+INSERT INTO json_test_strings VALUES (E'"\x08"');
+INSERT INTO json_test_strings VALUES (E'"\x09"');
+INSERT INTO json_test_strings VALUES (E'"\x0A"');
+INSERT INTO json_test_strings VALUES (E'"\x0B"');
+INSERT INTO json_test_strings VALUES (E'"\x0C"');
+INSERT INTO json_test_strings VALUES (E'"\x0D"');
+INSERT INTO json_test_strings VALUES (E'"\x0E"');
+INSERT INTO json_test_strings VALUES (E'"\x0F"');
+INSERT INTO json_test_strings VALUES (E'"\x10"');
+INSERT INTO json_test_strings VALUES (E'"\x11"');
+INSERT INTO json_test_strings VALUES (E'"\x12"');
+INSERT INTO json_test_strings VALUES (E'"\x13"');
+INSERT INTO json_test_strings VALUES (E'"\x14"');
+INSERT INTO json_test_strings VALUES (E'"\x15"');
+INSERT INTO json_test_strings VALUES (E'"\x16"');
+INSERT INTO json_test_strings VALUES (E'"\x17"');
+INSERT INTO json_test_strings VALUES (E'"\x18"');
+INSERT INTO json_test_strings VALUES (E'"\x19"');
+INSERT INTO json_test_strings VALUES (E'"\x1A"');
+INSERT INTO json_test_strings VALUES (E'"\x1B"');
+INSERT INTO json_test_strings VALUES (E'"\x1C"');
+INSERT INTO json_test_strings VALUES (E'"\x1D"');
+INSERT INTO json_test_strings VALUES (E'"\x1E"');
+INSERT INTO json_test_strings VALUES (E'"\x1F"');
+
+-- Although \x7F is a control character, the JSON RFC only says
+-- "..., and the control characters (U+0000 through U+001F)".
+-- However, whether to trust the RFC here or not is a tough call.
+INSERT INTO json_test_strings VALUES (E'"\x7F"');
