12#include "catalog/pg_type.h"
13#include "utils/lsyscache.h"
14#include "utils/typcache.h"
23#include <unordered_set>
36 case TEXTOID:
case VARCHAROID:
case BPCHAROID:
case CHAROID:
case NAMEOID:
45 case INT2OID:
case INT4OID:
case INT8OID:
53 return oid == BOOLOID;
63 Oid elem = get_element_type(oid);
64 return elem == BOOLOID;
72 case INT2OID:
case INT4OID:
case INT8OID:
73 case FLOAT4OID:
case FLOAT8OID:
case NUMERICOID:
84 const std::string &threshold,
85 std::vector<long> &ranks,
long &threshold_rank) {
86 TypeCacheEntry *tce = lookup_type_cache(typoid, TYPECACHE_CMP_PROC_FINFO);
87 if (tce == NULL || !OidIsValid(tce->cmp_proc))
89 Oid typinput, typioparam;
90 getTypeInputInfo(typoid, &typinput, &typioparam);
91 Oid collation = get_typcollation(typoid);
93 std::vector<Datum> datums;
94 datums.reserve(vals.size() + 1);
95 for (
const auto &v : vals)
96 datums.push_back(OidInputFunctionCall(typinput,
const_cast<char *
>(v.c_str()),
98 datums.push_back(OidInputFunctionCall(typinput,
99 const_cast<char *
>(threshold.c_str()),
102 auto cmp = [&](
size_t a,
size_t b) ->
int {
103 return DatumGetInt32(FunctionCall2Coll(&tce->cmp_proc_finfo, collation,
104 datums[a], datums[b]));
106 std::vector<size_t> order(datums.size());
107 for (
size_t i = 0; i < order.size(); ++i) order[i] = i;
108 std::sort(order.begin(), order.end(),
109 [&](
size_t a,
size_t b) { return cmp(a, b) < 0; });
111 std::vector<long> rank(datums.size());
113 for (
size_t k = 0; k < order.size(); ++k) {
114 if (k > 0 && cmp(order[k - 1], order[k]) != 0)
118 ranks.assign(rank.begin(), rank.end() - 1);
119 threshold_rank = rank.back();
130 size_t i = 0, n = s.size();
131 while (i < n && isspace((
unsigned char) s[i])) i++;
132 if (i >= n || s[i] !=
'{')
return false;
134 while (i < n && isspace((
unsigned char) s[i])) i++;
135 if (i < n && s[i] ==
'}')
return true;
138 while (i < n && isspace((
unsigned char) s[i])) i++;
139 if (i < n && s[i] ==
'"') {
141 while (i < n && s[i] !=
'"') {
142 if (s[i] ==
'\\' && i + 1 < n) { elem.push_back(s[i + 1]); i += 2; }
143 else { elem.push_back(s[i]); i++; }
145 if (i >= n)
return false;
148 while (i < n && s[i] !=
',' && s[i] !=
'}') { elem.push_back(s[i]); i++; }
149 while (!elem.empty() && isspace((
unsigned char) elem.back())) elem.pop_back();
152 if (elem.size() == 4 && strcasecmp(elem.c_str(),
"NULL") == 0)
153 elem = array_null_element();
156 while (i < n && isspace((
unsigned char) s[i])) i++;
157 if (i < n && s[i] ==
',') { i++;
continue; }
158 if (i < n && s[i] ==
'}')
return true;
169 if (s.empty())
return false;
172 if (s[i] ==
'+' || s[i] ==
'-') { neg = (s[i] ==
'-'); ++i; }
176 bool seen_dot =
false, seen_digit =
false;
177 for (; i < s.size(); ++i) {
180 if (seen_dot)
return false;
182 }
else if (ch >=
'0' && ch <=
'9') {
183 digits.push_back(ch);
186 }
else if (ch ==
'e' || ch ==
'E') {
195 if (!seen_digit)
return false;
197 if (i < s.size() && (s[i] ==
'+' || s[i] ==
'-')) {
198 eneg = (s[i] ==
'-');
201 for (; i < s.size(); ++i) {
202 if (s[i] <
'0' || s[i] >
'9')
return false;
203 edigits.push_back(s[i]);
204 if (edigits.size() > 4)
return false;
206 if (edigits.empty())
return false;
207 exponent = std::stoi(edigits);
208 if (eneg) exponent = -exponent;
214 if (!seen_digit)
return false;
221 while (sc > 0 && !digits.empty() && digits.back() ==
'0') {
231 digits.push_back(
'0');
233 if (digits.size() > 18)
return false;
237 long long val = std::stoll(digits, &pos);
238 if (pos != digits.size())
return false;
239 mantissa = neg ? -
static_cast<long>(val) :
static_cast<long>(val);
249bool rescale_to(
long mantissa,
int scale,
int target_scale,
long &out) {
251 for (
int k = 0; k < target_scale - scale; ++k) {
252 if (factor > (LONG_MAX / 10))
return false;
256 (mantissa > LONG_MAX / factor || mantissa < LONG_MIN / factor))
258 out = mantissa * factor;
291 if (w.size() != 2)
return false;
342 std::vector<gate_t> out;
343 std::vector<std::pair<gate_t, bool>> stack;
344 stack.emplace_back(start,
false);
346 std::unordered_set<gate_t> seen;
348 while (!stack.empty()) {
349 auto [cur, expanded] = stack.back();
353 if (!seen.insert(cur).second)
continue;
354 stack.emplace_back(cur,
true);
357 stack.emplace_back(ch,
false);
363 if (cw.size() == 2) {
ComparisonOperator cmpOpFromOid(Oid op_oid, bool &ok)
Map a PostgreSQL comparison-operator OID to a ComparisonOperator.
ComparisonOperator
SQL comparison operators used in gate_cmp circuit gates.
@ LE
Less than or equal (<=).
@ GE
Greater than or equal (>=).
gate_t
Strongly-typed gate identifier.
Fix macro conflicts between PostgreSQL headers and the C++ STL/Boost.
std::vector< gate_t > & getWires(gate_t g)
Return a mutable reference to the child-wire list of gate g.
gateType getGateType(gate_t g) const
Return the type of gate g.
In-memory provenance circuit with semiring-generic evaluation.
std::string getExtra(gate_t g) const
Return the string extra for gate g.
std::pair< unsigned, unsigned > getInfos(gate_t g) const
Return the integer annotation pair for gate g.
static Datum semimod_gate(const pg_uuid_t *value_token, const pg_uuid_t *token)
The semimod gate value_token ⊗ token.
Provenance evaluation helper for HAVING-clause circuits.
bool rescale_to(long mantissa, int scale, int target_scale, long &out)
bool aggtype_is_text(unsigned oid)
bool aggtype_is_numeric(unsigned oid)
bool aggtype_is_integer(unsigned oid)
bool parse_array_literal(const std::string &s, std::vector< std::string > &out)
ComparisonOperator flip_op(ComparisonOperator op)
bool rank_values_by_type(unsigned typoid, const std::vector< std::string > &vals, const std::string &threshold, std::vector< long > &ranks, long &threshold_rank)
static bool side_has_agg(GenericCircuit &c, gate_t g)
bool aggtype_elem_is_boolean(unsigned oid)
std::vector< gate_t > collect_sp_cmp_gates(GenericCircuit &c, gate_t start)
bool parse_decimal_scaled(const std::string &s, long &mantissa, int &scale)
ComparisonOperator map_cmp_op(GenericCircuit &c, gate_t cmp_gate, bool &ok)
bool aggtype_is_boolean(unsigned oid)
bool semimod_extract_string_and_K(GenericCircuit &c, gate_t semimod_gate, std::string &m_out, gate_t &k_gate_out)
bool extract_constant_string(GenericCircuit &c, gate_t x, std::string &C_out)
@ gate_arith
n-ary arithmetic gate over scalar-valued children (info1 holds operator tag)