ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
provsql_error.h
Go to the documentation of this file.
1/**
2 * @file provsql_error.h
3 * @brief Uniform error-reporting macros for ProvSQL.
4 *
5 * Defines four convenience macros that wrap PostgreSQL's @c elog() and
6 * always prefix the user-visible message with @c "ProvSQL: ", giving every
7 * diagnostic a consistent origin tag regardless of which source file emits
8 * it.
9 *
10 * The prefix is inserted by compile-time string-literal concatenation, so
11 * @p fmt **must** be a string literal (not a runtime @c char* variable).
12 *
13 * ### Availability of @c elog()
14 * This header intentionally contains no @c \#include directives. The
15 * caller is responsible for making @c elog() visible before including this
16 * header:
17 * - In normal PostgreSQL extension code, @c elog() comes from
18 * @c <utils/elog.h>, pulled in transitively through @c postgres.h or
19 * @c provsql_utils.h (which already includes this file at its end).
20 * - In the standalone @c tdkc binary, @c BooleanCircuit.cpp defines a
21 * lightweight @c \#define @c elog stub that writes to @c stderr and calls
22 * @c exit() on @c ERROR; @c provsql_error.h is included after that stub.
23 */
24
25#ifndef PROVSQL_ERROR_H
26#define PROVSQL_ERROR_H
27
28/**
29 * @brief Report a fatal ProvSQL error and abort the current transaction.
30 *
31 * Expands to @c elog(ERROR, "ProvSQL: " fmt, ...). In PostgreSQL, @c ERROR
32 * performs a non-local exit via @c longjmp; the call never returns. In the
33 * standalone @c tdkc build the @c elog stub calls @c exit(EXIT_FAILURE).
34 *
35 * @param fmt A string literal format string (printf-style).
36 * @param ... Optional format arguments.
37 */
38#define provsql_error(fmt, ...) elog(ERROR, "ProvSQL: " fmt, ##__VA_ARGS__)
39
40/**
41 * @brief What kind of limit a refusal or a freezing is.
42 *
43 * @c PROVSQL_DELIBERATE: the shape has no provenance to give, so refusing it is
44 * the answer and not a shortcoming -- @c EXCEPT @c ALL and @c INTERSECT @c ALL,
45 * whose kept copies have no provenance of their own; @c IN read as a value,
46 * whose unknown truth no count of matches tells from false; two subquery
47 * conditions in one Boolean combination, whose two counts do not meet on one
48 * row. No rewriting will remove these.
49 *
50 * @c PROVSQL_GAP: the query has a provenance and the rewriting does not reach
51 * it yet. Every one of these is a candidate for work.
52 *
53 * @c PROVSQL_OUT_OF_SCOPE: the feature lies outside what the provenance of the
54 * supported query fragment covers -- random variables and continuous
55 * distributions, where-provenance, conditioning, and ProvSQL's own surfaces
56 * (a @c provenance() call in an expression, an @c INSERT into an untracked
57 * table) -- so neither of the two above applies to it.
58 *
59 * The kind reaches tooling on the @c DETAIL line, next to the tag, so that a
60 * survey of what is covered can tell a deliberate refusal from a gap without
61 * keeping a table of its own.
62 */
63#define PROVSQL_DELIBERATE "deliberate"
64#define PROVSQL_GAP "gap"
65#define PROVSQL_OUT_OF_SCOPE "out-of-scope"
66
67/**
68 * @brief Refuse a query ProvSQL cannot track, and abort the transaction.
69 *
70 * Like @c provsql_error, with SQLSTATE @c 0A000 (@c feature_not_supported)
71 * rather than @c XX000 (@c internal_error), so that clients can tell a
72 * deliberate refusal from a bug.
73 *
74 * Every refusal carries a stable short tag, reported on the @c DETAIL line as
75 * @c "provsql-reason: @c <tag>". The message is what a user reads and may be
76 * reworded freely; the tag is what tooling keys on -- the differential-testing
77 * harness groups its refusals by it, and the study of what the fragment covers
78 * joins on it -- so a tag changes only with a reason. It is the first
79 * argument, so that no refusal can be added without one.
80 *
81 * @param scope @c PROVSQL_DELIBERATE, @c PROVSQL_GAP or
82 * @c PROVSQL_OUT_OF_SCOPE.
83 * @param tag Stable kebab-case identifier of the cause.
84 * @param fmt A string literal format string (printf-style).
85 * @param ... Optional format arguments.
86 */
87#ifdef TDKC
88#define provsql_unsupported(scope, tag, fmt, ...) \
89 provsql_error(fmt, ##__VA_ARGS__)
90#else
91#define provsql_unsupported(scope, tag, fmt, ...) \
92 ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
93 errmsg("ProvSQL: " fmt, ##__VA_ARGS__), \
94 errdetail("provsql-reason: %s; scope: %s", tag, scope)))
95#endif
96
97/**
98 * @brief Emit a ProvSQL warning message (execution continues).
99 *
100 * Expands to @c elog(WARNING, "ProvSQL: " fmt, ...). The message is sent
101 * to the client and server log according to the PostgreSQL
102 * @c log_min_messages / @c client_min_messages settings.
103 *
104 * @param fmt A string literal format string (printf-style).
105 * @param ... Optional format arguments.
106 */
107#define provsql_warning(fmt, ...) elog(WARNING, "ProvSQL: " fmt, ##__VA_ARGS__)
108
109/**
110 * @brief Emit a ProvSQL warning that names its cause by a stable tag.
111 *
112 * The warning counterpart of @c provsql_unsupported: a freezing is reported as
113 * a warning or, under @c provsql.implicit_freeze @c = @c 'error', as a
114 * refusal, and both carry the same tag on their @c DETAIL line so that
115 * tooling reads one key whichever the setting.
116 *
117 * @param scope @c PROVSQL_DELIBERATE, @c PROVSQL_GAP or
118 * @c PROVSQL_OUT_OF_SCOPE.
119 * @param tag Stable kebab-case identifier of the cause.
120 * @param fmt A string literal format string (printf-style).
121 * @param ... Optional format arguments.
122 */
123#ifdef TDKC
124#define provsql_warning_tagged(scope, tag, fmt, ...) \
125 provsql_warning(fmt, ##__VA_ARGS__)
126#else
127#define provsql_warning_tagged(scope, tag, fmt, ...) \
128 ereport(WARNING, (errmsg("ProvSQL: " fmt, ##__VA_ARGS__), \
129 errdetail("provsql-reason: %s; scope: %s", tag, scope)))
130#endif
131
132/**
133 * @brief Emit a ProvSQL informational notice (execution continues).
134 *
135 * Expands to @c elog(NOTICE, "ProvSQL: " fmt, ...). Typically used for
136 * progress messages gated on @c provsql.verbose_level.
137 *
138 * @param fmt A string literal format string (printf-style).
139 * @param ... Optional format arguments.
140 */
141#define provsql_notice(fmt, ...) elog(NOTICE, "ProvSQL: " fmt, ##__VA_ARGS__)
142
143/**
144 * @brief Write a ProvSQL message to the server log only.
145 *
146 * Expands to @c elog(LOG, "ProvSQL: " fmt, ...). @c LOG messages go to the
147 * PostgreSQL server log and are not forwarded to the client. Suitable for
148 * background-worker lifecycle events (e.g. worker startup).
149 *
150 * @param fmt A string literal format string (printf-style).
151 * @param ... Optional format arguments.
152 */
153#define provsql_log(fmt, ...) elog(LOG, "ProvSQL: " fmt, ##__VA_ARGS__)
154
155#endif /* PROVSQL_ERROR_H */