since-v12.diff.txt
text/plain
Filename: since-v12.diff.txt
Type: text/plain
Part: 0
1: e80c124c3d ! 1: 1e17a1059f common/jsonapi: support FRONTEND clients
@@ Commit message
memory owned by the JsonLexContext, so clients don't need to worry about
freeing it.
- For convenience, the backend now has destroyJsonLexContext() to mirror
- other create/destroy APIs. The frontend has init/term versions of the
- API to handle stack-allocated JsonLexContexts.
-
We can now partially revert b44669b2ca, now that json_errdetail() works
correctly.
- ## src/backend/utils/adt/jsonfuncs.c ##
-@@ src/backend/utils/adt/jsonfuncs.c: json_object_keys(PG_FUNCTION_ARGS)
- pg_parse_json_or_ereport(lex, sem);
- /* keys are now in state->result */
-
-- pfree(lex->strval->data);
-- pfree(lex->strval);
-- pfree(lex);
-+ destroyJsonLexContext(lex);
- pfree(sem);
-
- MemoryContextSwitchTo(oldcontext);
-
## src/bin/pg_verifybackup/parse_manifest.c ##
-@@ src/bin/pg_verifybackup/parse_manifest.c: void
- json_parse_manifest(JsonManifestParseContext *context, char *buffer,
- size_t size)
- {
-- JsonLexContext *lex;
-+ JsonLexContext lex = {0};
- JsonParseErrorType json_error;
- JsonSemAction sem;
- JsonManifestParseState parse;
-@@ src/bin/pg_verifybackup/parse_manifest.c: json_parse_manifest(JsonManifestParseContext *context, char *buffer,
- parse.state = JM_EXPECT_TOPLEVEL_START;
- parse.saw_version_field = false;
-
-- /* Create a JSON lexing context. */
-- lex = makeJsonLexContextCstringLen(buffer, size, PG_UTF8, true);
-+ /* Initialize a JSON lexing context. */
-+ initJsonLexContextCstringLen(&lex, buffer, size, PG_UTF8, true);
-
- /* Set up semantic actions. */
- sem.semstate = &parse;
@@ src/bin/pg_verifybackup/parse_manifest.c: json_parse_manifest(JsonManifestParseContext *context, char *buffer,
- sem.scalar = json_manifest_scalar;
-
/* Run the actual JSON parser. */
-- json_error = pg_parse_json(lex, &sem);
-+ json_error = pg_parse_json(&lex, &sem);
+ json_error = pg_parse_json(lex, &sem);
if (json_error != JSON_SUCCESS)
- json_manifest_parse_failure(context, "parsing failed");
-+ json_manifest_parse_failure(context, json_errdetail(json_error, &lex));
++ json_manifest_parse_failure(context, json_errdetail(json_error, lex));
if (parse.state != JM_EXPECT_EOF)
json_manifest_parse_failure(context, "manifest ended unexpectedly");
- /* Verify the manifest checksum. */
- verify_manifest_checksum(&parse, buffer, size);
-+
-+ /* Clean up. */
-+ termJsonLexContext(&lex);
- }
-
- /*
## src/bin/pg_verifybackup/t/005_bad_manifest.pl ##
@@ src/bin/pg_verifybackup/t/005_bad_manifest.pl: use Test::More;
@@ src/common/jsonapi.c
/*
* The context of the parser is maintained by the recursive descent
* mechanism, but is passed explicitly to the error reporting routine
-@@ src/common/jsonapi.c: IsValidJsonNumber(const char *str, int len)
- return (!numeric_error) && (total_len == dummy_lex.input_length);
- }
-
-+#ifndef FRONTEND
-+
- /*
- * makeJsonLexContextCstringLen
- *
-- * lex constructor, with or without StringInfo object for de-escaped lexemes.
-+ * lex constructor, with or without a string object for de-escaped lexemes.
- *
- * Without is better as it makes the processing faster, so only make one
- * if really required.
-@@ src/common/jsonapi.c: makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escape
- {
- JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
-
-+ initJsonLexContextCstringLen(lex, json, len, encoding, need_escapes);
-+
-+ return lex;
-+}
-+
-+void
-+destroyJsonLexContext(JsonLexContext *lex)
-+{
-+ termJsonLexContext(lex);
-+ pfree(lex);
-+}
-+
-+#endif /* !FRONTEND */
-+
-+void
-+initJsonLexContextCstringLen(JsonLexContext *lex, char *json, int len, int encoding, bool need_escapes)
-+{
- lex->input = lex->token_terminator = lex->line_start = json;
- lex->line_number = 1;
- lex->input_length = len;
+@@ src/common/jsonapi.c: makeJsonLexContextCstringLen(JsonLexContext *lex, char *json,
lex->input_encoding = encoding;
-- if (need_escapes)
+ if (need_escapes)
+ {
- lex->strval = makeStringInfo();
-- return lex;
-+ lex->parse_strval = need_escapes;
-+ if (lex->parse_strval)
-+ {
+ /*
+ * This call can fail in FRONTEND code. We defer error handling to time
-+ * of use (json_lex_string()) since there's no way to signal failure
-+ * here, and we might not need to parse any strings anyway.
++ * of use (json_lex_string()) since we might not need to parse any
++ * strings anyway.
+ */
+ lex->strval = createStrVal();
-+ }
+ lex->flags |= JSONLEX_FREE_STRVAL;
++ lex->parse_strval = true;
+ }
+ lex->errormsg = NULL;
-+}
-+
-+void
-+termJsonLexContext(JsonLexContext *lex)
-+{
+
+ return lex;
+ }
+@@ src/common/jsonapi.c: makeJsonLexContextCstringLen(JsonLexContext *lex, char *json,
+ void
+ freeJsonLexContext(JsonLexContext *lex)
+ {
+ static const JsonLexContext empty = {0};
+
-+ if (lex->strval)
-+ {
+ if (lex->flags & JSONLEX_FREE_STRVAL)
+ {
+#ifdef FRONTEND
+ destroyPQExpBuffer(lex->strval);
+#else
-+ pfree(lex->strval->data);
-+ pfree(lex->strval);
+ pfree(lex->strval->data);
+ pfree(lex->strval);
+#endif
+ }
-+
+ if (lex->errormsg)
+ {
+#ifdef FRONTEND
@@ src/common/jsonapi.c: makeJsonLexContextCstringLen(char *json, int len, int enco
+ pfree(lex->errormsg->data);
+ pfree(lex->errormsg);
+#endif
-+ }
-+
-+ *lex = empty;
+ }
+ if (lex->flags & JSONLEX_FREE_STRUCT)
+ pfree(lex);
++ else
++ *lex = empty;
}
/*
@@ src/common/jsonapi.c: json_errdetail(JsonParseErrorType error, JsonLexContext *l
+ return lex->errormsg->data;
+}
+ ## src/common/meson.build ##
+@@ src/common/meson.build: common_sources_frontend_static += files(
+ # least cryptohash_openssl.c, hmac_openssl.c depend on it.
+ # controldata_utils.c depends on wait_event_types_h. That's arguably a
+ # layering violation, but ...
++#
++# XXX Frontend builds need libpq's pqexpbuffer.h, so adjust the include paths
++# appropriately. This seems completely broken.
+ pgcommon = {}
+ pgcommon_variants = {
+ '_srv': internal_lib_args + {
++ 'include_directories': include_directories('.'),
+ 'sources': common_sources + [lwlocknames_h] + [wait_event_types_h],
+ 'dependencies': [backend_common_code],
+ },
+ '': default_lib_args + {
++ 'include_directories': include_directories('../interfaces/libpq', '.'),
+ 'sources': common_sources_frontend_static,
+ 'dependencies': [frontend_common_code],
+ # Files in libpgcommon.a should use/export the "xxx_private" versions
+@@ src/common/meson.build: pgcommon_variants = {
+ },
+ '_shlib': default_lib_args + {
+ 'pic': true,
++ 'include_directories': include_directories('../interfaces/libpq', '.'),
+ 'sources': common_sources_frontend_shlib,
+ 'dependencies': [frontend_common_code],
+ },
+@@ src/common/meson.build: foreach name, opts : pgcommon_variants
+ c_args = opts.get('c_args', []) + common_cflags[cflagname]
+ cflag_libs += static_library('libpgcommon@0@_@1@'.format(name, cflagname),
+ c_pch: pch_c_h,
+- include_directories: include_directories('.'),
+ kwargs: opts + {
+ 'sources': sources,
+ 'c_args': c_args,
+@@ src/common/meson.build: foreach name, opts : pgcommon_variants
+ lib = static_library('libpgcommon@0@'.format(name),
+ link_with: cflag_libs,
+ c_pch: pch_c_h,
+- include_directories: include_directories('.'),
+ kwargs: opts + {
+ 'dependencies': opts['dependencies'] + [ssl],
+ }
+
## src/include/common/jsonapi.h ##
@@
#ifndef JSONAPI_H
@@ src/include/common/jsonapi.h: typedef enum JsonParseErrorType
JSON_UNICODE_ESCAPE_FORMAT,
JSON_UNICODE_HIGH_ESCAPE,
@@ src/include/common/jsonapi.h: typedef enum JsonParseErrorType
- JSON_SEM_ACTION_FAILED /* error should already be reported */
+ JSON_SEM_ACTION_FAILED, /* error should already be reported */
} JsonParseErrorType;
+/*
@@ src/include/common/jsonapi.h: typedef enum JsonParseErrorType
/*
* All the fields in this structure should be treated as read-only.
@@ src/include/common/jsonapi.h: typedef struct JsonLexContext
- int lex_level;
+ bits32 flags;
int line_number; /* line number, starting from 1 */
char *line_start; /* where that line starts within input */
- StringInfo strval;
@@ src/include/common/jsonapi.h: typedef struct JsonLexContext
} JsonLexContext;
typedef JsonParseErrorType (*json_struct_action) (void *state);
-@@ src/include/common/jsonapi.h: extern PGDLLIMPORT JsonSemAction nullSemAction;
- */
- extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
- int *elements);
-+#ifndef FRONTEND
-
- /*
-- * constructor for JsonLexContext, with or without strval element.
-+ * allocating constructor for JsonLexContext, with or without strval element.
- * If supplied, the strval element will contain a de-escaped version of
- * the lexeme. However, doing this imposes a performance penalty, so
- * it should be avoided if the de-escaped lexeme is not required.
-@@ src/include/common/jsonapi.h: extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
- int encoding,
- bool need_escapes);
-
-+/*
-+ * Counterpart to makeJsonLexContextCstringLen(): clears and deallocates lex.
-+ * The context pointer should not be used after this call.
-+ */
-+extern void destroyJsonLexContext(JsonLexContext *lex);
-+
-+#endif /* !FRONTEND */
-+
-+/*
-+ * stack constructor for JsonLexContext, with or without strval element.
-+ * If supplied, the strval element will contain a de-escaped version of
-+ * the lexeme. However, doing this imposes a performance penalty, so
-+ * it should be avoided if the de-escaped lexeme is not required.
-+ */
-+extern void initJsonLexContextCstringLen(JsonLexContext *lex,
-+ char *json,
-+ int len,
-+ int encoding,
-+ bool need_escapes);
-+
-+/*
-+ * Counterpart to initJsonLexContextCstringLen(): clears the contents of lex,
-+ * but does not deallocate lex itself.
-+ */
-+extern void termJsonLexContext(JsonLexContext *lex);
-+
- /* lex one token */
- extern JsonParseErrorType json_lex(JsonLexContext *lex);
-
2: 02eea9ffe0 ! 2: e941ba5807 libpq: add OAUTHBEARER SASL mechanism
@@ src/Makefile.global.in: with_ldap = @with_ldap@
with_uuid = @with_uuid@
with_zlib = @with_zlib@
- ## src/common/meson.build ##
-@@ src/common/meson.build: common_sources_frontend_static += files(
- # least cryptohash_openssl.c, hmac_openssl.c depend on it.
- # controldata_utils.c depends on wait_event_types_h. That's arguably a
- # layering violation, but ...
-+#
-+# XXX Frontend builds need libpq's pqexpbuffer.h, so adjust the include paths
-+# appropriately. This seems completely broken.
- pgcommon = {}
- pgcommon_variants = {
- '_srv': internal_lib_args + {
-+ 'include_directories': include_directories('.'),
- 'sources': common_sources + [lwlocknames_h] + [wait_event_types_h],
- 'dependencies': [backend_common_code],
- },
- '': default_lib_args + {
-+ 'include_directories': include_directories('../interfaces/libpq', '.'),
- 'sources': common_sources_frontend_static,
- 'dependencies': [frontend_common_code],
- },
- '_shlib': default_lib_args + {
- 'pic': true,
-+ 'include_directories': include_directories('../interfaces/libpq', '.'),
- 'sources': common_sources_frontend_shlib,
- 'dependencies': [frontend_common_code],
- },
-@@ src/common/meson.build: foreach name, opts : pgcommon_variants
- c_args = opts.get('c_args', []) + common_cflags[cflagname]
- cflag_libs += static_library('libpgcommon@0@_@1@'.format(name, cflagname),
- c_pch: pch_c_h,
-- include_directories: include_directories('.'),
- kwargs: opts + {
- 'sources': sources,
- 'c_args': c_args,
-@@ src/common/meson.build: foreach name, opts : pgcommon_variants
- lib = static_library('libpgcommon@0@'.format(name),
- link_with: cflag_libs,
- c_pch: pch_c_h,
-- include_directories: include_directories('.'),
- kwargs: opts + {
- 'dependencies': opts['dependencies'] + [ssl],
- }
-
## src/include/common/oauth-common.h (new) ##
@@
+/*-------------------------------------------------------------------------
@@ src/interfaces/libpq/fe-auth-oauth-curl.c (new)
+ goto cleanup;
+ }
+
-+ initJsonLexContextCstringLen(&lex, resp->data, resp->len, PG_UTF8, true);
++ makeJsonLexContextCstringLen(&lex, resp->data, resp->len, PG_UTF8, true);
+
+ ctx.errbuf = &actx->errbuf;
+ ctx.fields = fields;
@@ src/interfaces/libpq/fe-auth-oauth-curl.c (new)
+ success = true;
+
+cleanup:
-+ termJsonLexContext(&lex);
++ freeJsonLexContext(&lex);
+ return success;
+}
+
@@ src/interfaces/libpq/fe-auth-oauth.c (new)
+ return false;
+ }
+
-+ initJsonLexContextCstringLen(&lex, msg, msglen, PG_UTF8, true);
++ makeJsonLexContextCstringLen(&lex, msg, msglen, PG_UTF8, true);
+
+ initPQExpBuffer(&ctx.errbuf);
+ sem.semstate = &ctx;
@@ src/interfaces/libpq/fe-auth-oauth.c (new)
+
+ /* Don't need the error buffer or the JSON lexer anymore. */
+ termPQExpBuffer(&ctx.errbuf);
-+ termJsonLexContext(&lex);
++ freeJsonLexContext(&lex);
+
+ if (errmsg)
+ return false;
3: b3a731b695 ! 3: 37eaa5ceb6 backend: add OAUTHBEARER SASL mechanism
@@ src/include/libpq/auth.h: extern PGDLLIMPORT bool pg_gss_accept_delegation;
## src/include/libpq/hba.h ##
@@ src/include/libpq/hba.h: typedef enum UserAuth
- uaLDAP,
uaCert,
uaRADIUS,
-- uaPeer
+ uaPeer,
-#define USER_AUTH_LAST uaPeer /* Must be last value of this enum */
-+ uaPeer,
-+ uaOAuth
++ uaOAuth,
+#define USER_AUTH_LAST uaOAuth /* Must be last value of this enum */
} UserAuth;
4: b2a570114e = 4: 7177943f0c Add pytest suite for OAuth
5: 48cd916bfe = 5: bea695c317 squash! Add pytest suite for OAuth