mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Move jsonapi.c and jsonapi.h to src/common.
To make this work, (1) makeJsonLexContextCstringLen now takes the encoding to be used as an argument; (2) check_stack_depth() is made to do nothing in frontend code, and (3) elog(ERROR, ...) is changed to pg_log_fatal + exit in frontend code. Mark Dilger, reviewed and slightly revised by me. Discussion: http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com
This commit is contained in:
parent
dc788668bb
commit
beb4699091
@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
#include "hstore.h"
|
#include "hstore.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/json.h"
|
#include "utils/json.h"
|
||||||
#include "utils/jsonapi.h"
|
|
||||||
#include "utils/jsonb.h"
|
#include "utils/jsonb.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "tsearch/ts_cache.h"
|
#include "tsearch/ts_cache.h"
|
||||||
#include "tsearch/ts_utils.h"
|
#include "tsearch/ts_utils.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/jsonapi.h"
|
|
||||||
#include "utils/jsonfuncs.h"
|
#include "utils/jsonfuncs.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
#include "tsearch/ts_cache.h"
|
#include "tsearch/ts_cache.h"
|
||||||
#include "tsearch/ts_utils.h"
|
#include "tsearch/ts_utils.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/jsonapi.h"
|
|
||||||
#include "utils/jsonfuncs.h"
|
#include "utils/jsonfuncs.h"
|
||||||
#include "utils/varlena.h"
|
#include "utils/varlena.h"
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ OBJS = \
|
|||||||
int.o \
|
int.o \
|
||||||
int8.o \
|
int8.o \
|
||||||
json.o \
|
json.o \
|
||||||
jsonapi.o \
|
|
||||||
jsonb.o \
|
jsonb.o \
|
||||||
jsonb_gin.o \
|
jsonb_gin.o \
|
||||||
jsonb_op.o \
|
jsonb_op.o \
|
||||||
|
@ -127,7 +127,7 @@ json_recv(PG_FUNCTION_ARGS)
|
|||||||
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
|
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
|
||||||
|
|
||||||
/* Validate it. */
|
/* Validate it. */
|
||||||
lex = makeJsonLexContextCstringLen(str, nbytes, false);
|
lex = makeJsonLexContextCstringLen(str, nbytes, GetDatabaseEncoding(), false);
|
||||||
pg_parse_json_or_ereport(lex, &nullSemAction);
|
pg_parse_json_or_ereport(lex, &nullSemAction);
|
||||||
|
|
||||||
PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
|
PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
|
||||||
|
@ -261,7 +261,7 @@ jsonb_from_cstring(char *json, int len)
|
|||||||
|
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&state, 0, sizeof(state));
|
||||||
memset(&sem, 0, sizeof(sem));
|
memset(&sem, 0, sizeof(sem));
|
||||||
lex = makeJsonLexContextCstringLen(json, len, true);
|
lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
|
||||||
|
|
||||||
sem.semstate = (void *) &state;
|
sem.semstate = (void *) &state;
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
|
|
||||||
#include "catalog/pg_collation.h"
|
#include "catalog/pg_collation.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/datetime.h"
|
#include "utils/datetime.h"
|
||||||
#include "utils/hashutils.h"
|
#include "utils/hashutils.h"
|
||||||
#include "utils/json.h"
|
#include "utils/json.h"
|
||||||
#include "utils/jsonapi.h"
|
|
||||||
#include "utils/jsonb.h"
|
#include "utils/jsonb.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/varlena.h"
|
#include "utils/varlena.h"
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "access/htup_details.h"
|
#include "access/htup_details.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "funcapi.h"
|
#include "funcapi.h"
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
@ -27,7 +28,6 @@
|
|||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#include "utils/json.h"
|
#include "utils/json.h"
|
||||||
#include "utils/jsonapi.h"
|
|
||||||
#include "utils/jsonb.h"
|
#include "utils/jsonb.h"
|
||||||
#include "utils/jsonfuncs.h"
|
#include "utils/jsonfuncs.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
@ -514,6 +514,7 @@ makeJsonLexContext(text *json, bool need_escapes)
|
|||||||
{
|
{
|
||||||
return makeJsonLexContextCstringLen(VARDATA_ANY(json),
|
return makeJsonLexContextCstringLen(VARDATA_ANY(json),
|
||||||
VARSIZE_ANY_EXHDR(json),
|
VARSIZE_ANY_EXHDR(json),
|
||||||
|
GetDatabaseEncoding(),
|
||||||
need_escapes);
|
need_escapes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2605,7 +2606,7 @@ populate_array_json(PopulateArrayContext *ctx, char *json, int len)
|
|||||||
PopulateArrayState state;
|
PopulateArrayState state;
|
||||||
JsonSemAction sem;
|
JsonSemAction sem;
|
||||||
|
|
||||||
state.lex = makeJsonLexContextCstringLen(json, len, true);
|
state.lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
|
||||||
state.ctx = ctx;
|
state.ctx = ctx;
|
||||||
|
|
||||||
memset(&sem, 0, sizeof(sem));
|
memset(&sem, 0, sizeof(sem));
|
||||||
@ -3448,7 +3449,7 @@ get_json_object_as_hash(char *json, int len, const char *funcname)
|
|||||||
HASHCTL ctl;
|
HASHCTL ctl;
|
||||||
HTAB *tab;
|
HTAB *tab;
|
||||||
JHashState *state;
|
JHashState *state;
|
||||||
JsonLexContext *lex = makeJsonLexContextCstringLen(json, len, true);
|
JsonLexContext *lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
|
||||||
JsonSemAction *sem;
|
JsonSemAction *sem;
|
||||||
|
|
||||||
memset(&ctl, 0, sizeof(ctl));
|
memset(&ctl, 0, sizeof(ctl));
|
||||||
|
@ -56,6 +56,7 @@ OBJS_COMMON = \
|
|||||||
f2s.o \
|
f2s.o \
|
||||||
file_perm.o \
|
file_perm.o \
|
||||||
ip.o \
|
ip.o \
|
||||||
|
jsonapi.o \
|
||||||
keywords.o \
|
keywords.o \
|
||||||
kwlookup.o \
|
kwlookup.o \
|
||||||
link-canary.o \
|
link-canary.o \
|
||||||
|
@ -7,15 +7,32 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* src/backend/utils/adt/jsonapi.c
|
* src/common/jsonapi.c
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
#ifndef FRONTEND
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
#else
|
||||||
|
#include "postgres_fe.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/jsonapi.h"
|
||||||
#include "mb/pg_wchar.h"
|
#include "mb/pg_wchar.h"
|
||||||
|
|
||||||
|
#ifdef FRONTEND
|
||||||
|
#include "common/logging.h"
|
||||||
|
#else
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/jsonapi.h"
|
#endif
|
||||||
|
|
||||||
|
#ifdef FRONTEND
|
||||||
|
#define check_stack_depth()
|
||||||
|
#define json_log_and_abort(...) \
|
||||||
|
do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0)
|
||||||
|
#else
|
||||||
|
#define json_log_and_abort(...) elog(ERROR, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The context of the parser is maintained by the recursive descent
|
* The context of the parser is maintained by the recursive descent
|
||||||
@ -135,13 +152,14 @@ IsValidJsonNumber(const char *str, int len)
|
|||||||
* if really required.
|
* if really required.
|
||||||
*/
|
*/
|
||||||
JsonLexContext *
|
JsonLexContext *
|
||||||
makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
|
makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
|
||||||
{
|
{
|
||||||
JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
|
JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
|
||||||
|
|
||||||
lex->input = lex->token_terminator = lex->line_start = json;
|
lex->input = lex->token_terminator = lex->line_start = json;
|
||||||
lex->line_number = 1;
|
lex->line_number = 1;
|
||||||
lex->input_length = len;
|
lex->input_length = len;
|
||||||
|
lex->input_encoding = encoding;
|
||||||
if (need_escapes)
|
if (need_escapes)
|
||||||
lex->strval = makeStringInfo();
|
lex->strval = makeStringInfo();
|
||||||
return lex;
|
return lex;
|
||||||
@ -720,7 +738,7 @@ json_lex_string(JsonLexContext *lex)
|
|||||||
ch = (ch * 16) + (*s - 'A') + 10;
|
ch = (ch * 16) + (*s - 'A') + 10;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lex->token_terminator = s + pg_mblen(s);
|
lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
|
||||||
return JSON_UNICODE_ESCAPE_FORMAT;
|
return JSON_UNICODE_ESCAPE_FORMAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,7 +777,7 @@ json_lex_string(JsonLexContext *lex)
|
|||||||
/* We can't allow this, since our TEXT type doesn't */
|
/* We can't allow this, since our TEXT type doesn't */
|
||||||
return JSON_UNICODE_CODE_POINT_ZERO;
|
return JSON_UNICODE_CODE_POINT_ZERO;
|
||||||
}
|
}
|
||||||
else if (GetDatabaseEncoding() == PG_UTF8)
|
else if (lex->input_encoding == PG_UTF8)
|
||||||
{
|
{
|
||||||
unicode_to_utf8(ch, (unsigned char *) utf8str);
|
unicode_to_utf8(ch, (unsigned char *) utf8str);
|
||||||
utf8len = pg_utf_mblen((unsigned char *) utf8str);
|
utf8len = pg_utf_mblen((unsigned char *) utf8str);
|
||||||
@ -809,7 +827,7 @@ json_lex_string(JsonLexContext *lex)
|
|||||||
default:
|
default:
|
||||||
/* Not a valid string escape, so signal error. */
|
/* Not a valid string escape, so signal error. */
|
||||||
lex->token_start = s;
|
lex->token_start = s;
|
||||||
lex->token_terminator = s + pg_mblen(s);
|
lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
|
||||||
return JSON_ESCAPING_INVALID;
|
return JSON_ESCAPING_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -823,7 +841,7 @@ json_lex_string(JsonLexContext *lex)
|
|||||||
* shown it's not a performance win.
|
* shown it's not a performance win.
|
||||||
*/
|
*/
|
||||||
lex->token_start = s;
|
lex->token_start = s;
|
||||||
lex->token_terminator = s + pg_mblen(s);
|
lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
|
||||||
return JSON_ESCAPING_INVALID;
|
return JSON_ESCAPING_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1010,7 +1028,7 @@ report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
|
|||||||
* unhandled enum values. But this needs to be here anyway to cover the
|
* unhandled enum values. But this needs to be here anyway to cover the
|
||||||
* possibility of an incorrect input.
|
* possibility of an incorrect input.
|
||||||
*/
|
*/
|
||||||
elog(ERROR, "unexpected json parse state: %d", (int) ctx);
|
json_log_and_abort("unexpected json parse state: %d", (int) ctx);
|
||||||
return JSON_SUCCESS; /* silence stupider compilers */
|
return JSON_SUCCESS; /* silence stupider compilers */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1077,7 +1095,7 @@ json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
|
|||||||
* unhandled enum values. But this needs to be here anyway to cover the
|
* unhandled enum values. But this needs to be here anyway to cover the
|
||||||
* possibility of an incorrect input.
|
* possibility of an incorrect input.
|
||||||
*/
|
*/
|
||||||
elog(ERROR, "unexpected json parse error type: %d", (int) error);
|
json_log_and_abort("unexpected json parse error type: %d", (int) error);
|
||||||
return NULL; /* silence stupider compilers */
|
return NULL; /* silence stupider compilers */
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +73,7 @@ typedef struct JsonLexContext
|
|||||||
{
|
{
|
||||||
char *input;
|
char *input;
|
||||||
int input_length;
|
int input_length;
|
||||||
|
int input_encoding;
|
||||||
char *token_start;
|
char *token_start;
|
||||||
char *token_terminator;
|
char *token_terminator;
|
||||||
char *prev_token_terminator;
|
char *prev_token_terminator;
|
||||||
@ -149,6 +150,7 @@ extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
|
|||||||
*/
|
*/
|
||||||
extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
|
extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
|
||||||
int len,
|
int len,
|
||||||
|
int encoding,
|
||||||
bool need_escapes);
|
bool need_escapes);
|
||||||
|
|
||||||
/* lex one token */
|
/* lex one token */
|
@ -14,7 +14,7 @@
|
|||||||
#ifndef JSONFUNCS_H
|
#ifndef JSONFUNCS_H
|
||||||
#define JSONFUNCS_H
|
#define JSONFUNCS_H
|
||||||
|
|
||||||
#include "utils/jsonapi.h"
|
#include "common/jsonapi.h"
|
||||||
#include "utils/jsonb.h"
|
#include "utils/jsonb.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user