public inbox for [email protected]
help / color / mirror / Atom feed[PATCH v5 4/7] Row pattern recognition patch (executor).
25+ messages / 4 participants
[nested] [flat]
* [PATCH v5 4/7] Row pattern recognition patch (executor).
@ 2023-09-02 06:32 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Tatsuo Ishii @ 2023-09-02 06:32 UTC (permalink / raw)
---
src/backend/executor/nodeWindowAgg.c | 671 ++++++++++++++++++++++++++-
src/backend/utils/adt/windowfuncs.c | 38 +-
src/include/catalog/pg_proc.dat | 6 +
src/include/nodes/execnodes.h | 19 +
4 files changed, 722 insertions(+), 12 deletions(-)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 310ac23e3a..2e59369a71 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -36,6 +36,7 @@
#include "access/htup_details.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_aggregate.h"
+#include "catalog/pg_collation_d.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "executor/nodeWindowAgg.h"
@@ -48,6 +49,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
+#include "utils/fmgroids.h"
#include "utils/expandeddatum.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
@@ -182,8 +184,9 @@ static void begin_partition(WindowAggState *winstate);
static void spool_tuples(WindowAggState *winstate, int64 pos);
static void release_partition(WindowAggState *winstate);
-static int row_is_in_frame(WindowAggState *winstate, int64 pos,
+static int row_is_in_frame(WindowAggState *winstate, int64 pos,
TupleTableSlot *slot);
+
static void update_frameheadpos(WindowAggState *winstate);
static void update_frametailpos(WindowAggState *winstate);
static void update_grouptailpos(WindowAggState *winstate);
@@ -195,9 +198,25 @@ static Datum GetAggInitVal(Datum textInitVal, Oid transtype);
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1,
TupleTableSlot *slot2);
-static bool window_gettupleslot(WindowObject winobj, int64 pos,
- TupleTableSlot *slot);
+static int WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout);
+static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot);
+
+static void attno_map(Node *node);
+static bool attno_map_walker(Node *node, void *context);
+static int row_is_in_reduced_frame(WindowObject winobj, int64 pos);
+
+static int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result);
+
+static bool get_slots(WindowObject winobj, int64 current_pos);
+
+static int search_str_set(char *pattern, StringInfo *str_set, int set_size);
+static void search_str_set_recurse(char *pattern, StringInfo *str_set, int set_size, int set_index,
+ char *encoded_str, int *resultlen);
+static char pattern_initial(WindowAggState *winstate, char *vname);
/*
* initialize_windowaggregate
@@ -673,6 +692,9 @@ eval_windowaggregates(WindowAggState *winstate)
WindowObject agg_winobj;
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot;
+ bool reduced_frame_set;
+ bool check_reduced_frame;
+ int num_rows_in_reduced_frame;
numaggs = winstate->numaggs;
if (numaggs == 0)
@@ -790,6 +812,7 @@ eval_windowaggregates(WindowAggState *winstate)
(winstate->frameOptions & FRAMEOPTION_EXCLUSION) ||
winstate->aggregatedupto <= winstate->frameheadpos)
{
+ elog(DEBUG1, "peraggstate->restart is set");
peraggstate->restart = true;
numaggs_restart++;
}
@@ -861,8 +884,10 @@ eval_windowaggregates(WindowAggState *winstate)
* If we created a mark pointer for aggregates, keep it pushed up to frame
* head, so that tuplestore can discard unnecessary rows.
*/
+#ifdef NOT_USED
if (agg_winobj->markptr >= 0)
WinSetMarkPosition(agg_winobj, winstate->frameheadpos);
+#endif
/*
* Now restart the aggregates that require it.
@@ -919,6 +944,10 @@ eval_windowaggregates(WindowAggState *winstate)
ExecClearTuple(agg_row_slot);
}
+ reduced_frame_set = false;
+ check_reduced_frame = false;
+ num_rows_in_reduced_frame = 0;
+
/*
* Advance until we reach a row not in frame (or end of partition).
*
@@ -930,12 +959,18 @@ eval_windowaggregates(WindowAggState *winstate)
{
int ret;
+ elog(DEBUG1, "===== loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* Fetch next row if we didn't already */
if (TupIsNull(agg_row_slot))
{
if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto,
agg_row_slot))
+ {
+ if (check_reduced_frame)
+ winstate->aggregatedupto--;
break; /* must be end of partition */
+ }
}
/*
@@ -944,10 +979,47 @@ eval_windowaggregates(WindowAggState *winstate)
*/
ret = row_is_in_frame(winstate, winstate->aggregatedupto, agg_row_slot);
if (ret < 0)
+ {
+ if (winstate->patternVariableList != NIL && check_reduced_frame)
+ winstate->aggregatedupto--;
break;
+ }
if (ret == 0)
goto next_tuple;
+ if (winstate->patternVariableList != NIL)
+ {
+ if (!reduced_frame_set)
+ {
+ num_rows_in_reduced_frame = row_is_in_reduced_frame(winstate->agg_winobj, winstate->aggregatedupto);
+ reduced_frame_set = true;
+ elog(DEBUG1, "set num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+
+ if (num_rows_in_reduced_frame <= 0)
+ break;
+
+ else if (num_rows_in_reduced_frame > 0)
+ check_reduced_frame = true;
+ }
+
+ if (check_reduced_frame)
+ {
+ elog(DEBUG1, "decrease num_rows_in_reduced_frame: %d pos: " INT64_FORMAT,
+ num_rows_in_reduced_frame, winstate->aggregatedupto);
+ num_rows_in_reduced_frame--;
+ if (num_rows_in_reduced_frame < 0)
+ {
+ /*
+ * No more rows remain in the reduced frame. Finish
+ * accumulating row into the aggregates.
+ */
+ winstate->aggregatedupto--;
+ break;
+ }
+ }
+ }
+
/* Set tuple context for evaluation of aggregate arguments */
winstate->tmpcontext->ecxt_outertuple = agg_row_slot;
@@ -976,6 +1048,8 @@ next_tuple:
ExecClearTuple(agg_row_slot);
}
+ elog(DEBUG1, "===== break loop in frame starts: " INT64_FORMAT, winstate->aggregatedupto);
+
/* The frame's end is not supposed to move backwards, ever */
Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto);
@@ -2053,6 +2127,8 @@ ExecWindowAgg(PlanState *pstate)
CHECK_FOR_INTERRUPTS();
+ elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT , winstate->currentpos);
+
if (winstate->status == WINDOWAGG_DONE)
return NULL;
@@ -2388,6 +2464,9 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
TupleDesc scanDesc;
ListCell *l;
+ TargetEntry *te;
+ Expr *expr;
+
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -2483,6 +2562,16 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc,
&TTSOpsMinimalTuple);
+ winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+
+ winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc,
+ &TTSOpsMinimalTuple);
+ winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot);
+
/*
* create frame head and tail slots only if needed (must create slots in
* exactly the same cases that update_frameheadpos and update_frametailpos
@@ -2667,6 +2756,39 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate->inRangeAsc = node->inRangeAsc;
winstate->inRangeNullsFirst = node->inRangeNullsFirst;
+ /* Set up SKIP TO type */
+ winstate->rpSkipTo = node->rpSkipTo;
+ /* Set up row pattern recognition PATTERN clause */
+ winstate->patternVariableList = node->patternVariable;
+ winstate->patternRegexpList = node->patternRegexp;
+
+ /* Set up row pattern recognition DEFINE clause */
+ winstate->defineInitial = node->defineInitial;
+ winstate->defineVariableList = NIL;
+ winstate->defineClauseList = NIL;
+ if (node->defineClause != NIL)
+ {
+ /*
+ * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot.
+ */
+ foreach(l, node->defineClause)
+ {
+ char *name;
+ ExprState *exps;
+
+ te = lfirst(l);
+ name = te->resname;
+ expr = te->expr;
+
+ elog(DEBUG1, "defineVariable name: %s", name);
+ winstate->defineVariableList = lappend(winstate->defineVariableList,
+ makeString(pstrdup(name)));
+ attno_map((Node *)expr);
+ exps = ExecInitExpr(expr, (PlanState *) winstate);
+ winstate->defineClauseList = lappend(winstate->defineClauseList, exps);
+ }
+ }
+
winstate->all_first = true;
winstate->partition_spooled = false;
winstate->more_partitions = false;
@@ -2674,6 +2796,57 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
return winstate;
}
+/*
+ * Rewrite varno of Var node that is the argument of PREV/NET so that it sees
+ * scan tuple (PREV) or inner tuple (NEXT).
+ */
+static void
+attno_map(Node *node)
+{
+ (void) expression_tree_walker(node, attno_map_walker, NULL);
+}
+
+static bool
+attno_map_walker(Node *node, void *context)
+{
+ FuncExpr *func;
+ int nargs;
+ Expr *expr;
+ Var *var;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, FuncExpr))
+ {
+ func = (FuncExpr *)node;
+
+ if (func->funcid == F_PREV || func->funcid == F_NEXT)
+ {
+ /* sanity check */
+ nargs = list_length(func->args);
+ if (list_length(func->args) != 1)
+ elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", func->funcid, nargs);
+
+ expr = (Expr *) lfirst(list_head(func->args));
+ if (!IsA(expr, Var))
+ elog(ERROR, "PREV/NEXT's arg is not Var"); /* XXX: is it possible that arg type is Const? */
+ var = (Var *)expr;
+
+ if (func->funcid == F_PREV)
+ /*
+ * Rewrite varno from OUTER_VAR to regular var no so that the
+ * var references scan tuple.
+ */
+ var->varno = var->varnosyn;
+ else
+ var->varno = INNER_VAR;
+ elog(DEBUG1, "PREV/NEXT's varno is rewritten to: %d", var->varno);
+ }
+ }
+ return expression_tree_walker(node, attno_map_walker, NULL);
+}
+
/* -----------------
* ExecEndWindowAgg
* -----------------
@@ -2691,6 +2864,8 @@ ExecEndWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -2740,6 +2915,8 @@ ExecReScanWindowAgg(WindowAggState *node)
ExecClearTuple(node->agg_row_slot);
ExecClearTuple(node->temp_slot_1);
ExecClearTuple(node->temp_slot_2);
+ ExecClearTuple(node->prev_slot);
+ ExecClearTuple(node->next_slot);
if (node->framehead_slot)
ExecClearTuple(node->framehead_slot);
if (node->frametail_slot)
@@ -3100,7 +3277,7 @@ window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
return false;
if (pos < winobj->markpos)
- elog(ERROR, "cannot fetch row before WindowObject's mark position");
+ elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, pos, winobj->markpos );
oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory);
@@ -3420,14 +3597,54 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
WindowAggState *winstate;
ExprContext *econtext;
TupleTableSlot *slot;
- int64 abs_pos;
- int64 mark_pos;
Assert(WindowObjectIsValid(winobj));
winstate = winobj->winstate;
econtext = winstate->ss.ps.ps_ExprContext;
slot = winstate->temp_slot_1;
+ if (WinGetSlotInFrame(winobj, slot,
+ relpos, seektype, set_mark,
+ isnull, isout) == 0)
+ {
+ econtext->ecxt_outertuple = slot;
+ return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
+ econtext, isnull);
+ }
+
+ if (isout)
+ *isout = true;
+ *isnull = true;
+ return (Datum) 0;
+}
+
+/*
+ * WinGetSlotInFrame
+ * slot: TupleTableSlot to store the result
+ * relpos: signed rowcount offset from the seek position
+ * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL
+ * set_mark: If the row is found/in frame and set_mark is true, the mark is
+ * moved to the row as a side-effect.
+ * isnull: output argument, receives isnull status of result
+ * isout: output argument, set to indicate whether target row position
+ * is out of frame (can pass NULL if caller doesn't care about this)
+ *
+ * Returns 0 if we successfullt got the slot. false if out of frame.
+ * (also isout is set)
+ */
+static int
+WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot,
+ int relpos, int seektype, bool set_mark,
+ bool *isnull, bool *isout)
+{
+ WindowAggState *winstate;
+ int64 abs_pos;
+ int64 mark_pos;
+ int num_reduced_frame;
+
+ Assert(WindowObjectIsValid(winobj));
+ winstate = winobj->winstate;
+
switch (seektype)
{
case WINDOW_SEEK_CURRENT:
@@ -3494,6 +3711,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
winstate->frameOptions);
break;
}
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ if (relpos >= num_reduced_frame)
+ goto out_of_frame;
break;
case WINDOW_SEEK_TAIL:
/* rejecting relpos > 0 is easy and simplifies code below */
@@ -3565,6 +3788,12 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
mark_pos = 0; /* keep compiler quiet */
break;
}
+
+ num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos + relpos);
+ if (num_reduced_frame < 0)
+ goto out_of_frame;
+ else if (num_reduced_frame > 0)
+ abs_pos = winstate->frameheadpos + relpos + num_reduced_frame - 1;
break;
default:
elog(ERROR, "unrecognized window seek type: %d", seektype);
@@ -3583,15 +3812,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno,
*isout = false;
if (set_mark)
WinSetMarkPosition(winobj, mark_pos);
- econtext->ecxt_outertuple = slot;
- return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
- econtext, isnull);
+ return 0;
out_of_frame:
if (isout)
*isout = true;
*isnull = true;
- return (Datum) 0;
+ return -1;
}
/*
@@ -3622,3 +3849,427 @@ WinGetFuncArgCurrent(WindowObject winobj, int argno, bool *isnull)
return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
econtext, isnull);
}
+
+/*
+ * row_is_in_reduced_frame
+ * Determine whether a row is in the current row's reduced window frame according
+ * to row pattern matching
+ *
+ * The row must has been already determined that it is in a full window frame
+ * and fetched it into slot.
+ *
+ * Returns:
+ * = 0, RPR is not defined.
+ * >0, if the row is the first in the reduced frame. Return the number of rows in the reduced frame.
+ * -1, if the row is unmatched row
+ * -2, if the row is in the reduced frame but needed to be skipped because of
+ * AFTER MATCH SKIP PAST LAST ROW
+ */
+static
+int row_is_in_reduced_frame(WindowObject winobj, int64 pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ListCell *lc1, *lc2;
+ bool expression_result;
+ int num_matched_rows;
+ int64 original_pos;
+ bool anymatch;
+ StringInfo encoded_str;
+ StringInfo pattern_str = makeStringInfo();
+
+ /*
+ * Array of pattern variables evaluted to true.
+ * Each character corresponds to pattern variable.
+ * Example:
+ * str_set[0] = "AB";
+ * str_set[1] = "AC";
+ * In this case at row 0 A and B are true, and A and C are true in row 1.
+ */
+ #define ENCODED_STR_ARRAY_ALLOC_SIZE 128
+ StringInfo *str_set = NULL;
+ int str_set_index;
+ int str_set_size;
+
+ if (winstate->patternVariableList == NIL)
+ {
+ /*
+ * RPR is not defined. Assume that we are always in the the reduced
+ * window frame.
+ */
+ return 0;
+ }
+
+ /* save original pos */
+ original_pos = pos;
+
+ /*
+ * Check whether the row speicied by pos is in the reduced frame. The
+ * second and subsequent rows need to be recognized as "unmatched" rows if
+ * AFTER MATCH SKIP PAST LAST ROW is defined.
+ */
+ if (winstate->rpSkipTo == ST_PAST_LAST_ROW &&
+ pos > winstate->headpos_in_reduced_frame &&
+ pos < (winstate->headpos_in_reduced_frame + winstate->num_rows_in_reduced_frame))
+ return -2;
+
+ /*
+ * Loop over until none of pattern matches or encounters end of frame.
+ */
+ for (;;)
+ {
+ int64 result_pos = -1;
+
+ /*
+ * Loop over each PATTERN variable.
+ */
+ anymatch = false;
+ encoded_str = makeStringInfo();
+
+ forboth(lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", pos, vname, quantifier);
+
+ expression_result = false;
+
+ /* evaluate row pattern against current row */
+ result_pos = evaluate_pattern(winobj, pos, vname, encoded_str, &expression_result);
+ if (expression_result)
+ {
+ elog(DEBUG1, "expression result is true");
+ anymatch = true;
+ }
+
+ /*
+ * If out of frame, we are done.
+ */
+ if (result_pos < 0)
+ break;
+ }
+
+ if (!anymatch)
+ {
+ /* none of patterns matched. */
+ break;
+ }
+
+ /* build encoded string array */
+ if (str_set == NULL)
+ {
+ str_set_index = 0;
+ str_set_size = ENCODED_STR_ARRAY_ALLOC_SIZE * sizeof(StringInfo);
+ str_set = palloc(str_set_size);
+ }
+
+ str_set[str_set_index++] = encoded_str;
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " str_set_index: %d encoded_str: %s", pos, str_set_index, encoded_str->data);
+
+ if (str_set_index >= str_set_size)
+ {
+ str_set_size *= 2;
+ str_set = repalloc(str_set, str_set_size);
+ }
+
+ /* move to next row */
+ pos++;
+
+ if (result_pos < 0)
+ {
+ /* out of frame */
+ break;
+ }
+ }
+
+ if (str_set == NULL)
+ {
+ /* no matches found in the first row */
+ return -1;
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", pos, encoded_str->data);
+
+ /* build regular expression */
+ pattern_str = makeStringInfo();
+ appendStringInfoChar(pattern_str, '^');
+ forboth (lc1, winstate->patternVariableList, lc2, winstate->patternRegexpList)
+ {
+ char *vname = strVal(lfirst(lc1));
+ char *quantifier = strVal(lfirst(lc2));
+ char initial;
+
+ initial = pattern_initial(winstate, vname);
+ Assert(initial != 0);
+ appendStringInfoChar(pattern_str, initial);
+ if (quantifier[0])
+ appendStringInfoChar(pattern_str, quantifier[0]);
+ elog(DEBUG1, "vname: %s initial: %c quantifier: %s", vname, initial, quantifier);
+ }
+
+ elog(DEBUG1, "pos: " INT64_FORMAT " pattern: %s", pos, pattern_str->data);
+
+ /* look for matching pattern variable sequence */
+ num_matched_rows = search_str_set(pattern_str->data, str_set, str_set_index);
+ if (num_matched_rows <= 0)
+ return -1;
+
+ /*
+ * We are at the first row in the reduced frame. Save the number of
+ * matched rows as the number of rows in the reduced frame.
+ */
+ winstate->headpos_in_reduced_frame = original_pos;
+ winstate->num_rows_in_reduced_frame = num_matched_rows;
+
+ return num_matched_rows;
+}
+
+/*
+ * search set of encode_str.
+ * set_size: size of set_str array.
+ */
+static
+int search_str_set(char *pattern, StringInfo *str_set, int set_size)
+{
+ char *encoded_str = palloc0(set_size+1);
+ int resultlen = 0;
+
+ search_str_set_recurse(pattern, str_set, set_size, 0, encoded_str, &resultlen);
+ elog(DEBUG1, "search_str_set returns %d", resultlen);
+ return resultlen;
+}
+
+static
+void search_str_set_recurse(char *pattern, StringInfo *str_set,
+ int set_size, int set_index, char *encoded_str, int *resultlen)
+{
+ char *p;
+
+ if (set_index >= set_size)
+ {
+ Datum d;
+ text *res;
+ char *substr;
+
+ /*
+ * We first perform pattern matching using regexp_instr, then call
+ * textregexsubstr to get matched substring to know how log the
+ * matched string is. That is the number of rows in the reduced window
+ * frame. The reason why we can't call textregexsubstr is, it error
+ * out if pattern is not match.
+ */
+ if (DatumGetInt32(DirectFunctionCall2Coll(regexp_instr, DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)))) > 0)
+ {
+ d = DirectFunctionCall2Coll(textregexsubstr,
+ DEFAULT_COLLATION_OID,
+ PointerGetDatum(cstring_to_text(encoded_str)),
+ PointerGetDatum(cstring_to_text(pattern)));
+ if (d != 0)
+ {
+ int len;
+
+ res = DatumGetTextPP(d);
+ substr = text_to_cstring(res);
+ len = strlen(substr);
+ if (len > *resultlen)
+ /* remember the longest match */
+ *resultlen = len;
+ }
+ }
+ return;
+ }
+
+ p = str_set[set_index]->data;
+ while (*p)
+ {
+ encoded_str[set_index] = *p;
+ p++;
+ search_str_set_recurse(pattern, str_set, set_size, set_index + 1, encoded_str, resultlen);
+ }
+}
+
+
+/*
+ * Evaluate expression associated with PATTERN variable vname.
+ * relpos is relative row position in a frame (starting from 0).
+ * "quantifier" is the quatifier part of the PATTERN regular expression.
+ * Currently only '+' is allowed.
+ * result is out paramater representing the expression evaluation result
+ * is true of false.
+ * Return values are:
+ * >=0: the last match absolute row position
+ * other wise out of frame.
+ */
+static
+int64 evaluate_pattern(WindowObject winobj, int64 current_pos,
+ char *vname, StringInfo encoded_str, bool *result)
+{
+ WindowAggState *winstate = winobj->winstate;
+ ExprContext *econtext = winstate->ss.ps.ps_ExprContext;
+ ListCell *lc1, *lc2, *lc3;
+ ExprState *pat;
+ Datum eval_result;
+ bool out_of_frame = false;
+ bool isnull;
+
+ forthree (lc1, winstate->defineVariableList, lc2, winstate->defineClauseList, lc3, winstate->defineInitial)
+ {
+ char initial;
+ char *name = strVal(lfirst(lc1));
+
+ elog(DEBUG1, "evaluate_pattern: define variable: %s, pattern variable: %s", name, vname);
+
+ if (strcmp(vname, name))
+ continue;
+
+ initial = *(strVal(lfirst(lc3)));
+
+ /* set expression to evaluate */
+ pat = lfirst(lc2);
+
+ /* get current, previous and next tuples */
+ if (!get_slots(winobj, current_pos))
+ {
+ out_of_frame = true;
+ }
+ else
+ {
+ /* evaluate the expression */
+ eval_result = ExecEvalExpr(pat, econtext, &isnull);
+ if (isnull)
+ {
+ /* expression is NULL */
+ elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ if (!DatumGetBool(eval_result))
+ {
+ /* expression is false */
+ elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, vname, current_pos);
+ *result = false;
+ }
+ else
+ {
+ /* expression is true */
+ elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, vname, current_pos);
+ appendStringInfoChar(encoded_str, initial);
+ *result = true;
+ }
+ }
+ break;
+ }
+
+ if (out_of_frame)
+ {
+ *result = false;
+ return -1;
+ }
+ }
+ return current_pos;
+}
+
+/*
+ * Get current, previous and next tuples.
+ * Returns false if current row is out of partition/full frame.
+ */
+static
+bool get_slots(WindowObject winobj, int64 current_pos)
+{
+ WindowAggState *winstate = winobj->winstate;
+ TupleTableSlot *slot;
+ int ret;
+ ExprContext *econtext;
+
+ econtext = winstate->ss.ps.ps_ExprContext;
+
+ /* set up current row tuple slot */
+ slot = winstate->temp_slot_1;
+ if (!window_gettupleslot(winobj, current_pos, slot))
+ {
+ elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, current_pos);
+ return false;
+
+ ret = row_is_in_frame(winstate, current_pos, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, current_pos);
+ return false;
+ }
+ }
+ econtext->ecxt_outertuple = slot;
+
+ /* for PREV */
+ if (current_pos > 0)
+ {
+ slot = winstate->prev_slot;
+ if (!window_gettupleslot(winobj, current_pos - 1, slot))
+ {
+ elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos - 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, current_pos - 1);
+ econtext->ecxt_scantuple = winstate->null_slot;
+ }
+ else
+ {
+ econtext->ecxt_scantuple = slot;
+ }
+ }
+ }
+ else
+ econtext->ecxt_scantuple = winstate->null_slot;
+
+ /* for NEXT */
+ slot = winstate->next_slot;
+ if (!window_gettupleslot(winobj, current_pos + 1, slot))
+ {
+ elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ {
+ ret = row_is_in_frame(winstate, current_pos + 1, slot);
+ if (ret <= 0)
+ {
+ elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, current_pos + 1);
+ econtext->ecxt_innertuple = winstate->null_slot;
+ }
+ else
+ econtext->ecxt_innertuple = slot;
+ }
+ return true;
+}
+
+/*
+ * Return pattern variable initial character
+ * matching with pattern variable name vname.
+ * If not found, return 0.
+ */
+static
+char pattern_initial(WindowAggState *winstate, char *vname)
+{
+ char initial;
+ char *name;
+ ListCell *lc1, *lc2;
+
+ forboth (lc1, winstate->defineVariableList, lc2, winstate->defineInitial)
+ {
+ name = strVal(lfirst(lc1)); /* DEFINE variable name */
+ initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */
+
+
+ if (!strcmp(name, vname))
+ return initial; /* found */
+ }
+ return 0;
+}
diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c
index b87a624fb2..e4cab36ec9 100644
--- a/src/backend/utils/adt/windowfuncs.c
+++ b/src/backend/utils/adt/windowfuncs.c
@@ -13,6 +13,9 @@
*/
#include "postgres.h"
+#include "catalog/pg_collation_d.h"
+#include "executor/executor.h"
+#include "nodes/execnodes.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "windowapi.h"
@@ -36,11 +39,19 @@ typedef struct
int64 remainder; /* (total rows) % (bucket num) */
} ntile_context;
+/*
+ * rpr process information.
+ * Used for AFTER MATCH SKIP PAST LAST ROW
+ */
+typedef struct SkipContext
+{
+ int64 pos; /* last row absolute position */
+} SkipContext;
+
static bool rank_up(WindowObject winobj);
static Datum leadlag_common(FunctionCallInfo fcinfo,
bool forward, bool withoffset, bool withdefault);
-
/*
* utility routine for *_rank functions.
*/
@@ -673,7 +684,7 @@ window_last_value(PG_FUNCTION_ARGS)
bool isnull;
result = WinGetFuncArgInFrame(winobj, 0,
- 0, WINDOW_SEEK_TAIL, true,
+ 0, WINDOW_SEEK_TAIL, false,
&isnull, NULL);
if (isnull)
PG_RETURN_NULL();
@@ -713,3 +724,26 @@ window_nth_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * prev
+ * Dummy function to invoke RPR's navigation operator "PREV".
+ * This is *not* a window function.
+ */
+Datum
+window_prev(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+/*
+ * next
+ * Dummy function to invoke RPR's navigation operation "NEXT".
+ * This is *not* a window function.
+ */
+Datum
+window_next(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9805bc6118..d20f803cf5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10416,6 +10416,12 @@
{ oid => '3114', descr => 'fetch the Nth row value',
proname => 'nth_value', prokind => 'w', prorettype => 'anyelement',
proargtypes => 'anyelement int4', prosrc => 'window_nth_value' },
+{ oid => '6122', descr => 'previous value',
+ proname => 'prev', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_prev' },
+{ oid => '6123', descr => 'next value',
+ proname => 'next', provolatile => 's', prorettype => 'anyelement',
+ proargtypes => 'anyelement', prosrc => 'window_next' },
# functions for range types
{ oid => '3832', descr => 'I/O',
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cb714f4a19..2bd6fcb5e1 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2519,6 +2519,15 @@ typedef struct WindowAggState
int64 groupheadpos; /* current row's peer group head position */
int64 grouptailpos; /* " " " " tail position (group end+1) */
+ /* these fields are used in Row pattern recognition: */
+ RPSkipTo rpSkipTo; /* Row Pattern Skip To type */
+ List *patternVariableList; /* list of row pattern variables names (list of String) */
+ List *patternRegexpList; /* list of row pattern regular expressions ('+' or ''. list of String) */
+ List *defineVariableList; /* list of row pattern definition variables (list of String) */
+ List *defineClauseList; /* expression for row pattern definition
+ * search conditions ExprState list */
+ List *defineInitial; /* list of row pattern definition variable initials (list of String) */
+
MemoryContext partcontext; /* context for partition-lifespan data */
MemoryContext aggcontext; /* shared context for aggregate working data */
MemoryContext curaggcontext; /* current aggregate's working data */
@@ -2555,6 +2564,16 @@ typedef struct WindowAggState
TupleTableSlot *agg_row_slot;
TupleTableSlot *temp_slot_1;
TupleTableSlot *temp_slot_2;
+
+ /* temporary slots for RPR */
+ TupleTableSlot *prev_slot; /* PREV row navigation operator */
+ TupleTableSlot *next_slot; /* NEXT row navigation operator */
+ TupleTableSlot *null_slot; /* all NULL slot */
+
+ /* head of the reduced window frame */
+ int64 headpos_in_reduced_frame;
+ /* number of rows in the reduced window frame */
+ int64 num_rows_in_reduced_frame;
} WindowAggState;
/* ----------------
--
2.25.1
----Next_Part(Sat_Sep__2_15_52_35_2023_273)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v5-0005-Row-pattern-recognition-patch-docs.patch"
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-04 02:55 Thomas Munro <[email protected]>
0 siblings, 3 replies; 25+ messages in thread
From: Thomas Munro @ 2024-07-04 02:55 UTC (permalink / raw)
To: Heikki Linnakangas <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, Jul 3, 2024 at 1:34 AM Heikki Linnakangas <[email protected]> wrote:
> On 18/04/2024 23:29, Thomas Munro wrote:
> > On Thu, Apr 18, 2024 at 8:47 PM Peter Eisentraut <[email protected]> wrote:
> >> I'm not sure I understand the problem here. Do you mean that in theory
> >> a platform's PRId64 could be something other than "l" or "ll"?
> >
> > Yes. I don't know why anyone would do that, and the systems I checked
> > all have the obvious definitions, eg "ld", "lld" etc. Perhaps it's an
> > acceptable risk? It certainly gives us a tidier result.
>
> Could we have a configure check or static assertion for that?
Unfortunately, that theory turned out to be wrong. The usual suspect,
Windows, uses something else: "I64" or something like that. We could
teach our snprintf to grok that, but I don't like the idea anymore.
So let's go back to INT64_MODIFIER, with just a small amount of
configure time work to pick the right value. I couldn't figure out
any header-only way to do that.
> Personally, I find "PRId64" pretty unreadable. "INT64_MODIFIER" wasn't
> nice either, though, and following standards is good, so I'm sure I'll
> get used to it.
Yeah, I like standards a lot but we've painted ourselves into a corner here...
New version attached. This time I was brave enough to try to tackle
src/timezone too, which had comments planning to drop a lot of small
differences against the upstream tzcode once all supported branches
required C99. I suppose that should make future maintenance easier,
and C89 disappeared from our window of interest with PostgreSQL 11.
It's a little hard to understand what changed, but to try to show it
better I diff'd master against upstream (after filtering through sed
and pgindent as recommended by README), and then diff'd patched
against upstream, and then ... ehm.. diff'd the two diffs, so that you
can see there are some hunks that go away.
IMHO it's a rather scary choice on tzcode's part to use int_fastN_t,
and hard for us to verify that it works correctly especially when
combined with our changes, but on the other hand I don't really expect
any system that PostgreSQL can run on to have "fast" types that really
differ from the "exact width" types. My understanding is that this is
something of interest to historical supercomputers and
microcontrollers, but I can't find any evidence of general
purpose/commodity systems that we target using different sizes (anyone
know better?).
--- zic.c-master-vs-upstream.diff 2024-07-04 14:38:42.919508000 +1200
+++ zic.c-patched-vs-upstream.diff 2024-07-04 14:37:23.663247000 +1200
@@ -1,6 +1,6 @@
--- zic.filtered.c 2024-07-04 12:24:07.383657000 +1200
-+++ zic.c 2024-07-04 14:38:19.086696000 +1200
-@@ -3,104 +3,66 @@
++++ zic.c 2024-07-04 14:17:36.438520000 +1200
+@@ -3,104 +3,72 @@
/*
* This file is in the public domain, so clarified as of
* 2006-07-17 by Arthur David Olson.
@@ -19,6 +19,8 @@
-#include "version.h"
+#include <fcntl.h>
++#include <inttypes.h>
++#include <stdint.h>
+#include <sys/stat.h>
+#include <time.h>
+
@@ -36,20 +38,18 @@
+#define ZIC_VERSION_PRE_2013 '2'
+#define ZIC_VERSION '3'
--typedef int_fast64_t zic_t;
--static zic_t const
-- ZIC_MIN = INT_FAST64_MIN,
-- ZIC_MAX = INT_FAST64_MAX,
+ typedef int_fast64_t zic_t;
+ static zic_t const
+ ZIC_MIN = INT_FAST64_MIN,
+ ZIC_MAX = INT_FAST64_MAX,
- ZIC32_MIN = -1 - (zic_t) 0x7fffffff,
- ZIC32_MAX = 0x7fffffff;
--#define SCNdZIC SCNdFAST64
-+typedef int64 zic_t;
-+#define ZIC_MIN PG_INT64_MIN
-+#define ZIC_MAX PG_INT64_MAX
++ ZIC32_MIN = INT32_MIN,
++ ZIC32_MAX = INT32_MAX;
+ #define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
--#define ZIC_MAX_ABBR_LEN_WO_WARN 6
-+#define ZIC_MAX_ABBR_LEN_WO_WARN 6
+ #define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
-/* Minimum and maximum years, assuming signed 32-bit pg_time_t. */
@@ -137,7 +137,7 @@
bool r_hiwasnum;
int r_month; /* 0..11 */
-@@ -121,18 +83,16 @@
+@@ -121,18 +89,16 @@
};
/*
@@ -162,7 +162,7 @@
lineno_t z_linenum;
const char *z_name;
-@@ -151,59 +111,46 @@
+@@ -151,59 +117,46 @@
zic_t z_untiltime;
};
@@ -245,7 +245,7 @@
const char *loyearp, const char *hiyearp,
const char *typep, const char *monthp,
const char *dayp, const char *timep);
-@@ -214,10 +161,21 @@
+@@ -214,10 +167,21 @@
{
PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
@@ -268,7 +268,7 @@
static int leapcnt;
static bool leapseen;
static zic_t leapminyear;
-@@ -228,132 +186,99 @@
+@@ -228,132 +192,99 @@
static zic_t max_year;
static zic_t min_year;
static bool noise;
@@ -453,7 +453,7 @@
static struct rule *rules;
static ptrdiff_t nrules; /* number of rules */
-@@ -365,7 +290,7 @@
+@@ -365,7 +296,7 @@
struct link
{
@@ -462,7 +462,7 @@
lineno_t l_linenum;
const char *l_target;
const char *l_linkname;
-@@ -381,8 +306,8 @@
+@@ -381,8 +312,8 @@
const int l_value;
};
@@ -473,7 +473,7 @@
static struct lookup const zi_line_codes[] = {
{"Rule", LC_RULE},
-@@ -436,10 +361,12 @@
+@@ -436,10 +367,12 @@
static struct lookup const begin_years[] = {
{"minimum", YR_MINIMUM},
@@ -486,7 +486,7 @@
{"maximum", YR_MAXIMUM},
{"only", YR_ONLY},
{NULL, 0}
-@@ -480,79 +407,30 @@
+@@ -480,79 +413,30 @@
* Memory allocation.
*/
@@ -574,7 +574,7 @@
emalloc(size_t size)
{
return memcheck(malloc(size));
-@@ -564,100 +442,66 @@
+@@ -564,100 +448,66 @@
return memcheck(realloc(ptr, size));
}
@@ -703,7 +703,7 @@
{
va_list args;
-@@ -667,8 +511,8 @@
+@@ -667,8 +517,8 @@
errors = true;
}
@@ -714,7 +714,7 @@
{
va_list args;
-@@ -679,11 +523,8 @@
+@@ -679,11 +529,8 @@
warnings = true;
}
@@ -727,7 +727,7 @@
{
char const *e = (ferror(stream) ? _("I/O error")
: fclose(stream) != 0 ? strerror(errno) : NULL);
-@@ -694,26 +535,23 @@
+@@ -694,26 +541,23 @@
dir ? dir : "", dir ? "/" : "",
name ? name : "", name ? ": " : "",
e);
@@ -759,7 +759,7 @@
exit(status);
}
-@@ -741,221 +579,8 @@
+@@ -741,221 +585,8 @@
}
}
@@ -982,7 +982,7 @@
/* The minimum and maximum values representable in a TZif file. */
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
-@@ -965,19 +590,18 @@
+@@ -965,13 +596,12 @@
static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
@@ -999,32 +999,8 @@
/* Set the time range of the output to TIMERANGE.
Return true if successful. */
static bool
- timerange_option(char *timerange)
- {
-- intmax_t lo = min_time,
-+ int64 lo = min_time,
- hi = max_time;
- char *lo_end = timerange,
- *hi_end;
-@@ -986,7 +610,7 @@
- {
- errno = 0;
- lo = strtoimax(timerange + 1, &lo_end, 10);
-- if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE))
-+ if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE))
- return false;
+@@ -1000,33 +630,15 @@
}
- hi_end = lo_end;
-@@ -994,39 +618,21 @@
- {
- errno = 0;
- hi = strtoimax(lo_end + 2, &hi_end, 10);
-- if (hi_end == lo_end + 2 || hi == INTMAX_MIN)
-+ if (hi_end == lo_end + 2 || hi == PG_INT64_MIN)
- return false;
-- hi -= !(hi == INTMAX_MAX && errno == ERANGE);
-+ hi -= !(hi == PG_INT64_MAX && errno == ERANGE);
- }
if (*hi_end || hi < lo || max_time < lo || hi < min_time)
return false;
- lo_time = max(lo, min_time);
@@ -1060,7 +1036,7 @@
static const char *tzdefault;
/* -1 if the TZif output file should be slim, 0 if default, 1 if the
-@@ -1053,18 +659,10 @@
+@@ -1053,18 +665,10 @@
j;
bool timerange_given = false;
@@ -1081,7 +1057,7 @@
if (TYPE_BIT(zic_t) < 64)
{
fprintf(stderr, "%s: %s\n", progname,
-@@ -1074,16 +672,15 @@
+@@ -1074,16 +678,15 @@
for (k = 1; k < argc; k++)
if (strcmp(argv[k], "--version") == 0)
{
@@ -1101,7 +1077,7 @@
switch (c)
{
default:
-@@ -1106,36 +703,33 @@
+@@ -1106,36 +709,33 @@
break;
case 'd':
if (directory == NULL)
@@ -1144,7 +1120,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1156,12 +750,11 @@
+@@ -1156,12 +756,11 @@
break;
case 'L':
if (leapsec == NULL)
@@ -1159,7 +1135,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1169,12 +762,15 @@
+@@ -1169,12 +768,15 @@
case 'v':
noise = true;
break;
@@ -1177,7 +1153,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1187,27 +783,12 @@
+@@ -1187,27 +789,12 @@
}
timerange_given = true;
break;
@@ -1205,7 +1181,7 @@
if (bloat == 0)
{
static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
-@@ -1220,23 +801,22 @@
+@@ -1220,23 +807,22 @@
abort(); /* Configuration error. */
}
if (directory == NULL)
@@ -1232,7 +1208,7 @@
for (i = 0; i < nzones; i = j)
{
/*
-@@ -1246,15 +826,28 @@
+@@ -1246,15 +832,28 @@
continue;
outzone(&zones[i], j - i);
}
@@ -1264,7 +1240,7 @@
dolink(psxrules, TZDEFRULES, true);
}
if (warnings && (ferror(stderr) || fclose(stderr) != 0))
-@@ -1347,211 +940,22 @@
+@@ -1347,211 +946,22 @@
return componentcheck(name, component, cp);
}
@@ -1487,7 +1463,7 @@
char const *f = target;
char *result = NULL;
-@@ -1559,14 +963,13 @@
+@@ -1559,14 +969,13 @@
{
/* Make F absolute too. */
size_t len = strlen(directory);
@@ -1506,7 +1482,7 @@
}
for (i = 0; f[i] && f[i] == linkname[i]; i++)
if (f[i] == '/')
-@@ -1574,7 +977,7 @@
+@@ -1574,7 +983,7 @@
for (; linkname[i]; i++)
dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
taillen = strlen(f + dir_len);
@@ -1515,7 +1491,7 @@
if (dotdotetcsize <= linksize)
{
if (!result)
-@@ -1585,133 +988,80 @@
+@@ -1585,133 +994,80 @@
}
return result;
}
@@ -1693,7 +1669,7 @@
{
FILE *fp,
*tp;
-@@ -1726,37 +1076,69 @@
+@@ -1726,37 +1082,69 @@
progname, directory, target, e);
exit(EXIT_FAILURE);
}
@@ -1776,7 +1752,7 @@
/*
* Associate sets of rules with zones.
*/
-@@ -1768,10 +1150,8 @@
+@@ -1768,10 +1156,8 @@
static int
rcomp(const void *cp1, const void *cp2)
{
@@ -1789,7 +1765,7 @@
}
static void
-@@ -1784,7 +1164,7 @@
+@@ -1784,7 +1170,7 @@
base,
out;
@@ -1798,7 +1774,7 @@
{
qsort(rules, nrules, sizeof *rules, rcomp);
for (i = 0; i < nrules - 1; ++i)
-@@ -1792,21 +1172,23 @@
+@@ -1792,21 +1178,23 @@
if (strcmp(rules[i].r_name,
rules[i + 1].r_name) != 0)
continue;
@@ -1828,7 +1804,7 @@
continue;
break;
}
-@@ -1842,7 +1224,7 @@
+@@ -1842,7 +1230,7 @@
/*
* Maybe we have a local standard time offset.
*/
@@ -1837,7 +1813,7 @@
zp->z_save = getsave(zp->z_rule, &zp->z_isdst);
/*
-@@ -1857,85 +1239,71 @@
+@@ -1857,85 +1245,60 @@
exit(EXIT_FAILURE);
}
@@ -1947,23 +1923,12 @@
- /* nothing to do */
+ if (name == leapsec && *buf == '#')
+ {
-+ /*
-+ * PG: INT64_FORMAT isn't portable for sscanf, so be content
-+ * with scanning a "long". Once we are requiring C99 in all
-+ * live branches, it'd be sensible to adopt upstream's
-+ * practice of using the <inttypes.h> macros. But for now, we
-+ * don't actually use this code, and it won't overflow before
-+ * 2038 anyway.
-+ */
-+ long cl_tmp;
-+
-+ sscanf(buf, "#expires %ld", &cl_tmp);
-+ comment_leapexpires = cl_tmp;
++ sscanf(buf, "#expires %" SCNdZIC, &comment_leapexpires);
+ }
}
else if (wantcont)
{
-@@ -1944,7 +1312,7 @@
+@@ -1944,7 +1307,7 @@
else
{
struct lookup const *line_codes
@@ -1972,7 +1937,7 @@
lp = byword(fields[0], line_codes);
if (lp == NULL)
-@@ -1971,12 +1339,16 @@
+@@ -1971,12 +1334,16 @@
inexpires(fields, nfields);
wantcont = false;
break;
@@ -1992,26 +1957,7 @@
if (wantcont)
error(_("expected continuation line not found"));
}
-@@ -1992,7 +1364,8 @@
- static zic_t
- gethms(char const *string, char const *errstring)
- {
-- zic_t hh;
-+ /* PG: make hh be int not zic_t to avoid sscanf portability issues */
-+ int hh;
- int sign,
- mm = 0,
- ss = 0;
-@@ -2014,7 +1387,7 @@
- else
- sign = 1;
- switch (sscanf(string,
-- "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
-+ "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
- &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
- {
- default:
-@@ -2022,19 +1395,19 @@
+@@ -2022,19 +1389,19 @@
break;
case 8:
ok = '0' <= xr && xr <= '9';
@@ -2035,12 +1981,12 @@
case 1:
break;
}
-@@ -2050,16 +1423,19 @@
+@@ -2050,16 +1417,19 @@
error("%s", errstring);
return 0;
}
+ /* Some compilers warn that this test is unsatisfiable for 32-bit ints */
-+#if INT_MAX > PG_INT32_MAX
++#if INT_MAX > INT32_MAX
if (ZIC_MAX / SECSPERHOUR < hh)
{
error(_("time overflow"));
@@ -2056,7 +2002,7 @@
sign * (mm * SECSPERMIN + ss));
}
-@@ -2068,7 +1444,7 @@
+@@ -2068,7 +1438,7 @@
{
int dst = -1;
zic_t save;
@@ -2065,7 +2011,7 @@
if (fieldlen != 0)
{
-@@ -2094,7 +1470,7 @@
+@@ -2094,7 +1464,7 @@
static void
inrule(char **fields, int nfields)
{
@@ -2074,7 +2020,7 @@
if (nfields != RULE_FIELDS)
{
-@@ -2125,15 +1501,13 @@
+@@ -2125,15 +1495,13 @@
error(_("Invalid rule name \"%s\""), fields[RF_NAME]);
return;
}
@@ -2095,7 +2041,7 @@
if (max_abbrvar_len < strlen(r.r_abbrvar))
max_abbrvar_len = strlen(r.r_abbrvar);
rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
-@@ -2152,13 +1526,15 @@
+@@ -2152,13 +1520,15 @@
}
if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0)
{
@@ -2113,7 +2059,7 @@
TZDEFRULES);
return false;
}
-@@ -2167,9 +1543,9 @@
+@@ -2167,9 +1537,9 @@
strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
{
error(_("duplicate zone name %s"
@@ -2125,7 +2071,7 @@
zones[i].z_linenum);
return false;
}
-@@ -2192,8 +1568,7 @@
+@@ -2192,8 +1562,7 @@
{
char *cp;
char *cp1;
@@ -2135,7 +2081,7 @@
int i_stdoff,
i_rule,
i_format;
-@@ -2212,6 +1587,7 @@
+@@ -2212,6 +1581,7 @@
i_untilmonth = ZFC_TILMONTH;
i_untilday = ZFC_TILDAY;
i_untiltime = ZFC_TILTIME;
@@ -2143,7 +2089,7 @@
}
else if (!namecheck(fields[ZF_NAME]))
return false;
-@@ -2224,11 +1600,12 @@
+@@ -2224,11 +1594,12 @@
i_untilmonth = ZF_TILMONTH;
i_untilday = ZF_TILDAY;
i_untiltime = ZF_TILTIME;
@@ -2158,7 +2104,7 @@
{
if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
|| strchr(fields[i_format], '/'))
-@@ -2237,25 +1614,31 @@
+@@ -2237,25 +1608,31 @@
return false;
}
}
@@ -2204,7 +2150,7 @@
z.z_untiltime = rpytime(&z.z_untilrule,
z.z_untilrule.r_loyear);
if (iscont && nzones > 0 &&
-@@ -2265,21 +1648,10 @@
+@@ -2265,21 +1642,10 @@
zones[nzones - 1].z_untiltime < max_time &&
zones[nzones - 1].z_untiltime >= z.z_untiltime)
{
@@ -2227,7 +2173,7 @@
zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
zones[nzones++] = z;
-@@ -2291,13 +1663,15 @@
+@@ -2291,12 +1657,13 @@
}
static zic_t
@@ -2238,23 +2184,11 @@
const struct lookup *lp;
zic_t i,
j;
-- zic_t year;
+
-+ /* PG: make year be int not zic_t to avoid sscanf portability issues */
-+ int year;
+ zic_t year;
int month,
day;
- zic_t dayoff,
-@@ -2307,7 +1681,7 @@
-
- dayoff = 0;
- cp = fields[LP_YEAR];
-- if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1)
-+ if (sscanf(cp, "%d%c", &year, &xs) != 1)
- {
- /*
- * Leapin' Lizards!
-@@ -2384,7 +1758,7 @@
+@@ -2384,7 +1751,7 @@
error(_("wrong number of fields on Leap line"));
else
{
@@ -2263,7 +2197,7 @@
if (0 <= t)
{
-@@ -2417,7 +1791,7 @@
+@@ -2417,7 +1784,7 @@
else if (0 <= leapexpires)
error(_("multiple Expires lines"));
else
@@ -2272,7 +2206,7 @@
}
static void
-@@ -2437,15 +1811,15 @@
+@@ -2437,15 +1804,15 @@
}
if (!namecheck(fields[LF_LINKNAME]))
return;
@@ -2292,13 +2226,7 @@
rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
const char *typep, const char *monthp, const char *dayp,
const char *timep)
-@@ -2456,15 +1830,18 @@
- char *ep;
- char xs;
-
-+ /* PG: year_tmp is to avoid sscanf portability issues */
-+ int year_tmp;
-+
+@@ -2459,12 +1826,12 @@
if ((lp = byword(monthp, mon_names)) == NULL)
{
error(_("invalid month name"));
@@ -2313,7 +2241,7 @@
if (*dp != '\0')
{
ep = dp + strlen(dp) - 1;
-@@ -2497,22 +1874,28 @@
+@@ -2497,22 +1864,26 @@
*/
cp = loyearp;
lp = byword(cp, begin_years);
@@ -2340,10 +2268,7 @@
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
}
-- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
-+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
-+ rp->r_loyear = year_tmp;
-+ else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
{
error(_("invalid starting year"));
- return false;
@@ -2351,7 +2276,7 @@
}
cp = hiyearp;
lp = byword(cp, end_years);
-@@ -2520,37 +1903,45 @@
+@@ -2520,37 +1891,43 @@
if (!rp->r_hiwasnum)
switch (lp->l_value)
{
@@ -2372,10 +2297,7 @@
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
}
-- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
-+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
-+ rp->r_hiyear = year_tmp;
-+ else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
{
error(_("invalid ending year"));
- return false;
@@ -2404,7 +2326,7 @@
if ((lp = byword(dp, lasts)) != NULL)
{
rp->r_dycode = DC_DOWLEQ;
-@@ -2559,9 +1950,9 @@
+@@ -2559,9 +1936,9 @@
}
else
{
@@ -2416,7 +2338,7 @@
rp->r_dycode = DC_DOWGEQ;
else
{
-@@ -2575,13 +1966,13 @@
+@@ -2575,13 +1952,13 @@
{
error(_("invalid day of month"));
free(dp);
@@ -2432,7 +2354,7 @@
}
rp->r_wday = lp->l_value;
}
-@@ -2591,37 +1982,36 @@
+@@ -2591,37 +1968,36 @@
{
error(_("invalid day of month"));
free(dp);
@@ -2446,7 +2368,7 @@
static void
-convert(uint_fast32_t val, char *buf)
-+convert(const int32 val, char *const buf)
++convert(const int_fast32_t val, char *const buf)
{
int i;
int shift;
@@ -2459,7 +2381,7 @@
static void
-convert64(uint_fast64_t val, char *buf)
-+convert64(const zic_t val, char *const buf)
++convert64(uint_fast64_t val, char *const buf)
{
int i;
int shift;
@@ -2472,11 +2394,11 @@
static void
-puttzcode(zic_t val, FILE *fp)
-+puttzcode(const int32 val, FILE *const fp)
++puttzcode(zic_t val, FILE *const fp)
{
char buf[4];
-@@ -2646,12 +2036,10 @@
+@@ -2646,12 +2022,10 @@
static int
atcomp(const void *avp, const void *bvp)
{
@@ -2492,7 +2414,7 @@
}
struct timerange
-@@ -2661,44 +2049,25 @@
+@@ -2661,44 +2035,25 @@
count;
int leapbase,
leapcount;
@@ -2539,7 +2461,7 @@
{
while (0 < r.count && hi + 1 < ats[r.base + r.count - 1])
r.count--;
-@@ -2706,9 +2075,6 @@
+@@ -2706,9 +2061,6 @@
r.leapcount--;
}
@@ -2549,7 +2471,7 @@
return r;
}
-@@ -2720,20 +2086,23 @@
+@@ -2720,20 +2072,23 @@
ptrdiff_t i,
j;
int pass;
@@ -2582,7 +2504,7 @@
/*
* Sort.
-@@ -2810,49 +2179,61 @@
+@@ -2810,49 +2165,61 @@
}
}
@@ -2611,9 +2533,8 @@
- max(hi_time,
- redundant_time - (ZIC_MIN < redundant_time)),
- ats, types);
-- range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types);
+ range64 = limitrange(rangeall, lo_time, hi_time, ats, types);
-+ range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types);
+ range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types);
/*
- * TZif version 4 is needed if a no-op transition is appended to indicate
@@ -2674,7 +2595,7 @@
for (pass = 1; pass <= 2; ++pass)
{
ptrdiff_t thistimei,
-@@ -2861,15 +2242,11 @@
+@@ -2861,15 +2228,11 @@
int thisleapi,
thisleapcnt,
thisleaplim;
@@ -2693,7 +2614,7 @@
int old0;
char omittype[TZ_MAX_TYPES];
int typemap[TZ_MAX_TYPES];
-@@ -2883,15 +2260,28 @@
+@@ -2883,15 +2246,28 @@
if (pass == 1)
{
@@ -2701,7 +2622,7 @@
+ /*
+ * Arguably the default time type in the 32-bit data should be
+ * range32.defaulttype, which is suited for timestamps just before
-+ * PG_INT32_MIN. However, zic traditionally used the time type of
++ * INT32_MIN. However, zic traditionally used the time type of
+ * the indefinite past instead. Internet RFC 8532 says readers
+ * should ignore 32-bit data, so this discrepancy matters only to
+ * obsolete readers where the traditional type might be more
@@ -2709,7 +2630,7 @@
+ * value, unless -r specifies a low cutoff that excludes some
+ * 32-bit timestamps.
+ */
-+ thisdefaulttype = (lo_time <= PG_INT32_MIN
++ thisdefaulttype = (lo_time <= INT32_MIN
+ ? range64.defaulttype
+ : range32.defaulttype);
+
@@ -2721,12 +2642,12 @@
- thisleapexpiry = range32.leapexpiry;
- thismin = ZIC32_MIN;
- thismax = ZIC32_MAX;
-+ locut = PG_INT32_MIN < lo_time;
-+ hicut = hi_time < PG_INT32_MAX;
++ locut = INT32_MIN < lo_time;
++ hicut = hi_time < INT32_MAX;
}
else
{
-@@ -2901,52 +2291,40 @@
+@@ -2901,52 +2277,40 @@
toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
thisleapi = range64.leapbase;
thisleapcnt = range64.leapcount;
@@ -2801,7 +2722,7 @@
/*
* Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap
-@@ -2972,14 +2350,7 @@
+@@ -2972,14 +2336,7 @@
type;
hidst = histd = mrudst = mrustd = -1;
@@ -2817,7 +2738,7 @@
if (isdsts[types[i]])
mrudst = types[i];
else
-@@ -3059,20 +2430,19 @@
+@@ -3059,20 +2416,19 @@
}
if (pass == 1 && !want_bloat())
{
@@ -2844,11 +2765,16 @@
convert(thistypecnt, tzh.tzh_typecnt);
convert(thischarcnt, tzh.tzh_charcnt);
DO(tzh_magic);
-@@ -3095,26 +2465,62 @@
- continue;
+@@ -3096,25 +2452,67 @@
}
-+ /* PG: print current timezone abbreviations if requested */
+ /*
++ * PG: print current timezone abbreviations if requested. Note that
++ * we cast to int64_t, because int_fast64_t is not required to be
++ * compatible with INT64_FORMAT. We can't use PRIdFAST64 here because
++ * we override fprintf with our own implementation that might not
++ * understand it.
++ */
+ if (print_abbrevs && pass == 2)
+ {
+ /* Print "type" data for periods ending after print_cutoff */
@@ -2861,7 +2787,7 @@
+
+ fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+ thisabbrev,
-+ utoffs[tm],
++ (int64_t) utoffs[tm],
+ isdsts[tm] ? "\tD" : "");
+ }
+ }
@@ -2873,17 +2799,16 @@
+
+ fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+ thisabbrev,
-+ utoffs[tm],
++ (int64_t) utoffs[tm],
+ isdsts[tm] ? "\tD" : "");
+ }
+ }
+
- /*
++ /*
* Output a LO_TIME transition if needed; see limitrange. But do not
* go below the minimum representable value for this pass.
*/
-- lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time;
-+ lo = pass == 1 && lo_time < PG_INT32_MIN ? PG_INT32_MIN : lo_time;
+ lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time;
- if (0 <= pretranstype)
+ if (locut)
@@ -2915,7 +2840,7 @@
for (i = old0; i < typecnt; i++)
{
-@@ -3131,7 +2537,6 @@
+@@ -3131,7 +2529,6 @@
if (thischarcnt != 0)
fwrite(thischars, sizeof thischars[0],
thischarcnt, fp);
@@ -2923,7 +2848,7 @@
for (i = thisleapi; i < thisleaplim; ++i)
{
zic_t todo;
-@@ -3163,17 +2568,6 @@
+@@ -3163,17 +2560,6 @@
puttzcodepass(todo, fp, pass);
puttzcode(corr[i], fp);
}
@@ -2941,7 +2866,7 @@
if (stdcnt != 0)
for (i = old0; i < typecnt; i++)
if (!omittype[i])
-@@ -3184,8 +2578,7 @@
+@@ -3184,8 +2570,7 @@
putc(ttisuts[i], fp);
}
fprintf(fp, "\n%s\n", string);
@@ -2951,7 +2876,7 @@
free(ats);
}
-@@ -3233,15 +2626,13 @@
+@@ -3233,15 +2618,13 @@
}
}
@@ -2969,7 +2894,7 @@
char const *format = zp->z_format;
slashp = strchr(format, '/');
-@@ -3253,8 +2644,6 @@
+@@ -3253,8 +2636,6 @@
letters = abbroffset(letterbuf, zp->z_stdoff + save);
else if (!letters)
letters = "%s";
@@ -2978,7 +2903,7 @@
sprintf(abbr, format, letters);
}
else if (isdst)
-@@ -3413,17 +2802,11 @@
+@@ -3413,17 +2794,11 @@
return 1;
if (a->r_hiyear != b->r_hiyear)
return a->r_hiyear < b->r_hiyear ? -1 : 1;
@@ -2996,7 +2921,7 @@
static int
stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
{
-@@ -3432,17 +2815,13 @@
+@@ -3432,17 +2807,13 @@
struct rule *stdrp;
struct rule *dstrp;
ptrdiff_t i;
@@ -3016,7 +2941,7 @@
result[0] = '\0';
-@@ -3454,74 +2833,72 @@
+@@ -3454,74 +2825,72 @@
return -1;
zp = zpfirst + zonecount - 1;
@@ -3146,7 +3071,7 @@
if (!offsetlen)
{
result[0] = '\0';
-@@ -3530,12 +2907,12 @@
+@@ -3530,12 +2899,12 @@
len += offsetlen;
if (dstrp == NULL)
return compat;
@@ -3161,7 +3086,7 @@
if (!offsetlen)
{
result[0] = '\0';
-@@ -3544,7 +2921,7 @@
+@@ -3544,7 +2913,7 @@
len += offsetlen;
}
result[len++] = ',';
@@ -3170,7 +3095,7 @@
if (c < 0)
{
result[0] = '\0';
-@@ -3554,7 +2931,7 @@
+@@ -3554,7 +2923,7 @@
compat = c;
len += strlen(result + len);
result[len++] = ',';
@@ -3179,7 +3104,7 @@
if (c < 0)
{
result[0] = '\0';
-@@ -3568,31 +2945,38 @@
+@@ -3568,31 +2937,38 @@
static void
outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
{
@@ -3224,7 +3149,7 @@
startbuf = emalloc(max_abbr_len + 1);
ab = emalloc(max_abbr_len + 1);
envvar = emalloc(max_envvar_len + 1);
-@@ -3605,6 +2989,7 @@
+@@ -3605,6 +2981,7 @@
timecnt = 0;
typecnt = 0;
charcnt = 0;
@@ -3232,7 +3157,7 @@
/*
* Thanks to Earl Chew for noting the need to unconditionally initialize
-@@ -3620,17 +3005,18 @@
+@@ -3620,17 +2997,18 @@
}
for (i = 0; i < zonecount; ++i)
{
@@ -3256,7 +3181,7 @@
}
}
-@@ -3638,14 +3024,13 @@
+@@ -3638,14 +3016,13 @@
* Generate lots of data if a rule can't cover all future times.
*/
compat = stringzone(envvar, zpfirst, zonecount);
@@ -3273,7 +3198,7 @@
zpfirst->z_name);
else if (compat != 0)
{
-@@ -3660,6 +3045,22 @@
+@@ -3660,6 +3037,22 @@
}
if (do_extend)
{
@@ -3296,7 +3221,7 @@
if (min_year >= ZIC_MIN + years_of_observations)
min_year -= years_of_observations;
else
-@@ -3668,9 +3069,18 @@
+@@ -3668,9 +3061,18 @@
max_year += years_of_observations;
else
max_year = ZIC_MAX;
@@ -3317,7 +3242,7 @@
max_year0 = max_year;
if (want_bloat())
{
-@@ -3678,35 +3088,31 @@
+@@ -3678,35 +3080,31 @@
* For the benefit of older systems, generate data from 1900 through
* 2038.
*/
@@ -3366,7 +3291,7 @@
save = zp->z_save;
doabbr(startbuf, zp, NULL, zp->z_isdst, save, false);
type = addtype(oadd(zp->z_stdoff, save),
-@@ -3715,20 +3121,12 @@
+@@ -3715,20 +3113,12 @@
if (usestart)
{
addtt(starttime, type);
@@ -3387,7 +3312,7 @@
for (year = min_year; year <= max_year; ++year)
{
if (useuntil && year > zp->z_untilrule.r_hiyear)
-@@ -3741,12 +3139,9 @@
+@@ -3741,12 +3131,9 @@
*/
for (j = 0; j < zp->z_nrules; ++j)
{
@@ -3403,7 +3328,7 @@
rp->r_todo = year >= rp->r_loyear &&
year <= rp->r_hiyear;
if (rp->r_todo)
-@@ -3763,8 +3158,6 @@
+@@ -3763,8 +3150,6 @@
zic_t jtime,
ktime;
zic_t offset;
@@ -3412,7 +3337,7 @@
INITIALIZE(ktime);
if (useuntil)
-@@ -3789,16 +3182,15 @@
+@@ -3789,16 +3174,15 @@
k = -1;
for (j = 0; j < zp->z_nrules; ++j)
{
@@ -3436,7 +3361,7 @@
if (jtime == min_time ||
jtime == max_time)
continue;
-@@ -3813,12 +3205,12 @@
+@@ -3813,12 +3197,12 @@
char const *dup_rules_msg =
_("two rules for same instant");
@@ -3454,7 +3379,7 @@
error("%s", dup_rules_msg);
}
}
-@@ -3827,15 +3219,7 @@
+@@ -3827,15 +3211,7 @@
rp = &zp->z_rules[k];
rp->r_todo = false;
if (useuntil && ktime >= untiltime)
@@ -3470,7 +3395,7 @@
save = rp->r_save;
if (usestart && ktime == starttime)
usestart = false;
-@@ -3864,41 +3248,44 @@
+@@ -3864,41 +3240,44 @@
false);
}
}
@@ -3534,7 +3459,7 @@
if (defaulttype < 0 && !isdst)
defaulttype = type;
addtt(starttime, type);
-@@ -3921,50 +3308,17 @@
+@@ -3921,50 +3300,17 @@
}
if (defaulttype < 0)
defaulttype = 0;
@@ -3592,7 +3517,7 @@
* transitions up to that point.
*/
struct rule xr;
-@@ -4055,11 +3409,6 @@
+@@ -4055,11 +3401,6 @@
error(_("too many leap seconds"));
exit(EXIT_FAILURE);
}
@@ -3604,7 +3529,7 @@
for (i = 0; i < leapcnt; ++i)
if (t <= trans[i])
break;
-@@ -4094,6 +3443,13 @@
+@@ -4094,6 +3435,13 @@
last = corr[i] += last;
}
@@ -3618,7 +3543,7 @@
if (0 <= leapexpires)
{
leapexpires = oadd(leapexpires, last);
-@@ -4102,6 +3458,8 @@
+@@ -4102,6 +3450,8 @@
error(_("last Leap time does not precede Expires time"));
exit(EXIT_FAILURE);
}
@@ -3627,7 +3552,7 @@
}
}
-@@ -4252,7 +3610,7 @@
+@@ -4252,7 +3602,7 @@
}
/* case-insensitive equality */
@@ -3636,7 +3561,7 @@
ciequal(const char *ap, const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
-@@ -4261,7 +3619,7 @@
+@@ -4261,7 +3611,7 @@
return false;
}
@@ -3645,7 +3570,7 @@
itsabbr(const char *abbr, const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
-@@ -4278,7 +3636,7 @@
+@@ -4278,7 +3628,7 @@
/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
@@ -3654,7 +3579,7 @@
ciprefix(char const *abbr, char const *word)
{
do
-@@ -4355,22 +3713,24 @@
+@@ -4355,22 +3705,24 @@
return foundlp;
}
@@ -3684,7 +3609,7 @@
do
{
if ((*dp = *cp++) != '"')
-@@ -4388,53 +3748,48 @@
+@@ -4388,53 +3740,48 @@
if (is_space(*cp))
++cp;
*dp = '\0';
@@ -3765,7 +3690,7 @@
}
/*
-@@ -4450,31 +3805,39 @@
+@@ -4450,31 +3797,39 @@
zic_t dayoff; /* with a nod to Margaret O. */
zic_t t,
y;
@@ -3820,7 +3745,7 @@
}
while (m != rp->r_month)
{
-@@ -4497,17 +3860,27 @@
+@@ -4497,17 +3852,27 @@
dayoff = oadd(dayoff, i);
if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ)
{
@@ -3852,7 +3777,7 @@
wday = 0;
++i;
}
-@@ -4515,7 +3888,7 @@
+@@ -4515,7 +3880,7 @@
{
dayoff = oadd(dayoff, -1);
if (--wday < 0)
@@ -3861,7 +3786,7 @@
--i;
}
if (i < 0 || i >= len_months[isleap(y)][m])
-@@ -4570,13 +3943,15 @@
+@@ -4570,13 +3935,15 @@
/* Ensure that the directories of ARGNAME exist, by making any missing
ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise,
do it for ARGNAME too. Exit with failure if there is trouble.
@@ -3880,7 +3805,7 @@
/*
* On MS-Windows systems, do not worry about drive letters or backslashes,
* as this should suffice in practice. Time zone names do not use drive
-@@ -4603,20 +3978,15 @@
+@@ -4603,20 +3970,15 @@
if (mkdir(name, MKDIR_UMASK) != 0)
{
/*
@@ -3906,7 +3831,7 @@
progname, name, strerror(err));
exit(EXIT_FAILURE);
}
-@@ -4626,3 +3996,20 @@
+@@ -4626,3 +3988,20 @@
}
free(name);
}
--- localtime.c-master-vs-upstream.diff 2024-07-04 14:38:31.386232000 +1200
+++ localtime.c-patched-vs-upstream.diff 2024-07-04 14:37:46.783150000 +1200
@@ -1,6 +1,6 @@
--- localtime.filtered.c 2024-07-04 13:04:23.744118000 +1200
-+++ localtime.c 2024-07-04 14:38:19.086065000 +1200
-@@ -3,64 +3,28 @@
++++ localtime.c 2024-07-04 14:17:36.438049000 +1200
+@@ -3,64 +3,29 @@
/*
* This file is in the public domain, so clarified as of
* 1996-06-05 by Arthur David Olson.
@@ -25,6 +25,7 @@
-#include "tzdir.h"
-#include "tzfile.h"
#include <fcntl.h>
++#include <stdint.h>
-#if defined THREAD_SAFE && THREAD_SAFE
-#include <pthread.h>
@@ -75,7 +76,7 @@
#ifndef WILDABBR
/*
* Someone might make incorrect use of a time zone abbreviation:
-@@ -72,7 +36,7 @@
+@@ -72,7 +37,7 @@
* in which Daylight Saving Time is never observed.
* 4. They might reference tzname[0] after setting to a time zone
* in which Standard Time is never observed.
@@ -84,7 +85,7 @@
* What's best to do in the above cases is open to debate;
* for now, we just set things up so that in any of the five cases
* WILDABBR is used. Another possibility: initialize tzname[0] to the
-@@ -81,89 +45,28 @@
+@@ -81,89 +46,28 @@
* manual page of what this "time zone abbreviation" means (doing this so
* that tzname[0] has the "normal" length of three characters).
*/
@@ -179,12 +180,8 @@
};
struct rule
-@@ -172,70 +75,37 @@
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
-- int_fast32_t r_time; /* transition time of rule */
-+ int32 r_time; /* transition time of rule */
+@@ -175,64 +79,31 @@
+ int_fast32_t r_time; /* transition time of rule */
};
-static struct pg_tm *gmtsub(struct state const *, pg_time_t const *, int_fast32_t,
@@ -204,13 +201,13 @@
-static struct state *lclptr;
-static struct state *gmtptr;
-#endif /* defined ALL_STATE */
-+static struct pg_tm *gmtsub(pg_time_t const *timep, int32 offset,
++static struct pg_tm *gmtsub(pg_time_t const *timep, int_fast32_t offset,
+ struct pg_tm *tmp);
+static bool increment_overflow(int *ip, int j);
-+static bool increment_overflow_time(pg_time_t *tp, int32 j);
++static bool increment_overflow_time(pg_time_t *tp, int_fast32_t j);
+static int64 leapcorr(struct state const *sp, pg_time_t t);
+static struct pg_tm *timesub(pg_time_t const *timep,
-+ int32 offset, struct state const *sp,
++ int_fast32_t offset, struct state const *sp,
+ struct pg_tm *tmp);
+static bool typesequiv(struct state const *sp, int a, int b);
@@ -259,12 +256,8 @@
-
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
--init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
-+init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
- {
- s->tt_utoff = utoff;
- s->tt_isdst = isdst;
-@@ -244,25 +114,15 @@
+ init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
+@@ -244,16 +115,6 @@
s->tt_ttisut = false;
}
@@ -278,64 +271,13 @@
- return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
-}
-
--static int_fast32_t
-+static int32
+ static int_fast32_t
detzcode(const char *const codep)
{
-- int_fast32_t result;
-+ int32 result;
- int i;
-- int_fast32_t one = 1;
-- int_fast32_t halfmaxval = one << (32 - 2);
-- int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
-- int_fast32_t minval = -1 - maxval;
-+ int32 one = 1;
-+ int32 halfmaxval = one << (32 - 2);
-+ int32 maxval = halfmaxval - 1 + halfmaxval;
-+ int32 minval = -1 - maxval;
-
- result = codep[0] & 0x7f;
- for (i = 1; i < 4; ++i)
-@@ -274,21 +134,21 @@
- * Do two's-complement negation even on non-two's-complement machines.
- * If the result would be minval - 1, return minval.
- */
-- result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
-+ result -= !TWOS_COMPLEMENT(int32) && result != 0;
- result += minval;
- }
+@@ -306,125 +167,25 @@
return result;
}
--static int_fast64_t
-+static int64
- detzcode64(const char *const codep)
- {
-- int_fast64_t result;
-+ uint64 result;
- int i;
-- int_fast64_t one = 1;
-- int_fast64_t halfmaxval = one << (64 - 2);
-- int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
-- int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
-+ int64 one = 1;
-+ int64 halfmaxval = one << (64 - 2);
-+ int64 maxval = halfmaxval - 1 + halfmaxval;
-+ int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
-
- result = codep[0] & 0x7f;
- for (i = 1; i < 8; ++i)
-@@ -300,131 +160,31 @@
- * Do two's-complement negation even on non-two's-complement machines.
- * If the result would be minval - 1, return minval.
- */
-- result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
-+ result -= !TWOS_COMPLEMENT(int64) && result != 0;
- result += minval;
- }
- return result;
- }
-
-static void
-update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
+static bool
@@ -464,7 +406,7 @@
/* Local storage needed for 'tzloadbody'. */
union local_storage
{
-@@ -438,28 +198,23 @@
+@@ -438,28 +199,23 @@
struct state st;
} u;
@@ -500,7 +442,7 @@
union input_buffer *up = &lsp->u.u;
int tzheadsize = sizeof(struct tzhead);
-@@ -474,50 +229,10 @@
+@@ -474,50 +230,10 @@
if (name[0] == ':')
++name;
@@ -553,33 +495,23 @@
nread = read(fid, up->buf, sizeof up->buf);
if (nread < tzheadsize)
-@@ -531,17 +246,14 @@
+@@ -531,13 +247,10 @@
return errno;
for (stored = 4; stored <= 8; stored *= 2)
{
- char version = up->tzhead.tzh_version[0];
- bool skip_datablock = stored == 4 && version;
- int_fast32_t datablock_size;
-- int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
-- int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
+ int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
- int_fast64_t prevtr = -1;
- int_fast32_t prevcorr;
-- int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
-- int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
-- int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
-- int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
-+ int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
-+ int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
-+ int64 prevtr = 0;
-+ int32 prevcorr = 0;
-+ int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
-+ int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
-+ int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
-+ int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
- char const *p = up->buf + tzheadsize;
-
- /*
-@@ -553,177 +265,152 @@
++ int_fast64_t prevtr = 0;
++ int_fast32_t prevcorr = 0;
+ int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+ int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+ int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+@@ -553,177 +266,152 @@
&& 0 <= typecnt && typecnt < TZ_MAX_TYPES
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
@@ -743,8 +675,8 @@
+ leapcnt = 0;
+ for (i = 0; i < sp->leapcnt; ++i)
+ {
-+ int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
-+ int32 corr = detzcode(p + stored);
++ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
++ int_fast32_t corr = detzcode(p + stored);
- /* Read leap seconds, discarding those out of pg_time_t range. */
- leapcnt = 0;
@@ -764,7 +696,7 @@
- * Leap seconds cannot occur before the Epoch, or out of
- * order.
+ * Leap seconds cannot occur more than once per UTC month, and
-+ * UTC months are at least 28 days long (minus 1 second for a
++ * UTC months are at least 2 days long (minus 1 second for a
+ * negative leap second). Each leap second's correction must
+ * differ from the previous one's by 1 second.
*/
@@ -870,7 +802,7 @@
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
-@@ -732,9 +419,8 @@
+@@ -732,9 +420,8 @@
struct state *ts = &lsp->u.st;
up->buf[nread - 1] = '\0';
@@ -881,7 +813,7 @@
/*
* Attempt to reuse existing abbreviations. Without this,
* America/Anchorage would be right on the edge after 2037 when
-@@ -785,25 +471,20 @@
+@@ -785,25 +472,20 @@
== sp->types[sp->timecnt - 2]))
sp->timecnt--;
@@ -916,7 +848,7 @@
}
for (i = 0; i < ts->typecnt; i++)
sp->ttis[sp->typecnt++] = ts->ttis[i];
-@@ -812,6 +493,25 @@
+@@ -812,6 +494,25 @@
}
if (sp->typecnt == 0)
return EINVAL;
@@ -942,7 +874,7 @@
/*
* Infer sp->defaulttype from the data. Although this default type is
-@@ -826,13 +526,13 @@
+@@ -826,13 +527,13 @@
*/
/*
@@ -959,7 +891,7 @@
/*
* Absent the above, if there are transition times and the first
-@@ -878,29 +578,49 @@
+@@ -878,29 +579,49 @@
}
/* Load tz data from the file named NAME into *SP. Read extended
@@ -1021,7 +953,7 @@
}
static const int mon_lengths[2][MONSPERYEAR] = {
-@@ -912,20 +632,13 @@
+@@ -912,20 +633,13 @@
DAYSPERNYEAR, DAYSPERLYEAR
};
@@ -1043,7 +975,7 @@
getzname(const char *strp)
{
char c;
-@@ -946,7 +659,7 @@
+@@ -946,7 +660,7 @@
* We don't do any checking here; checking is done later in common-case code.
*/
@@ -1052,16 +984,9 @@
getqzname(const char *strp, const int delim)
{
int c;
-@@ -994,20 +707,19 @@
- */
+@@ -1000,8 +714,8 @@
+ int_fast32_t secsperhour = SECSPERHOUR;
- static const char *
--getsecs(const char *strp, int_fast32_t * const secsp)
-+getsecs(const char *strp, int32 *const secsp)
- {
- int num;
-- int_fast32_t secsperhour = SECSPERHOUR;
-
/*
- * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
- * "M10.4.6/26", which does not conform to POSIX, but which specifies the
@@ -1070,24 +995,8 @@
* equivalent of "02:00 on the first Sunday on or after 23 Oct".
*/
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
- if (strp == NULL)
- return NULL;
-- *secsp = num * secsperhour;
-+ *secsp = num * (int32) SECSPERHOUR;
- if (*strp == ':')
- {
- ++strp;
-@@ -1036,7 +748,7 @@
- */
+@@ -1057,8 +771,7 @@
- static const char *
--getoffset(const char *strp, int_fast32_t * const offsetp)
-+getoffset(const char *strp, int32 *const offsetp)
- {
- bool neg = false;
-
-@@ -1057,8 +769,7 @@
-
/*
* Given a pointer into a timezone string, extract a rule in the form
- * date[/time]. See POSIX Base Definitions section 8.3 variable TZ
@@ -1096,23 +1005,7 @@
* If a valid rule is not found, return NULL.
* Otherwise, return a pointer to the first character not part of the rule.
*/
-@@ -1124,12 +835,12 @@
- * effect, calculate the year-relative time that rule takes effect.
- */
-
--static int_fast32_t
-+static int32
- transtime(const int year, const struct rule *const rulep,
-- const int_fast32_t offset)
-+ const int32 offset)
- {
- bool leapyear;
-- int_fast32_t value;
-+ int32 value;
- int i;
- int d,
- m1,
-@@ -1138,6 +849,7 @@
+@@ -1138,6 +851,7 @@
yy2,
dow;
@@ -1120,7 +1013,7 @@
leapyear = isleap(year);
switch (rulep->r_type)
{
-@@ -1193,7 +905,7 @@
+@@ -1193,7 +907,7 @@
for (i = 1; i < rulep->r_week; ++i)
{
if (d + DAYSPERWEEK >=
@@ -1129,7 +1022,7 @@
break;
d += DAYSPERWEEK;
}
-@@ -1203,11 +915,8 @@
+@@ -1203,11 +917,8 @@
*/
value = d * SECSPERDAY;
for (i = 0; i < rulep->r_mon - 1; ++i)
@@ -1142,7 +1035,7 @@
}
/*
-@@ -1219,64 +928,71 @@
+@@ -1219,64 +930,71 @@
}
/*
@@ -1159,14 +1052,12 @@
{
const char *stdname;
- const char *dstname;
-- int_fast32_t stdoffset;
-- int_fast32_t dstoffset;
+ const char *dstname = NULL;
+ size_t stdlen;
+ size_t dstlen;
+ size_t charcnt;
-+ int32 stdoffset;
-+ int32 dstoffset;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
char *cp;
bool load_ok;
- ptrdiff_t stdlen,
@@ -1258,7 +1149,7 @@
if (*name != '\0')
{
if (*name == '<')
-@@ -1294,9 +1010,11 @@
+@@ -1294,9 +1012,11 @@
name = getzname(name);
dstlen = name - dstname; /* length of DST abbr. */
}
@@ -1271,22 +1162,21 @@
if (*name != '\0' && *name != ',' && *name != ';')
{
name = getoffset(name, &dstoffset);
-@@ -1312,11 +1030,11 @@
+@@ -1312,11 +1032,11 @@
struct rule start;
struct rule end;
int year;
+ int yearlim;
int timecnt;
pg_time_t janfirst;
-- int_fast32_t janoffset = 0;
+ int_fast32_t janoffset = 0;
- int yearbeg,
- yearlim;
-+ int32 janoffset = 0;
+ int yearbeg;
++name;
if ((name = getrule(name, &start)) == NULL)
-@@ -1334,13 +1052,14 @@
+@@ -1334,6 +1054,7 @@
*/
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
@@ -1294,15 +1184,7 @@
timecnt = 0;
janfirst = 0;
yearbeg = EPOCH_YEAR;
-
- do
- {
-- int_fast32_t yearsecs
-+ int32 yearsecs
- = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
-
- yearbeg--;
-@@ -1349,72 +1068,48 @@
+@@ -1349,27 +1070,9 @@
janoffset = -yearsecs;
break;
}
@@ -1331,27 +1213,8 @@
+ yearlim = yearbeg + YEARSPERREPEAT + 1;
for (year = yearbeg; year < yearlim; year++)
{
-- int_fast32_t
-- starttime = transtime(year, &start, stdoffset),
-- endtime = transtime(year, &end, dstoffset);
-- int_fast32_t
-- yearsecs = (year_lengths[isleap(year)]
-- * SECSPERDAY);
-+ int32
-+ starttime = transtime(year, &start, stdoffset),
-+ endtime = transtime(year, &end, dstoffset);
-+ int32
-+ yearsecs = (year_lengths[isleap(year)]
-+ * SECSPERDAY);
- bool reversed = endtime < starttime;
-
- if (reversed)
- {
-- int_fast32_t swap = starttime;
-+ int32 swap = starttime;
-
- starttime = endtime;
- endtime = swap;
+ int_fast32_t
+@@ -1389,32 +1092,26 @@
}
if (reversed
|| (starttime < endtime
@@ -1390,7 +1253,7 @@
if (increment_overflow_time
(&janfirst, janoffset + yearsecs))
break;
-@@ -1426,14 +1121,14 @@
+@@ -1426,7 +1123,7 @@
sp->ttis[0] = sp->ttis[1];
sp->typecnt = 1; /* Perpetual DST. */
}
@@ -1399,17 +1262,7 @@
sp->goback = sp->goahead = true;
}
else
- {
-- int_fast32_t theirstdoffset;
-- int_fast32_t theirdstoffset;
-- int_fast32_t theiroffset;
-+ int32 theirstdoffset;
-+ int32 theirdstoffset;
-+ int32 theiroffset;
- bool isdst;
- int i;
- int j;
-@@ -1471,6 +1166,7 @@
+@@ -1471,6 +1168,7 @@
* Initially we're assumed to be in standard time.
*/
isdst = false;
@@ -1417,7 +1270,7 @@
/*
* Now juggle transition times and types tracking offsets as you
-@@ -1495,7 +1191,7 @@
+@@ -1495,7 +1193,7 @@
*/
/*
* Transitions from DST to DDST will effectively disappear
@@ -1426,7 +1279,7 @@
*/
if (isdst && !sp->ttis[j].tt_ttisstd)
{
-@@ -1521,6 +1217,7 @@
+@@ -1521,6 +1219,7 @@
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->typecnt = 2;
@@ -1434,7 +1287,7 @@
}
}
else
-@@ -1529,8 +1226,8 @@
+@@ -1529,8 +1228,8 @@
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
@@ -1444,7 +1297,7 @@
sp->charcnt = charcnt;
cp = sp->chars;
memcpy(cp, stdname, stdlen);
-@@ -1547,155 +1244,19 @@
+@@ -1547,155 +1246,19 @@
static void
gmtload(struct state *const sp)
{
@@ -1603,7 +1456,7 @@
struct pg_tm *const tmp)
{
const struct ttinfo *ttisp;
-@@ -1704,14 +1265,11 @@
+@@ -1704,14 +1267,11 @@
const pg_time_t t = *timep;
if (sp == NULL)
@@ -1620,7 +1473,7 @@
pg_time_t seconds;
pg_time_t years;
-@@ -1720,34 +1278,19 @@
+@@ -1720,33 +1280,18 @@
else
seconds = t - sp->ats[sp->timecnt - 1];
--seconds;
@@ -1655,12 +1508,10 @@
- result->tm_year, years))
- return NULL;
-#else
-- int_fast64_t newy;
-+ int64 newy;
+ int_fast64_t newy;
newy = result->tm_year;
- if (t < sp->ats[0])
-@@ -1757,7 +1300,6 @@
+@@ -1757,7 +1302,6 @@
if (!(INT_MIN <= newy && newy <= INT_MAX))
return NULL;
result->tm_year = newy;
@@ -1668,7 +1519,7 @@
}
return result;
}
-@@ -1779,7 +1321,7 @@
+@@ -1779,7 +1323,7 @@
else
lo = mid + 1;
}
@@ -1677,7 +1528,7 @@
}
ttisp = &sp->ttis[i];
-@@ -1792,132 +1334,76 @@
+@@ -1792,132 +1336,76 @@
if (result)
{
result->tm_isdst = ttisp->tt_isdst;
@@ -1745,7 +1596,7 @@
static struct pg_tm *
-gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, pg_time_t const *timep,
- int_fast32_t offset, struct pg_tm *tmp)
-+gmtsub(pg_time_t const *timep, int32 offset,
++gmtsub(pg_time_t const *timep, int_fast32_t offset,
+ struct pg_tm *tmp)
{
struct pg_tm *result;
@@ -1840,13 +1691,7 @@
{
return (y < 0
? -1 - leaps_thru_end_of_nonneg(-1 - y)
-@@ -1925,28 +1411,21 @@
- }
-
- static struct pg_tm *
--timesub(const pg_time_t *timep, int_fast32_t offset,
-+timesub(const pg_time_t *timep, int32 offset,
- const struct state *sp, struct pg_tm *tmp)
+@@ -1930,23 +1418,16 @@
{
const struct lsinfo *lp;
pg_time_t tdays;
@@ -1876,7 +1721,7 @@
i = (sp == NULL) ? 0 : sp->leapcnt;
while (--i >= 0)
{
-@@ -1954,175 +1433,134 @@
+@@ -1954,175 +1435,134 @@
if (*timep >= lp->ls_trans)
{
corr = lp->ls_corr;
@@ -2092,8 +1937,7 @@
static bool
-increment_overflow32(int_fast32_t * const lp, int const m)
-+increment_overflow_time(pg_time_t *tp, int32 j)
- {
+-{
-#ifdef ckd_add
- return ckd_add(lp, *lp, m);
-#else
@@ -2107,8 +1951,8 @@
-}
-
-static bool
--increment_overflow_time(pg_time_t *tp, int_fast32_t j)
--{
+ increment_overflow_time(pg_time_t *tp, int_fast32_t j)
+ {
-#ifdef ckd_add
- return ckd_add(tp, *tp, j);
-#else
@@ -2124,7 +1968,7 @@
*/
if (!(j < 0
? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
-@@ -2130,637 +1568,339 @@
+@@ -2130,637 +1570,339 @@
return true;
*tp += j;
return false;
Attachments:
[text/plain] tzcode.diff.diff.txt (46.6K, ../../CA+hUKG+rYp-=fTP5kjRmnfPq7YgK-e=J+gJxBvKarkPVzLwQmQ@mail.gmail.com/2-tzcode.diff.diff.txt)
download | inline:
--- zic.c-master-vs-upstream.diff 2024-07-04 14:38:42.919508000 +1200
+++ zic.c-patched-vs-upstream.diff 2024-07-04 14:37:23.663247000 +1200
@@ -1,6 +1,6 @@
--- zic.filtered.c 2024-07-04 12:24:07.383657000 +1200
-+++ zic.c 2024-07-04 14:38:19.086696000 +1200
-@@ -3,104 +3,66 @@
++++ zic.c 2024-07-04 14:17:36.438520000 +1200
+@@ -3,104 +3,72 @@
/*
* This file is in the public domain, so clarified as of
* 2006-07-17 by Arthur David Olson.
@@ -19,6 +19,8 @@
-#include "version.h"
+#include <fcntl.h>
++#include <inttypes.h>
++#include <stdint.h>
+#include <sys/stat.h>
+#include <time.h>
+
@@ -36,20 +38,18 @@
+#define ZIC_VERSION_PRE_2013 '2'
+#define ZIC_VERSION '3'
--typedef int_fast64_t zic_t;
--static zic_t const
-- ZIC_MIN = INT_FAST64_MIN,
-- ZIC_MAX = INT_FAST64_MAX,
+ typedef int_fast64_t zic_t;
+ static zic_t const
+ ZIC_MIN = INT_FAST64_MIN,
+ ZIC_MAX = INT_FAST64_MAX,
- ZIC32_MIN = -1 - (zic_t) 0x7fffffff,
- ZIC32_MAX = 0x7fffffff;
--#define SCNdZIC SCNdFAST64
-+typedef int64 zic_t;
-+#define ZIC_MIN PG_INT64_MIN
-+#define ZIC_MAX PG_INT64_MAX
++ ZIC32_MIN = INT32_MIN,
++ ZIC32_MAX = INT32_MAX;
+ #define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
--#define ZIC_MAX_ABBR_LEN_WO_WARN 6
-+#define ZIC_MAX_ABBR_LEN_WO_WARN 6
+ #define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
-/* Minimum and maximum years, assuming signed 32-bit pg_time_t. */
@@ -137,7 +137,7 @@
bool r_hiwasnum;
int r_month; /* 0..11 */
-@@ -121,18 +83,16 @@
+@@ -121,18 +89,16 @@
};
/*
@@ -162,7 +162,7 @@
lineno_t z_linenum;
const char *z_name;
-@@ -151,59 +111,46 @@
+@@ -151,59 +117,46 @@
zic_t z_untiltime;
};
@@ -245,7 +245,7 @@
const char *loyearp, const char *hiyearp,
const char *typep, const char *monthp,
const char *dayp, const char *timep);
-@@ -214,10 +161,21 @@
+@@ -214,10 +167,21 @@
{
PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
@@ -268,7 +268,7 @@
static int leapcnt;
static bool leapseen;
static zic_t leapminyear;
-@@ -228,132 +186,99 @@
+@@ -228,132 +192,99 @@
static zic_t max_year;
static zic_t min_year;
static bool noise;
@@ -453,7 +453,7 @@
static struct rule *rules;
static ptrdiff_t nrules; /* number of rules */
-@@ -365,7 +290,7 @@
+@@ -365,7 +296,7 @@
struct link
{
@@ -462,7 +462,7 @@
lineno_t l_linenum;
const char *l_target;
const char *l_linkname;
-@@ -381,8 +306,8 @@
+@@ -381,8 +312,8 @@
const int l_value;
};
@@ -473,7 +473,7 @@
static struct lookup const zi_line_codes[] = {
{"Rule", LC_RULE},
-@@ -436,10 +361,12 @@
+@@ -436,10 +367,12 @@
static struct lookup const begin_years[] = {
{"minimum", YR_MINIMUM},
@@ -486,7 +486,7 @@
{"maximum", YR_MAXIMUM},
{"only", YR_ONLY},
{NULL, 0}
-@@ -480,79 +407,30 @@
+@@ -480,79 +413,30 @@
* Memory allocation.
*/
@@ -574,7 +574,7 @@
emalloc(size_t size)
{
return memcheck(malloc(size));
-@@ -564,100 +442,66 @@
+@@ -564,100 +448,66 @@
return memcheck(realloc(ptr, size));
}
@@ -703,7 +703,7 @@
{
va_list args;
-@@ -667,8 +511,8 @@
+@@ -667,8 +517,8 @@
errors = true;
}
@@ -714,7 +714,7 @@
{
va_list args;
-@@ -679,11 +523,8 @@
+@@ -679,11 +529,8 @@
warnings = true;
}
@@ -727,7 +727,7 @@
{
char const *e = (ferror(stream) ? _("I/O error")
: fclose(stream) != 0 ? strerror(errno) : NULL);
-@@ -694,26 +535,23 @@
+@@ -694,26 +541,23 @@
dir ? dir : "", dir ? "/" : "",
name ? name : "", name ? ": " : "",
e);
@@ -759,7 +759,7 @@
exit(status);
}
-@@ -741,221 +579,8 @@
+@@ -741,221 +585,8 @@
}
}
@@ -982,7 +982,7 @@
/* The minimum and maximum values representable in a TZif file. */
static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
-@@ -965,19 +590,18 @@
+@@ -965,13 +596,12 @@
static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE);
static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE);
@@ -999,32 +999,8 @@
/* Set the time range of the output to TIMERANGE.
Return true if successful. */
static bool
- timerange_option(char *timerange)
- {
-- intmax_t lo = min_time,
-+ int64 lo = min_time,
- hi = max_time;
- char *lo_end = timerange,
- *hi_end;
-@@ -986,7 +610,7 @@
- {
- errno = 0;
- lo = strtoimax(timerange + 1, &lo_end, 10);
-- if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE))
-+ if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE))
- return false;
+@@ -1000,33 +630,15 @@
}
- hi_end = lo_end;
-@@ -994,39 +618,21 @@
- {
- errno = 0;
- hi = strtoimax(lo_end + 2, &hi_end, 10);
-- if (hi_end == lo_end + 2 || hi == INTMAX_MIN)
-+ if (hi_end == lo_end + 2 || hi == PG_INT64_MIN)
- return false;
-- hi -= !(hi == INTMAX_MAX && errno == ERANGE);
-+ hi -= !(hi == PG_INT64_MAX && errno == ERANGE);
- }
if (*hi_end || hi < lo || max_time < lo || hi < min_time)
return false;
- lo_time = max(lo, min_time);
@@ -1060,7 +1036,7 @@
static const char *tzdefault;
/* -1 if the TZif output file should be slim, 0 if default, 1 if the
-@@ -1053,18 +659,10 @@
+@@ -1053,18 +665,10 @@
j;
bool timerange_given = false;
@@ -1081,7 +1057,7 @@
if (TYPE_BIT(zic_t) < 64)
{
fprintf(stderr, "%s: %s\n", progname,
-@@ -1074,16 +672,15 @@
+@@ -1074,16 +678,15 @@
for (k = 1; k < argc; k++)
if (strcmp(argv[k], "--version") == 0)
{
@@ -1101,7 +1077,7 @@
switch (c)
{
default:
-@@ -1106,36 +703,33 @@
+@@ -1106,36 +709,33 @@
break;
case 'd':
if (directory == NULL)
@@ -1144,7 +1120,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1156,12 +750,11 @@
+@@ -1156,12 +756,11 @@
break;
case 'L':
if (leapsec == NULL)
@@ -1159,7 +1135,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1169,12 +762,15 @@
+@@ -1169,12 +768,15 @@
case 'v':
noise = true;
break;
@@ -1177,7 +1153,7 @@
progname);
return EXIT_FAILURE;
}
-@@ -1187,27 +783,12 @@
+@@ -1187,27 +789,12 @@
}
timerange_given = true;
break;
@@ -1205,7 +1181,7 @@
if (bloat == 0)
{
static char const bloat_default[] = ZIC_BLOAT_DEFAULT;
-@@ -1220,23 +801,22 @@
+@@ -1220,23 +807,22 @@
abort(); /* Configuration error. */
}
if (directory == NULL)
@@ -1232,7 +1208,7 @@
for (i = 0; i < nzones; i = j)
{
/*
-@@ -1246,15 +826,28 @@
+@@ -1246,15 +832,28 @@
continue;
outzone(&zones[i], j - i);
}
@@ -1264,7 +1240,7 @@
dolink(psxrules, TZDEFRULES, true);
}
if (warnings && (ferror(stderr) || fclose(stderr) != 0))
-@@ -1347,211 +940,22 @@
+@@ -1347,211 +946,22 @@
return componentcheck(name, component, cp);
}
@@ -1487,7 +1463,7 @@
char const *f = target;
char *result = NULL;
-@@ -1559,14 +963,13 @@
+@@ -1559,14 +969,13 @@
{
/* Make F absolute too. */
size_t len = strlen(directory);
@@ -1506,7 +1482,7 @@
}
for (i = 0; f[i] && f[i] == linkname[i]; i++)
if (f[i] == '/')
-@@ -1574,7 +977,7 @@
+@@ -1574,7 +983,7 @@
for (; linkname[i]; i++)
dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
taillen = strlen(f + dir_len);
@@ -1515,7 +1491,7 @@
if (dotdotetcsize <= linksize)
{
if (!result)
-@@ -1585,133 +988,80 @@
+@@ -1585,133 +994,80 @@
}
return result;
}
@@ -1693,7 +1669,7 @@
{
FILE *fp,
*tp;
-@@ -1726,37 +1076,69 @@
+@@ -1726,37 +1082,69 @@
progname, directory, target, e);
exit(EXIT_FAILURE);
}
@@ -1776,7 +1752,7 @@
/*
* Associate sets of rules with zones.
*/
-@@ -1768,10 +1150,8 @@
+@@ -1768,10 +1156,8 @@
static int
rcomp(const void *cp1, const void *cp2)
{
@@ -1789,7 +1765,7 @@
}
static void
-@@ -1784,7 +1164,7 @@
+@@ -1784,7 +1170,7 @@
base,
out;
@@ -1798,7 +1774,7 @@
{
qsort(rules, nrules, sizeof *rules, rcomp);
for (i = 0; i < nrules - 1; ++i)
-@@ -1792,21 +1172,23 @@
+@@ -1792,21 +1178,23 @@
if (strcmp(rules[i].r_name,
rules[i + 1].r_name) != 0)
continue;
@@ -1828,7 +1804,7 @@
continue;
break;
}
-@@ -1842,7 +1224,7 @@
+@@ -1842,7 +1230,7 @@
/*
* Maybe we have a local standard time offset.
*/
@@ -1837,7 +1813,7 @@
zp->z_save = getsave(zp->z_rule, &zp->z_isdst);
/*
-@@ -1857,85 +1239,71 @@
+@@ -1857,85 +1245,60 @@
exit(EXIT_FAILURE);
}
@@ -1947,23 +1923,12 @@
- /* nothing to do */
+ if (name == leapsec && *buf == '#')
+ {
-+ /*
-+ * PG: INT64_FORMAT isn't portable for sscanf, so be content
-+ * with scanning a "long". Once we are requiring C99 in all
-+ * live branches, it'd be sensible to adopt upstream's
-+ * practice of using the <inttypes.h> macros. But for now, we
-+ * don't actually use this code, and it won't overflow before
-+ * 2038 anyway.
-+ */
-+ long cl_tmp;
-+
-+ sscanf(buf, "#expires %ld", &cl_tmp);
-+ comment_leapexpires = cl_tmp;
++ sscanf(buf, "#expires %" SCNdZIC, &comment_leapexpires);
+ }
}
else if (wantcont)
{
-@@ -1944,7 +1312,7 @@
+@@ -1944,7 +1307,7 @@
else
{
struct lookup const *line_codes
@@ -1972,7 +1937,7 @@
lp = byword(fields[0], line_codes);
if (lp == NULL)
-@@ -1971,12 +1339,16 @@
+@@ -1971,12 +1334,16 @@
inexpires(fields, nfields);
wantcont = false;
break;
@@ -1992,26 +1957,7 @@
if (wantcont)
error(_("expected continuation line not found"));
}
-@@ -1992,7 +1364,8 @@
- static zic_t
- gethms(char const *string, char const *errstring)
- {
-- zic_t hh;
-+ /* PG: make hh be int not zic_t to avoid sscanf portability issues */
-+ int hh;
- int sign,
- mm = 0,
- ss = 0;
-@@ -2014,7 +1387,7 @@
- else
- sign = 1;
- switch (sscanf(string,
-- "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
-+ "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
- &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
- {
- default:
-@@ -2022,19 +1395,19 @@
+@@ -2022,19 +1389,19 @@
break;
case 8:
ok = '0' <= xr && xr <= '9';
@@ -2035,12 +1981,12 @@
case 1:
break;
}
-@@ -2050,16 +1423,19 @@
+@@ -2050,16 +1417,19 @@
error("%s", errstring);
return 0;
}
+ /* Some compilers warn that this test is unsatisfiable for 32-bit ints */
-+#if INT_MAX > PG_INT32_MAX
++#if INT_MAX > INT32_MAX
if (ZIC_MAX / SECSPERHOUR < hh)
{
error(_("time overflow"));
@@ -2056,7 +2002,7 @@
sign * (mm * SECSPERMIN + ss));
}
-@@ -2068,7 +1444,7 @@
+@@ -2068,7 +1438,7 @@
{
int dst = -1;
zic_t save;
@@ -2065,7 +2011,7 @@
if (fieldlen != 0)
{
-@@ -2094,7 +1470,7 @@
+@@ -2094,7 +1464,7 @@
static void
inrule(char **fields, int nfields)
{
@@ -2074,7 +2020,7 @@
if (nfields != RULE_FIELDS)
{
-@@ -2125,15 +1501,13 @@
+@@ -2125,15 +1495,13 @@
error(_("Invalid rule name \"%s\""), fields[RF_NAME]);
return;
}
@@ -2095,7 +2041,7 @@
if (max_abbrvar_len < strlen(r.r_abbrvar))
max_abbrvar_len = strlen(r.r_abbrvar);
rules = growalloc(rules, sizeof *rules, nrules, &nrules_alloc);
-@@ -2152,13 +1526,15 @@
+@@ -2152,13 +1520,15 @@
}
if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0)
{
@@ -2113,7 +2059,7 @@
TZDEFRULES);
return false;
}
-@@ -2167,9 +1543,9 @@
+@@ -2167,9 +1537,9 @@
strcmp(zones[i].z_name, fields[ZF_NAME]) == 0)
{
error(_("duplicate zone name %s"
@@ -2125,7 +2071,7 @@
zones[i].z_linenum);
return false;
}
-@@ -2192,8 +1568,7 @@
+@@ -2192,8 +1562,7 @@
{
char *cp;
char *cp1;
@@ -2135,7 +2081,7 @@
int i_stdoff,
i_rule,
i_format;
-@@ -2212,6 +1587,7 @@
+@@ -2212,6 +1581,7 @@
i_untilmonth = ZFC_TILMONTH;
i_untilday = ZFC_TILDAY;
i_untiltime = ZFC_TILTIME;
@@ -2143,7 +2089,7 @@
}
else if (!namecheck(fields[ZF_NAME]))
return false;
-@@ -2224,11 +1600,12 @@
+@@ -2224,11 +1594,12 @@
i_untilmonth = ZF_TILMONTH;
i_untilday = ZF_TILDAY;
i_untiltime = ZF_TILTIME;
@@ -2158,7 +2104,7 @@
{
if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
|| strchr(fields[i_format], '/'))
-@@ -2237,25 +1614,31 @@
+@@ -2237,25 +1608,31 @@
return false;
}
}
@@ -2204,7 +2150,7 @@
z.z_untiltime = rpytime(&z.z_untilrule,
z.z_untilrule.r_loyear);
if (iscont && nzones > 0 &&
-@@ -2265,21 +1648,10 @@
+@@ -2265,21 +1642,10 @@
zones[nzones - 1].z_untiltime < max_time &&
zones[nzones - 1].z_untiltime >= z.z_untiltime)
{
@@ -2227,7 +2173,7 @@
zones = growalloc(zones, sizeof *zones, nzones, &nzones_alloc);
zones[nzones++] = z;
-@@ -2291,13 +1663,15 @@
+@@ -2291,12 +1657,13 @@
}
static zic_t
@@ -2238,23 +2184,11 @@
const struct lookup *lp;
zic_t i,
j;
-- zic_t year;
+
-+ /* PG: make year be int not zic_t to avoid sscanf portability issues */
-+ int year;
+ zic_t year;
int month,
day;
- zic_t dayoff,
-@@ -2307,7 +1681,7 @@
-
- dayoff = 0;
- cp = fields[LP_YEAR];
-- if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1)
-+ if (sscanf(cp, "%d%c", &year, &xs) != 1)
- {
- /*
- * Leapin' Lizards!
-@@ -2384,7 +1758,7 @@
+@@ -2384,7 +1751,7 @@
error(_("wrong number of fields on Leap line"));
else
{
@@ -2263,7 +2197,7 @@
if (0 <= t)
{
-@@ -2417,7 +1791,7 @@
+@@ -2417,7 +1784,7 @@
else if (0 <= leapexpires)
error(_("multiple Expires lines"));
else
@@ -2272,7 +2206,7 @@
}
static void
-@@ -2437,15 +1811,15 @@
+@@ -2437,15 +1804,15 @@
}
if (!namecheck(fields[LF_LINKNAME]))
return;
@@ -2292,13 +2226,7 @@
rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
const char *typep, const char *monthp, const char *dayp,
const char *timep)
-@@ -2456,15 +1830,18 @@
- char *ep;
- char xs;
-
-+ /* PG: year_tmp is to avoid sscanf portability issues */
-+ int year_tmp;
-+
+@@ -2459,12 +1826,12 @@
if ((lp = byword(monthp, mon_names)) == NULL)
{
error(_("invalid month name"));
@@ -2313,7 +2241,7 @@
if (*dp != '\0')
{
ep = dp + strlen(dp) - 1;
-@@ -2497,22 +1874,28 @@
+@@ -2497,22 +1864,26 @@
*/
cp = loyearp;
lp = byword(cp, begin_years);
@@ -2340,10 +2268,7 @@
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
}
-- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
-+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
-+ rp->r_loyear = year_tmp;
-+ else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
{
error(_("invalid starting year"));
- return false;
@@ -2351,7 +2276,7 @@
}
cp = hiyearp;
lp = byword(cp, end_years);
-@@ -2520,37 +1903,45 @@
+@@ -2520,37 +1891,43 @@
if (!rp->r_hiwasnum)
switch (lp->l_value)
{
@@ -2372,10 +2297,7 @@
+ progname, lp->l_value);
+ exit(EXIT_FAILURE);
}
-- else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
-+ else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
-+ rp->r_hiyear = year_tmp;
-+ else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
{
error(_("invalid ending year"));
- return false;
@@ -2404,7 +2326,7 @@
if ((lp = byword(dp, lasts)) != NULL)
{
rp->r_dycode = DC_DOWLEQ;
-@@ -2559,9 +1950,9 @@
+@@ -2559,9 +1936,9 @@
}
else
{
@@ -2416,7 +2338,7 @@
rp->r_dycode = DC_DOWGEQ;
else
{
-@@ -2575,13 +1966,13 @@
+@@ -2575,13 +1952,13 @@
{
error(_("invalid day of month"));
free(dp);
@@ -2432,7 +2354,7 @@
}
rp->r_wday = lp->l_value;
}
-@@ -2591,37 +1982,36 @@
+@@ -2591,37 +1968,36 @@
{
error(_("invalid day of month"));
free(dp);
@@ -2446,7 +2368,7 @@
static void
-convert(uint_fast32_t val, char *buf)
-+convert(const int32 val, char *const buf)
++convert(const int_fast32_t val, char *const buf)
{
int i;
int shift;
@@ -2459,7 +2381,7 @@
static void
-convert64(uint_fast64_t val, char *buf)
-+convert64(const zic_t val, char *const buf)
++convert64(uint_fast64_t val, char *const buf)
{
int i;
int shift;
@@ -2472,11 +2394,11 @@
static void
-puttzcode(zic_t val, FILE *fp)
-+puttzcode(const int32 val, FILE *const fp)
++puttzcode(zic_t val, FILE *const fp)
{
char buf[4];
-@@ -2646,12 +2036,10 @@
+@@ -2646,12 +2022,10 @@
static int
atcomp(const void *avp, const void *bvp)
{
@@ -2492,7 +2414,7 @@
}
struct timerange
-@@ -2661,44 +2049,25 @@
+@@ -2661,44 +2035,25 @@
count;
int leapbase,
leapcount;
@@ -2539,7 +2461,7 @@
{
while (0 < r.count && hi + 1 < ats[r.base + r.count - 1])
r.count--;
-@@ -2706,9 +2075,6 @@
+@@ -2706,9 +2061,6 @@
r.leapcount--;
}
@@ -2549,7 +2471,7 @@
return r;
}
-@@ -2720,20 +2086,23 @@
+@@ -2720,20 +2072,23 @@
ptrdiff_t i,
j;
int pass;
@@ -2582,7 +2504,7 @@
/*
* Sort.
-@@ -2810,49 +2179,61 @@
+@@ -2810,49 +2165,61 @@
}
}
@@ -2611,9 +2533,8 @@
- max(hi_time,
- redundant_time - (ZIC_MIN < redundant_time)),
- ats, types);
-- range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types);
+ range64 = limitrange(rangeall, lo_time, hi_time, ats, types);
-+ range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types);
+ range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types);
/*
- * TZif version 4 is needed if a no-op transition is appended to indicate
@@ -2674,7 +2595,7 @@
for (pass = 1; pass <= 2; ++pass)
{
ptrdiff_t thistimei,
-@@ -2861,15 +2242,11 @@
+@@ -2861,15 +2228,11 @@
int thisleapi,
thisleapcnt,
thisleaplim;
@@ -2693,7 +2614,7 @@
int old0;
char omittype[TZ_MAX_TYPES];
int typemap[TZ_MAX_TYPES];
-@@ -2883,15 +2260,28 @@
+@@ -2883,15 +2246,28 @@
if (pass == 1)
{
@@ -2701,7 +2622,7 @@
+ /*
+ * Arguably the default time type in the 32-bit data should be
+ * range32.defaulttype, which is suited for timestamps just before
-+ * PG_INT32_MIN. However, zic traditionally used the time type of
++ * INT32_MIN. However, zic traditionally used the time type of
+ * the indefinite past instead. Internet RFC 8532 says readers
+ * should ignore 32-bit data, so this discrepancy matters only to
+ * obsolete readers where the traditional type might be more
@@ -2709,7 +2630,7 @@
+ * value, unless -r specifies a low cutoff that excludes some
+ * 32-bit timestamps.
+ */
-+ thisdefaulttype = (lo_time <= PG_INT32_MIN
++ thisdefaulttype = (lo_time <= INT32_MIN
+ ? range64.defaulttype
+ : range32.defaulttype);
+
@@ -2721,12 +2642,12 @@
- thisleapexpiry = range32.leapexpiry;
- thismin = ZIC32_MIN;
- thismax = ZIC32_MAX;
-+ locut = PG_INT32_MIN < lo_time;
-+ hicut = hi_time < PG_INT32_MAX;
++ locut = INT32_MIN < lo_time;
++ hicut = hi_time < INT32_MAX;
}
else
{
-@@ -2901,52 +2291,40 @@
+@@ -2901,52 +2277,40 @@
toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0;
thisleapi = range64.leapbase;
thisleapcnt = range64.leapcount;
@@ -2801,7 +2722,7 @@
/*
* Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap
-@@ -2972,14 +2350,7 @@
+@@ -2972,14 +2336,7 @@
type;
hidst = histd = mrudst = mrustd = -1;
@@ -2817,7 +2738,7 @@
if (isdsts[types[i]])
mrudst = types[i];
else
-@@ -3059,20 +2430,19 @@
+@@ -3059,20 +2416,19 @@
}
if (pass == 1 && !want_bloat())
{
@@ -2844,11 +2765,16 @@
convert(thistypecnt, tzh.tzh_typecnt);
convert(thischarcnt, tzh.tzh_charcnt);
DO(tzh_magic);
-@@ -3095,26 +2465,62 @@
- continue;
+@@ -3096,25 +2452,67 @@
}
-+ /* PG: print current timezone abbreviations if requested */
+ /*
++ * PG: print current timezone abbreviations if requested. Note that
++ * we cast to int64_t, because int_fast64_t is not required to be
++ * compatible with INT64_FORMAT. We can't use PRIdFAST64 here because
++ * we override fprintf with our own implementation that might not
++ * understand it.
++ */
+ if (print_abbrevs && pass == 2)
+ {
+ /* Print "type" data for periods ending after print_cutoff */
@@ -2861,7 +2787,7 @@
+
+ fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+ thisabbrev,
-+ utoffs[tm],
++ (int64_t) utoffs[tm],
+ isdsts[tm] ? "\tD" : "");
+ }
+ }
@@ -2873,17 +2799,16 @@
+
+ fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
+ thisabbrev,
-+ utoffs[tm],
++ (int64_t) utoffs[tm],
+ isdsts[tm] ? "\tD" : "");
+ }
+ }
+
- /*
++ /*
* Output a LO_TIME transition if needed; see limitrange. But do not
* go below the minimum representable value for this pass.
*/
-- lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time;
-+ lo = pass == 1 && lo_time < PG_INT32_MIN ? PG_INT32_MIN : lo_time;
+ lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time;
- if (0 <= pretranstype)
+ if (locut)
@@ -2915,7 +2840,7 @@
for (i = old0; i < typecnt; i++)
{
-@@ -3131,7 +2537,6 @@
+@@ -3131,7 +2529,6 @@
if (thischarcnt != 0)
fwrite(thischars, sizeof thischars[0],
thischarcnt, fp);
@@ -2923,7 +2848,7 @@
for (i = thisleapi; i < thisleaplim; ++i)
{
zic_t todo;
-@@ -3163,17 +2568,6 @@
+@@ -3163,17 +2560,6 @@
puttzcodepass(todo, fp, pass);
puttzcode(corr[i], fp);
}
@@ -2941,7 +2866,7 @@
if (stdcnt != 0)
for (i = old0; i < typecnt; i++)
if (!omittype[i])
-@@ -3184,8 +2578,7 @@
+@@ -3184,8 +2570,7 @@
putc(ttisuts[i], fp);
}
fprintf(fp, "\n%s\n", string);
@@ -2951,7 +2876,7 @@
free(ats);
}
-@@ -3233,15 +2626,13 @@
+@@ -3233,15 +2618,13 @@
}
}
@@ -2969,7 +2894,7 @@
char const *format = zp->z_format;
slashp = strchr(format, '/');
-@@ -3253,8 +2644,6 @@
+@@ -3253,8 +2636,6 @@
letters = abbroffset(letterbuf, zp->z_stdoff + save);
else if (!letters)
letters = "%s";
@@ -2978,7 +2903,7 @@
sprintf(abbr, format, letters);
}
else if (isdst)
-@@ -3413,17 +2802,11 @@
+@@ -3413,17 +2794,11 @@
return 1;
if (a->r_hiyear != b->r_hiyear)
return a->r_hiyear < b->r_hiyear ? -1 : 1;
@@ -2996,7 +2921,7 @@
static int
stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
{
-@@ -3432,17 +2815,13 @@
+@@ -3432,17 +2807,13 @@
struct rule *stdrp;
struct rule *dstrp;
ptrdiff_t i;
@@ -3016,7 +2941,7 @@
result[0] = '\0';
-@@ -3454,74 +2833,72 @@
+@@ -3454,74 +2825,72 @@
return -1;
zp = zpfirst + zonecount - 1;
@@ -3146,7 +3071,7 @@
if (!offsetlen)
{
result[0] = '\0';
-@@ -3530,12 +2907,12 @@
+@@ -3530,12 +2899,12 @@
len += offsetlen;
if (dstrp == NULL)
return compat;
@@ -3161,7 +3086,7 @@
if (!offsetlen)
{
result[0] = '\0';
-@@ -3544,7 +2921,7 @@
+@@ -3544,7 +2913,7 @@
len += offsetlen;
}
result[len++] = ',';
@@ -3170,7 +3095,7 @@
if (c < 0)
{
result[0] = '\0';
-@@ -3554,7 +2931,7 @@
+@@ -3554,7 +2923,7 @@
compat = c;
len += strlen(result + len);
result[len++] = ',';
@@ -3179,7 +3104,7 @@
if (c < 0)
{
result[0] = '\0';
-@@ -3568,31 +2945,38 @@
+@@ -3568,31 +2937,38 @@
static void
outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
{
@@ -3224,7 +3149,7 @@
startbuf = emalloc(max_abbr_len + 1);
ab = emalloc(max_abbr_len + 1);
envvar = emalloc(max_envvar_len + 1);
-@@ -3605,6 +2989,7 @@
+@@ -3605,6 +2981,7 @@
timecnt = 0;
typecnt = 0;
charcnt = 0;
@@ -3232,7 +3157,7 @@
/*
* Thanks to Earl Chew for noting the need to unconditionally initialize
-@@ -3620,17 +3005,18 @@
+@@ -3620,17 +2997,18 @@
}
for (i = 0; i < zonecount; ++i)
{
@@ -3256,7 +3181,7 @@
}
}
-@@ -3638,14 +3024,13 @@
+@@ -3638,14 +3016,13 @@
* Generate lots of data if a rule can't cover all future times.
*/
compat = stringzone(envvar, zpfirst, zonecount);
@@ -3273,7 +3198,7 @@
zpfirst->z_name);
else if (compat != 0)
{
-@@ -3660,6 +3045,22 @@
+@@ -3660,6 +3037,22 @@
}
if (do_extend)
{
@@ -3296,7 +3221,7 @@
if (min_year >= ZIC_MIN + years_of_observations)
min_year -= years_of_observations;
else
-@@ -3668,9 +3069,18 @@
+@@ -3668,9 +3061,18 @@
max_year += years_of_observations;
else
max_year = ZIC_MAX;
@@ -3317,7 +3242,7 @@
max_year0 = max_year;
if (want_bloat())
{
-@@ -3678,35 +3088,31 @@
+@@ -3678,35 +3080,31 @@
* For the benefit of older systems, generate data from 1900 through
* 2038.
*/
@@ -3366,7 +3291,7 @@
save = zp->z_save;
doabbr(startbuf, zp, NULL, zp->z_isdst, save, false);
type = addtype(oadd(zp->z_stdoff, save),
-@@ -3715,20 +3121,12 @@
+@@ -3715,20 +3113,12 @@
if (usestart)
{
addtt(starttime, type);
@@ -3387,7 +3312,7 @@
for (year = min_year; year <= max_year; ++year)
{
if (useuntil && year > zp->z_untilrule.r_hiyear)
-@@ -3741,12 +3139,9 @@
+@@ -3741,12 +3131,9 @@
*/
for (j = 0; j < zp->z_nrules; ++j)
{
@@ -3403,7 +3328,7 @@
rp->r_todo = year >= rp->r_loyear &&
year <= rp->r_hiyear;
if (rp->r_todo)
-@@ -3763,8 +3158,6 @@
+@@ -3763,8 +3150,6 @@
zic_t jtime,
ktime;
zic_t offset;
@@ -3412,7 +3337,7 @@
INITIALIZE(ktime);
if (useuntil)
-@@ -3789,16 +3182,15 @@
+@@ -3789,16 +3174,15 @@
k = -1;
for (j = 0; j < zp->z_nrules; ++j)
{
@@ -3436,7 +3361,7 @@
if (jtime == min_time ||
jtime == max_time)
continue;
-@@ -3813,12 +3205,12 @@
+@@ -3813,12 +3197,12 @@
char const *dup_rules_msg =
_("two rules for same instant");
@@ -3454,7 +3379,7 @@
error("%s", dup_rules_msg);
}
}
-@@ -3827,15 +3219,7 @@
+@@ -3827,15 +3211,7 @@
rp = &zp->z_rules[k];
rp->r_todo = false;
if (useuntil && ktime >= untiltime)
@@ -3470,7 +3395,7 @@
save = rp->r_save;
if (usestart && ktime == starttime)
usestart = false;
-@@ -3864,41 +3248,44 @@
+@@ -3864,41 +3240,44 @@
false);
}
}
@@ -3534,7 +3459,7 @@
if (defaulttype < 0 && !isdst)
defaulttype = type;
addtt(starttime, type);
-@@ -3921,50 +3308,17 @@
+@@ -3921,50 +3300,17 @@
}
if (defaulttype < 0)
defaulttype = 0;
@@ -3592,7 +3517,7 @@
* transitions up to that point.
*/
struct rule xr;
-@@ -4055,11 +3409,6 @@
+@@ -4055,11 +3401,6 @@
error(_("too many leap seconds"));
exit(EXIT_FAILURE);
}
@@ -3604,7 +3529,7 @@
for (i = 0; i < leapcnt; ++i)
if (t <= trans[i])
break;
-@@ -4094,6 +3443,13 @@
+@@ -4094,6 +3435,13 @@
last = corr[i] += last;
}
@@ -3618,7 +3543,7 @@
if (0 <= leapexpires)
{
leapexpires = oadd(leapexpires, last);
-@@ -4102,6 +3458,8 @@
+@@ -4102,6 +3450,8 @@
error(_("last Leap time does not precede Expires time"));
exit(EXIT_FAILURE);
}
@@ -3627,7 +3552,7 @@
}
}
-@@ -4252,7 +3610,7 @@
+@@ -4252,7 +3602,7 @@
}
/* case-insensitive equality */
@@ -3636,7 +3561,7 @@
ciequal(const char *ap, const char *bp)
{
while (lowerit(*ap) == lowerit(*bp++))
-@@ -4261,7 +3619,7 @@
+@@ -4261,7 +3611,7 @@
return false;
}
@@ -3645,7 +3570,7 @@
itsabbr(const char *abbr, const char *word)
{
if (lowerit(*abbr) != lowerit(*word))
-@@ -4278,7 +3636,7 @@
+@@ -4278,7 +3628,7 @@
/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
@@ -3654,7 +3579,7 @@
ciprefix(char const *abbr, char const *word)
{
do
-@@ -4355,22 +3713,24 @@
+@@ -4355,22 +3705,24 @@
return foundlp;
}
@@ -3684,7 +3609,7 @@
do
{
if ((*dp = *cp++) != '"')
-@@ -4388,53 +3748,48 @@
+@@ -4388,53 +3740,48 @@
if (is_space(*cp))
++cp;
*dp = '\0';
@@ -3765,7 +3690,7 @@
}
/*
-@@ -4450,31 +3805,39 @@
+@@ -4450,31 +3797,39 @@
zic_t dayoff; /* with a nod to Margaret O. */
zic_t t,
y;
@@ -3820,7 +3745,7 @@
}
while (m != rp->r_month)
{
-@@ -4497,17 +3860,27 @@
+@@ -4497,17 +3852,27 @@
dayoff = oadd(dayoff, i);
if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ)
{
@@ -3852,7 +3777,7 @@
wday = 0;
++i;
}
-@@ -4515,7 +3888,7 @@
+@@ -4515,7 +3880,7 @@
{
dayoff = oadd(dayoff, -1);
if (--wday < 0)
@@ -3861,7 +3786,7 @@
--i;
}
if (i < 0 || i >= len_months[isleap(y)][m])
-@@ -4570,13 +3943,15 @@
+@@ -4570,13 +3935,15 @@
/* Ensure that the directories of ARGNAME exist, by making any missing
ones. If ANCESTORS, do this only for ARGNAME's ancestors; otherwise,
do it for ARGNAME too. Exit with failure if there is trouble.
@@ -3880,7 +3805,7 @@
/*
* On MS-Windows systems, do not worry about drive letters or backslashes,
* as this should suffice in practice. Time zone names do not use drive
-@@ -4603,20 +3978,15 @@
+@@ -4603,20 +3970,15 @@
if (mkdir(name, MKDIR_UMASK) != 0)
{
/*
@@ -3906,7 +3831,7 @@
progname, name, strerror(err));
exit(EXIT_FAILURE);
}
-@@ -4626,3 +3996,20 @@
+@@ -4626,3 +3988,20 @@
}
free(name);
}
--- localtime.c-master-vs-upstream.diff 2024-07-04 14:38:31.386232000 +1200
+++ localtime.c-patched-vs-upstream.diff 2024-07-04 14:37:46.783150000 +1200
@@ -1,6 +1,6 @@
--- localtime.filtered.c 2024-07-04 13:04:23.744118000 +1200
-+++ localtime.c 2024-07-04 14:38:19.086065000 +1200
-@@ -3,64 +3,28 @@
++++ localtime.c 2024-07-04 14:17:36.438049000 +1200
+@@ -3,64 +3,29 @@
/*
* This file is in the public domain, so clarified as of
* 1996-06-05 by Arthur David Olson.
@@ -25,6 +25,7 @@
-#include "tzdir.h"
-#include "tzfile.h"
#include <fcntl.h>
++#include <stdint.h>
-#if defined THREAD_SAFE && THREAD_SAFE
-#include <pthread.h>
@@ -75,7 +76,7 @@
#ifndef WILDABBR
/*
* Someone might make incorrect use of a time zone abbreviation:
-@@ -72,7 +36,7 @@
+@@ -72,7 +37,7 @@
* in which Daylight Saving Time is never observed.
* 4. They might reference tzname[0] after setting to a time zone
* in which Standard Time is never observed.
@@ -84,7 +85,7 @@
* What's best to do in the above cases is open to debate;
* for now, we just set things up so that in any of the five cases
* WILDABBR is used. Another possibility: initialize tzname[0] to the
-@@ -81,89 +45,28 @@
+@@ -81,89 +46,28 @@
* manual page of what this "time zone abbreviation" means (doing this so
* that tzname[0] has the "normal" length of three characters).
*/
@@ -179,12 +180,8 @@
};
struct rule
-@@ -172,70 +75,37 @@
- int r_day; /* day number of rule */
- int r_week; /* week number of rule */
- int r_mon; /* month number of rule */
-- int_fast32_t r_time; /* transition time of rule */
-+ int32 r_time; /* transition time of rule */
+@@ -175,64 +79,31 @@
+ int_fast32_t r_time; /* transition time of rule */
};
-static struct pg_tm *gmtsub(struct state const *, pg_time_t const *, int_fast32_t,
@@ -204,13 +201,13 @@
-static struct state *lclptr;
-static struct state *gmtptr;
-#endif /* defined ALL_STATE */
-+static struct pg_tm *gmtsub(pg_time_t const *timep, int32 offset,
++static struct pg_tm *gmtsub(pg_time_t const *timep, int_fast32_t offset,
+ struct pg_tm *tmp);
+static bool increment_overflow(int *ip, int j);
-+static bool increment_overflow_time(pg_time_t *tp, int32 j);
++static bool increment_overflow_time(pg_time_t *tp, int_fast32_t j);
+static int64 leapcorr(struct state const *sp, pg_time_t t);
+static struct pg_tm *timesub(pg_time_t const *timep,
-+ int32 offset, struct state const *sp,
++ int_fast32_t offset, struct state const *sp,
+ struct pg_tm *tmp);
+static bool typesequiv(struct state const *sp, int a, int b);
@@ -259,12 +256,8 @@
-
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
--init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
-+init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
- {
- s->tt_utoff = utoff;
- s->tt_isdst = isdst;
-@@ -244,25 +114,15 @@
+ init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
+@@ -244,16 +115,6 @@
s->tt_ttisut = false;
}
@@ -278,64 +271,13 @@
- return memcmp(abbr, UNSPEC, sizeof UNSPEC) == 0;
-}
-
--static int_fast32_t
-+static int32
+ static int_fast32_t
detzcode(const char *const codep)
{
-- int_fast32_t result;
-+ int32 result;
- int i;
-- int_fast32_t one = 1;
-- int_fast32_t halfmaxval = one << (32 - 2);
-- int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
-- int_fast32_t minval = -1 - maxval;
-+ int32 one = 1;
-+ int32 halfmaxval = one << (32 - 2);
-+ int32 maxval = halfmaxval - 1 + halfmaxval;
-+ int32 minval = -1 - maxval;
-
- result = codep[0] & 0x7f;
- for (i = 1; i < 4; ++i)
-@@ -274,21 +134,21 @@
- * Do two's-complement negation even on non-two's-complement machines.
- * If the result would be minval - 1, return minval.
- */
-- result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
-+ result -= !TWOS_COMPLEMENT(int32) && result != 0;
- result += minval;
- }
+@@ -306,125 +167,25 @@
return result;
}
--static int_fast64_t
-+static int64
- detzcode64(const char *const codep)
- {
-- int_fast64_t result;
-+ uint64 result;
- int i;
-- int_fast64_t one = 1;
-- int_fast64_t halfmaxval = one << (64 - 2);
-- int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
-- int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
-+ int64 one = 1;
-+ int64 halfmaxval = one << (64 - 2);
-+ int64 maxval = halfmaxval - 1 + halfmaxval;
-+ int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
-
- result = codep[0] & 0x7f;
- for (i = 1; i < 8; ++i)
-@@ -300,131 +160,31 @@
- * Do two's-complement negation even on non-two's-complement machines.
- * If the result would be minval - 1, return minval.
- */
-- result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
-+ result -= !TWOS_COMPLEMENT(int64) && result != 0;
- result += minval;
- }
- return result;
- }
-
-static void
-update_tzname_etc(struct state const *sp, struct ttinfo const *ttisp)
+static bool
@@ -464,7 +406,7 @@
/* Local storage needed for 'tzloadbody'. */
union local_storage
{
-@@ -438,28 +198,23 @@
+@@ -438,28 +199,23 @@
struct state st;
} u;
@@ -500,7 +442,7 @@
union input_buffer *up = &lsp->u.u;
int tzheadsize = sizeof(struct tzhead);
-@@ -474,50 +229,10 @@
+@@ -474,50 +230,10 @@
if (name[0] == ':')
++name;
@@ -553,33 +495,23 @@
nread = read(fid, up->buf, sizeof up->buf);
if (nread < tzheadsize)
-@@ -531,17 +246,14 @@
+@@ -531,13 +247,10 @@
return errno;
for (stored = 4; stored <= 8; stored *= 2)
{
- char version = up->tzhead.tzh_version[0];
- bool skip_datablock = stored == 4 && version;
- int_fast32_t datablock_size;
-- int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
-- int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
+ int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
- int_fast64_t prevtr = -1;
- int_fast32_t prevcorr;
-- int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
-- int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
-- int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
-- int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
-+ int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
-+ int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
-+ int64 prevtr = 0;
-+ int32 prevcorr = 0;
-+ int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
-+ int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
-+ int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
-+ int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
- char const *p = up->buf + tzheadsize;
-
- /*
-@@ -553,177 +265,152 @@
++ int_fast64_t prevtr = 0;
++ int_fast32_t prevcorr = 0;
+ int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+ int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+ int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+@@ -553,177 +266,152 @@
&& 0 <= typecnt && typecnt < TZ_MAX_TYPES
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
@@ -743,8 +675,8 @@
+ leapcnt = 0;
+ for (i = 0; i < sp->leapcnt; ++i)
+ {
-+ int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
-+ int32 corr = detzcode(p + stored);
++ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
++ int_fast32_t corr = detzcode(p + stored);
- /* Read leap seconds, discarding those out of pg_time_t range. */
- leapcnt = 0;
@@ -764,7 +696,7 @@
- * Leap seconds cannot occur before the Epoch, or out of
- * order.
+ * Leap seconds cannot occur more than once per UTC month, and
-+ * UTC months are at least 28 days long (minus 1 second for a
++ * UTC months are at least 2 days long (minus 1 second for a
+ * negative leap second). Each leap second's correction must
+ * differ from the previous one's by 1 second.
*/
@@ -870,7 +802,7 @@
}
if (doextend && nread > 2 &&
up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
-@@ -732,9 +419,8 @@
+@@ -732,9 +420,8 @@
struct state *ts = &lsp->u.st;
up->buf[nread - 1] = '\0';
@@ -881,7 +813,7 @@
/*
* Attempt to reuse existing abbreviations. Without this,
* America/Anchorage would be right on the edge after 2037 when
-@@ -785,25 +471,20 @@
+@@ -785,25 +472,20 @@
== sp->types[sp->timecnt - 2]))
sp->timecnt--;
@@ -916,7 +848,7 @@
}
for (i = 0; i < ts->typecnt; i++)
sp->ttis[sp->typecnt++] = ts->ttis[i];
-@@ -812,6 +493,25 @@
+@@ -812,6 +494,25 @@
}
if (sp->typecnt == 0)
return EINVAL;
@@ -942,7 +874,7 @@
/*
* Infer sp->defaulttype from the data. Although this default type is
-@@ -826,13 +526,13 @@
+@@ -826,13 +527,13 @@
*/
/*
@@ -959,7 +891,7 @@
/*
* Absent the above, if there are transition times and the first
-@@ -878,29 +578,49 @@
+@@ -878,29 +579,49 @@
}
/* Load tz data from the file named NAME into *SP. Read extended
@@ -1021,7 +953,7 @@
}
static const int mon_lengths[2][MONSPERYEAR] = {
-@@ -912,20 +632,13 @@
+@@ -912,20 +633,13 @@
DAYSPERNYEAR, DAYSPERLYEAR
};
@@ -1043,7 +975,7 @@
getzname(const char *strp)
{
char c;
-@@ -946,7 +659,7 @@
+@@ -946,7 +660,7 @@
* We don't do any checking here; checking is done later in common-case code.
*/
@@ -1052,16 +984,9 @@
getqzname(const char *strp, const int delim)
{
int c;
-@@ -994,20 +707,19 @@
- */
+@@ -1000,8 +714,8 @@
+ int_fast32_t secsperhour = SECSPERHOUR;
- static const char *
--getsecs(const char *strp, int_fast32_t * const secsp)
-+getsecs(const char *strp, int32 *const secsp)
- {
- int num;
-- int_fast32_t secsperhour = SECSPERHOUR;
-
/*
- * 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-POSIX rules like
- * "M10.4.6/26", which does not conform to POSIX, but which specifies the
@@ -1070,24 +995,8 @@
* equivalent of "02:00 on the first Sunday on or after 23 Oct".
*/
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
- if (strp == NULL)
- return NULL;
-- *secsp = num * secsperhour;
-+ *secsp = num * (int32) SECSPERHOUR;
- if (*strp == ':')
- {
- ++strp;
-@@ -1036,7 +748,7 @@
- */
+@@ -1057,8 +771,7 @@
- static const char *
--getoffset(const char *strp, int_fast32_t * const offsetp)
-+getoffset(const char *strp, int32 *const offsetp)
- {
- bool neg = false;
-
-@@ -1057,8 +769,7 @@
-
/*
* Given a pointer into a timezone string, extract a rule in the form
- * date[/time]. See POSIX Base Definitions section 8.3 variable TZ
@@ -1096,23 +1005,7 @@
* If a valid rule is not found, return NULL.
* Otherwise, return a pointer to the first character not part of the rule.
*/
-@@ -1124,12 +835,12 @@
- * effect, calculate the year-relative time that rule takes effect.
- */
-
--static int_fast32_t
-+static int32
- transtime(const int year, const struct rule *const rulep,
-- const int_fast32_t offset)
-+ const int32 offset)
- {
- bool leapyear;
-- int_fast32_t value;
-+ int32 value;
- int i;
- int d,
- m1,
-@@ -1138,6 +849,7 @@
+@@ -1138,6 +851,7 @@
yy2,
dow;
@@ -1120,7 +1013,7 @@
leapyear = isleap(year);
switch (rulep->r_type)
{
-@@ -1193,7 +905,7 @@
+@@ -1193,7 +907,7 @@
for (i = 1; i < rulep->r_week; ++i)
{
if (d + DAYSPERWEEK >=
@@ -1129,7 +1022,7 @@
break;
d += DAYSPERWEEK;
}
-@@ -1203,11 +915,8 @@
+@@ -1203,11 +917,8 @@
*/
value = d * SECSPERDAY;
for (i = 0; i < rulep->r_mon - 1; ++i)
@@ -1142,7 +1035,7 @@
}
/*
-@@ -1219,64 +928,71 @@
+@@ -1219,64 +930,71 @@
}
/*
@@ -1159,14 +1052,12 @@
{
const char *stdname;
- const char *dstname;
-- int_fast32_t stdoffset;
-- int_fast32_t dstoffset;
+ const char *dstname = NULL;
+ size_t stdlen;
+ size_t dstlen;
+ size_t charcnt;
-+ int32 stdoffset;
-+ int32 dstoffset;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
char *cp;
bool load_ok;
- ptrdiff_t stdlen,
@@ -1258,7 +1149,7 @@
if (*name != '\0')
{
if (*name == '<')
-@@ -1294,9 +1010,11 @@
+@@ -1294,9 +1012,11 @@
name = getzname(name);
dstlen = name - dstname; /* length of DST abbr. */
}
@@ -1271,22 +1162,21 @@
if (*name != '\0' && *name != ',' && *name != ';')
{
name = getoffset(name, &dstoffset);
-@@ -1312,11 +1030,11 @@
+@@ -1312,11 +1032,11 @@
struct rule start;
struct rule end;
int year;
+ int yearlim;
int timecnt;
pg_time_t janfirst;
-- int_fast32_t janoffset = 0;
+ int_fast32_t janoffset = 0;
- int yearbeg,
- yearlim;
-+ int32 janoffset = 0;
+ int yearbeg;
++name;
if ((name = getrule(name, &start)) == NULL)
-@@ -1334,13 +1052,14 @@
+@@ -1334,6 +1054,7 @@
*/
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
@@ -1294,15 +1184,7 @@
timecnt = 0;
janfirst = 0;
yearbeg = EPOCH_YEAR;
-
- do
- {
-- int_fast32_t yearsecs
-+ int32 yearsecs
- = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
-
- yearbeg--;
-@@ -1349,72 +1068,48 @@
+@@ -1349,27 +1070,9 @@
janoffset = -yearsecs;
break;
}
@@ -1331,27 +1213,8 @@
+ yearlim = yearbeg + YEARSPERREPEAT + 1;
for (year = yearbeg; year < yearlim; year++)
{
-- int_fast32_t
-- starttime = transtime(year, &start, stdoffset),
-- endtime = transtime(year, &end, dstoffset);
-- int_fast32_t
-- yearsecs = (year_lengths[isleap(year)]
-- * SECSPERDAY);
-+ int32
-+ starttime = transtime(year, &start, stdoffset),
-+ endtime = transtime(year, &end, dstoffset);
-+ int32
-+ yearsecs = (year_lengths[isleap(year)]
-+ * SECSPERDAY);
- bool reversed = endtime < starttime;
-
- if (reversed)
- {
-- int_fast32_t swap = starttime;
-+ int32 swap = starttime;
-
- starttime = endtime;
- endtime = swap;
+ int_fast32_t
+@@ -1389,32 +1092,26 @@
}
if (reversed
|| (starttime < endtime
@@ -1390,7 +1253,7 @@
if (increment_overflow_time
(&janfirst, janoffset + yearsecs))
break;
-@@ -1426,14 +1121,14 @@
+@@ -1426,7 +1123,7 @@
sp->ttis[0] = sp->ttis[1];
sp->typecnt = 1; /* Perpetual DST. */
}
@@ -1399,17 +1262,7 @@
sp->goback = sp->goahead = true;
}
else
- {
-- int_fast32_t theirstdoffset;
-- int_fast32_t theirdstoffset;
-- int_fast32_t theiroffset;
-+ int32 theirstdoffset;
-+ int32 theirdstoffset;
-+ int32 theiroffset;
- bool isdst;
- int i;
- int j;
-@@ -1471,6 +1166,7 @@
+@@ -1471,6 +1168,7 @@
* Initially we're assumed to be in standard time.
*/
isdst = false;
@@ -1417,7 +1270,7 @@
/*
* Now juggle transition times and types tracking offsets as you
-@@ -1495,7 +1191,7 @@
+@@ -1495,7 +1193,7 @@
*/
/*
* Transitions from DST to DDST will effectively disappear
@@ -1426,7 +1279,7 @@
*/
if (isdst && !sp->ttis[j].tt_ttisstd)
{
-@@ -1521,6 +1217,7 @@
+@@ -1521,6 +1219,7 @@
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1);
sp->typecnt = 2;
@@ -1434,7 +1287,7 @@
}
}
else
-@@ -1529,8 +1226,8 @@
+@@ -1529,8 +1228,8 @@
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
@@ -1444,7 +1297,7 @@
sp->charcnt = charcnt;
cp = sp->chars;
memcpy(cp, stdname, stdlen);
-@@ -1547,155 +1244,19 @@
+@@ -1547,155 +1246,19 @@
static void
gmtload(struct state *const sp)
{
@@ -1603,7 +1456,7 @@
struct pg_tm *const tmp)
{
const struct ttinfo *ttisp;
-@@ -1704,14 +1265,11 @@
+@@ -1704,14 +1267,11 @@
const pg_time_t t = *timep;
if (sp == NULL)
@@ -1620,7 +1473,7 @@
pg_time_t seconds;
pg_time_t years;
-@@ -1720,34 +1278,19 @@
+@@ -1720,33 +1280,18 @@
else
seconds = t - sp->ats[sp->timecnt - 1];
--seconds;
@@ -1655,12 +1508,10 @@
- result->tm_year, years))
- return NULL;
-#else
-- int_fast64_t newy;
-+ int64 newy;
+ int_fast64_t newy;
newy = result->tm_year;
- if (t < sp->ats[0])
-@@ -1757,7 +1300,6 @@
+@@ -1757,7 +1302,6 @@
if (!(INT_MIN <= newy && newy <= INT_MAX))
return NULL;
result->tm_year = newy;
@@ -1668,7 +1519,7 @@
}
return result;
}
-@@ -1779,7 +1321,7 @@
+@@ -1779,7 +1323,7 @@
else
lo = mid + 1;
}
@@ -1677,7 +1528,7 @@
}
ttisp = &sp->ttis[i];
-@@ -1792,132 +1334,76 @@
+@@ -1792,132 +1336,76 @@
if (result)
{
result->tm_isdst = ttisp->tt_isdst;
@@ -1745,7 +1596,7 @@
static struct pg_tm *
-gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, pg_time_t const *timep,
- int_fast32_t offset, struct pg_tm *tmp)
-+gmtsub(pg_time_t const *timep, int32 offset,
++gmtsub(pg_time_t const *timep, int_fast32_t offset,
+ struct pg_tm *tmp)
{
struct pg_tm *result;
@@ -1840,13 +1691,7 @@
{
return (y < 0
? -1 - leaps_thru_end_of_nonneg(-1 - y)
-@@ -1925,28 +1411,21 @@
- }
-
- static struct pg_tm *
--timesub(const pg_time_t *timep, int_fast32_t offset,
-+timesub(const pg_time_t *timep, int32 offset,
- const struct state *sp, struct pg_tm *tmp)
+@@ -1930,23 +1418,16 @@
{
const struct lsinfo *lp;
pg_time_t tdays;
@@ -1876,7 +1721,7 @@
i = (sp == NULL) ? 0 : sp->leapcnt;
while (--i >= 0)
{
-@@ -1954,175 +1433,134 @@
+@@ -1954,175 +1435,134 @@
if (*timep >= lp->ls_trans)
{
corr = lp->ls_corr;
@@ -2092,8 +1937,7 @@
static bool
-increment_overflow32(int_fast32_t * const lp, int const m)
-+increment_overflow_time(pg_time_t *tp, int32 j)
- {
+-{
-#ifdef ckd_add
- return ckd_add(lp, *lp, m);
-#else
@@ -2107,8 +1951,8 @@
-}
-
-static bool
--increment_overflow_time(pg_time_t *tp, int_fast32_t j)
--{
+ increment_overflow_time(pg_time_t *tp, int_fast32_t j)
+ {
-#ifdef ckd_add
- return ckd_add(tp, *tp, j);
-#else
@@ -2124,7 +1968,7 @@
*/
if (!(j < 0
? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
-@@ -2130,637 +1568,339 @@
+@@ -2130,637 +1570,339 @@
return true;
*tp += j;
return false;
[text/x-patch] v3-0001-Use-int64_t-support-from-stdint.h.patch (47.7K, ../../CA+hUKG+rYp-=fTP5kjRmnfPq7YgK-e=J+gJxBvKarkPVzLwQmQ@mail.gmail.com/3-v3-0001-Use-int64_t-support-from-stdint.h.patch)
download | inline diff:
From eb323ba495a302540945bcb9c6527bdcce87d9a2 Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 18 Apr 2024 07:53:10 +1200
Subject: [PATCH v3 1/3] Use int64_t support from <stdint.h>.
Remove most of the configure probes for 64 bit integers. Map our names
to the standard C99 names for types like int64_t, limits like INT64_MAX,
constant constructors like INT64_C().
Unfortunately we can't use standard printf format macros like PRId64
from <inttypes.h>, because we have our own snprintf.c implementation.
It does not understand Windows' PRId64 macro, for example. Selecting
between "l" and "ll" by size alone is trivial, but we still some
configure-time help to work out which one will compile warning-free when
both are candidates, on systems that support printf format string type
checking.
We can get rid of pg_config_ext.h, which existed only to define
PG_INT64_TYPE for client interfaces, which is now redundant.
Reviewed-by: Peter Eisentraut <[email protected]>
Reviewed-by: Heikki Linnakangas <[email protected]>
Reviewed-by: Japin Li <[email protected]>
Reviewed-by: Tom Lane <[email protected]> (the idea, not the patch)
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
config/c-compiler.m4 | 111 +++---
configure | 377 ++++++------------
configure.ac | 54 +--
meson.build | 63 +--
src/Makefile.global.in | 6 -
src/include/.gitignore | 2 -
src/include/Makefile | 8 +-
src/include/c.h | 78 ++--
src/include/meson.build | 10 -
src/include/pg_config.h.in | 17 +-
src/include/pg_config_ext.h.in | 7 -
src/include/pg_config_ext.h.meson | 7 -
src/include/port/pg_bitutils.h | 18 +-
src/include/postgres_ext.h | 7 +-
src/interfaces/ecpg/ecpglib/typename.c | 5 +-
src/interfaces/ecpg/include/ecpg_config.h.in | 9 -
src/interfaces/ecpg/include/meson.build | 3 -
.../ecpg/include/pgtypes_interval.h | 13 +-
src/interfaces/ecpg/include/sqltypes.h | 2 +-
.../test/expected/compat_informix-sqlda.c | 2 +-
src/port/pg_bitutils.c | 7 +-
src/port/snprintf.c | 14 +-
22 files changed, 268 insertions(+), 552 deletions(-)
delete mode 100644 src/include/pg_config_ext.h.in
delete mode 100644 src/include/pg_config_ext.h.meson
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 10f8c7bd0a9..b3fdf1b8c48 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -38,58 +38,41 @@ ac_c_werror_flag=$ac_save_c_werror_flag
])# PGAC_TEST_PRINTF_ARCHETYPE
-# PGAC_TYPE_64BIT_INT(TYPE)
-# -------------------------
-# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
-# yes or no respectively, and define HAVE_TYPE_64 if yes.
-AC_DEFUN([PGAC_TYPE_64BIT_INT],
-[define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
-define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
-AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
-[AC_RUN_IFELSE([AC_LANG_SOURCE(
-[typedef $1 ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}])],
-[Ac_cachevar=yes],
-[Ac_cachevar=no],
-[# If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
- Ac_cachevar=yes,
- Ac_cachevar=no)])])
-
-Ac_define=$Ac_cachevar
-if test x"$Ac_cachevar" = xyes ; then
- AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
+# PGAC_PRINTF_INT64_MODIFIER
+# --------------------------
+# Determine which printf format modifier to use for int64_t values, to avoid
+# warnings from the format string checker (if there is one).
+AC_DEFUN([PGAC_PRINTF_INT64_MODIFIER],
+[AC_CACHE_CHECK([for printf int64_t modifier], pgac_cv_int64_modifier,
+[
+ac_save_c_werror_flag=$ac_c_werror_flag
+ac_c_werror_flag=yes
+if test "$ac_cv_sizeof_long" -lt 8; then
+ # long isn't wide enough, so use "ll"
+ pgac_cv_int64_modifier='"ll"'
+else
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[#include <stdint.h>],
+[extern void emit_log(int ignore, const char *fmt,...) __attribute__((format(printf,2,3)));
+ void
+ f()
+ {
+ emit_log(0, "%lld", (int64_t) 42);
+ }])],
+ # this system understands the attribute, and accepted "ll" without
+ # warning, so go with that (example: macOS)
+ [pgac_cv_int64_modifier='"ll"'],
+ # either this system doesn't understand the attribute at all (and
+ # "l" should be fine because now we only care about getting the
+ # right size), or it rejected "ll" with warnings because it expected
+ # "l" (example: FreeBSD)
+ [pgac_cv_int64_modifier='"l"'])
fi
-undefine([Ac_define])dnl
-undefine([Ac_cachevar])dnl
-])# PGAC_TYPE_64BIT_INT
+ac_c_werror_flag=$ac_save_c_werror_flag
+])
+AC_DEFINE_UNQUOTED([INT64_MODIFIER], [$pgac_cv_int64_modifier],
+[Define to printf format modifier to use for int64_t.])
+])# PGAC_PRINTF_INT64_MODIFIER
# PGAC_TYPE_128BIT_INT
@@ -269,10 +252,11 @@ fi])# PGAC_C_BUILTIN_CONSTANT_P
# optimize away the call.
AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW],
[AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+[
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
int oflo;
],
[oflo = __builtin_mul_overflow(a, b, &result);])],
@@ -557,9 +541,9 @@ fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
# types, and define HAVE_GCC__SYNC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);])],
[pgac_cv_gcc_sync_int64_cas="yes"],
[pgac_cv_gcc_sync_int64_cas="no"])])
if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
@@ -588,9 +572,9 @@ fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
[pgac_cv_gcc_atomic_int64_cas="yes"],
[pgac_cv_gcc_atomic_int64_cas="no"])])
@@ -733,9 +717,10 @@ AC_DEFUN([PGAC_AVX512_POPCNT_INTRINSICS],
AC_CACHE_CHECK([for _mm512_popcnt_epi64 with CFLAGS=$1], [Ac_cachevar],
[pgac_save_CFLAGS=$CFLAGS
CFLAGS="$pgac_save_CFLAGS $1"
-AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>],
+AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>
+ #include <stdint.h>],
[const char buf@<:@sizeof(__m512i)@:>@;
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
diff --git a/configure b/configure
index 76f06bd8fda..cfec577a1c1 100755
--- a/configure
+++ b/configure
@@ -14546,6 +14546,42 @@ if test x"$pgac_cv__builtin_constant_p" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CONSTANT_P 1" >>confdefs.h
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
+$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
+if ${pgac_cv__builtin_op_overflow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdint.h>
+int
+main ()
+{
+
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
+int oflo;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ pgac_cv__builtin_op_overflow=yes
+else
+ pgac_cv__builtin_op_overflow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
+$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
+if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
+
+$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_unreachable" >&5
$as_echo_n "checking for __builtin_unreachable... " >&6; }
@@ -16439,236 +16475,6 @@ fi
# Run tests below here
# --------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5
-$as_echo_n "checking whether long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_int_64" >&6; }
-
-HAVE_LONG_INT_64=$pgac_cv_type_long_int_64
-if test x"$pgac_cv_type_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h
-
-fi
-
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5
-$as_echo_n "checking whether long long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_long_int_64" >&6; }
-
-HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64
-if test x"$pgac_cv_type_long_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h
-
-fi
-
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- as_fn_error $? "Cannot find a working 64-bit integer type." "$LINENO" 5
- fi
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define PG_INT64_TYPE $pg_int64_type
-_ACEOF
-
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define INT64_MODIFIER $INT64_MODIFIER
-_ACEOF
-
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
-$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
-if ${pgac_cv__builtin_op_overflow+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
-int oflo;
-
-int
-main ()
-{
-oflo = __builtin_mul_overflow(a, b, &result);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- pgac_cv__builtin_op_overflow=yes
-else
- pgac_cv__builtin_op_overflow=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
-$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
-if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
-
-$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
-
-fi
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
@@ -16877,43 +16683,41 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- # The cast to long int works around a bug in the HP C Compiler,
+# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long long int" >&5
-$as_echo_n "checking alignment of long long int... " >&6; }
-if ${ac_cv_alignof_long_long_int+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of int64_t" >&5
+$as_echo_n "checking alignment of int64_t... " >&6; }
+if ${ac_cv_alignof_int64_t+:} false; then :
$as_echo_n "(cached) " >&6
else
- if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long_long_int" "$ac_includes_default
+ if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_int64_t" "$ac_includes_default
#ifndef offsetof
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
#endif
-typedef struct { char x; long long int y; } ac__type_alignof_;"; then :
+typedef struct { char x; int64_t y; } ac__type_alignof_;"; then :
else
- if test "$ac_cv_type_long_long_int" = yes; then
+ if test "$ac_cv_type_int64_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute alignment of long long int
+as_fn_error 77 "cannot compute alignment of int64_t
See \`config.log' for more details" "$LINENO" 5; }
else
- ac_cv_alignof_long_long_int=0
+ ac_cv_alignof_int64_t=0
fi
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long_long_int" >&5
-$as_echo "$ac_cv_alignof_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_int64_t" >&5
+$as_echo "$ac_cv_alignof_int64_t" >&6; }
cat >>confdefs.h <<_ACEOF
-#define ALIGNOF_LONG_LONG_INT $ac_cv_alignof_long_long_int
+#define ALIGNOF_INT64_T $ac_cv_alignof_int64_t
_ACEOF
-fi
# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of double" >&5
@@ -16971,8 +16775,8 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
@@ -16980,7 +16784,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-
# Some platforms predefine the types int8, int16, etc. Only check
# a (hopefully) representative subset.
ac_fn_c_check_type "$LINENO" "int8" "ac_cv_type_int8" "#include <stdio.h>
@@ -17025,6 +16828,60 @@ _ACEOF
fi
+# Check how to format int64_t without warnings from printf.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf int64_t modifier" >&5
+$as_echo_n "checking for printf int64_t modifier... " >&6; }
+if ${pgac_cv_int64_modifier+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ac_save_c_werror_flag=$ac_c_werror_flag
+ac_c_werror_flag=yes
+if test "$ac_cv_sizeof_long" -lt 8; then
+ # long isn't wide enough, so use "ll"
+ pgac_cv_int64_modifier='"ll"'
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdint.h>
+int
+main ()
+{
+extern void emit_log(int ignore, const char *fmt,...) __attribute__((format(printf,2,3)));
+ void
+ f()
+ {
+ emit_log(0, "%lld", (int64_t) 42);
+ }
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # this system understands the attribute, and accepted "ll" without
+ # warning, so go with that (example: macOS)
+ pgac_cv_int64_modifier='"ll"'
+else
+ # either this system doesn't understand the attribute at all (and
+ # "l" should be fine because now we only care about getting the
+ # right size), or it rejected "ll" with warnings because it expected
+ # "l" (example: FreeBSD)
+ pgac_cv_int64_modifier='"l"'
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_c_werror_flag=$ac_save_c_werror_flag
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_int64_modifier" >&5
+$as_echo "$pgac_cv_int64_modifier" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define INT64_MODIFIER $pgac_cv_int64_modifier
+_ACEOF
+
+
+
# Some compilers offer a 128-bit integer scalar type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
$as_echo_n "checking for __int128... " >&6; }
@@ -17279,12 +17136,12 @@ if ${pgac_cv_gcc_sync_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);
+int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);
;
return 0;
}
@@ -17344,12 +17201,12 @@ if ${pgac_cv_gcc_atomic_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
;
return 0;
@@ -17604,11 +17461,12 @@ CFLAGS="$pgac_save_CFLAGS "
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <immintrin.h>
+ #include <stdint.h>
int
main ()
{
const char buf[sizeof(__m512i)];
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -17647,11 +17505,12 @@ CFLAGS="$pgac_save_CFLAGS -mavx512vpopcntdq -mavx512bw"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <immintrin.h>
+ #include <stdint.h>
int
main ()
{
const char buf[sizeof(__m512i)];
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -19272,9 +19131,6 @@ fi
ac_config_headers="$ac_config_headers src/include/pg_config.h"
-ac_config_headers="$ac_config_headers src/include/pg_config_ext.h"
-
-
ac_config_headers="$ac_config_headers src/interfaces/ecpg/include/ecpg_config.h"
@@ -19989,7 +19845,6 @@ do
"src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;;
"src/include/pg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
- "src/include/pg_config_ext.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config_ext.h" ;;
"src/interfaces/ecpg/include/ecpg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/interfaces/ecpg/include/ecpg_config.h" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -20597,10 +20452,6 @@ $as_echo "$as_me: WARNING: *** link for $FILE -- please fix by hand" >&2;}
"src/include/pg_config.h":H)
# Update timestamp for pg_config.h (see Makefile.global)
echo >src/include/stamp-h
- ;;
- "src/include/pg_config_ext.h":H)
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
;;
"src/interfaces/ecpg/include/ecpg_config.h":H) echo >src/interfaces/ecpg/include/stamp-h ;;
diff --git a/configure.ac b/configure.ac
index ab2d51c21ce..10bfb994d4f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1630,6 +1630,7 @@ PGAC_C_STATIC_ASSERT
PGAC_C_TYPEOF
PGAC_C_TYPES_COMPATIBLE
PGAC_C_BUILTIN_CONSTANT_P
+PGAC_C_BUILTIN_OP_OVERFLOW
PGAC_C_BUILTIN_UNREACHABLE
PGAC_C_COMPUTED_GOTO
PGAC_STRUCT_TIMEZONE
@@ -1945,41 +1946,6 @@ for the exact reason.]])],
# Run tests below here
# --------------------
-dnl Check to see if we have a working 64-bit integer type.
-dnl Since Postgres 8.4, we no longer support compilers without a working
-dnl 64-bit type; but we have to determine whether that type is called
-dnl "long int" or "long long int".
-
-PGAC_TYPE_64BIT_INT([long int])
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- PGAC_TYPE_64BIT_INT([long long int])
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- AC_MSG_ERROR([Cannot find a working 64-bit integer type.])
- fi
-fi
-
-AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type,
- [Define to the name of a signed 64-bit integer type.])
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER,
- [Define to the appropriate printf length modifier for 64-bit ints.])
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-PGAC_C_BUILTIN_OP_OVERFLOW
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF([size_t])
@@ -1990,9 +1956,7 @@ AC_CHECK_SIZEOF([long])
AC_CHECK_ALIGNOF(short)
AC_CHECK_ALIGNOF(int)
AC_CHECK_ALIGNOF(long)
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- AC_CHECK_ALIGNOF(long long int)
-fi
+AC_CHECK_ALIGNOF(int64_t)
AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
@@ -2016,17 +1980,19 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- AC_MSG_ERROR([alignment of 'long long int' is greater than the alignment of 'double'])
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ AC_MSG_ERROR([alignment of 'int64_t' is greater than the alignment of 'double'])
fi
AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.])
-
# Some platforms predefine the types int8, int16, etc. Only check
# a (hopefully) representative subset.
AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
[#include <stdio.h>])
+# Check how to format int64_t without warnings from printf.
+PGAC_PRINTF_INT64_MODIFIER
+
# Some compilers offer a 128-bit integer scalar type.
PGAC_TYPE_128BIT_INT
@@ -2520,12 +2486,6 @@ AC_CONFIG_HEADERS([src/include/pg_config.h],
echo >src/include/stamp-h
])
-AC_CONFIG_HEADERS([src/include/pg_config_ext.h],
-[
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
-])
-
AC_CONFIG_HEADERS([src/interfaces/ecpg/include/ecpg_config.h],
[echo >src/interfaces/ecpg/include/stamp-h])
diff --git a/meson.build b/meson.build
index 5387bb6d5fd..6534bf6e17d 100644
--- a/meson.build
+++ b/meson.build
@@ -1491,18 +1491,6 @@ endif
sizeof_long = cc.sizeof('long', args: test_c_args)
cdata.set('SIZEOF_LONG', sizeof_long)
-if sizeof_long == 8
- cdata.set('HAVE_LONG_INT_64', 1)
- pg_int64_type = 'long int'
- cdata.set_quoted('INT64_MODIFIER', 'l')
-elif sizeof_long == 4 and cc.sizeof('long long', args: test_c_args) == 8
- cdata.set('HAVE_LONG_LONG_INT_64', 1)
- pg_int64_type = 'long long int'
- cdata.set_quoted('INT64_MODIFIER', 'll')
-else
- error('do not know how to get a 64bit int')
-endif
-cdata.set('PG_INT64_TYPE', pg_int64_type)
if host_machine.endian() == 'big'
cdata.set('WORDS_BIGENDIAN', 1)
@@ -1532,8 +1520,8 @@ endforeach
# any types wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8
# would be too much of a penalty for disk and memory space.
alignof_double = cdata.get('ALIGNOF_DOUBLE')
-if cc.alignment(pg_int64_type, args: test_c_args) > alignof_double
- error('alignment of int64 is greater than the alignment of double')
+if cc.alignment('int64_t', args: test_c_args, prefix: '#include <stdint.h>') > alignof_double
+ error('alignment of int64_t is greater than the alignment of double')
endif
cdata.set('MAXIMUM_ALIGNOF', alignof_double)
@@ -1686,6 +1674,34 @@ foreach a : printf_attributes
endforeach
+# Determine which printf format modifier to use for int64_t values, to avoid
+# warnings from the format string checker (if there is one).
+if cdata.get('SIZEOF_LONG') < 8
+ # long isn't wide enough, so use "ll"
+ cdata.set('INT64_MODIFIER', '"ll"')
+else
+ testsrc = '''
+#include <stdint.h>
+extern void emit_log(int ignore, const char *fmt,...) __attribute__((format(printf,2,3)));
+void
+f()
+{
+ emit_log(0, "%lld", (int64_t) 42);
+}
+'''
+ if cc.compiles(testsrc, args: test_c_args + attrib_error_args)
+ # this system understands the attribute, and accepted "ll" without warning,
+ # so go with that (example: macOS)
+ cdata.set('INT64_MODIFIER', '"ll"')
+ else
+ # either this system doesn't understand the attribute at all (and "l" should
+ # be fine because now we only care about getting the right size), or it
+ # rejected "ll" with warnings because it expected "l" (example: FreeBSD)
+ cdata.set('INT64_MODIFIER', '"l"')
+ endif
+endif
+
+
if cc.has_function_attribute('visibility:default') and \
cc.has_function_attribute('visibility:hidden')
cdata.set('HAVE_VISIBILITY_ATTRIBUTE', 1)
@@ -1745,17 +1761,17 @@ endif
# compile, and store the results in global variables so the compiler doesn't
# optimize away the call.
if cc.links('''
- INT64 a = 1;
- INT64 b = 1;
- INT64 result;
+ #include <stdint.h>
+ int64_t a = 1;
+ int64_t b = 1;
+ int64_t result;
int main(void)
{
return __builtin_mul_overflow(a, b, &result);
}''',
name: '__builtin_mul_overflow',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))],
- )
+ args: test_c_args)
cdata.set('HAVE__BUILTIN_OP_OVERFLOW', 1)
endif
@@ -2048,7 +2064,7 @@ int main(void)
cdata.set(check['name'],
cc.links(test,
name: check['desc'],
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))]) ? 1 : false
+ args: test_c_args) ? 1 : false
)
endforeach
@@ -2092,11 +2108,12 @@ if host_cpu == 'x86_64'
prog = '''
#include <immintrin.h>
+#include <stdint.h>
int main(void)
{
const char buf[sizeof(__m512i)];
- INT64 popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -2108,10 +2125,10 @@ int main(void)
'''
if cc.links(prog, name: 'AVX-512 popcount without -mavx512vpopcntdq -mavx512bw',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))])
+ args: test_c_args)
cdata.set('USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 1)
elif cc.links(prog, name: 'AVX-512 popcount with -mavx512vpopcntdq -mavx512bw',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))] + ['-mavx512vpopcntdq'] + ['-mavx512bw'])
+ args: test_c_args + ['-mavx512vpopcntdq'] + ['-mavx512bw'])
cdata.set('USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 1)
cflags_popcnt += ['-mavx512vpopcntdq'] + ['-mavx512bw']
endif
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 83b91fe9167..5fa9f3d6748 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -834,12 +834,6 @@ $(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ;
$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config.h
-# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above.
-$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ;
-
-$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status
- cd $(top_builddir) && ./config.status src/include/pg_config_ext.h
-
# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same
# logic as above.
$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ;
diff --git a/src/include/.gitignore b/src/include/.gitignore
index 51819fb4ddd..6e99e82fe0c 100644
--- a/src/include/.gitignore
+++ b/src/include/.gitignore
@@ -1,5 +1,3 @@
/stamp-h
-/stamp-ext-h
/pg_config.h
-/pg_config_ext.h
/pg_config_os.h
diff --git a/src/include/Makefile b/src/include/Makefile
index b8b576a4de3..26332ff9cbc 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -13,7 +13,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
-all: pg_config.h pg_config_ext.h pg_config_os.h
+all: pg_config.h pg_config_os.h
# Subdirectories containing installable headers
@@ -32,7 +32,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
# These headers are needed by the not-so-public headers of the interfaces.
@@ -43,7 +42,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes'
$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
@@ -66,7 +64,7 @@ installdirs:
uninstall:
- rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
+ rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
# heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
@@ -80,4 +78,4 @@ clean:
$(MAKE) -C catalog clean
distclean: clean
- rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h
+ rm -f pg_config.h pg_config_os.h stamp-h stamp-ext-h
diff --git a/src/include/c.h b/src/include/c.h
index dc1841346cd..024213f37f3 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -48,9 +48,6 @@
#include "postgres_ext.h"
-/* Must undef pg_config_ext.h symbols before including pg_config.h */
-#undef PG_INT64_TYPE
-
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#include "pg_config_os.h" /* must be before any system header files */
@@ -489,10 +486,13 @@ typedef char *Pointer;
* frontend/backend protocol.
*/
#ifndef HAVE_INT8
-typedef signed char int8; /* == 8 bits */
-typedef signed short int16; /* == 16 bits */
-typedef signed int int32; /* == 32 bits */
+typedef int8_t int8; /* == 8 bits */
+typedef int16_t int16; /* == 16 bits */
+typedef int32_t int32; /* == 32 bits */
#endif /* not HAVE_INT8 */
+#ifndef HAVE_INT64
+typedef int64_t int64; /* == 64 bits */
+#endif /* not HAVE_INT64 */
/*
* uintN
@@ -501,10 +501,13 @@ typedef signed int int32; /* == 32 bits */
* frontend/backend protocol.
*/
#ifndef HAVE_UINT8
-typedef unsigned char uint8; /* == 8 bits */
-typedef unsigned short uint16; /* == 16 bits */
-typedef unsigned int uint32; /* == 32 bits */
+typedef uint8_t uint8; /* == 8 bits */
+typedef uint16_t uint16; /* == 16 bits */
+typedef uint32_t uint32; /* == 32 bits */
#endif /* not HAVE_UINT8 */
+#ifndef HAVE_UINT64
+typedef uint64_t uint64; /* == 64 bits */
+#endif /* not HAVE_UINT64 */
/*
* bitsN
@@ -517,32 +520,8 @@ typedef uint32 bits32; /* >= 32 bits */
/*
* 64-bit integers
*/
-#ifdef HAVE_LONG_INT_64
-/* Plain "long int" fits, use it */
-
-#ifndef HAVE_INT64
-typedef long int int64;
-#endif
-#ifndef HAVE_UINT64
-typedef unsigned long int uint64;
-#endif
-#define INT64CONST(x) (x##L)
-#define UINT64CONST(x) (x##UL)
-#elif defined(HAVE_LONG_LONG_INT_64)
-/* We have working support for "long long int", use that */
-
-#ifndef HAVE_INT64
-typedef long long int int64;
-#endif
-#ifndef HAVE_UINT64
-typedef unsigned long long int uint64;
-#endif
-#define INT64CONST(x) (x##LL)
-#define UINT64CONST(x) (x##ULL)
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+#define INT64CONST(x) INT64_C(x)
+#define UINT64CONST(x) UINT64_C(x)
/* snprintf format strings to use for 64-bit integers */
#define INT64_FORMAT "%" INT64_MODIFIER "d"
@@ -575,22 +554,19 @@ typedef unsigned PG_INT128_TYPE uint128
#endif
#endif
-/*
- * stdint.h limits aren't guaranteed to have compatible types with our fixed
- * width types. So just define our own.
- */
-#define PG_INT8_MIN (-0x7F-1)
-#define PG_INT8_MAX (0x7F)
-#define PG_UINT8_MAX (0xFF)
-#define PG_INT16_MIN (-0x7FFF-1)
-#define PG_INT16_MAX (0x7FFF)
-#define PG_UINT16_MAX (0xFFFF)
-#define PG_INT32_MIN (-0x7FFFFFFF-1)
-#define PG_INT32_MAX (0x7FFFFFFF)
-#define PG_UINT32_MAX (0xFFFFFFFFU)
-#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
-#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
-#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF)
+/* Historical names for limits in stdint.h. */
+#define PG_INT8_MIN INT8_MIN
+#define PG_INT8_MAX INT8_MAX
+#define PG_UINT8_MAX UINT8_MAX
+#define PG_INT16_MIN INT16_MIN
+#define PG_INT16_MAX INT16_MAX
+#define PG_UINT16_MAX UINT16_MAX
+#define PG_INT32_MIN INT32_MIN
+#define PG_INT32_MAX INT32_MAX
+#define PG_UINT32_MAX UINT32_MAX
+#define PG_INT64_MIN INT64_MIN
+#define PG_INT64_MAX INT64_MAX
+#define PG_UINT64_MAX UINT64_MAX
/*
* We now always use int64 timestamps, but keep this symbol defined for the
diff --git a/src/include/meson.build b/src/include/meson.build
index 58b7a9c1e7e..e691b12b8a0 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -1,14 +1,5 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
-pg_config_ext = configure_file(
- input: 'pg_config_ext.h.meson',
- output: 'pg_config_ext.h',
- configuration: cdata,
- install: true,
- install_dir: dir_include,
-)
-configure_files += pg_config_ext
-
pg_config_os = configure_file(
output: 'pg_config_os.h',
input: files('port/@[email protected]'.format(portname)),
@@ -116,7 +107,6 @@ install_headers(
'postgres_fe.h',
'varatt.h',
'windowapi.h',
- pg_config_ext,
pg_config_os,
pg_config,
install_dir: dir_include_server,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index f8d3e3b6b84..3755eb69e24 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -9,12 +9,12 @@
/* The normal alignment of `int', in bytes. */
#undef ALIGNOF_INT
+/* The normal alignment of `int64_t', in bytes. */
+#undef ALIGNOF_INT64_T
+
/* The normal alignment of `long', in bytes. */
#undef ALIGNOF_LONG
-/* The normal alignment of `long long int', in bytes. */
-#undef ALIGNOF_LONG_LONG_INT
-
/* The normal alignment of `PG_INT128_TYPE', in bytes. */
#undef ALIGNOF_PG_INT128_TYPE
@@ -282,12 +282,6 @@
/* Define to 1 if you have the `zstd' library (-lzstd). */
#undef HAVE_LIBZSTD
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
-
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
-
/* Define to 1 if you have the <mbarrier.h> header file. */
#undef HAVE_MBARRIER_H
@@ -570,7 +564,7 @@
/* Define to 1 if your compiler understands _Static_assert. */
#undef HAVE__STATIC_ASSERT
-/* Define to the appropriate printf length modifier for 64-bit ints. */
+/* Define to printf format modifier to use for int64_t. */
#undef INT64_MODIFIER
/* Define to 1 if `locale_t' requires <xlocale.h>. */
@@ -607,9 +601,6 @@
/* Define to the name of a signed 128-bit integer type. */
#undef PG_INT128_TYPE
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
-
/* Define to the name of the default PostgreSQL service principal in Kerberos
(GSSAPI). (--with-krb-srvnam=NAME) */
#undef PG_KRB_SRVNAM
diff --git a/src/include/pg_config_ext.h.in b/src/include/pg_config_ext.h.in
deleted file mode 100644
index 8acadbdafd4..00000000000
--- a/src/include/pg_config_ext.h.in
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
diff --git a/src/include/pg_config_ext.h.meson b/src/include/pg_config_ext.h.meson
deleted file mode 100644
index 57cdfca0cfd..00000000000
--- a/src/include/pg_config_ext.h.meson
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#mesondefine PG_INT64_TYPE
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h
index 4d88478c9c2..1c09bf0ff27 100644
--- a/src/include/port/pg_bitutils.h
+++ b/src/include/port/pg_bitutils.h
@@ -74,13 +74,12 @@ pg_leftmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CLZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return 63 - __builtin_clzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
- return 63 - __builtin_clzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+ StaticAssertStmt(sizeof(word) == sizeof(long long), "unexpected size");
+ return 63 - __builtin_clzll(word);
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
@@ -147,13 +146,12 @@ pg_rightmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CTZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_ctzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
- return __builtin_ctzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+ StaticAssertStmt(sizeof(word) == sizeof(long long), "unexpected size");
+ return __builtin_ctzll(word);
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 240ad4e93bf..034056e7d94 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -23,7 +23,7 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
-#include "pg_config_ext.h"
+#include <stdint.h>
/*
* Object ID is a fundamental type in Postgres.
@@ -36,15 +36,14 @@ typedef unsigned int Oid;
#define InvalidOid ((Oid) 0)
#endif
-#define OID_MAX UINT_MAX
-/* you will need to include <limits.h> to use the above #define */
+#define OID_MAX UINT32_MAX
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
/* the above needs <stdlib.h> */
/* Define a signed 64-bit integer type for use in client API declarations. */
-typedef PG_INT64_TYPE pg_int64;
+typedef int64_t pg_int64;
/*
* Identifiers of error message fields. Kept here to keep common
diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c
index 1d482c4fa61..1ab2cda8487 100644
--- a/src/interfaces/ecpg/ecpglib/typename.c
+++ b/src/interfaces/ecpg/ecpglib/typename.c
@@ -131,10 +131,9 @@ sqlda_dynamic_type(Oid type, enum COMPAT_MODE compat)
case INTERVALOID:
return ECPGt_interval;
case INT8OID:
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG < 8
return ECPGt_long_long;
-#endif
-#ifdef HAVE_LONG_INT_64
+#else
return ECPGt_long;
#endif
/* Unhandled types always return a string */
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index 824617b9175..48bce0878a7 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,14 +1,5 @@
/* Define to 1 to build client libraries as thread-safe code. */
#define ENABLE_THREAD_SAFETY 1
-/* Define to 1 if the system has the type `int64'. */
-#undef HAVE_INT64
-
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
-
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
-
/* Define to 1 to use <stdbool.h> to define type bool. */
#undef PG_USE_STDBOOL
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index 31610fef589..d0234413fcd 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -3,9 +3,6 @@
ecpg_inc = include_directories('.')
ecpg_conf_keys = [
- 'HAVE_INT64',
- 'HAVE_LONG_INT_64',
- 'HAVE_LONG_LONG_INT_64',
'PG_USE_STDBOOL',
]
diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h
index 2809b356f73..d16f74970c9 100644
--- a/src/interfaces/ecpg/include/pgtypes_interval.h
+++ b/src/interfaces/ecpg/include/pgtypes_interval.h
@@ -8,18 +8,7 @@
#ifndef C_H
-#ifdef HAVE_LONG_INT_64
-#ifndef HAVE_INT64
-typedef long int int64;
-#endif
-#elif defined(HAVE_LONG_LONG_INT_64)
-#ifndef HAVE_INT64
-typedef long long int int64;
-#endif
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+typedef int64_t int64;
#define HAVE_INT64_TIMESTAMP
#endif /* C_H */
diff --git a/src/interfaces/ecpg/include/sqltypes.h b/src/interfaces/ecpg/include/sqltypes.h
index e7cbfa47956..aed055eb4ab 100644
--- a/src/interfaces/ecpg/include/sqltypes.h
+++ b/src/interfaces/ecpg/include/sqltypes.h
@@ -46,7 +46,7 @@
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG < 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 7e19319d27f..02ec7b668d3 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -97,7 +97,7 @@ typedef struct sqlda_struct sqlda_t;
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG < 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c
index 87f56e82b80..d4413a299a9 100644
--- a/src/port/pg_bitutils.c
+++ b/src/port/pg_bitutils.c
@@ -370,12 +370,11 @@ static inline int
pg_popcount64_slow(uint64 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_popcountl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
- return __builtin_popcountll(word);
#else
-#error must have a working 64-bit integer datatype
+ StaticAssertStmt(sizeof(word) == sizeof(long long), "unexpected size");
+ return __builtin_popcountll(word);
#endif
#else /* !HAVE__BUILTIN_POPCOUNT */
int result = 0;
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 884f0262dd1..291148b4e8b 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -568,12 +568,11 @@ nextch2:
goto nextch2;
case 'z':
#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
- longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
+ StaticAssertStmt(sizeof(size_t) == sizeof(long long), "unexpected size");
+ longlongflag = 1;
#endif
#else
/* assume size_t is same size as int */
@@ -835,12 +834,11 @@ nextch1:
goto nextch1;
case 'z':
#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
- longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
+ StaticAssertStmt(sizeof(size_t) == sizeof(long long), "unexpected size");
+ longlongflag = 1;
#endif
#else
/* assume size_t is same size as int */
--
2.45.2
[text/x-patch] v3-0002-Remove-traces-of-BeOS.patch (4.6K, ../../CA+hUKG+rYp-=fTP5kjRmnfPq7YgK-e=J+gJxBvKarkPVzLwQmQ@mail.gmail.com/4-v3-0002-Remove-traces-of-BeOS.patch)
download | inline diff:
From 2b3c15b079c5f8aebd2f6a8f861c9422db757c2b Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 18 Apr 2024 12:06:17 +1200
Subject: [PATCH v3 2/3] Remove traces of BeOS.
Commit 15abc7788e6 tolerated namespace pollution from BeOS system
headers. Commit 44f902122 de-supported BeOS. Since that stuff didn't
make it into the Meson build system, synchronize by removing from
configure.
Reviewed-by: Peter Eisentraut <[email protected]>
Reviewed-by: Heikki Linnakangas <[email protected]>
Reviewed-by: Japin Li <[email protected]>
Reviewed-by: Tom Lane <[email protected]> (the idea, not the patch)
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
configure | 44 --------------------------------------
configure.ac | 5 -----
src/include/c.h | 8 -------
src/include/pg_config.h.in | 12 -----------
4 files changed, 69 deletions(-)
diff --git a/configure b/configure
index cfec577a1c1..3bfbfdf6521 100755
--- a/configure
+++ b/configure
@@ -16784,50 +16784,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-# Some platforms predefine the types int8, int16, etc. Only check
-# a (hopefully) representative subset.
-ac_fn_c_check_type "$LINENO" "int8" "ac_cv_type_int8" "#include <stdio.h>
-"
-if test "x$ac_cv_type_int8" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_INT8 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_type "$LINENO" "uint8" "ac_cv_type_uint8" "#include <stdio.h>
-"
-if test "x$ac_cv_type_uint8" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_UINT8 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_type "$LINENO" "int64" "ac_cv_type_int64" "#include <stdio.h>
-"
-if test "x$ac_cv_type_int64" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_INT64 1
-_ACEOF
-
-
-fi
-ac_fn_c_check_type "$LINENO" "uint64" "ac_cv_type_uint64" "#include <stdio.h>
-"
-if test "x$ac_cv_type_uint64" = xyes; then :
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_UINT64 1
-_ACEOF
-
-
-fi
-
-
# Check how to format int64_t without warnings from printf.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for printf int64_t modifier" >&5
$as_echo_n "checking for printf int64_t modifier... " >&6; }
diff --git a/configure.ac b/configure.ac
index 10bfb994d4f..0560b9ce1a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1985,11 +1985,6 @@ if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
fi
AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.])
-# Some platforms predefine the types int8, int16, etc. Only check
-# a (hopefully) representative subset.
-AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
-[#include <stdio.h>])
-
# Check how to format int64_t without warnings from printf.
PGAC_PRINTF_INT64_MODIFIER
diff --git a/src/include/c.h b/src/include/c.h
index 024213f37f3..dd140d2ae57 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -485,14 +485,10 @@ typedef char *Pointer;
* used for numerical computations and the
* frontend/backend protocol.
*/
-#ifndef HAVE_INT8
typedef int8_t int8; /* == 8 bits */
typedef int16_t int16; /* == 16 bits */
typedef int32_t int32; /* == 32 bits */
-#endif /* not HAVE_INT8 */
-#ifndef HAVE_INT64
typedef int64_t int64; /* == 64 bits */
-#endif /* not HAVE_INT64 */
/*
* uintN
@@ -500,14 +496,10 @@ typedef int64_t int64; /* == 64 bits */
* used for numerical computations and the
* frontend/backend protocol.
*/
-#ifndef HAVE_UINT8
typedef uint8_t uint8; /* == 8 bits */
typedef uint16_t uint16; /* == 16 bits */
typedef uint32_t uint32; /* == 32 bits */
-#endif /* not HAVE_UINT8 */
-#ifndef HAVE_UINT64
typedef uint64_t uint64; /* == 64 bits */
-#endif /* not HAVE_UINT64 */
/*
* bitsN
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 3755eb69e24..797f6ba3d64 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -213,12 +213,6 @@
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
-/* Define to 1 if the system has the type `int64'. */
-#undef HAVE_INT64
-
-/* Define to 1 if the system has the type `int8'. */
-#undef HAVE_INT8
-
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@@ -465,12 +459,6 @@
/* Define to 1 if you have the <ucred.h> header file. */
#undef HAVE_UCRED_H
-/* Define to 1 if the system has the type `uint64'. */
-#undef HAVE_UINT64
-
-/* Define to 1 if the system has the type `uint8'. */
-#undef HAVE_UINT8
-
/* Define to 1 if the system has the type `union semun'. */
#undef HAVE_UNION_SEMUN
--
2.45.2
[text/x-patch] v3-0003-Allow-tzcode-to-use-stdint.h-and-inttypes.h.patch (19.9K, ../../CA+hUKG+rYp-=fTP5kjRmnfPq7YgK-e=J+gJxBvKarkPVzLwQmQ@mail.gmail.com/5-v3-0003-Allow-tzcode-to-use-stdint.h-and-inttypes.h.patch)
download | inline diff:
From 27462adab2f9971ce34972062e51baf7728dc3ea Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 4 Jul 2024 13:00:08 +1200
Subject: [PATCH v3 3/3] Allow tzcode to use <stdint.h> and <inttypes.h>.
Previously we removed the use of types and macros from these standard
headers when synchronizing with upstream tzcode, to that we could
continue to target C89 toolchains. Now that all supported branches of
PostgreSQL require C99, we can drop a lot of small differences.
Reviewed-by:
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
src/timezone/README | 14 -----
src/timezone/localtime.c | 110 ++++++++++++++++++++-------------------
src/timezone/zic.c | 88 ++++++++++++++-----------------
3 files changed, 96 insertions(+), 116 deletions(-)
diff --git a/src/timezone/README b/src/timezone/README
index dd5d5f9892a..1857f03e3dd 100644
--- a/src/timezone/README
+++ b/src/timezone/README
@@ -79,13 +79,6 @@ fixed that.)
includes relying on configure's results rather than hand-hacked
#defines (see private.h in particular).
-* Similarly, avoid relying on <stdint.h> features that may not exist on old
-systems. In particular this means using Postgres' definitions of the int32
-and int64 typedefs, not int_fast32_t/int_fast64_t. Likewise we use
-PG_INT32_MIN/MAX not INT32_MIN/MAX. (Once we desupport all PG versions
-that don't require C99, it'd be practical to rely on <stdint.h> and remove
-this set of diffs; but that day is not yet.)
-
* Since Postgres is typically built on a system that has its own copy
of the <time.h> functions, we must avoid conflicting with those. This
mandates renaming typedef time_t to pg_time_t, and similarly for most
@@ -119,13 +112,6 @@ to first run the tzcode source files through a sed filter like this:
-e 's|^\*/| */|' \
-e 's/\bregister[ \t]//g' \
-e 's/\bATTRIBUTE_PURE[ \t]//g' \
- -e 's/int_fast32_t/int32/g' \
- -e 's/int_fast64_t/int64/g' \
- -e 's/intmax_t/int64/g' \
- -e 's/INT32_MIN/PG_INT32_MIN/g' \
- -e 's/INT32_MAX/PG_INT32_MAX/g' \
- -e 's/INTMAX_MIN/PG_INT64_MIN/g' \
- -e 's/INTMAX_MAX/PG_INT64_MAX/g' \
-e 's/struct[ \t]+tm\b/struct pg_tm/g' \
-e 's/\btime_t\b/pg_time_t/g' \
-e 's/lineno/lineno_t/g' \
diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c
index 0bc160ea7d7..e9adfc5da04 100644
--- a/src/timezone/localtime.c
+++ b/src/timezone/localtime.c
@@ -17,6 +17,7 @@
#include "c.h"
#include <fcntl.h>
+#include <stdint.h>
#include "datatype/timestamp.h"
#include "pgtz.h"
@@ -75,20 +76,20 @@ struct rule
int r_day; /* day number of rule */
int r_week; /* week number of rule */
int r_mon; /* month number of rule */
- int32 r_time; /* transition time of rule */
+ int_fast32_t r_time; /* transition time of rule */
};
/*
* Prototypes for static functions.
*/
-static struct pg_tm *gmtsub(pg_time_t const *timep, int32 offset,
+static struct pg_tm *gmtsub(pg_time_t const *timep, int_fast32_t offset,
struct pg_tm *tmp);
static bool increment_overflow(int *ip, int j);
-static bool increment_overflow_time(pg_time_t *tp, int32 j);
+static bool increment_overflow_time(pg_time_t *tp, int_fast32_t j);
static int64 leapcorr(struct state const *sp, pg_time_t t);
static struct pg_tm *timesub(pg_time_t const *timep,
- int32 offset, struct state const *sp,
+ int_fast32_t offset, struct state const *sp,
struct pg_tm *tmp);
static bool typesequiv(struct state const *sp, int a, int b);
@@ -105,7 +106,7 @@ static struct pg_tm tm;
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
-init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
+init_ttinfo(struct ttinfo *s, int_fast32_t utoff, bool isdst, int desigidx)
{
s->tt_utoff = utoff;
s->tt_isdst = isdst;
@@ -114,15 +115,15 @@ init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
s->tt_ttisut = false;
}
-static int32
+static int_fast32_t
detzcode(const char *const codep)
{
- int32 result;
+ int_fast32_t result;
int i;
- int32 one = 1;
- int32 halfmaxval = one << (32 - 2);
- int32 maxval = halfmaxval - 1 + halfmaxval;
- int32 minval = -1 - maxval;
+ int_fast32_t one = 1;
+ int_fast32_t halfmaxval = one << (32 - 2);
+ int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
+ int_fast32_t minval = -1 - maxval;
result = codep[0] & 0x7f;
for (i = 1; i < 4; ++i)
@@ -134,21 +135,21 @@ detzcode(const char *const codep)
* Do two's-complement negation even on non-two's-complement machines.
* If the result would be minval - 1, return minval.
*/
- result -= !TWOS_COMPLEMENT(int32) && result != 0;
+ result -= !TWOS_COMPLEMENT(int_fast32_t) && result != 0;
result += minval;
}
return result;
}
-static int64
+static int_fast64_t
detzcode64(const char *const codep)
{
- uint64 result;
+ int_fast64_t result;
int i;
- int64 one = 1;
- int64 halfmaxval = one << (64 - 2);
- int64 maxval = halfmaxval - 1 + halfmaxval;
- int64 minval = -TWOS_COMPLEMENT(int64) - maxval;
+ int_fast64_t one = 1;
+ int_fast64_t halfmaxval = one << (64 - 2);
+ int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
+ int_fast64_t minval = -TWOS_COMPLEMENT(int_fast64_t) - maxval;
result = codep[0] & 0x7f;
for (i = 1; i < 8; ++i)
@@ -160,7 +161,7 @@ detzcode64(const char *const codep)
* Do two's-complement negation even on non-two's-complement machines.
* If the result would be minval - 1, return minval.
*/
- result -= !TWOS_COMPLEMENT(int64) && result != 0;
+ result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
result += minval;
}
return result;
@@ -246,14 +247,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
return errno;
for (stored = 4; stored <= 8; stored *= 2)
{
- int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
- int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
- int64 prevtr = 0;
- int32 prevcorr = 0;
- int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
- int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
- int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
- int32 charcnt = detzcode(up->tzhead.tzh_charcnt);
+ int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
+ int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
+ int_fast64_t prevtr = 0;
+ int_fast32_t prevcorr = 0;
+ int_fast32_t leapcnt = detzcode(up->tzhead.tzh_leapcnt);
+ int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
+ int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
+ int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
char const *p = up->buf + tzheadsize;
/*
@@ -350,8 +351,8 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
leapcnt = 0;
for (i = 0; i < sp->leapcnt; ++i)
{
- int64 tr = stored == 4 ? detzcode(p) : detzcode64(p);
- int32 corr = detzcode(p + stored);
+ int_fast64_t tr = stored == 4 ? detzcode(p) : detzcode64(p);
+ int_fast32_t corr = detzcode(p + stored);
p += stored + 4;
/* Leap seconds cannot occur before the Epoch. */
@@ -361,7 +362,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
{
/*
* Leap seconds cannot occur more than once per UTC month, and
- * UTC months are at least 28 days long (minus 1 second for a
+ * UTC months are at least 2 days long (minus 1 second for a
* negative leap second). Each leap second's correction must
* differ from the previous one's by 1 second.
*/
@@ -707,9 +708,10 @@ getnum(const char *strp, int *const nump, const int min, const int max)
*/
static const char *
-getsecs(const char *strp, int32 *const secsp)
+getsecs(const char *strp, int_fast32_t * const secsp)
{
int num;
+ int_fast32_t secsperhour = SECSPERHOUR;
/*
* 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
@@ -719,7 +721,7 @@ getsecs(const char *strp, int32 *const secsp)
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
if (strp == NULL)
return NULL;
- *secsp = num * (int32) SECSPERHOUR;
+ *secsp = num * secsperhour;
if (*strp == ':')
{
++strp;
@@ -748,7 +750,7 @@ getsecs(const char *strp, int32 *const secsp)
*/
static const char *
-getoffset(const char *strp, int32 *const offsetp)
+getoffset(const char *strp, int_fast32_t * const offsetp)
{
bool neg = false;
@@ -835,12 +837,12 @@ getrule(const char *strp, struct rule *const rulep)
* effect, calculate the year-relative time that rule takes effect.
*/
-static int32
+static int_fast32_t
transtime(const int year, const struct rule *const rulep,
- const int32 offset)
+ const int_fast32_t offset)
{
bool leapyear;
- int32 value;
+ int_fast32_t value;
int i;
int d,
m1,
@@ -940,8 +942,8 @@ tzparse(const char *name, struct state *sp, bool lastditch)
size_t stdlen;
size_t dstlen;
size_t charcnt;
- int32 stdoffset;
- int32 dstoffset;
+ int_fast32_t stdoffset;
+ int_fast32_t dstoffset;
char *cp;
bool load_ok;
@@ -1033,7 +1035,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
int yearlim;
int timecnt;
pg_time_t janfirst;
- int32 janoffset = 0;
+ int_fast32_t janoffset = 0;
int yearbeg;
++name;
@@ -1059,7 +1061,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
do
{
- int32 yearsecs
+ int_fast32_t yearsecs
= year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
yearbeg--;
@@ -1073,17 +1075,17 @@ tzparse(const char *name, struct state *sp, bool lastditch)
yearlim = yearbeg + YEARSPERREPEAT + 1;
for (year = yearbeg; year < yearlim; year++)
{
- int32
- starttime = transtime(year, &start, stdoffset),
- endtime = transtime(year, &end, dstoffset);
- int32
- yearsecs = (year_lengths[isleap(year)]
- * SECSPERDAY);
+ int_fast32_t
+ starttime = transtime(year, &start, stdoffset),
+ endtime = transtime(year, &end, dstoffset);
+ int_fast32_t
+ yearsecs = (year_lengths[isleap(year)]
+ * SECSPERDAY);
bool reversed = endtime < starttime;
if (reversed)
{
- int32 swap = starttime;
+ int_fast32_t swap = starttime;
starttime = endtime;
endtime = swap;
@@ -1126,9 +1128,9 @@ tzparse(const char *name, struct state *sp, bool lastditch)
}
else
{
- int32 theirstdoffset;
- int32 theirdstoffset;
- int32 theiroffset;
+ int_fast32_t theirstdoffset;
+ int_fast32_t theirdstoffset;
+ int_fast32_t theiroffset;
bool isdst;
int i;
int j;
@@ -1290,7 +1292,7 @@ localsub(struct state const *sp, pg_time_t const *timep,
result = localsub(sp, &newt, tmp);
if (result)
{
- int64 newy;
+ int_fast64_t newy;
newy = result->tm_year;
if (t < sp->ats[0])
@@ -1354,7 +1356,7 @@ pg_localtime(const pg_time_t *timep, const pg_tz *tz)
*/
static struct pg_tm *
-gmtsub(pg_time_t const *timep, int32 offset,
+gmtsub(pg_time_t const *timep, int_fast32_t offset,
struct pg_tm *tmp)
{
struct pg_tm *result;
@@ -1411,7 +1413,7 @@ leaps_thru_end_of(const int y)
}
static struct pg_tm *
-timesub(const pg_time_t *timep, int32 offset,
+timesub(const pg_time_t *timep, int_fast32_t offset,
const struct state *sp, struct pg_tm *tmp)
{
const struct lsinfo *lp;
@@ -1554,7 +1556,7 @@ increment_overflow(int *ip, int j)
}
static bool
-increment_overflow_time(pg_time_t *tp, int32 j)
+increment_overflow_time(pg_time_t *tp, int_fast32_t j)
{
/*----------
* This is like
diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index d605c721ecf..0a98bb0ebb6 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -11,6 +11,8 @@
#include "postgres_fe.h"
#include <fcntl.h>
+#include <inttypes.h>
+#include <stdint.h>
#include <sys/stat.h>
#include <time.h>
@@ -22,12 +24,16 @@
#define ZIC_VERSION_PRE_2013 '2'
#define ZIC_VERSION '3'
-typedef int64 zic_t;
-#define ZIC_MIN PG_INT64_MIN
-#define ZIC_MAX PG_INT64_MAX
+typedef int_fast64_t zic_t;
+static zic_t const
+ ZIC_MIN = INT_FAST64_MIN,
+ ZIC_MAX = INT_FAST64_MAX,
+ ZIC32_MIN = INT32_MIN,
+ ZIC32_MAX = INT32_MAX;
+#define SCNdZIC SCNdFAST64
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
-#define ZIC_MAX_ABBR_LEN_WO_WARN 6
+#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
#ifndef WIN32
@@ -601,7 +607,7 @@ static zic_t comment_leapexpires = -1;
static bool
timerange_option(char *timerange)
{
- int64 lo = min_time,
+ intmax_t lo = min_time,
hi = max_time;
char *lo_end = timerange,
*hi_end;
@@ -610,7 +616,7 @@ timerange_option(char *timerange)
{
errno = 0;
lo = strtoimax(timerange + 1, &lo_end, 10);
- if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE))
+ if (lo_end == timerange + 1 || (lo == INTMAX_MAX && errno == ERANGE))
return false;
}
hi_end = lo_end;
@@ -618,9 +624,9 @@ timerange_option(char *timerange)
{
errno = 0;
hi = strtoimax(lo_end + 2, &hi_end, 10);
- if (hi_end == lo_end + 2 || hi == PG_INT64_MIN)
+ if (hi_end == lo_end + 2 || hi == INTMAX_MIN)
return false;
- hi -= !(hi == PG_INT64_MAX && errno == ERANGE);
+ hi -= !(hi == INTMAX_MAX && errno == ERANGE);
}
if (*hi_end || hi < lo || max_time < lo || hi < min_time)
return false;
@@ -1291,18 +1297,7 @@ infile(const char *name)
{
if (name == leapsec && *buf == '#')
{
- /*
- * PG: INT64_FORMAT isn't portable for sscanf, so be content
- * with scanning a "long". Once we are requiring C99 in all
- * live branches, it'd be sensible to adopt upstream's
- * practice of using the <inttypes.h> macros. But for now, we
- * don't actually use this code, and it won't overflow before
- * 2038 anyway.
- */
- long cl_tmp;
-
- sscanf(buf, "#expires %ld", &cl_tmp);
- comment_leapexpires = cl_tmp;
+ sscanf(buf, "#expires %" SCNdZIC, &comment_leapexpires);
}
}
else if (wantcont)
@@ -1364,8 +1359,7 @@ infile(const char *name)
static zic_t
gethms(char const *string, char const *errstring)
{
- /* PG: make hh be int not zic_t to avoid sscanf portability issues */
- int hh;
+ zic_t hh;
int sign,
mm = 0,
ss = 0;
@@ -1387,7 +1381,7 @@ gethms(char const *string, char const *errstring)
else
sign = 1;
switch (sscanf(string,
- "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
+ "%" SCNdZIC "%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c",
&hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs))
{
default:
@@ -1424,7 +1418,7 @@ gethms(char const *string, char const *errstring)
return 0;
}
/* Some compilers warn that this test is unsatisfiable for 32-bit ints */
-#if INT_MAX > PG_INT32_MAX
+#if INT_MAX > INT32_MAX
if (ZIC_MAX / SECSPERHOUR < hh)
{
error(_("time overflow"));
@@ -1670,8 +1664,7 @@ getleapdatetime(char **fields, int nfields, bool expire_line)
zic_t i,
j;
- /* PG: make year be int not zic_t to avoid sscanf portability issues */
- int year;
+ zic_t year;
int month,
day;
zic_t dayoff,
@@ -1681,7 +1674,7 @@ getleapdatetime(char **fields, int nfields, bool expire_line)
dayoff = 0;
cp = fields[LP_YEAR];
- if (sscanf(cp, "%d%c", &year, &xs) != 1)
+ if (sscanf(cp, "%" SCNdZIC "%c", &year, &xs) != 1)
{
/*
* Leapin' Lizards!
@@ -1830,9 +1823,6 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
char *ep;
char xs;
- /* PG: year_tmp is to avoid sscanf portability issues */
- int year_tmp;
-
if ((lp = byword(monthp, mon_names)) == NULL)
{
error(_("invalid month name"));
@@ -1890,9 +1880,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
progname, lp->l_value);
exit(EXIT_FAILURE);
}
- else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
- rp->r_loyear = year_tmp;
- else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_loyear, &xs) != 1)
{
error(_("invalid starting year"));
return;
@@ -1918,9 +1906,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
progname, lp->l_value);
exit(EXIT_FAILURE);
}
- else if (sscanf(cp, "%d%c", &year_tmp, &xs) == 1)
- rp->r_hiyear = year_tmp;
- else
+ else if (sscanf(cp, "%" SCNdZIC "%c", &rp->r_hiyear, &xs) != 1)
{
error(_("invalid ending year"));
return;
@@ -1989,7 +1975,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
}
static void
-convert(const int32 val, char *const buf)
+convert(const int_fast32_t val, char *const buf)
{
int i;
int shift;
@@ -2000,7 +1986,7 @@ convert(const int32 val, char *const buf)
}
static void
-convert64(const zic_t val, char *const buf)
+convert64(uint_fast64_t val, char *const buf)
{
int i;
int shift;
@@ -2011,7 +1997,7 @@ convert64(const zic_t val, char *const buf)
}
static void
-puttzcode(const int32 val, FILE *const fp)
+puttzcode(zic_t val, FILE *const fp)
{
char buf[4];
@@ -2201,7 +2187,7 @@ writezone(const char *const name, const char *const string, char version,
rangeall.count = timecnt;
rangeall.leapcount = leapcnt;
range64 = limitrange(rangeall, lo_time, hi_time, ats, types);
- range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types);
+ range32 = limitrange(range64, ZIC32_MIN, ZIC32_MAX, ats, types);
/*
* Remove old file, if any, to snap links.
@@ -2263,7 +2249,7 @@ writezone(const char *const name, const char *const string, char version,
/*
* Arguably the default time type in the 32-bit data should be
* range32.defaulttype, which is suited for timestamps just before
- * PG_INT32_MIN. However, zic traditionally used the time type of
+ * INT32_MIN. However, zic traditionally used the time type of
* the indefinite past instead. Internet RFC 8532 says readers
* should ignore 32-bit data, so this discrepancy matters only to
* obsolete readers where the traditional type might be more
@@ -2271,7 +2257,7 @@ writezone(const char *const name, const char *const string, char version,
* value, unless -r specifies a low cutoff that excludes some
* 32-bit timestamps.
*/
- thisdefaulttype = (lo_time <= PG_INT32_MIN
+ thisdefaulttype = (lo_time <= INT32_MIN
? range64.defaulttype
: range32.defaulttype);
@@ -2280,8 +2266,8 @@ writezone(const char *const name, const char *const string, char version,
toomanytimes = thistimecnt >> 31 >> 1 != 0;
thisleapi = range32.leapbase;
thisleapcnt = range32.leapcount;
- locut = PG_INT32_MIN < lo_time;
- hicut = hi_time < PG_INT32_MAX;
+ locut = INT32_MIN < lo_time;
+ hicut = hi_time < INT32_MAX;
}
else
{
@@ -2465,7 +2451,13 @@ writezone(const char *const name, const char *const string, char version,
continue;
}
- /* PG: print current timezone abbreviations if requested */
+ /*
+ * PG: print current timezone abbreviations if requested. Note that
+ * we cast to int64_t, because int_fast64_t is not required to be
+ * compatible with INT64_FORMAT. We can't use PRIdFAST64 here because
+ * we override fprintf with our own implementation that might not
+ * understand it.
+ */
if (print_abbrevs && pass == 2)
{
/* Print "type" data for periods ending after print_cutoff */
@@ -2478,7 +2470,7 @@ writezone(const char *const name, const char *const string, char version,
fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
thisabbrev,
- utoffs[tm],
+ (int64_t) utoffs[tm],
isdsts[tm] ? "\tD" : "");
}
}
@@ -2490,7 +2482,7 @@ writezone(const char *const name, const char *const string, char version,
fprintf(stdout, "%s\t" INT64_FORMAT "%s\n",
thisabbrev,
- utoffs[tm],
+ (int64_t) utoffs[tm],
isdsts[tm] ? "\tD" : "");
}
}
@@ -2499,7 +2491,7 @@ writezone(const char *const name, const char *const string, char version,
* Output a LO_TIME transition if needed; see limitrange. But do not
* go below the minimum representable value for this pass.
*/
- lo = pass == 1 && lo_time < PG_INT32_MIN ? PG_INT32_MIN : lo_time;
+ lo = pass == 1 && lo_time < ZIC32_MIN ? ZIC32_MIN : lo_time;
if (locut)
puttzcodepass(lo, fp, pass);
--
2.45.2
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-04 03:10 Tom Lane <[email protected]>
parent: Thomas Munro <[email protected]>
2 siblings, 1 reply; 25+ messages in thread
From: Tom Lane @ 2024-07-04 03:10 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Peter Eisentraut <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Thomas Munro <[email protected]> writes:
> New version attached. This time I was brave enough to try to tackle
> src/timezone too, which had comments planning to drop a lot of small
> differences against the upstream tzcode once all supported branches
> required C99.
Unless you've specifically checked that this reduces diffs against
upstream tzcode, I'd really prefer not to touch that code right now.
I know I'm overdue for a round of syncing src/timezone/ with upstream,
but I can't see how drive-by changes will make that easier.
> IMHO it's a rather scary choice on tzcode's part to use int_fastN_t,
Yeah, I was never pleased with that choice of theirs. OTOH, I've
seen darn few portability complaints on their mailing list, so
it seems like they've got it right in isolation. The problem
from our standpoint is that I don't think we want int_fastN_t
to leak into APIs visible to the rest of Postgres, because then
we risk issues related to their configuration methods being
totally unlike ours.
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-04 03:44 Thomas Munro <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Thomas Munro @ 2024-07-04 03:44 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Peter Eisentraut <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Jul 4, 2024 at 3:10 PM Tom Lane <[email protected]> wrote:
> Unless you've specifically checked that this reduces diffs against
> upstream tzcode, I'd really prefer not to touch that code right now.
> I know I'm overdue for a round of syncing src/timezone/ with upstream,
> but I can't see how drive-by changes will make that easier.
Sure, I'll wait until you say it's a good time. It does remove a
dozen or so hunks of difference, which should hopefully make that job
easier eventually but I don't want to get in your way. I can see
there are a few more trivialities we could synchronise on, like const
keywords, to kill useless diffs (either dropping local improvements or
sending patches upstream).
> > IMHO it's a rather scary choice on tzcode's part to use int_fastN_t,
>
> Yeah, I was never pleased with that choice of theirs. OTOH, I've
> seen darn few portability complaints on their mailing list, so
> it seems like they've got it right in isolation. The problem
> from our standpoint is that I don't think we want int_fastN_t
> to leak into APIs visible to the rest of Postgres, because then
> we risk issues related to their configuration methods being
> totally unlike ours.
Yeah. My first swing at this touched only .c files, no .h files, with
that in mind.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-14 14:47 Peter Eisentraut <[email protected]>
parent: Thomas Munro <[email protected]>
2 siblings, 1 reply; 25+ messages in thread
From: Peter Eisentraut @ 2024-07-14 14:47 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; Heikki Linnakangas <[email protected]>; +Cc: Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On 04.07.24 03:55, Thomas Munro wrote:
> Unfortunately, that theory turned out to be wrong. The usual suspect,
> Windows, uses something else: "I64" or something like that. We could
> teach our snprintf to grok that, but I don't like the idea anymore.
> So let's go back to INT64_MODIFIER, with just a small amount of
> configure time work to pick the right value. I couldn't figure out
> any header-only way to do that.
src/port/snprintf.c used to support I64 in the past, but it was later
removed. We could probably put it back.
>> Personally, I find "PRId64" pretty unreadable. "INT64_MODIFIER" wasn't
>> nice either, though, and following standards is good, so I'm sure I'll
>> get used to it.
Using PRId64 would be very beneficial because gettext understands it,
and so we would no longer need the various workarounds for not putting
INT64_FORMAT into the middle of a translated string.
But this could be a separate patch. What you have works for now.
Here are some other comments on this patch set:
* v3-0001-Use-int64_t-support-from-stdint.h.patch
- src/include/c.h:
Maybe add a comment that above all the int8_t -> int8 etc. typedefs
that these are for backward compatibility or something like that.
Actually, just move the comment
+/* Historical names for limits in stdint.h. */
up a bit to it covers the types as well.
Also, these /* == 8 bits */ comments could be removed, I think.
- src/include/port/pg_bitutils.h:
- src/port/pg_bitutils.c:
- src/port/snprintf.c:
These changes look functionally correct, but I think I like the old
code layout better, like
#if (using long)
...
#elif (using long long)
...
#else
#error
#endif
rather than
#if (using long)
...
#else
static assertion
... // long long
#endif
which seems a bit more complicated. I think you could leave the code
mostly alone and just change
defined(HAVE_LONG_INT_64) to SIZEOF_LONG == 8
defined(HAVE_LONG_LONG_INT_64) to SIZEOF_LONG_LONG == 8
in each case.
- src/include/postgres_ext.h:
-#define OID_MAX UINT_MAX
-/* you will need to include <limits.h> to use the above #define */
+#define OID_MAX UINT32_MAX
If the type Oid is unsigned int, then the OID_MAX should be UINT_MAX.
So this should not be changed. Also, is the comment about <limits.h>
no longer applicable?
- src/interfaces/ecpg/ecpglib/typename.c:
- src/interfaces/ecpg/include/sqltypes.h:
- .../test/expected/compat_informix-sqlda.c:
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG < 8
These changes alter the library behavior unnecessarily. The old code
would always prefer to report back long long (ECPGt_long_long etc.),
but the new code will report back long (ECPGt_long etc.) if it is
64-bit. I don't know the impact of these changes, but it seems
preferable to keep the existing behavior.
- src/interfaces/ecpg/include/ecpg_config.h.in:
- src/interfaces/ecpg/include/meson.build:
In the past, we have kept obsolete symbols as always defined in
ecpg_config.h. We ought to do the same here.
* v3-0002-Remove-traces-of-BeOS.patch
This looks ok. This could also be committed before 0001.
* v3-0003-Allow-tzcode-to-use-stdint.h-and-inttypes.h.patch
- src/timezone/localtime.c:
Addition of #include <stdint.h> is unnecessary, since it's already
included in c.h, and it's also not in the upstream code.
This looks like a typo:
- * UTC months are at least 28 days long
(minus 1 second for a
+ * UTC months are at least 2 days long
(minus 1 second for a
-getsecs(const char *strp, int32 *const secsp)
+getsecs(const char *strp, int_fast32_t * const secsp)
Need to add int_fast32_t (and maybe the other types) to typedefs.list?
- src/timezone/zic.c:
+#include <inttypes.h>
+#include <stdint.h>
We don't need both of these. Also, this is not in the upstream code
AFAICT.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-14 14:51 Tom Lane <[email protected]>
parent: Peter Eisentraut <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Tom Lane @ 2024-07-14 14:51 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Thomas Munro <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Peter Eisentraut <[email protected]> writes:
> On 04.07.24 03:55, Thomas Munro wrote:
>>> Personally, I find "PRId64" pretty unreadable. "INT64_MODIFIER" wasn't
>>> nice either, though, and following standards is good, so I'm sure I'll
>>> get used to it.
> Using PRId64 would be very beneficial because gettext understands it,
> and so we would no longer need the various workarounds for not putting
> INT64_FORMAT into the middle of a translated string.
Uh, really? The translated strings live in /usr/share, which is
expected to be architecture-independent, so how would they make
that work?
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-07-22 14:39 Peter Eisentraut <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Peter Eisentraut @ 2024-07-22 14:39 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Thomas Munro <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On 14.07.24 16:51, Tom Lane wrote:
> Peter Eisentraut <[email protected]> writes:
>> On 04.07.24 03:55, Thomas Munro wrote:
>>>> Personally, I find "PRId64" pretty unreadable. "INT64_MODIFIER" wasn't
>>>> nice either, though, and following standards is good, so I'm sure I'll
>>>> get used to it.
>
>> Using PRId64 would be very beneficial because gettext understands it,
>> and so we would no longer need the various workarounds for not putting
>> INT64_FORMAT into the middle of a translated string.
>
> Uh, really? The translated strings live in /usr/share, which is
> expected to be architecture-independent, so how would they make
> that work?
Gettext has some special run-time support for this. See here:
<https://www.gnu.org/software/gettext/manual/html_node/Preparing-Strings.html#No-string-concatenation;
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-10-14 06:46 Peter Eisentraut <[email protected]>
parent: Thomas Munro <[email protected]>
2 siblings, 1 reply; 25+ messages in thread
From: Peter Eisentraut @ 2024-10-14 06:46 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; Heikki Linnakangas <[email protected]>; +Cc: Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
To move this along a bit, I have committed the "Remove traces of BeOS."
patch.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-11-29 10:12 Thomas Munro <[email protected]>
parent: Peter Eisentraut <[email protected]>
0 siblings, 2 replies; 25+ messages in thread
From: Thomas Munro @ 2024-11-29 10:12 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Tue, Jul 23, 2024 at 2:39 AM Peter Eisentraut <[email protected]> wrote:
> On 14.07.24 16:51, Tom Lane wrote:
> > Peter Eisentraut <[email protected]> writes:
> >> On 04.07.24 03:55, Thomas Munro wrote:
> >>>> Personally, I find "PRId64" pretty unreadable. "INT64_MODIFIER" wasn't
> >>>> nice either, though, and following standards is good, so I'm sure I'll
> >>>> get used to it.
> >
> >> Using PRId64 would be very beneficial because gettext understands it,
> >> and so we would no longer need the various workarounds for not putting
> >> INT64_FORMAT into the middle of a translated string.
> >
> > Uh, really? The translated strings live in /usr/share, which is
> > expected to be architecture-independent, so how would they make
> > that work?
>
> Gettext has some special run-time support for this. See here:
> <https://www.gnu.org/software/gettext/manual/html_node/Preparing-Strings.html#No-string-concatenation;
Nice. I've never really looked into gettext() very seriously, so I
wondered about the portability of it all. In our docs, a long time
ago, you wrote "... you need an implementation of the Gettext API.
Some operating systems have this built-in (e.g., Linux, NetBSD,
Solaris),". It looks like we might still have those implementations
of libintl.so in our build farm today: mostly the GNU one, but also
NetBSD's, illumos's, and to the unknowable extent it is different
Solaris's. They might all be using GNU msgfmt though.
I want to move this forward, but we have to decide which way. I'm now
leaning back towards using <inttypes.h> macros, based on your
feedback. So here's a rebase of v2, with some improvements, and some
responses to your earlier email:
On Mon, Jul 15, 2024 at 2:47 AM Peter Eisentraut <[email protected]> wrote:
> On 04.07.24 03:55, Thomas Munro wrote:
> > Unfortunately, that theory turned out to be wrong. The usual suspect,
> > Windows, uses something else: "I64" or something like that. We could
> > teach our snprintf to grok that, but I don't like the idea anymore.
> > So let's go back to INT64_MODIFIER, with just a small amount of
> > configure time work to pick the right value. I couldn't figure out
> > any header-only way to do that.
>
> src/port/snprintf.c used to support I64 in the past, but it was later
> removed. We could probably put it back.
New idea: let's just redefine PRI...{32,64,PTR} on that platform,
instead of modifying snprintf.c.
> - src/include/c.h:
>
> Maybe add a comment that above all the int8_t -> int8 etc. typedefs
> that these are for backward compatibility or something like that.
> Actually, just move the comment
>
> +/* Historical names for limits in stdint.h. */
>
> up a bit to it covers the types as well.
Hmm I think it deserves a separate comment but yeah "EXACTLY N BITS"
and can be "used for numerical computations" can definitely go. I
guess that's a memory of some pre-standard system that had similarly
named types with the "at least" meaning, but it's not helping anybody
today.
> Also, these /* == 8 bits */ comments could be removed, I think.
Yeah.
> - src/include/port/pg_bitutils.h:
> - src/port/pg_bitutils.c:
> - src/port/snprintf.c:
>
> These changes look functionally correct, but I think I like the old
> code layout better, like
>
> #if (using long)
> ...
> #elif (using long long)
> ...
> #else
> #error
> #endif
>
> rather than
>
> #if (using long)
> ...
> #else
> static assertion
> ... // long long
> #endif
Fair point, that was all a bit ugly. Let's see...
> which seems a bit more complicated. I think you could leave the code
> mostly alone and just change
>
> defined(HAVE_LONG_INT_64) to SIZEOF_LONG == 8
> defined(HAVE_LONG_LONG_INT_64) to SIZEOF_LONG_LONG == 8
>
> in each case.
What do you think about this approach?
case 'z':
#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
#error "cannot find integer type of the same size as size_t"
#endif
And then in the cases where the size is implied by the typename
(uint64_t -> 8) it's the same setup except with a number:
#if SIZEOF_LONG == 8
return 63 - __builtin_clzl(word);
#elif SIZEOF_LONG_LONG == 8
return 63 - __builtin_clzll(word);
#else
#error "cannot find integer type of the same size as uint64_t"
#endif
What I like about that is that it's very clear that the conditions
match the ...l() or ...ll() function. It's obviously correct, and
would fail on a Deathstation 9000 that is trying to trick us.
> - src/include/postgres_ext.h:
>
> -#define OID_MAX UINT_MAX
> -/* you will need to include <limits.h> to use the above #define */
> +#define OID_MAX UINT32_MAX
>
> If the type Oid is unsigned int, then the OID_MAX should be UINT_MAX.
> So this should not be changed. Also, is the comment about <limits.h>
> no longer applicable?
Right, yeah, hunk nuked.
> - src/interfaces/ecpg/ecpglib/typename.c:
> - src/interfaces/ecpg/include/sqltypes.h:
> - .../test/expected/compat_informix-sqlda.c:
>
> -#ifdef HAVE_LONG_LONG_INT_64
> +#if SIZEOF_LONG < 8
>
> These changes alter the library behavior unnecessarily. The old code
> would always prefer to report back long long (ECPGt_long_long etc.),
> but the new code will report back long (ECPGt_long etc.) if it is
> 64-bit. I don't know the impact of these changes, but it seems
> preferable to keep the existing behavior.
I agree that it should be better but I don't think that's right about
the preference. The order of the tests here didn't matter, because
only HAVE_LONG_INT_64 would have been defined if sizeof(long) == 8,
not both, so it would still have preferred the first of { long, long
long } that had size 8 in that order. But yeah that's confusing,
let's try changing it to the same form as the cases above (an
explicitly search for the integer type of the same size where the
conditions are obviously correct with a clear priority and no
default/fallback/assumption, just an error):
case INT8OID:
#if SIZEOF_LONG == 8
return ECPGt_long;
#elif SIZEOF_LONG_LONG == 8
return ECPGt_long_long;
#else
#error "cannot find integer type of the same size as INT8OID"
#endif
> - src/interfaces/ecpg/include/ecpg_config.h.in:
> - src/interfaces/ecpg/include/meson.build:
>
> In the past, we have kept obsolete symbols as always defined in
> ecpg_config.h. We ought to do the same here.
Normally we keep symbols that were once conditional and are now
constant, like ENABLE_THREAD_SAFETY. Should that include
HAVE_LONG_INT_64 and HAVE_LONG_LONG_INT_64? Only one would be
defined, but it might be that neither is true in the patch: it's a
typedef for int64_t, and the standard library might well have a
typedef to __internal_int64_type, which is neither long nor long long.
it seems like internal machinery for giving the client code an "int64"
type in the C89 days, and surely not part of our real API.
WIP patch attached.
(Let's leave that tzcode stuff far later.)
Attachments:
[application/octet-stream] v4-0001-Use-types-and-support-stdint.h-and-inttypes.h.patch (42.1K, ../../CA+hUKGL7YprY+mkWg-9rVkrzkeC62ppdzyb7KcPp9tcff_5F3Q@mail.gmail.com/2-v4-0001-Use-types-and-support-stdint.h-and-inttypes.h.patch)
download | inline diff:
From 3fa302632a9280e248ed5fce926a3af5a7898f55 Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 18 Apr 2024 07:53:10 +1200
Subject: [PATCH v4] Use types and support <stdint.h> and <inttypes.h>.
Rebase our 64 bit integer support onto modern C including int64_t,
INT64_MAX, INT64_C(), PRId64 etc.
One complication is that Windows' <inttypes.h> uses format strings like
$I64d for PRId64 that our own snprintf.c doesn't understand. Define our
own replacement macros that it can deal with.
Work in progress...
Reviewed-by: Peter Eisentraut <[email protected]>
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
configure | 263 ++++--------------
configure.ac | 47 +---
meson.build | 45 ++-
src/Makefile.global.in | 6 -
src/bin/pg_waldump/pg_waldump.c | 16 +-
src/bin/pgbench/pgbench.c | 4 +-
src/include/.gitignore | 2 -
src/include/Makefile | 8 +-
src/include/c.h | 101 +++----
src/include/meson.build | 10 -
src/include/pg_config.h.in | 21 +-
src/include/pg_config_ext.h.in | 7 -
src/include/pg_config_ext.h.meson | 7 -
src/include/port/pg_bitutils.h | 16 +-
src/include/port/win32_port.h | 47 ++++
src/include/postgres_ext.h | 4 +-
src/include/utils/dsa.h | 2 +-
src/interfaces/ecpg/ecpglib/typename.c | 9 +-
src/interfaces/ecpg/include/ecpg_config.h.in | 8 +-
src/interfaces/ecpg/include/meson.build | 4 +-
.../ecpg/include/pgtypes_interval.h | 12 +-
src/interfaces/ecpg/include/sqltypes.h | 8 +-
.../test/expected/compat_informix-sqlda.c | 8 +-
src/port/pg_bitutils.c | 6 +-
src/port/snprintf.c | 20 +-
25 files changed, 218 insertions(+), 463 deletions(-)
delete mode 100644 src/include/pg_config_ext.h.in
delete mode 100644 src/include/pg_config_ext.h.meson
diff --git a/configure b/configure
index ff59f1422d8..2c12d104f79 100755
--- a/configure
+++ b/configure
@@ -16196,197 +16196,6 @@ fi
# Run tests below here
# --------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5
-$as_echo_n "checking whether long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_int_64" >&6; }
-
-HAVE_LONG_INT_64=$pgac_cv_type_long_int_64
-if test x"$pgac_cv_type_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h
-
-fi
-
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5
-$as_echo_n "checking whether long long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_long_int_64" >&6; }
-
-HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64
-if test x"$pgac_cv_type_long_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h
-
-fi
-
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- as_fn_error $? "Cannot find a working 64-bit integer type." "$LINENO" 5
- fi
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define PG_INT64_TYPE $pg_int64_type
-_ACEOF
-
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define INT64_MODIFIER $INT64_MODIFIER
-_ACEOF
-
-
# has to be down here, rather than with the other builtins, because
# the test uses PG_INT64_TYPE.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
@@ -16526,6 +16335,39 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
# Determine memory alignment requirements for the basic C data types.
@@ -16634,43 +16476,41 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- # The cast to long int works around a bug in the HP C Compiler,
+# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long long int" >&5
-$as_echo_n "checking alignment of long long int... " >&6; }
-if ${ac_cv_alignof_long_long_int+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of int64_t" >&5
+$as_echo_n "checking alignment of int64_t... " >&6; }
+if ${ac_cv_alignof_int64_t+:} false; then :
$as_echo_n "(cached) " >&6
else
- if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long_long_int" "$ac_includes_default
+ if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_int64_t" "$ac_includes_default
#ifndef offsetof
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
#endif
-typedef struct { char x; long long int y; } ac__type_alignof_;"; then :
+typedef struct { char x; int64_t y; } ac__type_alignof_;"; then :
else
- if test "$ac_cv_type_long_long_int" = yes; then
+ if test "$ac_cv_type_int64_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute alignment of long long int
+as_fn_error 77 "cannot compute alignment of int64_t
See \`config.log' for more details" "$LINENO" 5; }
else
- ac_cv_alignof_long_long_int=0
+ ac_cv_alignof_int64_t=0
fi
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long_long_int" >&5
-$as_echo "$ac_cv_alignof_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_int64_t" >&5
+$as_echo "$ac_cv_alignof_int64_t" >&6; }
cat >>confdefs.h <<_ACEOF
-#define ALIGNOF_LONG_LONG_INT $ac_cv_alignof_long_long_int
+#define ALIGNOF_INT64_T $ac_cv_alignof_int64_t
_ACEOF
-fi
# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of double" >&5
@@ -16728,8 +16568,8 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
@@ -16737,7 +16577,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-
# Some compilers offer a 128-bit integer scalar type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
$as_echo_n "checking for __int128... " >&6; }
@@ -18954,9 +18793,6 @@ fi
ac_config_headers="$ac_config_headers src/include/pg_config.h"
-ac_config_headers="$ac_config_headers src/include/pg_config_ext.h"
-
-
ac_config_headers="$ac_config_headers src/interfaces/ecpg/include/ecpg_config.h"
@@ -19671,7 +19507,6 @@ do
"src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;;
"src/include/pg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
- "src/include/pg_config_ext.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config_ext.h" ;;
"src/interfaces/ecpg/include/ecpg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/interfaces/ecpg/include/ecpg_config.h" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -20279,10 +20114,6 @@ $as_echo "$as_me: WARNING: *** link for $FILE -- please fix by hand" >&2;}
"src/include/pg_config.h":H)
# Update timestamp for pg_config.h (see Makefile.global)
echo >src/include/stamp-h
- ;;
- "src/include/pg_config_ext.h":H)
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
;;
"src/interfaces/ecpg/include/ecpg_config.h":H) echo >src/interfaces/ecpg/include/stamp-h ;;
diff --git a/configure.ac b/configure.ac
index 21817009642..0e6d5819a03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1906,37 +1906,6 @@ for the exact reason.]])],
# Run tests below here
# --------------------
-dnl Check to see if we have a working 64-bit integer type.
-dnl Since Postgres 8.4, we no longer support compilers without a working
-dnl 64-bit type; but we have to determine whether that type is called
-dnl "long int" or "long long int".
-
-PGAC_TYPE_64BIT_INT([long int])
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- PGAC_TYPE_64BIT_INT([long long int])
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- AC_MSG_ERROR([Cannot find a working 64-bit integer type.])
- fi
-fi
-
-AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type,
- [Define to the name of a signed 64-bit integer type.])
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER,
- [Define to the appropriate printf length modifier for 64-bit ints.])
-
# has to be down here, rather than with the other builtins, because
# the test uses PG_INT64_TYPE.
PGAC_C_BUILTIN_OP_OVERFLOW
@@ -1945,15 +1914,14 @@ PGAC_C_BUILTIN_OP_OVERFLOW
AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF([size_t])
AC_CHECK_SIZEOF([long])
+AC_CHECK_SIZEOF([long long])
# Determine memory alignment requirements for the basic C data types.
AC_CHECK_ALIGNOF(short)
AC_CHECK_ALIGNOF(int)
AC_CHECK_ALIGNOF(long)
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- AC_CHECK_ALIGNOF(long long int)
-fi
+AC_CHECK_ALIGNOF(int64_t)
AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
@@ -1977,12 +1945,11 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- AC_MSG_ERROR([alignment of 'long long int' is greater than the alignment of 'double'])
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ AC_MSG_ERROR([alignment of 'int64_t' is greater than the alignment of 'double'])
fi
AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.])
-
# Some compilers offer a 128-bit integer scalar type.
PGAC_TYPE_128BIT_INT
@@ -2472,12 +2439,6 @@ AC_CONFIG_HEADERS([src/include/pg_config.h],
echo >src/include/stamp-h
])
-AC_CONFIG_HEADERS([src/include/pg_config_ext.h],
-[
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
-])
-
AC_CONFIG_HEADERS([src/interfaces/ecpg/include/ecpg_config.h],
[echo >src/interfaces/ecpg/include/stamp-h])
diff --git a/meson.build b/meson.build
index 451c3f6d851..bc47c7e5676 100644
--- a/meson.build
+++ b/meson.build
@@ -1588,21 +1588,6 @@ if not cc.compiles(c99_test, name: 'c99', args: test_c_args)
endif
endif
-sizeof_long = cc.sizeof('long', args: test_c_args)
-cdata.set('SIZEOF_LONG', sizeof_long)
-if sizeof_long == 8
- cdata.set('HAVE_LONG_INT_64', 1)
- pg_int64_type = 'long int'
- cdata.set_quoted('INT64_MODIFIER', 'l')
-elif sizeof_long == 4 and cc.sizeof('long long', args: test_c_args) == 8
- cdata.set('HAVE_LONG_LONG_INT_64', 1)
- pg_int64_type = 'long long int'
- cdata.set_quoted('INT64_MODIFIER', 'll')
-else
- error('do not know how to get a 64bit int')
-endif
-cdata.set('PG_INT64_TYPE', pg_int64_type)
-
if host_machine.endian() == 'big'
cdata.set('WORDS_BIGENDIAN', 1)
endif
@@ -1631,11 +1616,19 @@ endforeach
# any types wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8
# would be too much of a penalty for disk and memory space.
alignof_double = cdata.get('ALIGNOF_DOUBLE')
-if cc.alignment(pg_int64_type, args: test_c_args) > alignof_double
- error('alignment of int64 is greater than the alignment of double')
+if cc.alignment('int64_t', args: test_c_args, prefix: '#include <stdint.h>') > alignof_double
+ error('alignment of int64_t is greater than the alignment of double')
endif
cdata.set('MAXIMUM_ALIGNOF', alignof_double)
+cdata.set('SIZEOF_LONG', cc.sizeof('long', args: test_c_args))
+cdata.set('SIZEOF_LONG_LONG', cc.sizeof('long long', args: test_c_args))
+cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
+cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
+
+
+# Check if __int128 is a working 128 bit integer type, and if so
+# define PG_INT128_TYPE to that typename.
cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
@@ -1834,17 +1827,17 @@ endif
# compile, and store the results in global variables so the compiler doesn't
# optimize away the call.
if cc.links('''
- INT64 a = 1;
- INT64 b = 1;
- INT64 result;
+ #include <stdint.h>
+ int64_t a = 1;
+ int64_t b = 1;
+ int64_t result;
int main(void)
{
return __builtin_mul_overflow(a, b, &result);
}''',
name: '__builtin_mul_overflow',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))],
- )
+ args: test_c_args)
cdata.set('HAVE__BUILTIN_OP_OVERFLOW', 1)
endif
@@ -2134,7 +2127,7 @@ int main(void)
cdata.set(check['name'],
cc.links(test,
name: check['desc'],
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))]) ? 1 : false
+ args: test_c_args) ? 1 : false
)
endforeach
@@ -2172,6 +2165,7 @@ if host_cpu == 'x86_64'
prog = '''
#include <immintrin.h>
+#include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
@@ -2179,7 +2173,7 @@ __attribute__((target("avx512vpopcntdq,avx512bw")))
int main(void)
{
const char buf[sizeof(__m512i)];
- INT64 popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -2190,8 +2184,7 @@ int main(void)
}
'''
- if cc.links(prog, name: 'AVX-512 popcount',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))])
+ if cc.links(prog, name: 'AVX-512 popcount', args: test_c_args)
cdata.set('USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 1)
endif
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 0f38d712d15..eac3d001211 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -840,12 +840,6 @@ $(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ;
$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config.h
-# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above.
-$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ;
-
-$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status
- cd $(top_builddir) && ./config.status src/include/pg_config_ext.h
-
# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same
# logic as above.
$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ;
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 1f9403fc5cf..c4b04d62965 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -610,10 +610,10 @@ XLogDumpStatsRow(const char *name,
tot_len_pct = 100 * (double) tot_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f)\n",
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f)\n",
name, n, n_pct, rec_len, rec_len_pct, fpi_len, fpi_len_pct,
tot_len, tot_len_pct);
}
@@ -742,10 +742,10 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogStats *stats)
fpi_len_pct = 100 * (double) total_fpi_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-6s\n",
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-6s\n",
"Total", stats->count, "",
total_rec_len, psprintf("[%.02f%%]", rec_len_pct),
total_fpi_len, psprintf("[%.02f%%]", fpi_len_pct),
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 85e7b68baa3..c4c38099c5b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6568,13 +6568,13 @@ printResults(StatsData *total,
SimpleStats *cstats = &(*commands)->stats;
if (max_tries == 1)
- printf(" %11.3f %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
(*commands)->first_line);
else
- printf(" %11.3f %10" INT64_MODIFIER "d %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
diff --git a/src/include/.gitignore b/src/include/.gitignore
index 51819fb4ddd..6e99e82fe0c 100644
--- a/src/include/.gitignore
+++ b/src/include/.gitignore
@@ -1,5 +1,3 @@
/stamp-h
-/stamp-ext-h
/pg_config.h
-/pg_config_ext.h
/pg_config_os.h
diff --git a/src/include/Makefile b/src/include/Makefile
index b8b576a4de3..26332ff9cbc 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -13,7 +13,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
-all: pg_config.h pg_config_ext.h pg_config_os.h
+all: pg_config.h pg_config_os.h
# Subdirectories containing installable headers
@@ -32,7 +32,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
# These headers are needed by the not-so-public headers of the interfaces.
@@ -43,7 +42,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes'
$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
@@ -66,7 +64,7 @@ installdirs:
uninstall:
- rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
+ rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
# heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
@@ -80,4 +78,4 @@ clean:
$(MAKE) -C catalog clean
distclean: clean
- rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h
+ rm -f pg_config.h pg_config_os.h stamp-h stamp-ext-h
diff --git a/src/include/c.h b/src/include/c.h
index 304dff27e34..734626e75a8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -48,14 +48,12 @@
#include "postgres_ext.h"
-/* Must undef pg_config_ext.h symbols before including pg_config.h */
-#undef PG_INT64_TYPE
-
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#include "pg_config_os.h" /* must be before any system header files */
/* System header files that should be available everywhere in Postgres */
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -471,25 +469,15 @@ typedef void (*pg_funcptr_t) (void);
*/
typedef char *Pointer;
-/*
- * intN
- * Signed integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef signed char int8; /* == 8 bits */
-typedef signed short int16; /* == 16 bits */
-typedef signed int int32; /* == 32 bits */
-
-/*
- * uintN
- * Unsigned integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef unsigned char uint8; /* == 8 bits */
-typedef unsigned short uint16; /* == 16 bits */
-typedef unsigned int uint32; /* == 32 bits */
+/* Historical names for types in <stdint.h>. */
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
/*
* bitsN
@@ -502,30 +490,14 @@ typedef uint32 bits32; /* >= 32 bits */
/*
* 64-bit integers
*/
-#ifdef HAVE_LONG_INT_64
-/* Plain "long int" fits, use it */
-
-typedef long int int64;
-typedef unsigned long int uint64;
-#define INT64CONST(x) (x##L)
-#define UINT64CONST(x) (x##UL)
-#elif defined(HAVE_LONG_LONG_INT_64)
-/* We have working support for "long long int", use that */
-
-typedef long long int int64;
-typedef unsigned long long int uint64;
-#define INT64CONST(x) (x##LL)
-#define UINT64CONST(x) (x##ULL)
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+#define INT64CONST(x) INT64_C(x)
+#define UINT64CONST(x) UINT64_C(x)
/* snprintf format strings to use for 64-bit integers */
-#define INT64_FORMAT "%" INT64_MODIFIER "d"
-#define UINT64_FORMAT "%" INT64_MODIFIER "u"
-#define INT64_HEX_FORMAT "%" INT64_MODIFIER "x"
-#define UINT64_HEX_FORMAT "%" INT64_MODIFIER "x"
+#define INT64_FORMAT "%" PRId64
+#define UINT64_FORMAT "%" PRIu64
+#define INT64_HEX_FORMAT "%" PRIx64
+#define UINT64_HEX_FORMAT "%" PRIx64
/*
* 128-bit signed and unsigned integers
@@ -554,22 +526,19 @@ typedef unsigned PG_INT128_TYPE uint128
#endif
#endif
-/*
- * stdint.h limits aren't guaranteed to have compatible types with our fixed
- * width types. So just define our own.
- */
-#define PG_INT8_MIN (-0x7F-1)
-#define PG_INT8_MAX (0x7F)
-#define PG_UINT8_MAX (0xFF)
-#define PG_INT16_MIN (-0x7FFF-1)
-#define PG_INT16_MAX (0x7FFF)
-#define PG_UINT16_MAX (0xFFFF)
-#define PG_INT32_MIN (-0x7FFFFFFF-1)
-#define PG_INT32_MAX (0x7FFFFFFF)
-#define PG_UINT32_MAX (0xFFFFFFFFU)
-#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
-#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
-#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF)
+/* Historical names for limits in <stdint.h>. */
+#define PG_INT8_MIN INT8_MIN
+#define PG_INT8_MAX INT8_MAX
+#define PG_UINT8_MAX UINT8_MAX
+#define PG_INT16_MIN INT16_MIN
+#define PG_INT16_MAX INT16_MAX
+#define PG_UINT16_MAX UINT16_MAX
+#define PG_INT32_MIN INT32_MIN
+#define PG_INT32_MAX INT32_MAX
+#define PG_UINT32_MAX UINT32_MAX
+#define PG_INT64_MIN INT64_MIN
+#define PG_INT64_MAX INT64_MAX
+#define PG_UINT64_MAX UINT64_MAX
/*
* We now always use int64 timestamps, but keep this symbol defined for the
@@ -1272,21 +1241,25 @@ extern int fdatasync(int fildes);
* definition of int64. (For the naming, compare that POSIX has
* strtoimax()/strtoumax() which return intmax_t/uintmax_t.)
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base))
-#else
+#elif SIZEOF_LONG_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base))
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
* Similarly, wrappers around labs()/llabs() matching our int64.
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define i64abs(i) labs(i)
-#else
+#elif SIZEOF_LONG_LONG == 8
#define i64abs(i) llabs(i)
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
diff --git a/src/include/meson.build b/src/include/meson.build
index 58b7a9c1e7e..e691b12b8a0 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -1,14 +1,5 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
-pg_config_ext = configure_file(
- input: 'pg_config_ext.h.meson',
- output: 'pg_config_ext.h',
- configuration: cdata,
- install: true,
- install_dir: dir_include,
-)
-configure_files += pg_config_ext
-
pg_config_os = configure_file(
output: 'pg_config_os.h',
input: files('port/@[email protected]'.format(portname)),
@@ -116,7 +107,6 @@ install_headers(
'postgres_fe.h',
'varatt.h',
'windowapi.h',
- pg_config_ext,
pg_config_os,
pg_config,
install_dir: dir_include_server,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ab0f8cc2b4a..55b73e74feb 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -9,12 +9,12 @@
/* The normal alignment of `int', in bytes. */
#undef ALIGNOF_INT
+/* The normal alignment of `int64_t', in bytes. */
+#undef ALIGNOF_INT64_T
+
/* The normal alignment of `long', in bytes. */
#undef ALIGNOF_LONG
-/* The normal alignment of `long long int', in bytes. */
-#undef ALIGNOF_LONG_LONG_INT
-
/* The normal alignment of `PG_INT128_TYPE', in bytes. */
#undef ALIGNOF_PG_INT128_TYPE
@@ -265,12 +265,6 @@
/* Define to 1 if you have the `zstd' library (-lzstd). */
#undef HAVE_LIBZSTD
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
-
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
-
/* Define to 1 if you have the <mbarrier.h> header file. */
#undef HAVE_MBARRIER_H
@@ -544,9 +538,6 @@
/* Define to 1 if your compiler understands _Static_assert. */
#undef HAVE__STATIC_ASSERT
-/* Define to the appropriate printf length modifier for 64-bit ints. */
-#undef INT64_MODIFIER
-
/* Define as the maximum alignment requirement of any C data type. */
#undef MAXIMUM_ALIGNOF
@@ -578,9 +569,6 @@
/* Define to the name of a signed 128-bit integer type. */
#undef PG_INT128_TYPE
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
-
/* Define to the name of the default PostgreSQL service principal in Kerberos
(GSSAPI). (--with-krb-srvnam=NAME) */
#undef PG_KRB_SRVNAM
@@ -630,6 +618,9 @@
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
diff --git a/src/include/pg_config_ext.h.in b/src/include/pg_config_ext.h.in
deleted file mode 100644
index 8acadbdafd4..00000000000
--- a/src/include/pg_config_ext.h.in
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
diff --git a/src/include/pg_config_ext.h.meson b/src/include/pg_config_ext.h.meson
deleted file mode 100644
index 57cdfca0cfd..00000000000
--- a/src/include/pg_config_ext.h.meson
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#mesondefine PG_INT64_TYPE
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h
index 4d88478c9c2..a3cad46afe9 100644
--- a/src/include/port/pg_bitutils.h
+++ b/src/include/port/pg_bitutils.h
@@ -74,13 +74,13 @@ pg_leftmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CLZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return 63 - __builtin_clzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return 63 - __builtin_clzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
@@ -147,13 +147,13 @@ pg_rightmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CTZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_ctzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_ctzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 7789e0431aa..8cc1e1bd4be 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -415,6 +415,53 @@ extern int _pglstat64(const char *name, struct stat *buf);
#undef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
+/*
+ * Adjustments to <inttypes.h>. Windows has size prefixes "I64", "I32", "I"
+ * (intptr_t), but our snprintf.c is not expecting those. Redefine them using
+ * traditional values that have the same effect.
+ */
+
+#undef PRId64
+#undef PRIu64
+#undef PRIx64
+#undef PRIX64
+#undef PRIo64
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#define PRIx64 "llx"
+#define PRIX64 "llX"
+#define PRIo64 "llo"
+
+#undef PRId32
+#undef PRIu32
+#undef PRIx32
+#undef PRIX32
+#undef PRIo32
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRIx32 "x"
+#define PRIX32 "X"
+#define PRIo32 "o"
+
+#undef PRIdPTR
+#undef PRIuPTR
+#undef PRIxPTR
+#undef PRIXPTR
+#undef PRIoPTR
+#if SIZEOF_VOID_P == 8
+#define PRIdPTR PRId64
+#define PRIuPTR PRIu64
+#define PRIxPTR PRIx64
+#define PRIXPTR PRIX64
+#define PRIoPTR PRIo64
+#else
+#define PRIdPTR PRId32
+#define PRIuPTR PRIu32
+#define PRIxPTR PRIx32
+#define PRIXPTR PRIX32
+#define PRIoPTR PRIo32
+#endif
+
/*
* Supplement to <string.h>.
*/
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 240ad4e93bf..202eb049622 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -23,7 +23,7 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
-#include "pg_config_ext.h"
+#include <stdint.h>
/*
* Object ID is a fundamental type in Postgres.
@@ -44,7 +44,7 @@ typedef unsigned int Oid;
/* Define a signed 64-bit integer type for use in client API declarations. */
-typedef PG_INT64_TYPE pg_int64;
+typedef int64_t pg_int64;
/*
* Identifiers of error message fields. Kept here to keep common
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h
index 8dff964bf33..6c952a43f79 100644
--- a/src/include/utils/dsa.h
+++ b/src/include/utils/dsa.h
@@ -66,7 +66,7 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
#define dsa_pointer_atomic_write pg_atomic_write_u64
#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64
#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64
-#define DSA_POINTER_FORMAT "%016" INT64_MODIFIER "x"
+#define DSA_POINTER_FORMAT "%016" PRIx64
#endif
/* Flags for dsa_allocate_extended. */
diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c
index 1d482c4fa61..1fb9860371b 100644
--- a/src/interfaces/ecpg/ecpglib/typename.c
+++ b/src/interfaces/ecpg/ecpglib/typename.c
@@ -131,11 +131,12 @@ sqlda_dynamic_type(Oid type, enum COMPAT_MODE compat)
case INTERVALOID:
return ECPGt_interval;
case INT8OID:
-#ifdef HAVE_LONG_LONG_INT_64
- return ECPGt_long_long;
-#endif
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
return ECPGt_long;
+#elif SIZEOF_LONG_LONG == 8
+ return ECPGt_long_long;
+#else
+#error "cannot find integer type of the same size as INT8OID"
#endif
/* Unhandled types always return a string */
default:
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index 75f542f263b..4af45930b61 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,8 +1,8 @@
/* Define to 1 to build client libraries as thread-safe code. */
#define ENABLE_THREAD_SAFETY 1
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index a3beb3cc7be..c1a88e73fb8 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -3,8 +3,8 @@
ecpg_inc = include_directories('.')
ecpg_conf_keys = [
- 'HAVE_LONG_INT_64',
- 'HAVE_LONG_LONG_INT_64',
+ 'SIZEOF_LONG',
+ 'SIZEOF_LONG_LONG',
]
ecpg_conf_data = configuration_data()
diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h
index 46cfce65517..f0acbb4512a 100644
--- a/src/interfaces/ecpg/include/pgtypes_interval.h
+++ b/src/interfaces/ecpg/include/pgtypes_interval.h
@@ -3,21 +3,17 @@
#ifndef PGTYPES_INTERVAL
#define PGTYPES_INTERVAL
+#include <stdint.h>
+
#include <ecpg_config.h>
#include <pgtypes.h>
#ifndef C_H
-#ifdef HAVE_LONG_INT_64
-typedef long int int64;
-#elif defined(HAVE_LONG_LONG_INT_64)
-typedef long long int int64;
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+typedef int64_t int64;
#define HAVE_INT64_TIMESTAMP
+
#endif /* C_H */
typedef struct
diff --git a/src/interfaces/ecpg/include/sqltypes.h b/src/interfaces/ecpg/include/sqltypes.h
index e7cbfa47956..498840458c4 100644
--- a/src/interfaces/ecpg/include/sqltypes.h
+++ b/src/interfaces/ecpg/include/sqltypes.h
@@ -46,12 +46,14 @@
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 7e19319d27f..8eebc51664e 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -97,12 +97,14 @@ typedef struct sqlda_struct sqlda_t;
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c
index 87f56e82b80..c8399981ee0 100644
--- a/src/port/pg_bitutils.c
+++ b/src/port/pg_bitutils.c
@@ -370,12 +370,12 @@ static inline int
pg_popcount64_slow(uint64 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_popcountl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_popcountll(word);
#else
-#error must have a working 64-bit integer datatype
+#error "cannot find integer of the same size as uint64_t"
#endif
#else /* !HAVE__BUILTIN_POPCOUNT */
int result = 0;
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 884f0262dd1..eba6437cceb 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -567,16 +567,12 @@ nextch2:
longflag = 1;
goto nextch2;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch2;
case 'h':
@@ -834,16 +830,12 @@ nextch1:
longflag = 1;
goto nextch1;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch1;
case 'h':
--
2.39.5 (Apple Git-154)
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-11-29 19:30 Thomas Munro <[email protected]>
parent: Thomas Munro <[email protected]>
1 sibling, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-11-29 19:30 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Fri, Nov 29, 2024 at 11:12 PM Thomas Munro <[email protected]> wrote:
> WIP patch attached.
Slightly better version. I'd missed some configure stuff that could
be removed, and tidied up a few minor typos and mistakes.
I was thinking about that ECPG stuff: I bet real applications prefer
to use int64_t etc directly too instead of long, the worst type in C.
I wondered if the embedded SQL standard might know about that these
days (ECPGt_int64_t?), but I don't have the standard to hand. DB2's
embedded SQL seems to have a type sqlint64, but I didn't look too
closely and of course even if we wanted to do something like that as
an optional API option, that'd be a later change.
BTW I forgot to mention earlier, I peeked at the source of gettext on
NetBSD and illumos, and both appear to handle those special
<inttypes.h> tokens when loading message catalogues.
Attachments:
[application/octet-stream] v5-0001-Use-stdint.h-and-inttypes.h-for-integer-types.patch (51.3K, ../../CA+hUKGLgPoPLhXmgSgZ0KTaSchddJM=KhpzLWn8kgT5E_tgsdQ@mail.gmail.com/2-v5-0001-Use-stdint.h-and-inttypes.h-for-integer-types.patch)
download | inline diff:
From 90839bef67527935f190893d04be9430fb6b9b2e Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 18 Apr 2024 07:53:10 +1200
Subject: [PATCH v5] Use <stdint.h> and <inttypes.h> for integer types.
Use standard types and support for 64 bit integers, including int64_t,
INT64_MAX, INT64_C(), PRId64 etc. Also use standard definitions of the
smaller integers.
One complication is that Windows' <inttypes.h> uses format strings like
%I64d for PRId64 that our own snprintf.c doesn't understand. Define our
own replacement macros that it can deal with.
Work in progress...
Reviewed-by: Peter Eisentraut <[email protected]>
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
config/c-compiler.m4 | 78 +---
configure | 354 +++++-------------
configure.ac | 52 +--
meson.build | 44 +--
src/Makefile.global.in | 6 -
src/bin/pg_waldump/pg_waldump.c | 16 +-
src/bin/pgbench/pgbench.c | 4 +-
src/include/.gitignore | 2 -
src/include/Makefile | 8 +-
src/include/c.h | 101 ++---
src/include/meson.build | 10 -
src/include/pg_config.h.in | 25 +-
src/include/pg_config_ext.h.in | 7 -
src/include/pg_config_ext.h.meson | 7 -
src/include/port/pg_bitutils.h | 16 +-
src/include/port/win32_port.h | 47 +++
src/include/postgres_ext.h | 4 +-
src/include/utils/dsa.h | 2 +-
src/interfaces/ecpg/ecpglib/typename.c | 9 +-
src/interfaces/ecpg/include/ecpg_config.h.in | 8 +-
src/interfaces/ecpg/include/meson.build | 4 +-
.../ecpg/include/pgtypes_interval.h | 12 +-
src/interfaces/ecpg/include/sqltypes.h | 8 +-
.../test/expected/compat_informix-sqlda.c | 8 +-
src/port/pg_bitutils.c | 6 +-
src/port/snprintf.c | 20 +-
26 files changed, 277 insertions(+), 581 deletions(-)
delete mode 100644 src/include/pg_config_ext.h.in
delete mode 100644 src/include/pg_config_ext.h.meson
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 309d5b04b46..e112fd45d48 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -38,60 +38,6 @@ ac_c_werror_flag=$ac_save_c_werror_flag
])# PGAC_TEST_PRINTF_ARCHETYPE
-# PGAC_TYPE_64BIT_INT(TYPE)
-# -------------------------
-# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
-# yes or no respectively, and define HAVE_TYPE_64 if yes.
-AC_DEFUN([PGAC_TYPE_64BIT_INT],
-[define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
-define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
-AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
-[AC_RUN_IFELSE([AC_LANG_SOURCE(
-[typedef $1 ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}])],
-[Ac_cachevar=yes],
-[Ac_cachevar=no],
-[# If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
- Ac_cachevar=yes,
- Ac_cachevar=no)])])
-
-Ac_define=$Ac_cachevar
-if test x"$Ac_cachevar" = xyes ; then
- AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
-fi
-undefine([Ac_define])dnl
-undefine([Ac_cachevar])dnl
-])# PGAC_TYPE_64BIT_INT
-
-
# PGAC_TYPE_128BIT_INT
# --------------------
# Check if __int128 is a working 128 bit integer type, and if so
@@ -270,9 +216,10 @@ fi])# PGAC_C_BUILTIN_CONSTANT_P
AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW],
[AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
+#include <stdint.h>
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
int oflo;
],
[oflo = __builtin_mul_overflow(a, b, &result);])],
@@ -557,13 +504,13 @@ fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
# types, and define HAVE_GCC__SYNC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);])],
[pgac_cv_gcc_sync_int64_cas="yes"],
[pgac_cv_gcc_sync_int64_cas="no"])])
if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
- AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).])
+ AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64_t *, int64_t, int64_t).])
fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
@@ -588,9 +535,9 @@ fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
[pgac_cv_gcc_atomic_int64_cas="yes"],
[pgac_cv_gcc_atomic_int64_cas="no"])])
@@ -734,13 +681,14 @@ AC_DEFUN([PGAC_AVX512_POPCNT_INTRINSICS],
[define([Ac_cachevar], [AS_TR_SH([pgac_cv_avx512_popcnt_intrinsics])])dnl
AC_CACHE_CHECK([for _mm512_popcnt_epi64], [Ac_cachevar],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>
+ #include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
#endif
static int popcount_test(void)
{
const char buf@<:@sizeof(__m512i)@:>@;
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
diff --git a/configure b/configure
index ff59f1422d8..bc49cebc990 100755
--- a/configure
+++ b/configure
@@ -14436,6 +14436,43 @@ if test x"$pgac_cv__builtin_constant_p" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CONSTANT_P 1" >>confdefs.h
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
+$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
+if ${pgac_cv__builtin_op_overflow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdint.h>
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
+int oflo;
+
+int
+main ()
+{
+oflo = __builtin_mul_overflow(a, b, &result);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ pgac_cv__builtin_op_overflow=yes
+else
+ pgac_cv__builtin_op_overflow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
+$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
+if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
+
+$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_unreachable" >&5
$as_echo_n "checking for __builtin_unreachable... " >&6; }
@@ -16196,236 +16233,6 @@ fi
# Run tests below here
# --------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5
-$as_echo_n "checking whether long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_int_64" >&6; }
-
-HAVE_LONG_INT_64=$pgac_cv_type_long_int_64
-if test x"$pgac_cv_type_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h
-
-fi
-
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5
-$as_echo_n "checking whether long long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_long_int_64" >&6; }
-
-HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64
-if test x"$pgac_cv_type_long_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h
-
-fi
-
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- as_fn_error $? "Cannot find a working 64-bit integer type." "$LINENO" 5
- fi
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define PG_INT64_TYPE $pg_int64_type
-_ACEOF
-
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define INT64_MODIFIER $INT64_MODIFIER
-_ACEOF
-
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
-$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
-if ${pgac_cv__builtin_op_overflow+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
-int oflo;
-
-int
-main ()
-{
-oflo = __builtin_mul_overflow(a, b, &result);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- pgac_cv__builtin_op_overflow=yes
-else
- pgac_cv__builtin_op_overflow=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
-$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
-if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
-
-$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
-
-fi
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
@@ -16526,6 +16333,39 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
# Determine memory alignment requirements for the basic C data types.
@@ -16634,43 +16474,41 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- # The cast to long int works around a bug in the HP C Compiler,
+# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long long int" >&5
-$as_echo_n "checking alignment of long long int... " >&6; }
-if ${ac_cv_alignof_long_long_int+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of int64_t" >&5
+$as_echo_n "checking alignment of int64_t... " >&6; }
+if ${ac_cv_alignof_int64_t+:} false; then :
$as_echo_n "(cached) " >&6
else
- if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long_long_int" "$ac_includes_default
+ if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_int64_t" "$ac_includes_default
#ifndef offsetof
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
#endif
-typedef struct { char x; long long int y; } ac__type_alignof_;"; then :
+typedef struct { char x; int64_t y; } ac__type_alignof_;"; then :
else
- if test "$ac_cv_type_long_long_int" = yes; then
+ if test "$ac_cv_type_int64_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute alignment of long long int
+as_fn_error 77 "cannot compute alignment of int64_t
See \`config.log' for more details" "$LINENO" 5; }
else
- ac_cv_alignof_long_long_int=0
+ ac_cv_alignof_int64_t=0
fi
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long_long_int" >&5
-$as_echo "$ac_cv_alignof_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_int64_t" >&5
+$as_echo "$ac_cv_alignof_int64_t" >&6; }
cat >>confdefs.h <<_ACEOF
-#define ALIGNOF_LONG_LONG_INT $ac_cv_alignof_long_long_int
+#define ALIGNOF_INT64_T $ac_cv_alignof_int64_t
_ACEOF
-fi
# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of double" >&5
@@ -16728,8 +16566,8 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
@@ -16737,7 +16575,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-
# Some compilers offer a 128-bit integer scalar type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
$as_echo_n "checking for __int128... " >&6; }
@@ -16992,12 +16829,12 @@ if ${pgac_cv_gcc_sync_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);
+int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);
;
return 0;
}
@@ -17057,12 +16894,12 @@ if ${pgac_cv_gcc_atomic_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
;
return 0;
@@ -17278,13 +17115,14 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <immintrin.h>
+ #include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
#endif
static int popcount_test(void)
{
const char buf[sizeof(__m512i)];
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -18954,9 +18792,6 @@ fi
ac_config_headers="$ac_config_headers src/include/pg_config.h"
-ac_config_headers="$ac_config_headers src/include/pg_config_ext.h"
-
-
ac_config_headers="$ac_config_headers src/interfaces/ecpg/include/ecpg_config.h"
@@ -19671,7 +19506,6 @@ do
"src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;;
"src/include/pg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
- "src/include/pg_config_ext.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config_ext.h" ;;
"src/interfaces/ecpg/include/ecpg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/interfaces/ecpg/include/ecpg_config.h" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -20279,10 +20113,6 @@ $as_echo "$as_me: WARNING: *** link for $FILE -- please fix by hand" >&2;}
"src/include/pg_config.h":H)
# Update timestamp for pg_config.h (see Makefile.global)
echo >src/include/stamp-h
- ;;
- "src/include/pg_config_ext.h":H)
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
;;
"src/interfaces/ecpg/include/ecpg_config.h":H) echo >src/interfaces/ecpg/include/stamp-h ;;
diff --git a/configure.ac b/configure.ac
index 21817009642..074ecc62d20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1604,6 +1604,7 @@ PGAC_C_STATIC_ASSERT
PGAC_C_TYPEOF
PGAC_C_TYPES_COMPATIBLE
PGAC_C_BUILTIN_CONSTANT_P
+PGAC_C_BUILTIN_OP_OVERFLOW
PGAC_C_BUILTIN_UNREACHABLE
PGAC_C_COMPUTED_GOTO
PGAC_STRUCT_TIMEZONE
@@ -1906,54 +1907,18 @@ for the exact reason.]])],
# Run tests below here
# --------------------
-dnl Check to see if we have a working 64-bit integer type.
-dnl Since Postgres 8.4, we no longer support compilers without a working
-dnl 64-bit type; but we have to determine whether that type is called
-dnl "long int" or "long long int".
-
-PGAC_TYPE_64BIT_INT([long int])
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- PGAC_TYPE_64BIT_INT([long long int])
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- AC_MSG_ERROR([Cannot find a working 64-bit integer type.])
- fi
-fi
-
-AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type,
- [Define to the name of a signed 64-bit integer type.])
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER,
- [Define to the appropriate printf length modifier for 64-bit ints.])
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-PGAC_C_BUILTIN_OP_OVERFLOW
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF([size_t])
AC_CHECK_SIZEOF([long])
+AC_CHECK_SIZEOF([long long])
# Determine memory alignment requirements for the basic C data types.
AC_CHECK_ALIGNOF(short)
AC_CHECK_ALIGNOF(int)
AC_CHECK_ALIGNOF(long)
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- AC_CHECK_ALIGNOF(long long int)
-fi
+AC_CHECK_ALIGNOF(int64_t)
AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
@@ -1977,12 +1942,11 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- AC_MSG_ERROR([alignment of 'long long int' is greater than the alignment of 'double'])
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ AC_MSG_ERROR([alignment of 'int64_t' is greater than the alignment of 'double'])
fi
AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.])
-
# Some compilers offer a 128-bit integer scalar type.
PGAC_TYPE_128BIT_INT
@@ -2472,12 +2436,6 @@ AC_CONFIG_HEADERS([src/include/pg_config.h],
echo >src/include/stamp-h
])
-AC_CONFIG_HEADERS([src/include/pg_config_ext.h],
-[
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
-])
-
AC_CONFIG_HEADERS([src/interfaces/ecpg/include/ecpg_config.h],
[echo >src/interfaces/ecpg/include/stamp-h])
diff --git a/meson.build b/meson.build
index 451c3f6d851..a2e35bca077 100644
--- a/meson.build
+++ b/meson.build
@@ -1588,21 +1588,6 @@ if not cc.compiles(c99_test, name: 'c99', args: test_c_args)
endif
endif
-sizeof_long = cc.sizeof('long', args: test_c_args)
-cdata.set('SIZEOF_LONG', sizeof_long)
-if sizeof_long == 8
- cdata.set('HAVE_LONG_INT_64', 1)
- pg_int64_type = 'long int'
- cdata.set_quoted('INT64_MODIFIER', 'l')
-elif sizeof_long == 4 and cc.sizeof('long long', args: test_c_args) == 8
- cdata.set('HAVE_LONG_LONG_INT_64', 1)
- pg_int64_type = 'long long int'
- cdata.set_quoted('INT64_MODIFIER', 'll')
-else
- error('do not know how to get a 64bit int')
-endif
-cdata.set('PG_INT64_TYPE', pg_int64_type)
-
if host_machine.endian() == 'big'
cdata.set('WORDS_BIGENDIAN', 1)
endif
@@ -1626,16 +1611,21 @@ endforeach
# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms
# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF.
#
-# We assume without checking that int64's alignment is at least as strong
+# We assume without checking that int64_t's alignment is at least as strong
# as long, char, short, or int. Note that we intentionally do not consider
# any types wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8
# would be too much of a penalty for disk and memory space.
alignof_double = cdata.get('ALIGNOF_DOUBLE')
-if cc.alignment(pg_int64_type, args: test_c_args) > alignof_double
- error('alignment of int64 is greater than the alignment of double')
+if cc.alignment('int64_t', args: test_c_args, prefix: '#include <stdint.h>') > alignof_double
+ error('alignment of int64_t is greater than the alignment of double')
endif
cdata.set('MAXIMUM_ALIGNOF', alignof_double)
+cdata.set('SIZEOF_LONG', cc.sizeof('long', args: test_c_args))
+cdata.set('SIZEOF_LONG_LONG', cc.sizeof('long long', args: test_c_args))
+
+# Check if __int128 is a working 128 bit integer type, and if so
+# define PG_INT128_TYPE to that typename.
cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
@@ -1834,17 +1824,17 @@ endif
# compile, and store the results in global variables so the compiler doesn't
# optimize away the call.
if cc.links('''
- INT64 a = 1;
- INT64 b = 1;
- INT64 result;
+ #include <stdint.h>
+ int64_t a = 1;
+ int64_t b = 1;
+ int64_t result;
int main(void)
{
return __builtin_mul_overflow(a, b, &result);
}''',
name: '__builtin_mul_overflow',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))],
- )
+ args: test_c_args)
cdata.set('HAVE__BUILTIN_OP_OVERFLOW', 1)
endif
@@ -2134,7 +2124,7 @@ int main(void)
cdata.set(check['name'],
cc.links(test,
name: check['desc'],
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))]) ? 1 : false
+ args: test_c_args) ? 1 : false
)
endforeach
@@ -2172,6 +2162,7 @@ if host_cpu == 'x86_64'
prog = '''
#include <immintrin.h>
+#include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
@@ -2179,7 +2170,7 @@ __attribute__((target("avx512vpopcntdq,avx512bw")))
int main(void)
{
const char buf[sizeof(__m512i)];
- INT64 popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -2190,8 +2181,7 @@ int main(void)
}
'''
- if cc.links(prog, name: 'AVX-512 popcount',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))])
+ if cc.links(prog, name: 'AVX-512 popcount', args: test_c_args)
cdata.set('USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 1)
endif
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 0f38d712d15..eac3d001211 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -840,12 +840,6 @@ $(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ;
$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config.h
-# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above.
-$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ;
-
-$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status
- cd $(top_builddir) && ./config.status src/include/pg_config_ext.h
-
# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same
# logic as above.
$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ;
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 1f9403fc5cf..c4b04d62965 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -610,10 +610,10 @@ XLogDumpStatsRow(const char *name,
tot_len_pct = 100 * (double) tot_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f)\n",
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f)\n",
name, n, n_pct, rec_len, rec_len_pct, fpi_len, fpi_len_pct,
tot_len, tot_len_pct);
}
@@ -742,10 +742,10 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogStats *stats)
fpi_len_pct = 100 * (double) total_fpi_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-6s\n",
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-6s\n",
"Total", stats->count, "",
total_rec_len, psprintf("[%.02f%%]", rec_len_pct),
total_fpi_len, psprintf("[%.02f%%]", fpi_len_pct),
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 85e7b68baa3..c4c38099c5b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6568,13 +6568,13 @@ printResults(StatsData *total,
SimpleStats *cstats = &(*commands)->stats;
if (max_tries == 1)
- printf(" %11.3f %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
(*commands)->first_line);
else
- printf(" %11.3f %10" INT64_MODIFIER "d %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
diff --git a/src/include/.gitignore b/src/include/.gitignore
index 51819fb4ddd..6e99e82fe0c 100644
--- a/src/include/.gitignore
+++ b/src/include/.gitignore
@@ -1,5 +1,3 @@
/stamp-h
-/stamp-ext-h
/pg_config.h
-/pg_config_ext.h
/pg_config_os.h
diff --git a/src/include/Makefile b/src/include/Makefile
index b8b576a4de3..26332ff9cbc 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -13,7 +13,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
-all: pg_config.h pg_config_ext.h pg_config_os.h
+all: pg_config.h pg_config_os.h
# Subdirectories containing installable headers
@@ -32,7 +32,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
# These headers are needed by the not-so-public headers of the interfaces.
@@ -43,7 +42,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes'
$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
@@ -66,7 +64,7 @@ installdirs:
uninstall:
- rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
+ rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
# heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
@@ -80,4 +78,4 @@ clean:
$(MAKE) -C catalog clean
distclean: clean
- rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h
+ rm -f pg_config.h pg_config_os.h stamp-h stamp-ext-h
diff --git a/src/include/c.h b/src/include/c.h
index 304dff27e34..734626e75a8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -48,14 +48,12 @@
#include "postgres_ext.h"
-/* Must undef pg_config_ext.h symbols before including pg_config.h */
-#undef PG_INT64_TYPE
-
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#include "pg_config_os.h" /* must be before any system header files */
/* System header files that should be available everywhere in Postgres */
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -471,25 +469,15 @@ typedef void (*pg_funcptr_t) (void);
*/
typedef char *Pointer;
-/*
- * intN
- * Signed integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef signed char int8; /* == 8 bits */
-typedef signed short int16; /* == 16 bits */
-typedef signed int int32; /* == 32 bits */
-
-/*
- * uintN
- * Unsigned integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef unsigned char uint8; /* == 8 bits */
-typedef unsigned short uint16; /* == 16 bits */
-typedef unsigned int uint32; /* == 32 bits */
+/* Historical names for types in <stdint.h>. */
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
/*
* bitsN
@@ -502,30 +490,14 @@ typedef uint32 bits32; /* >= 32 bits */
/*
* 64-bit integers
*/
-#ifdef HAVE_LONG_INT_64
-/* Plain "long int" fits, use it */
-
-typedef long int int64;
-typedef unsigned long int uint64;
-#define INT64CONST(x) (x##L)
-#define UINT64CONST(x) (x##UL)
-#elif defined(HAVE_LONG_LONG_INT_64)
-/* We have working support for "long long int", use that */
-
-typedef long long int int64;
-typedef unsigned long long int uint64;
-#define INT64CONST(x) (x##LL)
-#define UINT64CONST(x) (x##ULL)
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+#define INT64CONST(x) INT64_C(x)
+#define UINT64CONST(x) UINT64_C(x)
/* snprintf format strings to use for 64-bit integers */
-#define INT64_FORMAT "%" INT64_MODIFIER "d"
-#define UINT64_FORMAT "%" INT64_MODIFIER "u"
-#define INT64_HEX_FORMAT "%" INT64_MODIFIER "x"
-#define UINT64_HEX_FORMAT "%" INT64_MODIFIER "x"
+#define INT64_FORMAT "%" PRId64
+#define UINT64_FORMAT "%" PRIu64
+#define INT64_HEX_FORMAT "%" PRIx64
+#define UINT64_HEX_FORMAT "%" PRIx64
/*
* 128-bit signed and unsigned integers
@@ -554,22 +526,19 @@ typedef unsigned PG_INT128_TYPE uint128
#endif
#endif
-/*
- * stdint.h limits aren't guaranteed to have compatible types with our fixed
- * width types. So just define our own.
- */
-#define PG_INT8_MIN (-0x7F-1)
-#define PG_INT8_MAX (0x7F)
-#define PG_UINT8_MAX (0xFF)
-#define PG_INT16_MIN (-0x7FFF-1)
-#define PG_INT16_MAX (0x7FFF)
-#define PG_UINT16_MAX (0xFFFF)
-#define PG_INT32_MIN (-0x7FFFFFFF-1)
-#define PG_INT32_MAX (0x7FFFFFFF)
-#define PG_UINT32_MAX (0xFFFFFFFFU)
-#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
-#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
-#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF)
+/* Historical names for limits in <stdint.h>. */
+#define PG_INT8_MIN INT8_MIN
+#define PG_INT8_MAX INT8_MAX
+#define PG_UINT8_MAX UINT8_MAX
+#define PG_INT16_MIN INT16_MIN
+#define PG_INT16_MAX INT16_MAX
+#define PG_UINT16_MAX UINT16_MAX
+#define PG_INT32_MIN INT32_MIN
+#define PG_INT32_MAX INT32_MAX
+#define PG_UINT32_MAX UINT32_MAX
+#define PG_INT64_MIN INT64_MIN
+#define PG_INT64_MAX INT64_MAX
+#define PG_UINT64_MAX UINT64_MAX
/*
* We now always use int64 timestamps, but keep this symbol defined for the
@@ -1272,21 +1241,25 @@ extern int fdatasync(int fildes);
* definition of int64. (For the naming, compare that POSIX has
* strtoimax()/strtoumax() which return intmax_t/uintmax_t.)
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base))
-#else
+#elif SIZEOF_LONG_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base))
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
* Similarly, wrappers around labs()/llabs() matching our int64.
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define i64abs(i) labs(i)
-#else
+#elif SIZEOF_LONG_LONG == 8
#define i64abs(i) llabs(i)
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
diff --git a/src/include/meson.build b/src/include/meson.build
index 58b7a9c1e7e..e691b12b8a0 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -1,14 +1,5 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
-pg_config_ext = configure_file(
- input: 'pg_config_ext.h.meson',
- output: 'pg_config_ext.h',
- configuration: cdata,
- install: true,
- install_dir: dir_include,
-)
-configure_files += pg_config_ext
-
pg_config_os = configure_file(
output: 'pg_config_os.h',
input: files('port/@[email protected]'.format(portname)),
@@ -116,7 +107,6 @@ install_headers(
'postgres_fe.h',
'varatt.h',
'windowapi.h',
- pg_config_ext,
pg_config_os,
pg_config,
install_dir: dir_include_server,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ab0f8cc2b4a..07b2f798abd 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -9,12 +9,12 @@
/* The normal alignment of `int', in bytes. */
#undef ALIGNOF_INT
+/* The normal alignment of `int64_t', in bytes. */
+#undef ALIGNOF_INT64_T
+
/* The normal alignment of `long', in bytes. */
#undef ALIGNOF_LONG
-/* The normal alignment of `long long int', in bytes. */
-#undef ALIGNOF_LONG_LONG_INT
-
/* The normal alignment of `PG_INT128_TYPE', in bytes. */
#undef ALIGNOF_PG_INT128_TYPE
@@ -153,8 +153,8 @@
/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */
#undef HAVE_GCC__SYNC_INT32_TAS
-/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).
- */
+/* Define to 1 if you have __sync_val_compare_and_swap(int64_t *, int64_t,
+ int64_t). */
#undef HAVE_GCC__SYNC_INT64_CAS
/* Define to 1 if you have the `getauxval' function. */
@@ -265,12 +265,6 @@
/* Define to 1 if you have the `zstd' library (-lzstd). */
#undef HAVE_LIBZSTD
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
-
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
-
/* Define to 1 if you have the <mbarrier.h> header file. */
#undef HAVE_MBARRIER_H
@@ -544,9 +538,6 @@
/* Define to 1 if your compiler understands _Static_assert. */
#undef HAVE__STATIC_ASSERT
-/* Define to the appropriate printf length modifier for 64-bit ints. */
-#undef INT64_MODIFIER
-
/* Define as the maximum alignment requirement of any C data type. */
#undef MAXIMUM_ALIGNOF
@@ -578,9 +569,6 @@
/* Define to the name of a signed 128-bit integer type. */
#undef PG_INT128_TYPE
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
-
/* Define to the name of the default PostgreSQL service principal in Kerberos
(GSSAPI). (--with-krb-srvnam=NAME) */
#undef PG_KRB_SRVNAM
@@ -630,6 +618,9 @@
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
diff --git a/src/include/pg_config_ext.h.in b/src/include/pg_config_ext.h.in
deleted file mode 100644
index 8acadbdafd4..00000000000
--- a/src/include/pg_config_ext.h.in
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
diff --git a/src/include/pg_config_ext.h.meson b/src/include/pg_config_ext.h.meson
deleted file mode 100644
index 57cdfca0cfd..00000000000
--- a/src/include/pg_config_ext.h.meson
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#mesondefine PG_INT64_TYPE
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h
index 4d88478c9c2..a3cad46afe9 100644
--- a/src/include/port/pg_bitutils.h
+++ b/src/include/port/pg_bitutils.h
@@ -74,13 +74,13 @@ pg_leftmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CLZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return 63 - __builtin_clzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return 63 - __builtin_clzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
@@ -147,13 +147,13 @@ pg_rightmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CTZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_ctzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_ctzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 7789e0431aa..9bcaba65624 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -415,6 +415,53 @@ extern int _pglstat64(const char *name, struct stat *buf);
#undef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
+/*
+ * Adjustments to <inttypes.h>. Windows has size prefixes "I64", "I32", "I"
+ * (intptr_t), but our snprintf.c is not expecting those. Redefine them using
+ * standard strings that have the same effect since we know the sizes.
+ */
+
+#undef PRId64
+#undef PRIu64
+#undef PRIx64
+#undef PRIX64
+#undef PRIo64
+#define PRId64 "lld"
+#define PRIu64 "llu"
+#define PRIx64 "llx"
+#define PRIX64 "llX"
+#define PRIo64 "llo"
+
+#undef PRId32
+#undef PRIu32
+#undef PRIx32
+#undef PRIX32
+#undef PRIo32
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRIx32 "x"
+#define PRIX32 "X"
+#define PRIo32 "o"
+
+#undef PRIdPTR
+#undef PRIuPTR
+#undef PRIxPTR
+#undef PRIXPTR
+#undef PRIoPTR
+#if SIZEOF_VOID_P == 8
+#define PRIdPTR PRId64
+#define PRIuPTR PRIu64
+#define PRIxPTR PRIx64
+#define PRIXPTR PRIX64
+#define PRIoPTR PRIo64
+#else
+#define PRIdPTR PRId32
+#define PRIuPTR PRIu32
+#define PRIxPTR PRIx32
+#define PRIXPTR PRIX32
+#define PRIoPTR PRIo32
+#endif
+
/*
* Supplement to <string.h>.
*/
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 240ad4e93bf..202eb049622 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -23,7 +23,7 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
-#include "pg_config_ext.h"
+#include <stdint.h>
/*
* Object ID is a fundamental type in Postgres.
@@ -44,7 +44,7 @@ typedef unsigned int Oid;
/* Define a signed 64-bit integer type for use in client API declarations. */
-typedef PG_INT64_TYPE pg_int64;
+typedef int64_t pg_int64;
/*
* Identifiers of error message fields. Kept here to keep common
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h
index 8dff964bf33..6c952a43f79 100644
--- a/src/include/utils/dsa.h
+++ b/src/include/utils/dsa.h
@@ -66,7 +66,7 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
#define dsa_pointer_atomic_write pg_atomic_write_u64
#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64
#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64
-#define DSA_POINTER_FORMAT "%016" INT64_MODIFIER "x"
+#define DSA_POINTER_FORMAT "%016" PRIx64
#endif
/* Flags for dsa_allocate_extended. */
diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c
index 1d482c4fa61..1fb9860371b 100644
--- a/src/interfaces/ecpg/ecpglib/typename.c
+++ b/src/interfaces/ecpg/ecpglib/typename.c
@@ -131,11 +131,12 @@ sqlda_dynamic_type(Oid type, enum COMPAT_MODE compat)
case INTERVALOID:
return ECPGt_interval;
case INT8OID:
-#ifdef HAVE_LONG_LONG_INT_64
- return ECPGt_long_long;
-#endif
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
return ECPGt_long;
+#elif SIZEOF_LONG_LONG == 8
+ return ECPGt_long_long;
+#else
+#error "cannot find integer type of the same size as INT8OID"
#endif
/* Unhandled types always return a string */
default:
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index 75f542f263b..4af45930b61 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,8 +1,8 @@
/* Define to 1 to build client libraries as thread-safe code. */
#define ENABLE_THREAD_SAFETY 1
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index a3beb3cc7be..c1a88e73fb8 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -3,8 +3,8 @@
ecpg_inc = include_directories('.')
ecpg_conf_keys = [
- 'HAVE_LONG_INT_64',
- 'HAVE_LONG_LONG_INT_64',
+ 'SIZEOF_LONG',
+ 'SIZEOF_LONG_LONG',
]
ecpg_conf_data = configuration_data()
diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h
index 46cfce65517..f0acbb4512a 100644
--- a/src/interfaces/ecpg/include/pgtypes_interval.h
+++ b/src/interfaces/ecpg/include/pgtypes_interval.h
@@ -3,21 +3,17 @@
#ifndef PGTYPES_INTERVAL
#define PGTYPES_INTERVAL
+#include <stdint.h>
+
#include <ecpg_config.h>
#include <pgtypes.h>
#ifndef C_H
-#ifdef HAVE_LONG_INT_64
-typedef long int int64;
-#elif defined(HAVE_LONG_LONG_INT_64)
-typedef long long int int64;
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+typedef int64_t int64;
#define HAVE_INT64_TIMESTAMP
+
#endif /* C_H */
typedef struct
diff --git a/src/interfaces/ecpg/include/sqltypes.h b/src/interfaces/ecpg/include/sqltypes.h
index e7cbfa47956..498840458c4 100644
--- a/src/interfaces/ecpg/include/sqltypes.h
+++ b/src/interfaces/ecpg/include/sqltypes.h
@@ -46,12 +46,14 @@
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 7e19319d27f..8eebc51664e 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -97,12 +97,14 @@ typedef struct sqlda_struct sqlda_t;
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c
index 87f56e82b80..c8399981ee0 100644
--- a/src/port/pg_bitutils.c
+++ b/src/port/pg_bitutils.c
@@ -370,12 +370,12 @@ static inline int
pg_popcount64_slow(uint64 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_popcountl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_popcountll(word);
#else
-#error must have a working 64-bit integer datatype
+#error "cannot find integer of the same size as uint64_t"
#endif
#else /* !HAVE__BUILTIN_POPCOUNT */
int result = 0;
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 884f0262dd1..eba6437cceb 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -567,16 +567,12 @@ nextch2:
longflag = 1;
goto nextch2;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch2;
case 'h':
@@ -834,16 +830,12 @@ nextch1:
longflag = 1;
goto nextch1;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch1;
case 'h':
--
2.39.5 (Apple Git-154)
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-11-29 23:42 Thomas Munro <[email protected]>
parent: Thomas Munro <[email protected]>
1 sibling, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-11-29 23:42 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Fri, Nov 29, 2024 at 11:12 PM Thomas Munro <[email protected]> wrote:
> New idea: let's just redefine PRI...{32,64,PTR} on that platform,
> instead of modifying snprintf.c.
D'oh, that's not going to fly. gettext() would replace %<PRId64> with
the system's PRId64, so we can't avoid teaching our snprintf.c to
understand Windowsian format strings. Here's a first attempt at that.
Tested a bit by removing the #ifdef WIN32 locally and playing around
with it. CI passes on Windows, and I think that should be exercising
it via existing [U]INT64_FORMAT in various places that would break if
it didn't work.
It would be nice to see it working via gettext() too, but NLS seems to
be disabled on that OS in CI (and also the BF). Huh, that seems
non-ideal. Transcripts on pgsql-bugs show it working on that OS
though (with occasional encoding glitches, apparently), so I guess the
EDB build must have it enabled.
I tried out the gettext() support for this on Unix. I didn't bother
with xgettext etc, I just manually added a message to fr.po to test
the runtime based on an example in another project, and it worked
unsurprisingly:
- errmsg("REJECT_LIMIT (%lld) must be
greater than zero",
- (long long) reject_limit)));
+ errmsg("REJECT_LIMIT (%" PRId64 ")
must be greater than zero",
+ reject_limit)));
+#, c-format
+msgid "REJECT_LIMIT (%<PRId64>) must be greater than zero"
+msgstr "REJECT_LIMIT (%<PRId64>) doit être supérieure à zéro"
postgres=# copy t from '/dev/null' with (reject_limit -1);
ERREUR: REJECT_LIMIT (-1) doit être supérieure à zéro
Attachments:
[text/x-patch] v6-0001-Use-stdint.h-and-inttypes.h-for-integer-types.patch (51.2K, ../../CA+hUKGK7WQX3nTuYbiiGZFcV70CqbmBx4VUOnDy6ZGm1v=qGqQ@mail.gmail.com/2-v6-0001-Use-stdint.h-and-inttypes.h-for-integer-types.patch)
download | inline diff:
From 22e6601f345285e0b823771d5f8acde5d59709e7 Mon Sep 17 00:00:00 2001
From: Thomas Munro <[email protected]>
Date: Thu, 18 Apr 2024 07:53:10 +1200
Subject: [PATCH v6] Use <stdint.h> and <inttypes.h> for integer types.
Use standard types and support for 64 bit integers, including int64_t,
INT64_MAX, INT64_C(), PRId64 etc. Also use standard definitions of the
smaller integers.
One complication is that Windows' <inttypes.h> uses format strings like
%I64d, %I32, %I for PRI*64, PRI*32, PTR*PTR, rather than standard format
strings like %ld as seen on other systems. We have to teach our own
snprintf.c to recognize them.
Work in progress...
Reviewed-by: Peter Eisentraut <[email protected]>
Discussion: https://postgr.es/m/ME3P282MB3166F9D1F71F787929C0C7E7B6312%40ME3P282MB3166.AUSP282.PROD.OUTLOOK.COM
---
config/c-compiler.m4 | 78 +---
configure | 354 +++++-------------
configure.ac | 52 +--
meson.build | 44 +--
src/Makefile.global.in | 6 -
src/bin/pg_waldump/pg_waldump.c | 16 +-
src/bin/pgbench/pgbench.c | 4 +-
src/include/.gitignore | 2 -
src/include/Makefile | 8 +-
src/include/c.h | 101 ++---
src/include/meson.build | 10 -
src/include/pg_config.h.in | 25 +-
src/include/pg_config_ext.h.in | 7 -
src/include/pg_config_ext.h.meson | 7 -
src/include/port/pg_bitutils.h | 16 +-
src/include/postgres_ext.h | 4 +-
src/include/utils/dsa.h | 2 +-
src/interfaces/ecpg/ecpglib/typename.c | 9 +-
src/interfaces/ecpg/include/ecpg_config.h.in | 8 +-
src/interfaces/ecpg/include/meson.build | 4 +-
.../ecpg/include/pgtypes_interval.h | 12 +-
src/interfaces/ecpg/include/sqltypes.h | 8 +-
.../test/expected/compat_informix-sqlda.c | 8 +-
src/port/pg_bitutils.c | 6 +-
src/port/snprintf.c | 64 +++-
25 files changed, 274 insertions(+), 581 deletions(-)
delete mode 100644 src/include/pg_config_ext.h.in
delete mode 100644 src/include/pg_config_ext.h.meson
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 309d5b04b46..e112fd45d48 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -38,60 +38,6 @@ ac_c_werror_flag=$ac_save_c_werror_flag
])# PGAC_TEST_PRINTF_ARCHETYPE
-# PGAC_TYPE_64BIT_INT(TYPE)
-# -------------------------
-# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
-# yes or no respectively, and define HAVE_TYPE_64 if yes.
-AC_DEFUN([PGAC_TYPE_64BIT_INT],
-[define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
-define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
-AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
-[AC_RUN_IFELSE([AC_LANG_SOURCE(
-[typedef $1 ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}])],
-[Ac_cachevar=yes],
-[Ac_cachevar=no],
-[# If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [sizeof($1) == 8])],
- Ac_cachevar=yes,
- Ac_cachevar=no)])])
-
-Ac_define=$Ac_cachevar
-if test x"$Ac_cachevar" = xyes ; then
- AC_DEFINE(Ac_define, 1, [Define to 1 if `]$1[' works and is 64 bits.])
-fi
-undefine([Ac_define])dnl
-undefine([Ac_cachevar])dnl
-])# PGAC_TYPE_64BIT_INT
-
-
# PGAC_TYPE_128BIT_INT
# --------------------
# Check if __int128 is a working 128 bit integer type, and if so
@@ -270,9 +216,10 @@ fi])# PGAC_C_BUILTIN_CONSTANT_P
AC_DEFUN([PGAC_C_BUILTIN_OP_OVERFLOW],
[AC_CACHE_CHECK(for __builtin_mul_overflow, pgac_cv__builtin_op_overflow,
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
+#include <stdint.h>
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
int oflo;
],
[oflo = __builtin_mul_overflow(a, b, &result);])],
@@ -557,13 +504,13 @@ fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS
# types, and define HAVE_GCC__SYNC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __sync int64 atomic operations, pgac_cv_gcc_sync_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);])],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);])],
[pgac_cv_gcc_sync_int64_cas="yes"],
[pgac_cv_gcc_sync_int64_cas="no"])])
if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then
- AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).])
+ AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64_t *, int64_t, int64_t).])
fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS
# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
@@ -588,9 +535,9 @@ fi])# PGAC_HAVE_GCC__ATOMIC_INT32_CAS
# types, and define HAVE_GCC__ATOMIC_INT64_CAS if so.
AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS],
[AC_CACHE_CHECK(for builtin __atomic int64 atomic operations, pgac_cv_gcc_atomic_int64_cas,
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([],
- [PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdint.h>],
+ [int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);])],
[pgac_cv_gcc_atomic_int64_cas="yes"],
[pgac_cv_gcc_atomic_int64_cas="no"])])
@@ -734,13 +681,14 @@ AC_DEFUN([PGAC_AVX512_POPCNT_INTRINSICS],
[define([Ac_cachevar], [AS_TR_SH([pgac_cv_avx512_popcnt_intrinsics])])dnl
AC_CACHE_CHECK([for _mm512_popcnt_epi64], [Ac_cachevar],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <immintrin.h>
+ #include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
#endif
static int popcount_test(void)
{
const char buf@<:@sizeof(__m512i)@:>@;
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
diff --git a/configure b/configure
index ff59f1422d8..bc49cebc990 100755
--- a/configure
+++ b/configure
@@ -14436,6 +14436,43 @@ if test x"$pgac_cv__builtin_constant_p" = xyes ; then
$as_echo "#define HAVE__BUILTIN_CONSTANT_P 1" >>confdefs.h
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
+$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
+if ${pgac_cv__builtin_op_overflow+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdint.h>
+int64_t a = 1;
+int64_t b = 1;
+int64_t result;
+int oflo;
+
+int
+main ()
+{
+oflo = __builtin_mul_overflow(a, b, &result);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ pgac_cv__builtin_op_overflow=yes
+else
+ pgac_cv__builtin_op_overflow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
+$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
+if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
+
+$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_unreachable" >&5
$as_echo_n "checking for __builtin_unreachable... " >&6; }
@@ -16196,236 +16233,6 @@ fi
# Run tests below here
# --------------------
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5
-$as_echo_n "checking whether long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_int_64=yes
-else
- pgac_cv_type_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_int_64" >&6; }
-
-HAVE_LONG_INT_64=$pgac_cv_type_long_int_64
-if test x"$pgac_cv_type_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_INT_64 1" >>confdefs.h
-
-fi
-
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long long int is 64 bits" >&5
-$as_echo_n "checking whether long long int is 64 bits... " >&6; }
-if ${pgac_cv_type_long_long_int_64+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test "$cross_compiling" = yes; then :
- # If cross-compiling, check the size reported by the compiler and
-# trust that the arithmetic works.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-static int test_array [1 - 2 * !(sizeof(long long int) == 8)];
-test_array [0] = 0;
-return test_array [0];
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-typedef long long int ac_int64;
-
-/*
- * These are globals to discourage the compiler from folding all the
- * arithmetic tests down to compile-time constants.
- */
-ac_int64 a = 20000001;
-ac_int64 b = 40000005;
-
-int does_int64_work()
-{
- ac_int64 c,d;
-
- if (sizeof(ac_int64) != 8)
- return 0; /* definitely not the right size */
-
- /* Do perfunctory checks to see if 64-bit arithmetic seems to work */
- c = a * b;
- d = (c + b) / b;
- if (d != a+1)
- return 0;
- return 1;
-}
-
-int
-main() {
- return (! does_int64_work());
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- pgac_cv_type_long_long_int_64=yes
-else
- pgac_cv_type_long_long_int_64=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_type_long_long_int_64" >&5
-$as_echo "$pgac_cv_type_long_long_int_64" >&6; }
-
-HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64
-if test x"$pgac_cv_type_long_long_int_64" = xyes ; then
-
-$as_echo "#define HAVE_LONG_LONG_INT_64 1" >>confdefs.h
-
-fi
-
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- as_fn_error $? "Cannot find a working 64-bit integer type." "$LINENO" 5
- fi
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define PG_INT64_TYPE $pg_int64_type
-_ACEOF
-
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-
-cat >>confdefs.h <<_ACEOF
-#define INT64_MODIFIER $INT64_MODIFIER
-_ACEOF
-
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5
-$as_echo_n "checking for __builtin_mul_overflow... " >&6; }
-if ${pgac_cv__builtin_op_overflow+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-PG_INT64_TYPE a = 1;
-PG_INT64_TYPE b = 1;
-PG_INT64_TYPE result;
-int oflo;
-
-int
-main ()
-{
-oflo = __builtin_mul_overflow(a, b, &result);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- pgac_cv__builtin_op_overflow=yes
-else
- pgac_cv__builtin_op_overflow=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_op_overflow" >&5
-$as_echo "$pgac_cv__builtin_op_overflow" >&6; }
-if test x"$pgac_cv__builtin_op_overflow" = xyes ; then
-
-$as_echo "#define HAVE__BUILTIN_OP_OVERFLOW 1" >>confdefs.h
-
-fi
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
@@ -16526,6 +16333,39 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
# Determine memory alignment requirements for the basic C data types.
@@ -16634,43 +16474,41 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- # The cast to long int works around a bug in the HP C Compiler,
+# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long long int" >&5
-$as_echo_n "checking alignment of long long int... " >&6; }
-if ${ac_cv_alignof_long_long_int+:} false; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of int64_t" >&5
+$as_echo_n "checking alignment of int64_t... " >&6; }
+if ${ac_cv_alignof_int64_t+:} false; then :
$as_echo_n "(cached) " >&6
else
- if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long_long_int" "$ac_includes_default
+ if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_int64_t" "$ac_includes_default
#ifndef offsetof
# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0)
#endif
-typedef struct { char x; long long int y; } ac__type_alignof_;"; then :
+typedef struct { char x; int64_t y; } ac__type_alignof_;"; then :
else
- if test "$ac_cv_type_long_long_int" = yes; then
+ if test "$ac_cv_type_int64_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute alignment of long long int
+as_fn_error 77 "cannot compute alignment of int64_t
See \`config.log' for more details" "$LINENO" 5; }
else
- ac_cv_alignof_long_long_int=0
+ ac_cv_alignof_int64_t=0
fi
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long_long_int" >&5
-$as_echo "$ac_cv_alignof_long_long_int" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_int64_t" >&5
+$as_echo "$ac_cv_alignof_int64_t" >&6; }
cat >>confdefs.h <<_ACEOF
-#define ALIGNOF_LONG_LONG_INT $ac_cv_alignof_long_long_int
+#define ALIGNOF_INT64_T $ac_cv_alignof_int64_t
_ACEOF
-fi
# The cast to long int works around a bug in the HP C Compiler,
# see AC_CHECK_SIZEOF for more information.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of double" >&5
@@ -16728,8 +16566,8 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
@@ -16737,7 +16575,6 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-
# Some compilers offer a 128-bit integer scalar type.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
$as_echo_n "checking for __int128... " >&6; }
@@ -16992,12 +16829,12 @@ if ${pgac_cv_gcc_sync_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE lock = 0;
- __sync_val_compare_and_swap(&lock, 0, (PG_INT64_TYPE) 37);
+int64_t lock = 0;
+ __sync_val_compare_and_swap(&lock, 0, (int64_t) 37);
;
return 0;
}
@@ -17057,12 +16894,12 @@ if ${pgac_cv_gcc_atomic_int64_cas+:} false; then :
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
+#include <stdint.h>
int
main ()
{
-PG_INT64_TYPE val = 0;
- PG_INT64_TYPE expect = 0;
+int64_t val = 0;
+ int64_t expect = 0;
__atomic_compare_exchange_n(&val, &expect, 37, 0, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
;
return 0;
@@ -17278,13 +17115,14 @@ else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <immintrin.h>
+ #include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
#endif
static int popcount_test(void)
{
const char buf[sizeof(__m512i)];
- PG_INT64_TYPE popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -18954,9 +18792,6 @@ fi
ac_config_headers="$ac_config_headers src/include/pg_config.h"
-ac_config_headers="$ac_config_headers src/include/pg_config_ext.h"
-
-
ac_config_headers="$ac_config_headers src/interfaces/ecpg/include/ecpg_config.h"
@@ -19671,7 +19506,6 @@ do
"src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;;
"check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;;
"src/include/pg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;;
- "src/include/pg_config_ext.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config_ext.h" ;;
"src/interfaces/ecpg/include/ecpg_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/interfaces/ecpg/include/ecpg_config.h" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -20279,10 +20113,6 @@ $as_echo "$as_me: WARNING: *** link for $FILE -- please fix by hand" >&2;}
"src/include/pg_config.h":H)
# Update timestamp for pg_config.h (see Makefile.global)
echo >src/include/stamp-h
- ;;
- "src/include/pg_config_ext.h":H)
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
;;
"src/interfaces/ecpg/include/ecpg_config.h":H) echo >src/interfaces/ecpg/include/stamp-h ;;
diff --git a/configure.ac b/configure.ac
index 21817009642..074ecc62d20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1604,6 +1604,7 @@ PGAC_C_STATIC_ASSERT
PGAC_C_TYPEOF
PGAC_C_TYPES_COMPATIBLE
PGAC_C_BUILTIN_CONSTANT_P
+PGAC_C_BUILTIN_OP_OVERFLOW
PGAC_C_BUILTIN_UNREACHABLE
PGAC_C_COMPUTED_GOTO
PGAC_STRUCT_TIMEZONE
@@ -1906,54 +1907,18 @@ for the exact reason.]])],
# Run tests below here
# --------------------
-dnl Check to see if we have a working 64-bit integer type.
-dnl Since Postgres 8.4, we no longer support compilers without a working
-dnl 64-bit type; but we have to determine whether that type is called
-dnl "long int" or "long long int".
-
-PGAC_TYPE_64BIT_INT([long int])
-
-if test x"$HAVE_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long int"
-else
- PGAC_TYPE_64BIT_INT([long long int])
- if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- pg_int64_type="long long int"
- else
- AC_MSG_ERROR([Cannot find a working 64-bit integer type.])
- fi
-fi
-
-AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type,
- [Define to the name of a signed 64-bit integer type.])
-
-# Select the printf length modifier that goes with that, too.
-if test x"$pg_int64_type" = x"long long int" ; then
- INT64_MODIFIER='"ll"'
-else
- INT64_MODIFIER='"l"'
-fi
-
-AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER,
- [Define to the appropriate printf length modifier for 64-bit ints.])
-
-# has to be down here, rather than with the other builtins, because
-# the test uses PG_INT64_TYPE.
-PGAC_C_BUILTIN_OP_OVERFLOW
-
# Check size of void *, size_t (enables tweaks for > 32bit address space)
AC_CHECK_SIZEOF([void *])
AC_CHECK_SIZEOF([size_t])
AC_CHECK_SIZEOF([long])
+AC_CHECK_SIZEOF([long long])
# Determine memory alignment requirements for the basic C data types.
AC_CHECK_ALIGNOF(short)
AC_CHECK_ALIGNOF(int)
AC_CHECK_ALIGNOF(long)
-if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then
- AC_CHECK_ALIGNOF(long long int)
-fi
+AC_CHECK_ALIGNOF(int64_t)
AC_CHECK_ALIGNOF(double)
# Compute maximum alignment of any basic type.
@@ -1977,12 +1942,11 @@ MAX_ALIGNOF=$ac_cv_alignof_double
if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
fi
-if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
- AC_MSG_ERROR([alignment of 'long long int' is greater than the alignment of 'double'])
+if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
+ AC_MSG_ERROR([alignment of 'int64_t' is greater than the alignment of 'double'])
fi
AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any C data type.])
-
# Some compilers offer a 128-bit integer scalar type.
PGAC_TYPE_128BIT_INT
@@ -2472,12 +2436,6 @@ AC_CONFIG_HEADERS([src/include/pg_config.h],
echo >src/include/stamp-h
])
-AC_CONFIG_HEADERS([src/include/pg_config_ext.h],
-[
-# Update timestamp for pg_config_ext.h (see Makefile.global)
-echo >src/include/stamp-ext-h
-])
-
AC_CONFIG_HEADERS([src/interfaces/ecpg/include/ecpg_config.h],
[echo >src/interfaces/ecpg/include/stamp-h])
diff --git a/meson.build b/meson.build
index 451c3f6d851..a2e35bca077 100644
--- a/meson.build
+++ b/meson.build
@@ -1588,21 +1588,6 @@ if not cc.compiles(c99_test, name: 'c99', args: test_c_args)
endif
endif
-sizeof_long = cc.sizeof('long', args: test_c_args)
-cdata.set('SIZEOF_LONG', sizeof_long)
-if sizeof_long == 8
- cdata.set('HAVE_LONG_INT_64', 1)
- pg_int64_type = 'long int'
- cdata.set_quoted('INT64_MODIFIER', 'l')
-elif sizeof_long == 4 and cc.sizeof('long long', args: test_c_args) == 8
- cdata.set('HAVE_LONG_LONG_INT_64', 1)
- pg_int64_type = 'long long int'
- cdata.set_quoted('INT64_MODIFIER', 'll')
-else
- error('do not know how to get a 64bit int')
-endif
-cdata.set('PG_INT64_TYPE', pg_int64_type)
-
if host_machine.endian() == 'big'
cdata.set('WORDS_BIGENDIAN', 1)
endif
@@ -1626,16 +1611,21 @@ endforeach
# of MAXIMUM_ALIGNOF to avoid that, but we no longer support any platforms
# where TYPALIGN_DOUBLE != MAXIMUM_ALIGNOF.
#
-# We assume without checking that int64's alignment is at least as strong
+# We assume without checking that int64_t's alignment is at least as strong
# as long, char, short, or int. Note that we intentionally do not consider
# any types wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8
# would be too much of a penalty for disk and memory space.
alignof_double = cdata.get('ALIGNOF_DOUBLE')
-if cc.alignment(pg_int64_type, args: test_c_args) > alignof_double
- error('alignment of int64 is greater than the alignment of double')
+if cc.alignment('int64_t', args: test_c_args, prefix: '#include <stdint.h>') > alignof_double
+ error('alignment of int64_t is greater than the alignment of double')
endif
cdata.set('MAXIMUM_ALIGNOF', alignof_double)
+cdata.set('SIZEOF_LONG', cc.sizeof('long', args: test_c_args))
+cdata.set('SIZEOF_LONG_LONG', cc.sizeof('long long', args: test_c_args))
+
+# Check if __int128 is a working 128 bit integer type, and if so
+# define PG_INT128_TYPE to that typename.
cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
@@ -1834,17 +1824,17 @@ endif
# compile, and store the results in global variables so the compiler doesn't
# optimize away the call.
if cc.links('''
- INT64 a = 1;
- INT64 b = 1;
- INT64 result;
+ #include <stdint.h>
+ int64_t a = 1;
+ int64_t b = 1;
+ int64_t result;
int main(void)
{
return __builtin_mul_overflow(a, b, &result);
}''',
name: '__builtin_mul_overflow',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))],
- )
+ args: test_c_args)
cdata.set('HAVE__BUILTIN_OP_OVERFLOW', 1)
endif
@@ -2134,7 +2124,7 @@ int main(void)
cdata.set(check['name'],
cc.links(test,
name: check['desc'],
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))]) ? 1 : false
+ args: test_c_args) ? 1 : false
)
endforeach
@@ -2172,6 +2162,7 @@ if host_cpu == 'x86_64'
prog = '''
#include <immintrin.h>
+#include <stdint.h>
#if defined(__has_attribute) && __has_attribute (target)
__attribute__((target("avx512vpopcntdq,avx512bw")))
@@ -2179,7 +2170,7 @@ __attribute__((target("avx512vpopcntdq,avx512bw")))
int main(void)
{
const char buf[sizeof(__m512i)];
- INT64 popcnt = 0;
+ int64_t popcnt = 0;
__m512i accum = _mm512_setzero_si512();
const __m512i val = _mm512_maskz_loadu_epi8((__mmask64) 0xf0f0f0f0f0f0f0f0, (const __m512i *) buf);
const __m512i cnt = _mm512_popcnt_epi64(val);
@@ -2190,8 +2181,7 @@ int main(void)
}
'''
- if cc.links(prog, name: 'AVX-512 popcount',
- args: test_c_args + ['-DINT64=@0@'.format(cdata.get('PG_INT64_TYPE'))])
+ if cc.links(prog, name: 'AVX-512 popcount', args: test_c_args)
cdata.set('USE_AVX512_POPCNT_WITH_RUNTIME_CHECK', 1)
endif
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 0f38d712d15..eac3d001211 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -840,12 +840,6 @@ $(top_builddir)/src/include/pg_config.h: $(top_builddir)/src/include/stamp-h ;
$(top_builddir)/src/include/stamp-h: $(top_srcdir)/src/include/pg_config.h.in $(top_builddir)/config.status
cd $(top_builddir) && ./config.status src/include/pg_config.h
-# Also remake pg_config_ext.h from pg_config_ext.h.in, same logic as above.
-$(top_builddir)/src/include/pg_config_ext.h: $(top_builddir)/src/include/stamp-ext-h ;
-
-$(top_builddir)/src/include/stamp-ext-h: $(top_srcdir)/src/include/pg_config_ext.h.in $(top_builddir)/config.status
- cd $(top_builddir) && ./config.status src/include/pg_config_ext.h
-
# Also remake ecpg_config.h from ecpg_config.h.in if the latter changed, same
# logic as above.
$(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h: $(top_builddir)/src/interfaces/ecpg/include/stamp-h ;
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 1f9403fc5cf..c4b04d62965 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -610,10 +610,10 @@ XLogDumpStatsRow(const char *name,
tot_len_pct = 100 * (double) tot_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f) "
- "%20" INT64_MODIFIER "u (%6.02f)\n",
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f) "
+ "%20" PRIu64 " (%6.02f)\n",
name, n, n_pct, rec_len, rec_len_pct, fpi_len, fpi_len_pct,
tot_len, tot_len_pct);
}
@@ -742,10 +742,10 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogStats *stats)
fpi_len_pct = 100 * (double) total_fpi_len / total_len;
printf("%-27s "
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-9s"
- "%20" INT64_MODIFIER "u %-6s\n",
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-9s"
+ "%20" PRIu64 " %-6s\n",
"Total", stats->count, "",
total_rec_len, psprintf("[%.02f%%]", rec_len_pct),
total_fpi_len, psprintf("[%.02f%%]", fpi_len_pct),
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 85e7b68baa3..c4c38099c5b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6568,13 +6568,13 @@ printResults(StatsData *total,
SimpleStats *cstats = &(*commands)->stats;
if (max_tries == 1)
- printf(" %11.3f %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
(*commands)->first_line);
else
- printf(" %11.3f %10" INT64_MODIFIER "d %10" INT64_MODIFIER "d %s\n",
+ printf(" %11.3f %10" PRId64 " %10" PRId64 " %s\n",
(cstats->count > 0) ?
1000.0 * cstats->sum / cstats->count : 0.0,
(*commands)->failures,
diff --git a/src/include/.gitignore b/src/include/.gitignore
index 51819fb4ddd..6e99e82fe0c 100644
--- a/src/include/.gitignore
+++ b/src/include/.gitignore
@@ -1,5 +1,3 @@
/stamp-h
-/stamp-ext-h
/pg_config.h
-/pg_config_ext.h
/pg_config_os.h
diff --git a/src/include/Makefile b/src/include/Makefile
index b8b576a4de3..26332ff9cbc 100644
--- a/src/include/Makefile
+++ b/src/include/Makefile
@@ -13,7 +13,7 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
-all: pg_config.h pg_config_ext.h pg_config_os.h
+all: pg_config.h pg_config_os.h
# Subdirectories containing installable headers
@@ -32,7 +32,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq'
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)'
# These headers are needed by the not-so-public headers of the interfaces.
@@ -43,7 +42,6 @@ install: all installdirs
$(INSTALL_DATA) $(srcdir)/libpq/protocol.h '$(DESTDIR)$(includedir_internal)/libpq'
# These headers are needed for server-side development
$(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)'
- $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)'
$(INSTALL_DATA) nodes/nodetags.h '$(DESTDIR)$(includedir_server)/nodes'
$(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils'
@@ -66,7 +64,7 @@ installdirs:
uninstall:
- rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
+ rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h)
rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h libpq/protocol.h)
# heuristic...
rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h)
@@ -80,4 +78,4 @@ clean:
$(MAKE) -C catalog clean
distclean: clean
- rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h
+ rm -f pg_config.h pg_config_os.h stamp-h stamp-ext-h
diff --git a/src/include/c.h b/src/include/c.h
index 304dff27e34..734626e75a8 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -48,14 +48,12 @@
#include "postgres_ext.h"
-/* Must undef pg_config_ext.h symbols before including pg_config.h */
-#undef PG_INT64_TYPE
-
#include "pg_config.h"
#include "pg_config_manual.h" /* must be after pg_config.h */
#include "pg_config_os.h" /* must be before any system header files */
/* System header files that should be available everywhere in Postgres */
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -471,25 +469,15 @@ typedef void (*pg_funcptr_t) (void);
*/
typedef char *Pointer;
-/*
- * intN
- * Signed integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef signed char int8; /* == 8 bits */
-typedef signed short int16; /* == 16 bits */
-typedef signed int int32; /* == 32 bits */
-
-/*
- * uintN
- * Unsigned integer, EXACTLY N BITS IN SIZE,
- * used for numerical computations and the
- * frontend/backend protocol.
- */
-typedef unsigned char uint8; /* == 8 bits */
-typedef unsigned short uint16; /* == 16 bits */
-typedef unsigned int uint32; /* == 32 bits */
+/* Historical names for types in <stdint.h>. */
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
/*
* bitsN
@@ -502,30 +490,14 @@ typedef uint32 bits32; /* >= 32 bits */
/*
* 64-bit integers
*/
-#ifdef HAVE_LONG_INT_64
-/* Plain "long int" fits, use it */
-
-typedef long int int64;
-typedef unsigned long int uint64;
-#define INT64CONST(x) (x##L)
-#define UINT64CONST(x) (x##UL)
-#elif defined(HAVE_LONG_LONG_INT_64)
-/* We have working support for "long long int", use that */
-
-typedef long long int int64;
-typedef unsigned long long int uint64;
-#define INT64CONST(x) (x##LL)
-#define UINT64CONST(x) (x##ULL)
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+#define INT64CONST(x) INT64_C(x)
+#define UINT64CONST(x) UINT64_C(x)
/* snprintf format strings to use for 64-bit integers */
-#define INT64_FORMAT "%" INT64_MODIFIER "d"
-#define UINT64_FORMAT "%" INT64_MODIFIER "u"
-#define INT64_HEX_FORMAT "%" INT64_MODIFIER "x"
-#define UINT64_HEX_FORMAT "%" INT64_MODIFIER "x"
+#define INT64_FORMAT "%" PRId64
+#define UINT64_FORMAT "%" PRIu64
+#define INT64_HEX_FORMAT "%" PRIx64
+#define UINT64_HEX_FORMAT "%" PRIx64
/*
* 128-bit signed and unsigned integers
@@ -554,22 +526,19 @@ typedef unsigned PG_INT128_TYPE uint128
#endif
#endif
-/*
- * stdint.h limits aren't guaranteed to have compatible types with our fixed
- * width types. So just define our own.
- */
-#define PG_INT8_MIN (-0x7F-1)
-#define PG_INT8_MAX (0x7F)
-#define PG_UINT8_MAX (0xFF)
-#define PG_INT16_MIN (-0x7FFF-1)
-#define PG_INT16_MAX (0x7FFF)
-#define PG_UINT16_MAX (0xFFFF)
-#define PG_INT32_MIN (-0x7FFFFFFF-1)
-#define PG_INT32_MAX (0x7FFFFFFF)
-#define PG_UINT32_MAX (0xFFFFFFFFU)
-#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
-#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
-#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF)
+/* Historical names for limits in <stdint.h>. */
+#define PG_INT8_MIN INT8_MIN
+#define PG_INT8_MAX INT8_MAX
+#define PG_UINT8_MAX UINT8_MAX
+#define PG_INT16_MIN INT16_MIN
+#define PG_INT16_MAX INT16_MAX
+#define PG_UINT16_MAX UINT16_MAX
+#define PG_INT32_MIN INT32_MIN
+#define PG_INT32_MAX INT32_MAX
+#define PG_UINT32_MAX UINT32_MAX
+#define PG_INT64_MIN INT64_MIN
+#define PG_INT64_MAX INT64_MAX
+#define PG_UINT64_MAX UINT64_MAX
/*
* We now always use int64 timestamps, but keep this symbol defined for the
@@ -1272,21 +1241,25 @@ extern int fdatasync(int fildes);
* definition of int64. (For the naming, compare that POSIX has
* strtoimax()/strtoumax() which return intmax_t/uintmax_t.)
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base))
-#else
+#elif SIZEOF_LONG_LONG == 8
#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base))
#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base))
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
* Similarly, wrappers around labs()/llabs() matching our int64.
*/
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
#define i64abs(i) labs(i)
-#else
+#elif SIZEOF_LONG_LONG == 8
#define i64abs(i) llabs(i)
+#else
+#error "cannot find integer type of the same size as int64_t"
#endif
/*
diff --git a/src/include/meson.build b/src/include/meson.build
index 58b7a9c1e7e..e691b12b8a0 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -1,14 +1,5 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group
-pg_config_ext = configure_file(
- input: 'pg_config_ext.h.meson',
- output: 'pg_config_ext.h',
- configuration: cdata,
- install: true,
- install_dir: dir_include,
-)
-configure_files += pg_config_ext
-
pg_config_os = configure_file(
output: 'pg_config_os.h',
input: files('port/@[email protected]'.format(portname)),
@@ -116,7 +107,6 @@ install_headers(
'postgres_fe.h',
'varatt.h',
'windowapi.h',
- pg_config_ext,
pg_config_os,
pg_config,
install_dir: dir_include_server,
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ab0f8cc2b4a..07b2f798abd 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -9,12 +9,12 @@
/* The normal alignment of `int', in bytes. */
#undef ALIGNOF_INT
+/* The normal alignment of `int64_t', in bytes. */
+#undef ALIGNOF_INT64_T
+
/* The normal alignment of `long', in bytes. */
#undef ALIGNOF_LONG
-/* The normal alignment of `long long int', in bytes. */
-#undef ALIGNOF_LONG_LONG_INT
-
/* The normal alignment of `PG_INT128_TYPE', in bytes. */
#undef ALIGNOF_PG_INT128_TYPE
@@ -153,8 +153,8 @@
/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */
#undef HAVE_GCC__SYNC_INT32_TAS
-/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).
- */
+/* Define to 1 if you have __sync_val_compare_and_swap(int64_t *, int64_t,
+ int64_t). */
#undef HAVE_GCC__SYNC_INT64_CAS
/* Define to 1 if you have the `getauxval' function. */
@@ -265,12 +265,6 @@
/* Define to 1 if you have the `zstd' library (-lzstd). */
#undef HAVE_LIBZSTD
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
-
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
-
/* Define to 1 if you have the <mbarrier.h> header file. */
#undef HAVE_MBARRIER_H
@@ -544,9 +538,6 @@
/* Define to 1 if your compiler understands _Static_assert. */
#undef HAVE__STATIC_ASSERT
-/* Define to the appropriate printf length modifier for 64-bit ints. */
-#undef INT64_MODIFIER
-
/* Define as the maximum alignment requirement of any C data type. */
#undef MAXIMUM_ALIGNOF
@@ -578,9 +569,6 @@
/* Define to the name of a signed 128-bit integer type. */
#undef PG_INT128_TYPE
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
-
/* Define to the name of the default PostgreSQL service principal in Kerberos
(GSSAPI). (--with-krb-srvnam=NAME) */
#undef PG_KRB_SRVNAM
@@ -630,6 +618,9 @@
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
diff --git a/src/include/pg_config_ext.h.in b/src/include/pg_config_ext.h.in
deleted file mode 100644
index 8acadbdafd4..00000000000
--- a/src/include/pg_config_ext.h.in
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#undef PG_INT64_TYPE
diff --git a/src/include/pg_config_ext.h.meson b/src/include/pg_config_ext.h.meson
deleted file mode 100644
index 57cdfca0cfd..00000000000
--- a/src/include/pg_config_ext.h.meson
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * src/include/pg_config_ext.h.in. This is generated manually, not by
- * autoheader, since we want to limit which symbols get defined here.
- */
-
-/* Define to the name of a signed 64-bit integer type. */
-#mesondefine PG_INT64_TYPE
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h
index 4d88478c9c2..a3cad46afe9 100644
--- a/src/include/port/pg_bitutils.h
+++ b/src/include/port/pg_bitutils.h
@@ -74,13 +74,13 @@ pg_leftmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CLZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return 63 - __builtin_clzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return 63 - __builtin_clzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
@@ -147,13 +147,13 @@ pg_rightmost_one_pos64(uint64 word)
#ifdef HAVE__BUILTIN_CTZ
Assert(word != 0);
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_ctzl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_ctzll(word);
#else
-#error must have a working 64-bit integer datatype
-#endif /* HAVE_LONG_INT_64 */
+#error "cannot find integer type of the same size as uint64_t"
+#endif
#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64))
unsigned long result;
diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h
index 240ad4e93bf..202eb049622 100644
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -23,7 +23,7 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
-#include "pg_config_ext.h"
+#include <stdint.h>
/*
* Object ID is a fundamental type in Postgres.
@@ -44,7 +44,7 @@ typedef unsigned int Oid;
/* Define a signed 64-bit integer type for use in client API declarations. */
-typedef PG_INT64_TYPE pg_int64;
+typedef int64_t pg_int64;
/*
* Identifiers of error message fields. Kept here to keep common
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h
index 8dff964bf33..6c952a43f79 100644
--- a/src/include/utils/dsa.h
+++ b/src/include/utils/dsa.h
@@ -66,7 +66,7 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
#define dsa_pointer_atomic_write pg_atomic_write_u64
#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64
#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64
-#define DSA_POINTER_FORMAT "%016" INT64_MODIFIER "x"
+#define DSA_POINTER_FORMAT "%016" PRIx64
#endif
/* Flags for dsa_allocate_extended. */
diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c
index 1d482c4fa61..1fb9860371b 100644
--- a/src/interfaces/ecpg/ecpglib/typename.c
+++ b/src/interfaces/ecpg/ecpglib/typename.c
@@ -131,11 +131,12 @@ sqlda_dynamic_type(Oid type, enum COMPAT_MODE compat)
case INTERVALOID:
return ECPGt_interval;
case INT8OID:
-#ifdef HAVE_LONG_LONG_INT_64
- return ECPGt_long_long;
-#endif
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_LONG == 8
return ECPGt_long;
+#elif SIZEOF_LONG_LONG == 8
+ return ECPGt_long_long;
+#else
+#error "cannot find integer type of the same size as INT8OID"
#endif
/* Unhandled types always return a string */
default:
diff --git a/src/interfaces/ecpg/include/ecpg_config.h.in b/src/interfaces/ecpg/include/ecpg_config.h.in
index 75f542f263b..4af45930b61 100644
--- a/src/interfaces/ecpg/include/ecpg_config.h.in
+++ b/src/interfaces/ecpg/include/ecpg_config.h.in
@@ -1,8 +1,8 @@
/* Define to 1 to build client libraries as thread-safe code. */
#define ENABLE_THREAD_SAFETY 1
-/* Define to 1 if `long int' works and is 64 bits. */
-#undef HAVE_LONG_INT_64
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
-/* Define to 1 if `long long int' works and is 64 bits. */
-#undef HAVE_LONG_LONG_INT_64
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
diff --git a/src/interfaces/ecpg/include/meson.build b/src/interfaces/ecpg/include/meson.build
index a3beb3cc7be..c1a88e73fb8 100644
--- a/src/interfaces/ecpg/include/meson.build
+++ b/src/interfaces/ecpg/include/meson.build
@@ -3,8 +3,8 @@
ecpg_inc = include_directories('.')
ecpg_conf_keys = [
- 'HAVE_LONG_INT_64',
- 'HAVE_LONG_LONG_INT_64',
+ 'SIZEOF_LONG',
+ 'SIZEOF_LONG_LONG',
]
ecpg_conf_data = configuration_data()
diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h
index 46cfce65517..f0acbb4512a 100644
--- a/src/interfaces/ecpg/include/pgtypes_interval.h
+++ b/src/interfaces/ecpg/include/pgtypes_interval.h
@@ -3,21 +3,17 @@
#ifndef PGTYPES_INTERVAL
#define PGTYPES_INTERVAL
+#include <stdint.h>
+
#include <ecpg_config.h>
#include <pgtypes.h>
#ifndef C_H
-#ifdef HAVE_LONG_INT_64
-typedef long int int64;
-#elif defined(HAVE_LONG_LONG_INT_64)
-typedef long long int int64;
-#else
-/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
-#error must have a working 64-bit integer datatype
-#endif
+typedef int64_t int64;
#define HAVE_INT64_TIMESTAMP
+
#endif /* C_H */
typedef struct
diff --git a/src/interfaces/ecpg/include/sqltypes.h b/src/interfaces/ecpg/include/sqltypes.h
index e7cbfa47956..498840458c4 100644
--- a/src/interfaces/ecpg/include/sqltypes.h
+++ b/src/interfaces/ecpg/include/sqltypes.h
@@ -46,12 +46,14 @@
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
index 7e19319d27f..8eebc51664e 100644
--- a/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
+++ b/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
@@ -97,12 +97,14 @@ typedef struct sqlda_struct sqlda_t;
#define SQLINTERVAL ECPGt_interval
#define SQLNCHAR ECPGt_char
#define SQLNVCHAR ECPGt_char
-#ifdef HAVE_LONG_LONG_INT_64
+#if SIZEOF_LONG == 8
+#define SQLINT8 ECPGt_long
+#define SQLSERIAL8 ECPGt_long
+#elif SIZEOF_LONG_LONG == 8
#define SQLINT8 ECPGt_long_long
#define SQLSERIAL8 ECPGt_long_long
#else
-#define SQLINT8 ECPGt_long
-#define SQLSERIAL8 ECPGt_long
+#error "cannot find integer type of the same size as SQLINT8"
#endif
#endif /* ndef ECPG_SQLTYPES_H */
diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c
index 87f56e82b80..c8399981ee0 100644
--- a/src/port/pg_bitutils.c
+++ b/src/port/pg_bitutils.c
@@ -370,12 +370,12 @@ static inline int
pg_popcount64_slow(uint64 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
-#if defined(HAVE_LONG_INT_64)
+#if SIZEOF_LONG == 8
return __builtin_popcountl(word);
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_LONG_LONG == 8
return __builtin_popcountll(word);
#else
-#error must have a working 64-bit integer datatype
+#error "cannot find integer of the same size as uint64_t"
#endif
#else /* !HAVE__BUILTIN_POPCOUNT */
int result = 0;
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 884f0262dd1..c21af2fb2e7 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -560,6 +560,28 @@ nextch2:
fmtpos = accum;
accum = 0;
goto nextch2;
+#ifdef WIN32
+ case 'I':
+ /* Windows PRI*{32,64,PTR} size */
+ if (format[0] == '3' && format[1] == '2')
+ format += 2;
+ else if (format[0] == '6' && format[1] == '4')
+ {
+ format += 2;
+ longlongflag = 1;
+ }
+ else
+ {
+#if SIZEOF_VOID_P == SIZEOF_LONG
+ longflag = 1;
+#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
+ longlongflag = 1;
+#else
+#error "cannot find integer type of the same size as intptr_t"
+#endif
+ }
+ goto nextch2;
+#endif
case 'l':
if (longflag)
longlongflag = 1;
@@ -567,16 +589,12 @@ nextch2:
longflag = 1;
goto nextch2;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch2;
case 'h':
@@ -827,6 +845,28 @@ nextch1:
fmtpos = accum;
accum = 0;
goto nextch1;
+#ifdef WIN32
+ case 'I':
+ /* Windows PRI*{32,64,PTR} size */
+ if (format[0] == '3' && format[1] == '2')
+ format += 2;
+ else if (format[0] == '6' && format[1] == '4')
+ {
+ format += 2;
+ longlongflag = 1;
+ }
+ else
+ {
+#if SIZEOF_VOID_P == SIZEOF_LONG
+ longflag = 1;
+#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG
+ longlongflag = 1;
+#else
+#error "cannot find integer type of the same size as intptr_t"
+#endif
+ }
+ goto nextch1;
+#endif
case 'l':
if (longflag)
longlongflag = 1;
@@ -834,16 +874,12 @@ nextch1:
longflag = 1;
goto nextch1;
case 'z':
-#if SIZEOF_SIZE_T == 8
-#ifdef HAVE_LONG_INT_64
+#if SIZEOF_SIZE_T == SIZEOF_LONG
longflag = 1;
-#elif defined(HAVE_LONG_LONG_INT_64)
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
longlongflag = 1;
#else
-#error "Don't know how to print 64bit integers"
-#endif
-#else
- /* assume size_t is same size as int */
+#error "cannot find integer type of the same size as size_t"
#endif
goto nextch1;
case 'h':
--
2.47.0
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-03 13:22 Peter Eisentraut <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Peter Eisentraut @ 2024-12-03 13:22 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On 29.11.24 20:30, Thomas Munro wrote:
> On Fri, Nov 29, 2024 at 11:12 PM Thomas Munro <[email protected]> wrote:
> I was thinking about that ECPG stuff: I bet real applications prefer
> to use int64_t etc directly too instead of long, the worst type in C.
> I wondered if the embedded SQL standard might know about that these
> days (ECPGt_int64_t?), but I don't have the standard to hand. DB2's
> embedded SQL seems to have a type sqlint64, but I didn't look too
> closely and of course even if we wanted to do something like that as
> an optional API option, that'd be a later change.
Interesting:
i) If “long long” is specified, then the <host parameter data type> of
HV is BIGINT.
ii) If “long” is specified, then the <host parameter data type> of HV is
INTEGER.
iii) If “short” is specified, then the <host parameter data type> of HV
is SMALLINT.
[...]
I suppose that makes sense.
> BTW I forgot to mention earlier, I peeked at the source of gettext on
> NetBSD and illumos, and both appear to handle those special
> <inttypes.h> tokens when loading message catalogues.
Ah great, thanks for checking that.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-03 13:24 Peter Eisentraut <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Peter Eisentraut @ 2024-12-03 13:24 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On 30.11.24 00:42, Thomas Munro wrote:
> On Fri, Nov 29, 2024 at 11:12 PM Thomas Munro <[email protected]> wrote:
>> New idea: let's just redefine PRI...{32,64,PTR} on that platform,
>> instead of modifying snprintf.c.
>
> D'oh, that's not going to fly. gettext() would replace %<PRId64> with
> the system's PRId64, so we can't avoid teaching our snprintf.c to
> understand Windowsian format strings. Here's a first attempt at that.
> Tested a bit by removing the #ifdef WIN32 locally and playing around
> with it. CI passes on Windows, and I think that should be exercising
> it via existing [U]INT64_FORMAT in various places that would break if
> it didn't work.
This patch looks good to me.
In meson.build, this comment seems to be misplaced by accident:
+# Check if __int128 is a working 128 bit integer type, and if so
+# define PG_INT128_TYPE to that typename.
cdata.set('SIZEOF_VOID_P', cc.sizeof('void *', args: test_c_args))
cdata.set('SIZEOF_SIZE_T', cc.sizeof('size_t', args: test_c_args))
In c.h, you include <inttypes.h> instead of <stdint.h>. Is there a
reason for that?
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 03:04 Thomas Munro <[email protected]>
parent: Peter Eisentraut <[email protected]>
0 siblings, 2 replies; 25+ messages in thread
From: Thomas Munro @ 2024-12-04 03:04 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, Dec 4, 2024 at 2:24 AM Peter Eisentraut <[email protected]> wrote:
> This patch looks good to me.
Thanks! Pushed. Let's see what the build farm says.
> In meson.build, this comment seems to be misplaced by accident:
Oops, fixed.
> In c.h, you include <inttypes.h> instead of <stdint.h>. Is there a
> reason for that?
<stdint.h> was already there for uintptr_t at least. <inttypes.h> is
needed to be able to define:
#define INT64_FORMAT "%" PRId64
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 05:58 Thomas Munro <[email protected]>
parent: Thomas Munro <[email protected]>
1 sibling, 0 replies; 25+ messages in thread
From: Thomas Munro @ 2024-12-04 05:58 UTC (permalink / raw)
To: Peter Eisentraut <[email protected]>; +Cc: Heikki Linnakangas <[email protected]>; Tom Lane <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Wed, Dec 4, 2024 at 4:04 PM Thomas Munro <[email protected]> wrote:
> Thanks! Pushed. Let's see what the build farm says.
A couple of armv7 animals seemed to die in the Perl tests. Huh. Well
I know that Perl was sensitive to this stuff but it passed on 32 bit
CI (x86). I will try to reproduce that on local ARM hardware...
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 06:19 Tom Lane <[email protected]>
parent: Thomas Munro <[email protected]>
1 sibling, 1 reply; 25+ messages in thread
From: Tom Lane @ 2024-12-04 06:19 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Thomas Munro <[email protected]> writes:
> A couple of armv7 animals seemed to die in the Perl tests. Huh. Well
> I know that Perl was sensitive to this stuff but it passed on 32 bit
> CI (x86). I will try to reproduce that on local ARM hardware...
turaco seems unhappy because of
2024-12-04 05:37:14.831 GMT [9584:18] pg_regress/plperl_setup LOG: statement: CREATE EXTENSION plperl;
Util.c: loadable library and perl binaries are mismatched (got first handshake key 0xa300080, needed 0xa400080)
Not clear to me what these changes would have done to trigger that.
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 19:41 Tom Lane <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 2 replies; 25+ messages in thread
From: Tom Lane @ 2024-12-04 19:41 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Also ... grison and turaco are emitting warnings that were
not there a couple of days ago:
grison | 2024-12-04 17:10:09 | reconstruct.c:701:33: warning: passing argument 2 of 'copy_file_range' from incompatible pointer type [-Wincompatible-pointer-types]
turaco | 2024-12-04 16:15:11 | reconstruct.c:701:61: warning: passing argument 2 of 'copy_file_range' from incompatible pointer type [-Wincompatible-pointer-types]
The code they are complaining about is from ac8110155 ("Allow using
copy_file_range in write_reconstructed_file") back in April:
off_t off = offsetmap[i];
...
wb = copy_file_range(s->fd, &off, wfd, NULL, BLCKSZ - nwritten, 0);
Now, on my Linux box "man copy_file_range" saith
ssize_t copy_file_range(int fd_in, loff_t *off_in,
int fd_out, loff_t *off_out,
size_t len, unsigned int flags);
So apparently, "off_t" was the same as "loff_t" before 962da900a,
but it no longer is the same on 32-bit machines. (In any case,
if all machines that have copy_file_range define it like this,
perhaps we ought to be declaring this variable as loff_t not off_t?)
Digging a bit deeper, the full warning report is
reconstruct.c: In function "write_reconstructed_file":
reconstruct.c:701:33: warning: passing argument 2 of "copy_file_range" from incompatible pointer type [-Wincompatible-pointer-types]
wb = copy_file_range(s->fd, &off, wfd, NULL, BLCKSZ - nwritten, 0);
^~~~
In file included from reconstruct.c:15:
/usr/include/unistd.h:1107:49: note: expected "__off64_t *" {aka "long long int *"} but argument is of type "off_t *" {aka "long int *"}
ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
~~~~~~~~~~~^~~~~~~~
Since these are 32-bit machines, "long int" is 32 bits (confirmed from
their configure results), which means "off_t" is only 32 bits, which
really sounds quite broken. I thought it was 64 bits pretty much
everywhere nowadays. Did 962da900a cause that? Maybe that explains
the Perl library compatibility problems these machines are reporting?
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 21:03 Thomas Munro <[email protected]>
parent: Tom Lane <[email protected]>
1 sibling, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-12-04 21:03 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Dec 5, 2024 at 8:41 AM Tom Lane <[email protected]> wrote:
> So apparently, "off_t" was the same as "loff_t" before 962da900a,
> but it no longer is the same on 32-bit machines.
Right, that's really weird.
> (In any case,
> if all machines that have copy_file_range define it like this,
> perhaps we ought to be declaring this variable as loff_t not off_t?)
Hmm. FreeBSD just has off_t in its declaration, but off_t is always
64 bit, and I don't think it knows about loff_t.
I guess copy_file_range() didn't follow the usual plan of respecting
_FILE_OFFSET_BITS, so there's no 32 bit off_t support for it in libc,
hence they needed to invent (or leak from the kernel?) loff_t. I
don't think we should change that, because we use AC_SYS_LARGEFILE to
find that we need -D_FILE_OFFSET_BITS=64 on 32 bit systems, so off_t
should be the same as loff_t. If something weren't broken
somewhere... Somehow it's getting lost?
> Since these are 32-bit machines, "long int" is 32 bits (confirmed from
> their configure results), which means "off_t" is only 32 bits, which
> really sounds quite broken. I thought it was 64 bits pretty much
> everywhere nowadays. Did 962da900a cause that? Maybe that explains
> the Perl library compatibility problems these machines are reporting?
Right, that definitely should upset Perl, as it changes the size of
struct stat and all kinds of stuff, probably.
The affected systems are mostly running ancient OSes, and lapwing is
32 bit x86, so it's not only armv7. Current 32 bit x86 systems are
working fine. Maybe I should boot up a Debian 7 x86 build (my
attempts to run ancient Debian/armv7 on qemu last night failed, x86
sounds easier...) The armv7 systems except turaco are running the
same era of Debian as lapwing, but I'm not sure what turaco is.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 21:20 Tom Lane <[email protected]>
parent: Tom Lane <[email protected]>
1 sibling, 1 reply; 25+ messages in thread
From: Tom Lane @ 2024-12-04 21:20 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
I wrote:
> So apparently, "off_t" was the same as "loff_t" before 962da900a,
> but it no longer is the same on 32-bit machines.
OK, I see what is happening. On platforms that need it, we define
_FILE_OFFSET_BITS as 64 in pg_config.h to ensure that off_t is
big enough. However, 962da900a did this:
--- a/src/include/postgres_ext.h
+++ b/src/include/postgres_ext.h
@@ -23,7 +23,7 @@
#ifndef POSTGRES_EXT_H
#define POSTGRES_EXT_H
-#include "pg_config_ext.h"
+#include <stdint.h>
Since c.h reads postgres_ext.h first, <stdint.h> is now pulled in
before pg_config.h, and that in turn pulls in <features.h>, which
locks down the decision that off_t will be 32 bits, as well as some
other decisions we don't want. We can NOT include any system headers
before pg_config.h; I'm surprised we're not seeing related failures on
the Solaris-en, where _LARGEFILE_SOURCE is similarly critical.
Another rather serious problem here is that we no longer provide
macro PG_INT64_TYPE, which seems rather likely to break applications
that were relying on it. That is part of our external API, we
can't just remove it on a whim.
I think the least painful solution would be to revert the parts
of 962da900a that got rid of pg_config_ext.h and PG_INT64_TYPE.
Since PG_INT64_TYPE is a macro not a typedef, it might be okay
to #define it as int64_t even before we've read that header,
so as not to give up the principle of relying on stdint.h for the
underlying definition.
Now that I see this, I'm fairly astonished that there aren't
more problems than we've noticed. I wonder whether it'd be
a good idea to put in a static assert somewhere about the
width of off_t, so that the next screwup of this sort will
be easier to diagnose.
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 21:44 Thomas Munro <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-12-04 21:44 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Dec 5, 2024 at 10:20 AM Tom Lane <[email protected]> wrote:
> I wrote:
> > So apparently, "off_t" was the same as "loff_t" before 962da900a,
> > but it no longer is the same on 32-bit machines.
>
> OK, I see what is happening. On platforms that need it, we define
> _FILE_OFFSET_BITS as 64 in pg_config.h to ensure that off_t is
> big enough. However, 962da900a did this:
>
> --- a/src/include/postgres_ext.h
> +++ b/src/include/postgres_ext.h
> @@ -23,7 +23,7 @@
> #ifndef POSTGRES_EXT_H
> #define POSTGRES_EXT_H
>
> -#include "pg_config_ext.h"
> +#include <stdint.h>
>
> Since c.h reads postgres_ext.h first, <stdint.h> is now pulled in
> before pg_config.h, and that in turn pulls in <features.h>, which
> locks down the decision that off_t will be 32 bits, as well as some
> other decisions we don't want. We can NOT include any system headers
> before pg_config.h; I'm surprised we're not seeing related failures on
> the Solaris-en, where _LARGEFILE_SOURCE is similarly critical.
Ah, right. Oops.
> Another rather serious problem here is that we no longer provide
> macro PG_INT64_TYPE, which seems rather likely to break applications
> that were relying on it. That is part of our external API, we
> can't just remove it on a whim.
I had concluded that PG_INT64_TYPE wasn't part of our external API but
pg_int64 was, based on the comment:
/* Define a signed 64-bit integer type for use in client API declarations. */
-typedef PG_INT64_TYPE pg_int64;
+typedef int64_t pg_int64;
But yeah, I obviously hadn't considered that other interaction, and ...
> I think the least painful solution would be to revert the parts
> of 962da900a that got rid of pg_config_ext.h and PG_INT64_TYPE.
> Since PG_INT64_TYPE is a macro not a typedef, it might be okay
> to #define it as int64_t even before we've read that header,
> so as not to give up the principle of relying on stdint.h for the
> underlying definition.
... yeah that sounds like a plan. Looking into it.
> Now that I see this, I'm fairly astonished that there aren't
> more problems than we've noticed. I wonder whether it'd be
> a good idea to put in a static assert somewhere about the
> width of off_t, so that the next screwup of this sort will
> be easier to diagnose.
Right, we could assert that it hasn't changed from what configure detected.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-04 21:50 Tom Lane <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Tom Lane @ 2024-12-04 21:50 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Thomas Munro <[email protected]> writes:
> On Thu, Dec 5, 2024 at 10:20 AM Tom Lane <[email protected]> wrote:
>> Another rather serious problem here is that we no longer provide
>> macro PG_INT64_TYPE, which seems rather likely to break applications
>> that were relying on it. That is part of our external API, we
>> can't just remove it on a whim.
> I had concluded that PG_INT64_TYPE wasn't part of our external API but
> pg_int64 was, based on the comment:
> /* Define a signed 64-bit integer type for use in client API declarations. */
> -typedef PG_INT64_TYPE pg_int64;
> +typedef int64_t pg_int64;
Oh, hmm, maybe so. OTOH, that typedef breaks the idea of #define'ing
PG_INT64_TYPE as int64_t. We need this header to be readable without
any prior system headers, so I'm afraid we're all the way back to
making configure derive the name of a 64-bit type.
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-05 00:59 Thomas Munro <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-12-05 00:59 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Dec 5, 2024 at 10:03 AM Thomas Munro <[email protected]> wrote:
> The affected systems are mostly running ancient OSes, and lapwing is
> 32 bit x86, so it's not only armv7. Current 32 bit x86 systems are
> working fine.
I was trying to figure out how I missed this, and I think it might be
that the meson build scripts didn't port AC_SYS_LARGEFILES. So if you
build on a 32 bit Linux system with meson (like one of CI's tasks, and
also build farm animal adder) then I think you finish up with 32 bit
off_t and no SIZEOF_OFF_T, because we don't do AC_SYS_LARGEFILES'
dance to figure out if this system needs -D_FILE_OFFSET_BITS=64 (or
other similar macros for AIX, Solaris etc). I will look into that.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-05 01:06 Thomas Munro <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Thomas Munro @ 2024-12-05 01:06 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Dec 5, 2024 at 1:59 PM Thomas Munro <[email protected]> wrote:
> I was trying to figure out how I missed this, and I think it might be
> that the meson build scripts didn't port AC_SYS_LARGEFILES. So if you
> build on a 32 bit Linux system with meson (like one of CI's tasks, and
> also build farm animal adder) then I think you finish up with 32 bit
> off_t and no SIZEOF_OFF_T, because we don't do AC_SYS_LARGEFILES'
> dance to figure out if this system needs -D_FILE_OFFSET_BITS=64 (or
> other similar macros for AIX, Solaris etc). I will look into that.
Ahh, correction, it does define it (or else perl would have
complained), but it seems that meson magically puts it into the
compiler command line without being asked. So it is defined without
pg_config.h being involved, and thus earlier. Huh.
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-05 03:29 Tom Lane <[email protected]>
parent: Thomas Munro <[email protected]>
0 siblings, 1 reply; 25+ messages in thread
From: Tom Lane @ 2024-12-05 03:29 UTC (permalink / raw)
To: Thomas Munro <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
Thomas Munro <[email protected]> writes:
> On Thu, Dec 5, 2024 at 1:59 PM Thomas Munro <[email protected]> wrote:
>> I was trying to figure out how I missed this, and I think it might be
>> that the meson build scripts didn't port AC_SYS_LARGEFILES. So if you
>> build on a 32 bit Linux system with meson (like one of CI's tasks, and
>> also build farm animal adder) then I think you finish up with 32 bit
>> off_t and no SIZEOF_OFF_T, because we don't do AC_SYS_LARGEFILES'
>> dance to figure out if this system needs -D_FILE_OFFSET_BITS=64 (or
>> other similar macros for AIX, Solaris etc). I will look into that.
> Ahh, correction, it does define it (or else perl would have
> complained), but it seems that meson magically puts it into the
> compiler command line without being asked. So it is defined without
> pg_config.h being involved, and thus earlier. Huh.
That does not seem great. Compile an extension without the same
CPPFLAGS, you silently get an ABI-incompatible module. We really
ought to be putting these ABI-critical flags into pg_config.h.
It's especially bad that this works differently between autoconf
and meson builds.
regards, tom lane
^ permalink raw reply [nested|flat] 25+ messages in thread
* Re: Cannot find a working 64-bit integer type on Illumos
@ 2024-12-05 04:26 Thomas Munro <[email protected]>
parent: Tom Lane <[email protected]>
0 siblings, 0 replies; 25+ messages in thread
From: Thomas Munro @ 2024-12-05 04:26 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Tomas Vondra <[email protected]>; Peter Eisentraut <[email protected]>; Heikki Linnakangas <[email protected]>; Japin Li <[email protected]>; Andres Freund <[email protected]>; PostgreSQL Hackers <[email protected]>
On Thu, Dec 5, 2024 at 4:29 PM Tom Lane <[email protected]> wrote:
> Thomas Munro <[email protected]> writes:
> > Ahh, correction, it does define it (or else perl would have
> > complained), but it seems that meson magically puts it into the
> > compiler command line without being asked. So it is defined without
> > pg_config.h being involved, and thus earlier. Huh.
>
> That does not seem great. Compile an extension without the same
> CPPFLAGS, you silently get an ABI-incompatible module. We really
> ought to be putting these ABI-critical flags into pg_config.h.
> It's especially bad that this works differently between autoconf
> and meson builds.
It makes the whole MinGW circus worse that I'd realised:
https://www.postgresql.org/message-id/flat/CA%2BhUKG%2B6ZPD_X5ADMwX2uUtXqe_wv8%2BKQ5xFeAR2zbcodjNZvw...
^ permalink raw reply [nested|flat] 25+ messages in thread
end of thread, other threads:[~2024-12-05 04:26 UTC | newest]
Thread overview: 25+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2023-09-02 06:32 [PATCH v5 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]>
2024-07-04 02:55 Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-07-04 03:10 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-07-04 03:44 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-07-14 14:47 ` Re: Cannot find a working 64-bit integer type on Illumos Peter Eisentraut <[email protected]>
2024-07-14 14:51 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-07-22 14:39 ` Re: Cannot find a working 64-bit integer type on Illumos Peter Eisentraut <[email protected]>
2024-10-14 06:46 ` Re: Cannot find a working 64-bit integer type on Illumos Peter Eisentraut <[email protected]>
2024-11-29 10:12 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-11-29 19:30 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-03 13:22 ` Re: Cannot find a working 64-bit integer type on Illumos Peter Eisentraut <[email protected]>
2024-11-29 23:42 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-03 13:24 ` Re: Cannot find a working 64-bit integer type on Illumos Peter Eisentraut <[email protected]>
2024-12-04 03:04 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-04 05:58 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-04 06:19 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-12-04 19:41 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-12-04 21:03 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-05 00:59 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-05 01:06 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-05 03:29 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-12-05 04:26 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-04 21:20 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
2024-12-04 21:44 ` Re: Cannot find a working 64-bit integer type on Illumos Thomas Munro <[email protected]>
2024-12-04 21:50 ` Re: Cannot find a working 64-bit integer type on Illumos Tom Lane <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox