1: 202b9ecef6 ! 1: 04b2b11001 common/jsonapi: support libpq as a client @@ src/common/jsonapi.c +#define jsonapi_appendStringInfoChar appendPQExpBufferChar +/* XXX should we add a macro version to PQExpBuffer? */ +#define jsonapi_appendStringInfoCharMacro appendPQExpBufferChar -+#define jsonapi_createStringInfo createPQExpBuffer ++#define jsonapi_makeStringInfo createPQExpBuffer +#define jsonapi_initStringInfo initPQExpBuffer +#define jsonapi_resetStringInfo resetPQExpBuffer +#define jsonapi_termStringInfo termPQExpBuffer @@ src/common/jsonapi.c +#define jsonapi_appendBinaryStringInfo appendBinaryStringInfo +#define jsonapi_appendStringInfoChar appendStringInfoChar +#define jsonapi_appendStringInfoCharMacro appendStringInfoCharMacro -+#define jsonapi_createStringInfo makeStringInfo ++#define jsonapi_makeStringInfo makeStringInfo +#define jsonapi_initStringInfo initStringInfo +#define jsonapi_resetStringInfo resetStringInfo +#define jsonapi_termStringInfo(s) pfree((s)->data) @@ src/common/jsonapi.c: struct JsonIncrementalState bool is_last_chunk; bool partial_completed; - StringInfoData partial_token; -+ StrValType partial_token; ++ jsonapi_StrValType partial_token; }; /* @@ src/common/jsonapi.c: makeJsonLexContextCstringLen(JsonLexContext *lex, const ch } else @@ src/common/jsonapi.c: makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, + lex->line_number = 1; + lex->input_length = len; lex->input_encoding = encoding; ++ lex->need_escapes = need_escapes; if (need_escapes) { - lex->strval = makeStringInfo(); @@ src/common/jsonapi.c: makeJsonLexContextCstringLen(JsonLexContext *lex, const ch + * of use (json_lex_string()) since we might not need to parse any + * strings anyway. + */ -+ lex->strval = jsonapi_createStringInfo(); ++ lex->strval = jsonapi_makeStringInfo(); lex->flags |= JSONLEX_FREE_STRVAL; -+ lex->parse_strval = true; } return lex; @@ src/common/jsonapi.c: makeJsonLexContextIncremental(JsonLexContext *lex, int enc + return lex; + } + ++ lex->need_escapes = need_escapes; if (need_escapes) { - lex->strval = makeStringInfo(); @@ src/common/jsonapi.c: makeJsonLexContextIncremental(JsonLexContext *lex, int enc + * of use (json_lex_string()) since we might not need to parse any + * strings anyway. + */ -+ lex->strval = jsonapi_createStringInfo(); ++ lex->strval = jsonapi_makeStringInfo(); lex->flags |= JSONLEX_FREE_STRVAL; -+ lex->parse_strval = true; } + return lex; @@ src/common/jsonapi.c: json_count_array_elements(JsonLexContext *lex, int *elemen */ memcpy(©lex, lex, sizeof(JsonLexContext)); - copylex.strval = NULL; /* not interested in values here */ -+ copylex.parse_strval = false; /* not interested in values here */ ++ copylex.need_escapes = false; /* not interested in values here */ copylex.lex_level++; count = 0; @@ src/common/jsonapi.c: pg_parse_json_incremental(JsonLexContext *lex, json_ofield_action oend = sem->object_field_end; - if ((ostart != NULL || oend != NULL) && lex->strval != NULL) -+ if ((ostart != NULL || oend != NULL) && lex->parse_strval) ++ if ((ostart != NULL || oend != NULL) && lex->need_escapes) { - fname = pstrdup(lex->strval->data); + fname = STRDUP(lex->strval->data); @@ src/common/jsonapi.c: pg_parse_json_incremental(JsonLexContext *lex, { - if (lex->strval != NULL) - pstack->scalar_val = pstrdup(lex->strval->data); -+ if (lex->parse_strval) ++ if (lex->need_escapes) + { + pstack->scalar_val = STRDUP(lex->strval->data); + if (pstack->scalar_val == NULL) @@ src/common/jsonapi.c: parse_scalar(JsonLexContext *lex, const JsonSemAction *sem { - if (lex->strval != NULL) - val = pstrdup(lex->strval->data); -+ if (lex->parse_strval) ++ if (lex->need_escapes) + { + val = STRDUP(lex->strval->data); + if (val == NULL) @@ src/common/jsonapi.c: parse_object_field(JsonLexContext *lex, const JsonSemActio return report_parse_error(JSON_PARSE_STRING, lex); - if ((ostart != NULL || oend != NULL) && lex->strval != NULL) - fname = pstrdup(lex->strval->data); -+ if ((ostart != NULL || oend != NULL) && lex->parse_strval) ++ if ((ostart != NULL || oend != NULL) && lex->need_escapes) + { + fname = STRDUP(lex->strval->data); + if (fname == NULL) @@ src/common/jsonapi.c: json_lex(JsonLexContext *lex) * recursive call */ - StringInfo ptok = &(lex->inc_state->partial_token); -+ StrValType *ptok = &(lex->inc_state->partial_token); ++ jsonapi_StrValType *ptok = &(lex->inc_state->partial_token); size_t added = 0; bool tok_done = false; JsonLexContext dummy_lex; @@ src/common/jsonapi.c: json_lex(JsonLexContext *lex) dummy_lex.input_length = ptok->len; dummy_lex.input_encoding = lex->input_encoding; dummy_lex.incremental = false; -+ dummy_lex.parse_strval = lex->parse_strval; ++ dummy_lex.need_escapes = lex->need_escapes; dummy_lex.strval = lex->strval; partial_result = json_lex(&dummy_lex); @@ src/common/jsonapi.c: json_lex_string(JsonLexContext *lex) - if (lex->strval != NULL) - resetStringInfo(lex->strval); -+ if (lex->parse_strval) ++ if (lex->need_escapes) + { +#ifdef JSONAPI_USE_PQEXPBUFFER + /* make sure initialization succeeded */ @@ src/common/jsonapi.c: json_lex_string(JsonLexContext *lex) FAIL_AT_CHAR_END(JSON_UNICODE_ESCAPE_FORMAT); } - if (lex->strval != NULL) -+ if (lex->parse_strval) ++ if (lex->need_escapes) { /* * Combine surrogate pairs. @@ src/common/jsonapi.c: json_lex_string(JsonLexContext *lex) } } - else if (lex->strval != NULL) -+ else if (lex->parse_strval) ++ else if (lex->need_escapes) { if (hi_surrogate != -1) FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE); @@ src/common/jsonapi.c: json_lex_string(JsonLexContext *lex) - if (lex->strval != NULL) - appendBinaryStringInfo(lex->strval, s, p - s); -+ if (lex->parse_strval) ++ if (lex->need_escapes) + jsonapi_appendBinaryStringInfo(lex->strval, s, p - s); /* @@ src/common/jsonapi.c: json_lex_string(JsonLexContext *lex) } +#ifdef JSONAPI_USE_PQEXPBUFFER -+ if (lex->parse_strval && PQExpBufferBroken(lex->strval)) ++ if (lex->need_escapes && PQExpBufferBroken(lex->strval)) + return JSON_OUT_OF_MEMORY; +#endif + @@ src/common/jsonapi.c: report_parse_error(JsonParseContext ctx, JsonLexContext *l + jsonapi_resetStringInfo(lex->errormsg); else - lex->errormsg = makeStringInfo(); -+ lex->errormsg = jsonapi_createStringInfo(); ++ lex->errormsg = jsonapi_makeStringInfo(); /* * A helper for error messages that should print the current token. The @@ src/include/common/jsonapi.h: typedef enum JsonParseErrorType + * then they can include the appropriate header themselves. + */ +#ifdef JSONAPI_USE_PQEXPBUFFER -+#define StrValType PQExpBufferData ++#define jsonapi_StrValType PQExpBufferData +#else -+#define StrValType StringInfoData ++#define jsonapi_StrValType StringInfoData +#endif -+ -+typedef struct StrValType StrValType; + /* * All the fields in this structure should be treated as read-only. @@ src/include/common/jsonapi.h: typedef struct JsonLexContext JsonIncrementalState *inc_state; - StringInfo strval; - StringInfo errormsg; -+ bool parse_strval; -+ StrValType *strval; /* only used if parse_strval == true */ -+ StrValType *errormsg; ++ bool need_escapes; ++ struct jsonapi_StrValType *strval; /* only used if need_escapes == true */ ++ struct jsonapi_StrValType *errormsg; } JsonLexContext; typedef JsonParseErrorType (*json_struct_action) (void *state); 2: 0335987632 = 2: 6be4888464 libpq: add OAUTHBEARER SASL mechanism 3: a0806d7c65 = 3: 1eb3d4798c backend: add OAUTHBEARER SASL mechanism 4: 5d5694934a = 4: de9b6ab514 Review comments 5: b459ce7e7b = 5: 3f19723018 DO NOT MERGE: Add pytest suite for OAuth