=== Applying patches on top of PostgreSQL commit ID fe05430ace8e0b3c945cf581564458a5983a07b6 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Wed Jul 2 20:30:20 UTC 2025 On branch cf/5670 nothing to commit, working tree clean === using 'git am' to apply patch ./0001-Optimize-function-byteain-to-avoid-double-scanning.patch === Applying: Optimize function byteain() to avoid double scanning .git/rebase-apply/patch:82: trailing whitespace. else if ((tp[1] >= '0' && tp[1] <= '3') && .git/rebase-apply/patch:83: trailing whitespace. (tp[2] >= '0' && tp[2] <= '7') && warning: 2 lines add whitespace errors. Using index info to reconstruct a base tree... M src/backend/utils/adt/varlena.c Falling back to patching base and 3-way merge... Auto-merging src/backend/utils/adt/varlena.c CONFLICT (content): Merge conflict in src/backend/utils/adt/varlena.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Optimize function byteain() to avoid double scanning When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". Unstaged changes after reset: M src/backend/utils/adt/varlena.c === using patch(1) to apply patch ./0001-Optimize-function-byteain-to-avoid-double-scanning.patch === patching file src/backend/utils/adt/varlena.c Hunk #1 FAILED at 291. Hunk #2 FAILED at 302. Hunk #3 FAILED at 318. Hunk #4 FAILED at 366. 4 out of 4 hunks FAILED -- saving rejects to file src/backend/utils/adt/varlena.c.rej Removing src/backend/utils/adt/varlena.c.rej === using 'git apply' to apply patch ./0001-Optimize-function-byteain-to-avoid-double-scanning.patch === /work/patches/./0001-Optimize-function-byteain-to-avoid-double-scanning.patch:91: trailing whitespace. else if ((tp[1] >= '0' && tp[1] <= '3') && /work/patches/./0001-Optimize-function-byteain-to-avoid-double-scanning.patch:92: trailing whitespace. (tp[2] >= '0' && tp[2] <= '7') && Applied patch to 'src/backend/utils/adt/varlena.c' with conflicts. U src/backend/utils/adt/varlena.c warning: 2 lines add whitespace errors. diff --cc src/backend/utils/adt/varlena.c index ffae8c23abf,f1f1efba053..00000000000 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@@ -268,6 -279,285 +268,288 @@@ text_to_cstring_buffer(const text *src * USER I/O ROUTINES * *****************************************************************************/ ++<<<<<<< ours ++======= + + #define VAL(CH) ((CH) - '0') + #define DIG(VAL) ((VAL) + '0') + + /* + * byteain - converts from printable representation of byte array + * + * Non-printable characters must be passed as '\nnn' (octal) and are + * converted to internal form. '\' must be passed as '\\'. + * ereport(ERROR, ...) if bad form. + * + * BUGS: + * The error checking of input is minimal. + */ + Datum + byteain(PG_FUNCTION_ARGS) + { + char *inputText = PG_GETARG_CSTRING(0); + Node *escontext = fcinfo->context; + char *tp; + char *rp; + int bc; + size_t input_len; + bytea *result; + + /* Recognize hex input */ + if (inputText[0] == '\\' && inputText[1] == 'x') + { + size_t len = strlen(inputText); + + bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */ + result = palloc(bc); + bc = hex_decode_safe(inputText + 2, len - 2, VARDATA(result), + escontext); + SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */ + + PG_RETURN_BYTEA_P(result); + } + + /* Handle traditional escaped style in a single pass */ + input_len = strlen(inputText); + result = palloc(input_len + VARHDRSZ); /* Allocate max possible size */ + rp = VARDATA(result); + tp = inputText; + + while (*tp != '\0') + { + if (tp[0] != '\\') + { + *rp++ = *tp++; + continue; + } + + if (tp[1] == '\\') + { + *rp++ = '\\'; + tp += 2; + } + else if ((tp[1] >= '0' && tp[1] <= '3') && + (tp[2] >= '0' && tp[2] <= '7') && + (tp[3] >= '0' && tp[3] <= '7')) + { + bc = VAL(tp[1]); + bc <<= 3; + bc += VAL(tp[2]); + bc <<= 3; + *rp++ = bc + VAL(tp[3]); + + tp += 4; + } + else + { + /* Invalid escape sequence: report error */ + ereturn(escontext, (Datum) 0, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "bytea"))); + } + } + + /* Set the actual size of the bytea */ + SET_VARSIZE(result, (rp - VARDATA(result)) + VARHDRSZ); + + PG_RETURN_BYTEA_P(result); + } + + /* + * byteaout - converts to printable representation of byte array + * + * In the traditional escaped format, non-printable characters are + * printed as '\nnn' (octal) and '\' as '\\'. + */ + Datum + byteaout(PG_FUNCTION_ARGS) + { + bytea *vlena = PG_GETARG_BYTEA_PP(0); + char *result; + char *rp; + + if (bytea_output == BYTEA_OUTPUT_HEX) + { + /* Print hex format */ + rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1); + *rp++ = '\\'; + *rp++ = 'x'; + rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp); + } + else if (bytea_output == BYTEA_OUTPUT_ESCAPE) + { + /* Print traditional escaped format */ + char *vp; + uint64 len; + int i; + + len = 1; /* empty string has 1 char */ + vp = VARDATA_ANY(vlena); + for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++) + { + if (*vp == '\\') + len += 2; + else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e) + len += 4; + else + len++; + } + + /* + * In principle len can't overflow uint32 if the input fit in 1GB, but + * for safety let's check rather than relying on palloc's internal + * check. + */ + if (len > MaxAllocSize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg_internal("result of bytea output conversion is too large"))); + rp = result = (char *) palloc(len); + + vp = VARDATA_ANY(vlena); + for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++) + { + if (*vp == '\\') + { + *rp++ = '\\'; + *rp++ = '\\'; + } + else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e) + { + int val; /* holds unprintable chars */ + + val = *vp; + rp[0] = '\\'; + rp[3] = DIG(val & 07); + val >>= 3; + rp[2] = DIG(val & 07); + val >>= 3; + rp[1] = DIG(val & 03); + rp += 4; + } + else + *rp++ = *vp; + } + } + else + { + elog(ERROR, "unrecognized \"bytea_output\" setting: %d", + bytea_output); + rp = result = NULL; /* keep compiler quiet */ + } + *rp = '\0'; + PG_RETURN_CSTRING(result); + } + + /* + * bytearecv - converts external binary format to bytea + */ + Datum + bytearecv(PG_FUNCTION_ARGS) + { + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + bytea *result; + int nbytes; + + nbytes = buf->len - buf->cursor; + result = (bytea *) palloc(nbytes + VARHDRSZ); + SET_VARSIZE(result, nbytes + VARHDRSZ); + pq_copymsgbytes(buf, VARDATA(result), nbytes); + PG_RETURN_BYTEA_P(result); + } + + /* + * byteasend - converts bytea to binary format + * + * This is a special case: just copy the input... + */ + Datum + byteasend(PG_FUNCTION_ARGS) + { + bytea *vlena = PG_GETARG_BYTEA_P_COPY(0); + + PG_RETURN_BYTEA_P(vlena); + } + + Datum + bytea_string_agg_transfn(PG_FUNCTION_ARGS) + { + StringInfo state; + + state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0); + + /* Append the value unless null, preceding it with the delimiter. */ + if (!PG_ARGISNULL(1)) + { + bytea *value = PG_GETARG_BYTEA_PP(1); + bool isfirst = false; + + /* + * You might think we can just throw away the first delimiter, however + * we must keep it as we may be a parallel worker doing partial + * aggregation building a state to send to the main process. We need + * to keep the delimiter of every aggregation so that the combine + * function can properly join up the strings of two separately + * partially aggregated results. The first delimiter is only stripped + * off in the final function. To know how much to strip off the front + * of the string, we store the length of the first delimiter in the + * StringInfo's cursor field, which we don't otherwise need here. + */ + if (state == NULL) + { + state = makeStringAggState(fcinfo); + isfirst = true; + } + + if (!PG_ARGISNULL(2)) + { + bytea *delim = PG_GETARG_BYTEA_PP(2); + + appendBinaryStringInfo(state, VARDATA_ANY(delim), + VARSIZE_ANY_EXHDR(delim)); + if (isfirst) + state->cursor = VARSIZE_ANY_EXHDR(delim); + } + + appendBinaryStringInfo(state, VARDATA_ANY(value), + VARSIZE_ANY_EXHDR(value)); + } + + /* + * The transition type for string_agg() is declared to be "internal", + * which is a pass-by-value type the same size as a pointer. + */ + if (state) + PG_RETURN_POINTER(state); + PG_RETURN_NULL(); + } + + Datum + bytea_string_agg_finalfn(PG_FUNCTION_ARGS) + { + StringInfo state; + + /* cannot be called directly because of internal-type argument */ + Assert(AggCheckCallContext(fcinfo, NULL)); + + state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0); + + if (state != NULL) + { + /* As per comment in transfn, strip data before the cursor position */ + bytea *result; + int strippedlen = state->len - state->cursor; + + result = (bytea *) palloc(strippedlen + VARHDRSZ); + SET_VARSIZE(result, strippedlen + VARHDRSZ); + memcpy(VARDATA(result), &state->data[state->cursor], strippedlen); + PG_RETURN_BYTEA_P(result); + } + else + PG_RETURN_NULL(); + } + ++>>>>>>> theirs /* * textin - converts cstring to internal representation */