PostgreSQL Source Code git master
Loading...
Searching...
No Matches
extended_stats_funcs.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * extended_stats_funcs.c
4 * Functions for manipulating extended statistics.
5 *
6 * This file includes the set of facilities required to support the direct
7 * manipulations of extended statistics objects.
8 *
9 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
11 *
12 * IDENTIFICATION
13 * src/backend/statistics/extended_stats_funcs.c
14 *
15 *-------------------------------------------------------------------------
16 */
17#include "postgres.h"
18
19#include "access/heapam.h"
20#include "catalog/indexing.h"
21#include "catalog/namespace.h"
22#include "catalog/pg_database.h"
25#include "miscadmin.h"
26#include "nodes/makefuncs.h"
27#include "nodes/nodeFuncs.h"
28#include "optimizer/optimizer.h"
31#include "utils/acl.h"
32#include "utils/array.h"
33#include "utils/builtins.h"
34#include "utils/fmgroids.h"
35#include "utils/lsyscache.h"
36#include "utils/syscache.h"
37
38
39/*
40 * Index of the arguments for the SQL functions.
41 */
56
57/*
58 * The argument names and type OIDs of the arguments for the SQL
59 * functions.
60 */
61static struct StatsArgInfo extarginfo[] =
62{
63 [RELSCHEMA_ARG] = {"schemaname", TEXTOID},
64 [RELNAME_ARG] = {"relname", TEXTOID},
65 [STATSCHEMA_ARG] = {"statistics_schemaname", TEXTOID},
66 [STATNAME_ARG] = {"statistics_name", TEXTOID},
67 [INHERITED_ARG] = {"inherited", BOOLOID},
68 [NDISTINCT_ARG] = {"n_distinct", PG_NDISTINCTOID},
69 [DEPENDENCIES_ARG] = {"dependencies", PG_DEPENDENCIESOID},
70 [MOST_COMMON_VALS_ARG] = {"most_common_vals", TEXTARRAYOID},
71 [MOST_COMMON_FREQS_ARG] = {"most_common_freqs", FLOAT8ARRAYOID},
72 [MOST_COMMON_BASE_FREQS_ARG] = {"most_common_base_freqs", FLOAT8ARRAYOID},
74};
75
77
79 const char *stxname);
81
82/*
83 * Track the extended statistics kinds expected for a pg_statistic_ext
84 * tuple.
85 */
86typedef struct
87{
90 bool mcv;
93
94static void expand_stxkind(HeapTuple tup, StakindFlags *enabled);
96 const bool *nulls,
97 const bool *replaces);
98
99static bool check_mcvlist_array(const ArrayType *arr, int argindex,
100 int required_ndims, int mcv_length);
101static Datum import_mcv(const ArrayType *mcv_arr,
102 const ArrayType *freqs_arr,
104 Oid *atttypids, int32 *atttypmods,
106 bool *ok);
107
108
109/*
110 * Fetch a pg_statistic_ext row by name and namespace OID.
111 */
112static HeapTuple
114{
115 ScanKeyData key[2];
116 SysScanDesc scan;
119
120 ScanKeyInit(&key[0],
123 F_NAMEEQ,
125 ScanKeyInit(&key[1],
128 F_OIDEQ,
130
131 /*
132 * Try to find matching pg_statistic_ext row.
133 */
136 true,
137 NULL,
138 2,
139 key);
140
141 /* Lookup is based on a unique index, so we get either 0 or 1 tuple. */
142 tup = systable_getnext(scan);
143
146
147 systable_endscan(scan);
148
149 if (!OidIsValid(stxoid))
150 return NULL;
151
153}
154
155/*
156 * Decode the stxkind column so that we know which stats types to expect,
157 * returning a StakindFlags set depending on the stats kinds expected by
158 * a pg_statistic_ext tuple.
159 */
160static void
162{
163 Datum datum;
164 ArrayType *arr;
165 char *kinds;
166
168 tup,
170 arr = DatumGetArrayTypeP(datum);
171 if (ARR_NDIM(arr) != 1 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID)
172 elog(ERROR, "stxkind is not a one-dimension char array");
173
174 kinds = (char *) ARR_DATA_PTR(arr);
175
176 for (int i = 0; i < ARR_DIMS(arr)[0]; i++)
177 {
178 switch (kinds[i])
179 {
181 enabled->ndistinct = true;
182 break;
184 enabled->dependencies = true;
185 break;
186 case STATS_EXT_MCV:
187 enabled->mcv = true;
188 break;
190 enabled->expressions = true;
191 break;
192 default:
193 elog(ERROR, "incorrect stxkind %c found", kinds[i]);
194 break;
195 }
196 }
197}
198
199/*
200 * Perform the actual storage of a pg_statistic_ext_data tuple.
201 */
202static void
238
239/*
240 * Insert or update an extended statistics object.
241 *
242 * Major errors, such as the table not existing or permission errors, are
243 * reported as ERRORs. There are a couple of paths that generate a WARNING,
244 * like when the statistics object or its schema do not exist, a conversion
245 * failure on one statistic kind, or when other statistic kinds may still
246 * be updated.
247 */
248static bool
250{
251 char *relnspname;
252 char *relname;
253 Oid nspoid;
254 char *nspname;
255 char *stxname;
256 bool inherited;
259
260 StakindFlags enabled = {false, false, false, false};
261 StakindFlags has = {false, false, false, false};
262
264
266 bool nulls[Natts_pg_statistic_ext_data] = {0};
268 bool success = true;
270 bool isnull;
271 List *exprs = NIL;
272 int numattnums = 0;
273 int numexprs = 0;
274 int numattrs = 0;
275
276 /* arrays of type info, if we need them */
277 Oid *atttypids = NULL;
278 int32 *atttypmods = NULL;
280 Oid relid;
282
283 /*
284 * Fill out the StakindFlags "has" structure based on which parameters
285 * were provided to the function.
286 *
287 * The MCV stats composite value is an array of record type, but this is
288 * externally represented as three arrays that must be interleaved into
289 * the array of records (pg_stats_ext stores four arrays,
290 * most_common_val_nulls is built from the contents of most_common_vals).
291 * Therefore, none of the three array values is meaningful unless the
292 * other two are also present and in sync in terms of array length.
293 */
297 has.ndistinct = !PG_ARGISNULL(NDISTINCT_ARG);
298 has.dependencies = !PG_ARGISNULL(DEPENDENCIES_ARG);
299
300 if (RecoveryInProgress())
301 {
304 errmsg("recovery is in progress"),
305 errhint("Statistics cannot be modified during recovery."));
306 return false;
307 }
308
309 /* relation arguments */
314
315 /* extended statistics arguments */
322
323 /*
324 * First open the relation where we expect to find the statistics. This
325 * is similar to relation and attribute statistics, so as ACL checks are
326 * done before any locks are taken, even before any attempts related to
327 * the extended stats object.
328 */
332
333 nspoid = get_namespace_oid(nspname, true);
334 if (nspoid == InvalidOid)
335 {
338 errmsg("could not find schema \"%s\"", nspname));
339 success = false;
340 goto cleanup;
341 }
342
345
346 if (!HeapTupleIsValid(tup))
347 {
350 errmsg("could not find extended statistics object \"%s\".\"%s\"",
351 quote_identifier(nspname),
353 success = false;
354 goto cleanup;
355 }
356
358
359 /*
360 * The relation tracked by the stats object has to match with the relation
361 * we have already locked.
362 */
363 if (stxform->stxrelid != relid)
364 {
367 errmsg("could not restore extended statistics object \"%s\".\"%s\": incorrect relation \"%s\".\"%s\" specified",
368 quote_identifier(nspname),
372
373 success = false;
374 goto cleanup;
375 }
376
377 /* Find out what extended statistics kinds we should expect. */
378 expand_stxkind(tup, &enabled);
379 numattnums = stxform->stxkeys.dim1;
380
381 /* decode expression (if any) */
383 tup,
385 &isnull);
386 if (!isnull)
387 {
388 char *s;
389
391 exprs = (List *) stringToNode(s);
392 pfree(s);
393
394 /*
395 * Run the expressions through eval_const_expressions(). This is not
396 * just an optimization, but is necessary, because the planner will be
397 * comparing them to similarly-processed qual clauses, and may fail to
398 * detect valid matches without this.
399 *
400 * We must not use canonicalize_qual(), however, since these are not
401 * qual expressions.
402 */
403 exprs = (List *) eval_const_expressions(NULL, (Node *) exprs);
404
405 /* May as well fix opfuncids too */
406 fix_opfuncids((Node *) exprs);
407
408 /* Compute the number of expression, for input validation. */
409 numexprs = list_length(exprs);
410 }
411
413
414 /*
415 * If the object cannot support ndistinct, we should not have data for it.
416 */
417 if (has.ndistinct && !enabled.ndistinct)
418 {
421 errmsg("cannot specify parameter \"%s\"",
423 errhint("Extended statistics object \"%s\".\"%s\" does not support statistics of this type.",
424 quote_identifier(nspname),
426
427 has.ndistinct = false;
428 success = false;
429 }
430
431 /*
432 * If the object cannot support dependencies, we should not have data for
433 * it.
434 */
435 if (has.dependencies && !enabled.dependencies)
436 {
439 errmsg("cannot specify parameter \"%s\"",
441 errhint("Extended statistics object \"%s\".\"%s\" does not support statistics of this type.",
442 quote_identifier(nspname),
444 has.dependencies = false;
445 success = false;
446 }
447
448 /*
449 * If the object cannot hold an MCV value, but any of the MCV parameters
450 * are set, then issue a WARNING and ensure that we do not try to load MCV
451 * stats later. In pg_stats_ext, most_common_val_nulls, most_common_freqs
452 * and most_common_base_freqs are NULL if most_common_vals is NULL.
453 */
454 if (!enabled.mcv)
455 {
459 {
462 errmsg("cannot specify parameters \"%s\", \"%s\" or \"%s\"",
466 errhint("Extended statistics object \"%s\".\"%s\" does not support statistics of this type.",
467 quote_identifier(nspname),
469
470 has.mcv = false;
471 success = false;
472 }
473 }
474 else if (!has.mcv)
475 {
476 /*
477 * If we do not have all of the MCV arrays set while the extended
478 * statistics object expects something, something is wrong. This
479 * issues a WARNING if a partial input has been provided.
480 */
484 {
487 errmsg("could not use \"%s\", \"%s\" and \"%s\": missing one or more parameters",
491 success = false;
492 }
493 }
494
495 /*
496 * Either of these statistic types requires that we supply a semi-filled
497 * VacAttrStatP array.
498 *
499 * It is not possible to use the existing lookup_var_attr_stats() and
500 * examine_attribute() because these functions will skip attributes where
501 * attstattarget is 0, and we may have statistics data to import for those
502 * attributes.
503 */
504 if (has.mcv)
505 {
507 atttypmods = palloc0_array(int32, numattrs);
509
510 /*
511 * The leading stxkeys are attribute numbers up through numattnums.
512 * These keys must be in ascending AttNumber order, but we do not rely
513 * on that.
514 */
515 for (int i = 0; i < numattnums; i++)
516 {
517 AttrNumber attnum = stxform->stxkeys.values[i];
519 ObjectIdGetDatum(relid),
521
523
524 /* Attribute not found */
526 elog(ERROR, "stxkeys references nonexistent attnum %d", attnum);
527
529
530 if (attr->attisdropped)
531 elog(ERROR, "stxkeys references dropped attnum %d", attnum);
532
533 atttypids[i] = attr->atttypid;
534 atttypmods[i] = attr->atttypmod;
535 atttypcolls[i] = attr->attcollation;
537 }
538
539 /*
540 * After all the positive number attnums in stxkeys come the negative
541 * numbers (if any) which represent expressions in the order that they
542 * appear in stxdexpr. Because the expressions are always
543 * monotonically decreasing from -1, there is no point in looking at
544 * the values in stxkeys, it's enough to know how many of them there
545 * are.
546 */
547 for (int i = numattnums; i < numattrs; i++)
548 {
549 Node *expr = list_nth(exprs, i - numattnums);
550
551 atttypids[i] = exprType(expr);
552 atttypmods[i] = exprTypmod(expr);
553 atttypcolls[i] = exprCollation(expr);
554 }
555 }
556
557 /*
558 * Populate the pg_statistic_ext_data result tuple.
559 */
560
561 /* Primary Key: cannot be NULL or replaced. */
563 nulls[Anum_pg_statistic_ext_data_stxoid - 1] = false;
566
567 /* All unspecified parameters will be left unmodified */
570 nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
571 nulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = true;
572
573 /*
574 * For each stats kind, deserialize the data at hand and perform a round
575 * of validation. The resulting tuple is filled with a set of updated
576 * values.
577 */
578
579 if (has.ndistinct)
580 {
584
585 if (statext_ndistinct_validate(ndistinct, &stxform->stxkeys,
587 {
591 }
592 else
593 success = false;
594
595 statext_ndistinct_free(ndistinct);
596 }
597
598 if (has.dependencies)
599 {
603
604 if (statext_dependencies_validate(dependencies, &stxform->stxkeys,
606 {
610 }
611 else
612 success = false;
613
614 statext_dependencies_free(dependencies);
615 }
616
617 if (has.mcv)
618 {
619 Datum datum;
620 bool val_ok = false;
621
625 atttypids, atttypmods, atttypcolls, numattrs,
626 &val_ok);
627
628 if (val_ok)
629 {
630 Assert(datum != (Datum) 0);
632 nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = false;
634 }
635 else
636 success = false;
637 }
638
640
641cleanup:
644 if (pg_stext != NULL)
646 if (atttypids != NULL)
648 if (atttypmods != NULL)
649 pfree(atttypmods);
650 if (atttypcolls != NULL)
652 return success;
653}
654
655/*
656 * Consistency checks to ensure that other mcvlist arrays are in alignment
657 * with the mcv array.
658 */
659static bool
660check_mcvlist_array(const ArrayType *arr, int argindex, int required_ndims,
661 int mcv_length)
662{
663 if (ARR_NDIM(arr) != required_ndims)
664 {
667 errmsg("could not parse array \"%s\": incorrect number of dimensions (%d required)",
668 extarginfo[argindex].argname, required_ndims));
669 return false;
670 }
671
672 if (array_contains_nulls(arr))
673 {
676 errmsg("could not parse array \"%s\": NULL value found",
677 extarginfo[argindex].argname));
678 return false;
679 }
680
681 if (ARR_DIMS(arr)[0] != mcv_length)
682 {
685 errmsg("could not parse array \"%s\": incorrect number of elements (same as \"%s\" required)",
686 extarginfo[argindex].argname,
688 return false;
689 }
690
691 return true;
692}
693
694/*
695 * Create the stxdmcv datum from the equal-sized arrays of most common values,
696 * their null flags, and the frequency and base frequency associated with
697 * each value.
698 */
699static Datum
701 const ArrayType *base_freqs_arr, Oid *atttypids, int32 *atttypmods,
702 Oid *atttypcolls, int numattrs, bool *ok)
703{
704 int nitems;
706 bool *mcv_nulls;
707 int check_nummcv;
708 Datum mcv = (Datum) 0;
709
710 *ok = false;
711
712 /*
713 * mcv_arr is an array of arrays. Each inner array must have the same
714 * number of elements "numattrs".
715 */
716 if (ARR_NDIM(mcv_arr) != 2)
717 {
720 errmsg("could not parse array \"%s\": incorrect number of dimensions (%d required)",
722 goto mcv_error;
723 }
724
725 if (ARR_DIMS(mcv_arr)[1] != numattrs)
726 {
729 errmsg("could not parse array \"%s\": found %d attributes but expected %d",
732 goto mcv_error;
733 }
734
735 /*
736 * "most_common_freqs" and "most_common_base_freqs" arrays must be of the
737 * same length, one-dimension and cannot contain NULLs. We use mcv_arr as
738 * the reference array for determining their length.
739 */
740 nitems = ARR_DIMS(mcv_arr)[0];
743 {
744 /* inconsistent input arrays found */
745 goto mcv_error;
746 }
747
748 /*
749 * This part builds the contents for "most_common_val_nulls", based on the
750 * values from "most_common_vals".
751 */
754
756 atttypids, atttypmods, atttypcolls,
760
761 *ok = (mcv != (Datum) 0);
762
764 return mcv;
765}
766
767/*
768 * Remove an existing pg_statistic_ext_data row for a given pg_statistic_ext
769 * row and "inherited" pair.
770 */
771static bool
773{
776 bool result = false;
777
778 /* Is there already a pg_statistic tuple for this attribute? */
782
784 {
785 CatalogTupleDelete(sed, &oldtup->t_self);
787 result = true;
788 }
789
791
793
794 return result;
795}
796
797/*
798 * Restore (insert or replace) statistics for the given statistics object.
799 *
800 * This function accepts variadic arguments in key-value pairs, which are
801 * given to stats_fill_fcinfo_from_arg_pairs to be mapped into positional
802 * arguments.
803 */
804Datum
821
822/*
823 * Delete statistics for the given statistics object.
824 */
825Datum
827{
828 char *relnspname;
829 char *relname;
830 char *nspname;
831 Oid nspoid;
832 Oid relid;
833 char *stxname;
834 bool inherited;
839
840 /* relation arguments */
845
846 /* extended statistics arguments */
853
854 if (RecoveryInProgress())
855 {
858 errmsg("recovery is in progress"),
859 errhint("Statistics cannot be modified during recovery."));
861 }
862
863 /*
864 * First open the relation where we expect to find the statistics. This
865 * is similar to relation and attribute statistics, so as ACL checks are
866 * done before any locks are taken, even before any attempts related to
867 * the extended stats object.
868 */
872
873 /* Now check if the namespace of the stats object exists. */
874 nspoid = get_namespace_oid(nspname, true);
875 if (nspoid == InvalidOid)
876 {
879 errmsg("could not find schema \"%s\"", nspname));
881 }
882
885
886 if (!HeapTupleIsValid(tup))
887 {
891 errmsg("could not find extended statistics object \"%s\".\"%s\"",
892 nspname, stxname));
894 }
895
897
898 /*
899 * This should be consistent, based on the lock taken on the table when we
900 * started.
901 */
902 if (stxform->stxrelid != relid)
903 {
907 errmsg("could not clear extended statistics object \"%s\".\"%s\": incorrect relation \"%s\".\"%s\" specified",
911 }
912
915
917
919}
#define ARR_NDIM(a)
Definition array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
bool array_contains_nulls(const ArrayType *array)
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
int16 AttrNumber
Definition attnum.h:21
static Datum values[MAXATTR]
Definition bootstrap.c:155
static void cleanup(void)
Definition bootstrap.c:717
#define TextDatumGetCString(d)
Definition builtins.h:98
#define Assert(condition)
Definition c.h:873
double float8
Definition c.h:644
int32_t int32
Definition c.h:542
#define OidIsValid(objectId)
Definition c.h:788
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition clauses.c:2267
MVDependencies * statext_dependencies_deserialize(bytea *data)
bool statext_dependencies_validate(const MVDependencies *dependencies, const int2vector *stxkeys, int numexprs, int elevel)
void statext_dependencies_free(MVDependencies *dependencies)
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
extended_stats_argnum
@ INHERITED_ARG
@ RELSCHEMA_ARG
@ NUM_EXTENDED_STATS_ARGS
@ RELNAME_ARG
@ MOST_COMMON_BASE_FREQS_ARG
@ MOST_COMMON_FREQS_ARG
@ STATNAME_ARG
@ STATSCHEMA_ARG
@ MOST_COMMON_VALS_ARG
@ NDISTINCT_ARG
@ DEPENDENCIES_ARG
Datum pg_clear_extended_stats(PG_FUNCTION_ARGS)
static void upsert_pg_statistic_ext_data(const Datum *values, const bool *nulls, const bool *replaces)
static bool delete_pg_statistic_ext_data(Oid stxoid, bool inherited)
static struct StatsArgInfo extarginfo[]
Datum pg_restore_extended_stats(PG_FUNCTION_ARGS)
static void expand_stxkind(HeapTuple tup, StakindFlags *enabled)
static HeapTuple get_pg_statistic_ext(Relation pg_stext, Oid nspoid, const char *stxname)
static bool extended_statistics_update(FunctionCallInfo fcinfo)
static bool check_mcvlist_array(const ArrayType *arr, int argindex, int required_ndims, int mcv_length)
static Datum import_mcv(const ArrayType *mcv_arr, const ArrayType *freqs_arr, const ArrayType *base_freqs_arr, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int numattrs, bool *ok)
#define palloc0_array(type, count)
Definition fe_memutils.h:77
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define DatumGetByteaPP(X)
Definition fmgr.h:292
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition fmgr.h:150
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define LOCAL_FCINFO(name, nargs)
Definition fmgr.h:110
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define nitems(x)
Definition indent.h:31
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
static bool success
Definition initdb.c:187
int i
Definition isn.c:77
#define ShareUpdateExclusiveLock
Definition lockdefs.h:39
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3516
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
Definition makefuncs.c:473
Datum statext_mcv_import(int elevel, int numattrs, Oid *atttypids, int32 *atttypmods, Oid *atttypcolls, int nitems, Datum *mcv_elems, bool *mcv_nulls, float8 *freqs, float8 *base_freqs)
Definition mcv.c:2204
void pfree(void *pointer)
Definition mcxt.c:1616
void statext_ndistinct_free(MVNDistinct *ndistinct)
Definition mvdistinct.c:332
MVNDistinct * statext_ndistinct_deserialize(bytea *data)
Definition mvdistinct.c:247
bool statext_ndistinct_validate(const MVNDistinct *ndistinct, const int2vector *stxkeys, int numexprs, int elevel)
Definition mvdistinct.c:352
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition namespace.c:3605
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition namespace.c:440
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:301
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:821
void fix_opfuncids(Node *node)
Definition nodeFuncs.c:1840
int16 attnum
FormData_pg_attribute * Form_pg_attribute
NameData relname
Definition pg_class.h:38
const void * data
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
FormData_pg_statistic_ext * Form_pg_statistic_ext
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
#define InvalidOid
unsigned int Oid
static int fb(int x)
void * stringToNode(const char *str)
Definition read.c:90
#define RelationGetDescr(relation)
Definition rel.h:540
const char * quote_identifier(const char *ident)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
bool stats_fill_fcinfo_from_arg_pairs(FunctionCallInfo pairs_fcinfo, FunctionCallInfo positional_fcinfo, struct StatsArgInfo *arginfo)
Definition stat_utils.c:348
void RangeVarCallbackForStats(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition stat_utils.c:142
void stats_check_required_arg(FunctionCallInfo fcinfo, struct StatsArgInfo *arginfo, int argnum)
Definition stat_utils.c:51
#define BTEqualStrategyNumber
Definition stratnum.h:31
Definition pg_list.h:54
Definition nodes.h:135
const char * argname
Definition stat_utils.h:24
Definition c.h:706
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
Definition syscache.c:230
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void CommandCounterIncrement(void)
Definition xact.c:1101
bool RecoveryInProgress(void)
Definition xlog.c:6460