($INBOX_DIR/description missing)help / color / mirror / Atom feed
[PATCH 2/3] Add operator <->(box, point) to GiST box_ops 3+ messages / 3 participants [nested] [flat]
* [PATCH 2/3] Add operator <->(box, point) to GiST box_ops @ 2019-03-07 20:49 Nikita Glukhov <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Nikita Glukhov @ 2019-03-07 20:49 UTC (permalink / raw) --- doc/src/sgml/gist.sgml | 1 + src/backend/access/gist/gistproc.c | 53 ++++++++++++++++++-------- src/include/catalog/pg_amop.dat | 3 ++ src/include/catalog/pg_amproc.dat | 2 + src/include/catalog/pg_proc.dat | 4 ++ src/test/regress/expected/gist.out | 76 ++++++++++++++++++++++++++++++++++++++ src/test/regress/sql/gist.sql | 16 ++++++++ 7 files changed, 140 insertions(+), 15 deletions(-) diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml index 44a3b2c..e903319 100644 --- a/doc/src/sgml/gist.sgml +++ b/doc/src/sgml/gist.sgml @@ -83,6 +83,7 @@ <literal>~=</literal> </entry> <entry> + <literal><-></literal> </entry> </row> <row> diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c index 1826b51..89bd656 100644 --- a/src/backend/access/gist/gistproc.c +++ b/src/backend/access/gist/gistproc.c @@ -1464,26 +1464,13 @@ gist_point_distance(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(distance); } -/* - * The inexact GiST distance method for geometric types that store bounding - * boxes. - * - * Compute lossy distance from point to index entries. The result is inexact - * because index entries are bounding boxes, not the exact shapes of the - * indexed geometric types. We use distance from point to MBR of index entry. - * This is a lower bound estimate of distance from point to indexed geometric - * type. - */ static float8 -gist_bbox_distance(GISTENTRY *entry, Datum query, - StrategyNumber strategy, bool *recheck) +gist_box_distance_helper(GISTENTRY *entry, Datum query, + StrategyNumber strategy) { float8 distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; - /* Bounding box distance is always inexact. */ - *recheck = true; - switch (strategyGroup) { case PointStrategyNumberGroup: @@ -1500,6 +1487,42 @@ gist_bbox_distance(GISTENTRY *entry, Datum query, } Datum +gist_box_distance(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + Datum query = PG_GETARG_DATUM(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + + /* Oid subtype = PG_GETARG_OID(3); */ + /* bool *recheck = (bool *) PG_GETARG_POINTER(4); */ + float8 distance; + + distance = gist_box_distance_helper(entry, query, strategy); + + PG_RETURN_FLOAT8(distance); +} + +/* + * The inexact GiST distance method for geometric types that store bounding + * boxes. + * + * Compute lossy distance from point to index entries. The result is inexact + * because index entries are bounding boxes, not the exact shapes of the + * indexed geometric types. We use distance from point to MBR of index entry. + * This is a lower bound estimate of distance from point to indexed geometric + * type. + */ +static float8 +gist_bbox_distance(GISTENTRY *entry, Datum query, + StrategyNumber strategy, bool *recheck) +{ + /* Bounding box distance is always inexact. */ + *recheck = true; + + return gist_box_distance_helper(entry, query, strategy); +} + +Datum gist_circle_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); diff --git a/src/include/catalog/pg_amop.dat b/src/include/catalog/pg_amop.dat index cf63eb7..ebc38ae 100644 --- a/src/include/catalog/pg_amop.dat +++ b/src/include/catalog/pg_amop.dat @@ -1081,6 +1081,9 @@ amopstrategy => '13', amopopr => '~(box,box)', amopmethod => 'gist' }, { amopfamily => 'gist/box_ops', amoplefttype => 'box', amoprighttype => 'box', amopstrategy => '14', amopopr => '@(box,box)', amopmethod => 'gist' }, +{ amopfamily => 'gist/box_ops', amoplefttype => 'box', amoprighttype => 'point', + amopstrategy => '15', amoppurpose => 'o', amopopr => '<->(box,point)', + amopmethod => 'gist', amopsortfamily => 'btree/float_ops' }, # gist point_ops { amopfamily => 'gist/point_ops', amoplefttype => 'point', diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index 020b741..5567b7e 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -419,6 +419,8 @@ amprocrighttype => 'box', amprocnum => '6', amproc => 'gist_box_picksplit' }, { amprocfamily => 'gist/box_ops', amproclefttype => 'box', amprocrighttype => 'box', amprocnum => '7', amproc => 'gist_box_same' }, +{ amprocfamily => 'gist/box_ops', amproclefttype => 'box', + amprocrighttype => 'box', amprocnum => '8', amproc => 'gist_box_distance' }, { amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon', amprocrighttype => 'polygon', amprocnum => '1', amproc => 'gist_poly_consistent' }, diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 54327bf..d15f94a 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -7816,6 +7816,10 @@ { oid => '2584', descr => 'GiST support', proname => 'gist_box_same', prorettype => 'internal', proargtypes => 'box box internal', prosrc => 'gist_box_same' }, +{ oid => '3998', descr => 'GiST support', + proname => 'gist_box_distance', prorettype => 'float8', + proargtypes => 'internal box int2 oid internal', + prosrc => 'gist_box_distance' }, { oid => '2585', descr => 'GiST support', proname => 'gist_poly_consistent', prorettype => 'bool', proargtypes => 'internal polygon int2 oid internal', diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index 0a43449..2234876 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -203,6 +203,82 @@ select b from gist_tbl where b <@ box(point(5,5), point(6,6)); (6,6),(6,6) (21 rows) +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + QUERY PLAN +------------------------------------------------------ + Index Only Scan using gist_tbl_box_index on gist_tbl + Index Cond: (b <@ '(6,6),(5,5)'::box) + Order By: (b <-> '(5.2,5.91)'::point) +(3 rows) + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + b +------------------------- + (5.55,5.55),(5.55,5.55) + (5.6,5.6),(5.6,5.6) + (5.5,5.5),(5.5,5.5) + (5.65,5.65),(5.65,5.65) + (5.45,5.45),(5.45,5.45) + (5.7,5.7),(5.7,5.7) + (5.4,5.4),(5.4,5.4) + (5.75,5.75),(5.75,5.75) + (5.35,5.35),(5.35,5.35) + (5.8,5.8),(5.8,5.8) + (5.3,5.3),(5.3,5.3) + (5.85,5.85),(5.85,5.85) + (5.25,5.25),(5.25,5.25) + (5.9,5.9),(5.9,5.9) + (5.2,5.2),(5.2,5.2) + (5.95,5.95),(5.95,5.95) + (5.15,5.15),(5.15,5.15) + (6,6),(6,6) + (5.1,5.1),(5.1,5.1) + (5.05,5.05),(5.05,5.05) + (5,5),(5,5) +(21 rows) + +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + QUERY PLAN +------------------------------------------------------ + Index Only Scan using gist_tbl_box_index on gist_tbl + Index Cond: (b <@ '(6,6),(5,5)'::box) + Order By: (b <-> '(5.2,5.91)'::point) +(3 rows) + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + b +------------------------- + (5.55,5.55),(5.55,5.55) + (5.6,5.6),(5.6,5.6) + (5.5,5.5),(5.5,5.5) + (5.65,5.65),(5.65,5.65) + (5.45,5.45),(5.45,5.45) + (5.7,5.7),(5.7,5.7) + (5.4,5.4),(5.4,5.4) + (5.75,5.75),(5.75,5.75) + (5.35,5.35),(5.35,5.35) + (5.8,5.8),(5.8,5.8) + (5.3,5.3),(5.3,5.3) + (5.85,5.85),(5.85,5.85) + (5.25,5.25),(5.25,5.25) + (5.9,5.9),(5.9,5.9) + (5.2,5.2),(5.2,5.2) + (5.95,5.95),(5.95,5.95) + (5.15,5.15),(5.15,5.15) + (6,6),(6,6) + (5.1,5.1),(5.1,5.1) + (5.05,5.05),(5.05,5.05) + (5,5),(5,5) +(21 rows) + drop index gist_tbl_box_index; -- Test that an index-only scan is not chosen, when the query involves the -- circle column (the circle opclass does not support index-only scans). diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index 657b195..b9d398e 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -109,6 +109,22 @@ select b from gist_tbl where b <@ box(point(5,5), point(6,6)); -- execute the same select b from gist_tbl where b <@ box(point(5,5), point(6,6)); +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + drop index gist_tbl_box_index; -- Test that an index-only scan is not chosen, when the query involves the -- 2.7.4 --------------07EE9595454874974EAD75E7 Content-Type: text/x-patch; name="0003-Add-operator-box-point-to-SP-GiST-box_ops-v02.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0003-Add-operator-box-point-to-SP-GiST-box_ops-v02.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
* [PATCH v5 4/7] Row pattern recognition patch (executor). @ 2023-09-02 06:32 Tatsuo Ishii <[email protected]> 0 siblings, 0 replies; 3+ 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] 3+ messages in thread
* [PATCH 2/3] replace CppAsString2(RELKIND_x) with RELKIND_x_STR @ 2026-02-01 23:45 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 3+ messages in thread From: Álvaro Herrera @ 2026-02-01 23:45 UTC (permalink / raw) --- contrib/oid2name/oid2name.c | 18 +++--- contrib/postgres_fdw/postgres_fdw.c | 10 +-- contrib/vacuumlo/vacuumlo.c | 2 +- src/backend/commands/subscriptioncmds.c | 4 +- src/backend/utils/adt/xml.c | 12 ++-- src/bin/initdb/initdb.c | 20 +++--- src/bin/pg_amcheck/pg_amcheck.c | 32 ++++----- src/bin/pg_dump/pg_dump.c | 36 +++++------ src/bin/pg_upgrade/check.c | 6 +- src/bin/pg_upgrade/info.c | 6 +- src/bin/pg_upgrade/pg_upgrade.c | 12 ++-- src/bin/psql/describe.c | 74 ++++++++++----------- src/bin/psql/tab-complete.in.c | 86 ++++++++++++------------- src/bin/scripts/reindexdb.c | 8 +-- src/bin/scripts/vacuuming.c | 14 ++-- 15 files changed, 170 insertions(+), 170 deletions(-) diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index 51802907138..463bdfae320 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -477,8 +477,8 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts) " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " " LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database()," " pg_catalog.pg_tablespace t " - "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_MATVIEW) "%s%s) AND " + "WHERE relkind IN (" RELKIND_RELATION_STR "," + RELKIND_MATVIEW_STR "%s%s) AND " " %s" " t.oid = CASE" " WHEN reltablespace <> 0 THEN reltablespace" @@ -486,8 +486,8 @@ sql_exec_dumpalltables(PGconn *conn, struct options *opts) " END " "ORDER BY relname", opts->extended ? addfields : "", - opts->indexes ? "," CppAsString2(RELKIND_INDEX) "," CppAsString2(RELKIND_SEQUENCE) : "", - opts->systables ? "," CppAsString2(RELKIND_TOASTVALUE) : "", + opts->indexes ? "," RELKIND_INDEX_STR "," RELKIND_SEQUENCE_STR : "", + opts->systables ? "," RELKIND_TOASTVALUE_STR : "", opts->systables ? "" : "n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND"); sql_exec(conn, todo, opts->quiet); @@ -548,11 +548,11 @@ sql_exec_searchtables(PGconn *conn, struct options *opts) " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n" " LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),\n" " pg_catalog.pg_tablespace t\n" - "WHERE relkind IN (" CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_INDEX) "," - CppAsString2(RELKIND_SEQUENCE) "," - CppAsString2(RELKIND_TOASTVALUE) ") AND\n" + "WHERE relkind IN (" RELKIND_RELATION_STR "," + RELKIND_MATVIEW_STR "," + RELKIND_INDEX_STR "," + RELKIND_SEQUENCE_STR "," + RELKIND_TOASTVALUE_STR ") AND\n" " t.oid = CASE\n" " WHEN reltablespace <> 0 THEN reltablespace\n" " ELSE dattablespace\n" diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 3572689e33b..e0457bb1253 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5496,11 +5496,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) appendStringInfoString(&buf, "WHERE c.relkind IN (" - CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_VIEW) "," - CppAsString2(RELKIND_FOREIGN_TABLE) "," - CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_PARTITIONED_TABLE) ") " + RELKIND_RELATION_STR "," + RELKIND_VIEW_STR "," + RELKIND_FOREIGN_TABLE_STR "," + RELKIND_MATVIEW_STR "," + RELKIND_PARTITIONED_TABLE_STR ") " " AND n.nspname = "); deparseStringLiteral(&buf, stmt->remote_schema); diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c index 8102569466b..343dae9bc20 100644 --- a/contrib/vacuumlo/vacuumlo.c +++ b/contrib/vacuumlo/vacuumlo.c @@ -198,7 +198,7 @@ vacuumlo(const char *database, const struct _param *param) strcat(buf, " AND a.atttypid = t.oid "); strcat(buf, " AND c.relnamespace = s.oid "); strcat(buf, " AND t.typname in ('oid', 'lo') "); - strcat(buf, " AND c.relkind in (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_MATVIEW) ")"); + strcat(buf, " AND c.relkind in ('" RELKIND_RELATION_STR "', " RELKIND_MATVIEW_STR ")"); strcat(buf, " AND s.nspname !~ '^pg_'"); res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_TUPLES_OK) diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 0b3c8499b49..33e3c25a50c 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -2921,7 +2921,7 @@ fetch_relation_list(WalReceiverConn *wrconn, List *publications) if (server_version >= 190000) appendStringInfo(&cmd, "UNION ALL\n" - " SELECT DISTINCT s.schemaname, s.sequencename, " CppAsString2(RELKIND_SEQUENCE) "::\"char\" AS relkind, NULL::int2vector AS attrs\n" + " SELECT DISTINCT s.schemaname, s.sequencename, " RELKIND_SEQUENCE_STR "::\"char\" AS relkind, NULL::int2vector AS attrs\n" " FROM pg_catalog.pg_publication_sequences s\n" " WHERE s.pubname IN ( %s )", pub_names.data); @@ -2929,7 +2929,7 @@ fetch_relation_list(WalReceiverConn *wrconn, List *publications) else { tableRow[3] = NAMEARRAYOID; - appendStringInfoString(&cmd, "SELECT DISTINCT t.schemaname, t.tablename, " CppAsString2(RELKIND_RELATION) "::\"char\" AS relkind \n"); + appendStringInfoString(&cmd, "SELECT DISTINCT t.schemaname, t.tablename, " RELKIND_RELATION_STR "::\"char\" AS relkind \n"); /* Get column lists for each relation if the publisher supports it */ if (check_columnlist) diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index f69dc68286c..7de019a7402 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -2857,9 +2857,9 @@ schema_get_xml_visible_tables(Oid nspid) initStringInfo(&query); appendStringInfo(&query, "SELECT oid FROM pg_catalog.pg_class" " WHERE relnamespace = %u AND relkind IN (" - CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_VIEW) ")" + RELKIND_RELATION_STR "," + RELKIND_MATVIEW_STR "," + RELKIND_VIEW_STR ")" " AND pg_catalog.has_table_privilege (oid, 'SELECT')" " ORDER BY relname;", nspid); @@ -2889,9 +2889,9 @@ database_get_xml_visible_tables(void) /* At the moment there is no order required here. */ return query_to_oid_list("SELECT oid FROM pg_catalog.pg_class" " WHERE relkind IN (" - CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_VIEW) ")" + RELKIND_RELATION_STR "," + RELKIND_MATVIEW_STR "," + RELKIND_VIEW_STR ")" " AND pg_catalog.has_table_privilege(pg_class.oid, 'SELECT')" " AND relnamespace IN (" XML_VISIBLE_SCHEMAS ");"); } diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index a3980e5535f..11bfdd31cbf 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -1806,12 +1806,12 @@ setup_privileges(FILE *cmdfd) " SET relacl = (SELECT array_agg(a.acl) FROM " " (SELECT E'=r/\"%s\"' as acl " " UNION SELECT unnest(pg_catalog.acldefault(" - " CASE WHEN relkind = " CppAsString2(RELKIND_SEQUENCE) " THEN 's' " + " CASE WHEN relkind = " RELKIND_SEQUENCE_STR " THEN 's' " " ELSE 'r' END::\"char\"," CppAsString2(BOOTSTRAP_SUPERUSERID) "::oid))" " ) as a) " - " WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_SEQUENCE) ")" + " WHERE relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", " + RELKIND_SEQUENCE_STR ")" " AND relacl IS NULL;\n\n", escape_quotes(username)); PG_CMD_PUTS("GRANT USAGE ON SCHEMA pg_catalog, public TO PUBLIC;\n\n"); @@ -1828,9 +1828,9 @@ setup_privileges(FILE *cmdfd) " pg_class" " WHERE" " relacl IS NOT NULL" - " AND relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_SEQUENCE) ");\n\n"); + " AND relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", " + RELKIND_SEQUENCE_STR ");\n\n"); PG_CMD_PUTS("INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1844,9 +1844,9 @@ setup_privileges(FILE *cmdfd) " JOIN pg_attribute ON (pg_class.oid = pg_attribute.attrelid)" " WHERE" " pg_attribute.attacl IS NOT NULL" - " AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_SEQUENCE) ");\n\n"); + " AND pg_class.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_VIEW_STR ", " RELKIND_MATVIEW_STR ", " + RELKIND_SEQUENCE_STR ");\n\n"); PG_CMD_PUTS("INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c index 03e24a2577c..72bfcd2c813 100644 --- a/src/bin/pg_amcheck/pg_amcheck.c +++ b/src/bin/pg_amcheck/pg_amcheck.c @@ -1976,28 +1976,28 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations, appendPQExpBuffer(&sql, " AND c.relam = %u " "AND c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_SEQUENCE) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ") " + RELKIND_RELATION_STR ", " + RELKIND_SEQUENCE_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_TOASTVALUE_STR ") " "AND c.relnamespace != %u", HEAP_TABLE_AM_OID, PG_TOAST_NAMESPACE); else appendPQExpBuffer(&sql, " AND c.relam IN (%u, %u)" "AND c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_SEQUENCE) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ", " - CppAsString2(RELKIND_INDEX) ") " + RELKIND_RELATION_STR ", " + RELKIND_SEQUENCE_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_TOASTVALUE_STR ", " + RELKIND_INDEX_STR ") " "AND ((c.relam = %u AND c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_SEQUENCE) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ")) OR " + RELKIND_RELATION_STR ", " + RELKIND_SEQUENCE_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_TOASTVALUE_STR ")) OR " "(c.relam = %u AND c.relkind = " - CppAsString2(RELKIND_INDEX) "))", + RELKIND_INDEX_STR "))", HEAP_TABLE_AM_OID, BTREE_AM_OID, HEAP_TABLE_AM_OID, BTREE_AM_OID); @@ -2058,7 +2058,7 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations, "\nWHERE true"); appendPQExpBuffer(&sql, " AND c.relam = %u " - "AND c.relkind = " CppAsString2(RELKIND_INDEX), + "AND c.relkind = " RELKIND_INDEX_STR, BTREE_AM_OID); if (opts.no_toast_expansion) appendPQExpBuffer(&sql, @@ -2095,7 +2095,7 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations, "\nWHERE true"); appendPQExpBuffer(&sql, " AND c.relam = %u" - " AND c.relkind = " CppAsString2(RELKIND_INDEX) ")", + " AND c.relkind = " RELKIND_INDEX_STR ")", BTREE_AM_OID); } diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 2bebefd0ba2..cdccccc1820 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -3158,14 +3158,14 @@ buildMatViewRefreshDependencies(Archive *fout) "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind " "FROM pg_depend d1 " "JOIN pg_class c1 ON c1.oid = d1.objid " - "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW) + "AND c1.relkind = " RELKIND_MATVIEW_STR " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid " "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass " "AND d2.objid = r1.oid " "AND d2.refobjid <> d1.objid " "JOIN pg_class c2 ON c2.oid = d2.refobjid " - "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_VIEW) ") " + "AND c2.relkind IN (" RELKIND_MATVIEW_STR "," + RELKIND_VIEW_STR ") " "WHERE d1.classid = 'pg_class'::regclass " "UNION " "SELECT w.objid, d3.refobjid, c3.relkind " @@ -3175,12 +3175,12 @@ buildMatViewRefreshDependencies(Archive *fout) "AND d3.objid = r3.oid " "AND d3.refobjid <> w.refobjid " "JOIN pg_class c3 ON c3.oid = d3.refobjid " - "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_VIEW) ") " + "AND c3.relkind IN (" RELKIND_MATVIEW_STR "," + RELKIND_VIEW_STR ") " ") " "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid " "FROM w " - "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW)); + "WHERE refrelkind = " RELKIND_MATVIEW_STR); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7279,9 +7279,9 @@ getTables(Archive *fout, int *numTables) "c.relhastriggers, c.relpersistence, " "c.reloftype, " "c.relacl, " - "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE) + "acldefault(CASE WHEN c.relkind = " RELKIND_SEQUENCE_STR " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, " - "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN " + "CASE WHEN c.relkind = " RELKIND_FOREIGN_TABLE_STR " THEN " "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) " "ELSE 0 END AS foreignserver, " "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, " @@ -7367,7 +7367,7 @@ getTables(Archive *fout, int *numTables) appendPQExpBufferStr(query, "\nFROM pg_class c\n" "LEFT JOIN pg_depend d ON " - "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND " + "(c.relkind = " RELKIND_SEQUENCE_STR " AND " "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND " "d.objsubid = 0 AND " "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n" @@ -7387,8 +7387,8 @@ getTables(Archive *fout, int *numTables) */ appendPQExpBufferStr(query, "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid" - " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE) - " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"); + " AND tc.relkind = " RELKIND_TOASTVALUE_STR + " AND c.relkind <> " RELKIND_PARTITIONED_TABLE_STR ")\n"); /* * Restrict to interesting relkinds (in particular, not indexes). Not all @@ -7402,13 +7402,13 @@ getTables(Archive *fout, int *numTables) */ appendPQExpBufferStr(query, "WHERE c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_SEQUENCE) ", " - CppAsString2(RELKIND_VIEW) ", " - CppAsString2(RELKIND_COMPOSITE_TYPE) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_FOREIGN_TABLE) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n" + RELKIND_RELATION_STR ", " + RELKIND_SEQUENCE_STR ", " + RELKIND_VIEW_STR ", " + RELKIND_COMPOSITE_TYPE_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_FOREIGN_TABLE_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")\n" "ORDER BY c.oid"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index a8d20a92a98..5d053563657 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -372,9 +372,9 @@ data_type_check_query(int checknum) " NOT a.attisdropped AND " " a.atttypid IN (SELECT oid FROM oids) AND " " c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_INDEX) ") AND " + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_INDEX_STR ") AND " " c.relnamespace = n.oid AND " /* exclude possible orphaned temp tables */ " n.nspname !~ '^pg_temp_' AND " diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c index 47e8d1039a2..89bda44fcf9 100644 --- a/src/bin/pg_upgrade/info.c +++ b/src/bin/pg_upgrade/info.c @@ -508,8 +508,8 @@ get_rel_infos_query(void) " SELECT c.oid, 0::oid, 0::oid " " FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " " ON c.relnamespace = n.oid " - " WHERE relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) "%s) AND " + " WHERE relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR "%s) AND " /* exclude possible orphaned temp tables */ " ((n.nspname !~ '^pg_temp_' AND " " n.nspname !~ '^pg_toast_temp_' AND " @@ -519,7 +519,7 @@ get_rel_infos_query(void) " (n.nspname = 'pg_catalog' AND " " relname IN ('pg_largeobject'%s) ))), ", (user_opts.transfer_mode == TRANSFER_MODE_SWAP) ? - ", " CppAsString2(RELKIND_SEQUENCE) : "", + ", " RELKIND_SEQUENCE_STR : "", FirstNormalObjectId, (GET_MAJOR_VERSION(old_cluster.major_version) >= 1600) ? ", 'pg_largeobject_metadata'" : ""); diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 2127d297bfe..e94f02fd369 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -990,9 +990,9 @@ set_frozenxids(bool minmxid_only) "SET relfrozenxid = '%u' " /* only heap, materialized view, and TOAST are vacuumed */ "WHERE relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ")", + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_TOASTVALUE_STR ")", old_cluster.controldata.chkpnt_nxtxid)); /* set pg_class.relminmxid */ @@ -1001,9 +1001,9 @@ set_frozenxids(bool minmxid_only) "SET relminmxid = '%u' " /* only heap, materialized view, and TOAST are vacuumed */ "WHERE relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_TOASTVALUE) ")", + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_TOASTVALUE_STR ")", old_cluster.controldata.chkpnt_nxtmulti)); PQfinish(conn); diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 3584c4e1428..f02a8df8875 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -689,7 +689,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) * composite types */ appendPQExpBufferStr(&buf, "WHERE (t.typrelid = 0 "); - appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE) + appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " RELKIND_COMPOSITE_TYPE_STR " FROM pg_catalog.pg_class c " "WHERE c.oid = t.typrelid))\n"); @@ -1063,12 +1063,12 @@ permissionsList(const char *pattern, bool showSystem) "SELECT n.nspname as \"%s\",\n" " c.relname as \"%s\",\n" " CASE c.relkind" - " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" + " WHEN " RELKIND_RELATION_STR " THEN '%s'" + " WHEN " RELKIND_VIEW_STR " THEN '%s'" + " WHEN " RELKIND_MATVIEW_STR " THEN '%s'" + " WHEN " RELKIND_SEQUENCE_STR " THEN '%s'" + " WHEN " RELKIND_FOREIGN_TABLE_STR " THEN '%s'" + " WHEN " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'" " END as \"%s\",\n" " ", gettext_noop("Schema"), @@ -1164,12 +1164,12 @@ permissionsList(const char *pattern, bool showSystem) appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n" "WHERE c.relkind IN (" - CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_VIEW) "," - CppAsString2(RELKIND_MATVIEW) "," - CppAsString2(RELKIND_SEQUENCE) "," - CppAsString2(RELKIND_FOREIGN_TABLE) "," - CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"); + RELKIND_RELATION_STR "," + RELKIND_VIEW_STR "," + RELKIND_MATVIEW_STR "," + RELKIND_SEQUENCE_STR "," + RELKIND_FOREIGN_TABLE_STR "," + RELKIND_PARTITIONED_TABLE_STR ")\n"); if (!showSystem && !pattern) appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" @@ -3471,8 +3471,8 @@ describeOneTableDetails(const char *schemaname, "SELECT c.oid::pg_catalog.regclass\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhparent AND i.inhrelid = '%s'\n" - " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_TABLE) - " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_INDEX) + " AND c.relkind != " RELKIND_PARTITIONED_TABLE_STR + " AND c.relkind != " RELKIND_PARTITIONED_INDEX_STR "\nORDER BY inhseqno;", oid); @@ -4067,15 +4067,15 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys "SELECT n.nspname as \"%s\",\n" " c.relname as \"%s\",\n" " CASE c.relkind" - " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" + " WHEN " RELKIND_RELATION_STR " THEN '%s'" + " WHEN " RELKIND_VIEW_STR " THEN '%s'" + " WHEN " RELKIND_MATVIEW_STR " THEN '%s'" + " WHEN " RELKIND_INDEX_STR " THEN '%s'" + " WHEN " RELKIND_SEQUENCE_STR " THEN '%s'" + " WHEN " RELKIND_TOASTVALUE_STR " THEN '%s'" + " WHEN " RELKIND_FOREIGN_TABLE_STR " THEN '%s'" + " WHEN " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'" + " WHEN " RELKIND_PARTITIONED_INDEX_STR " THEN '%s'" " END as \"%s\",\n" " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"", gettext_noop("Schema"), @@ -4157,25 +4157,25 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); if (showTables) { - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) "," - CppAsString2(RELKIND_PARTITIONED_TABLE) ","); + appendPQExpBufferStr(&buf, RELKIND_RELATION_STR "," + RELKIND_PARTITIONED_TABLE_STR ","); /* with 'S' or a pattern, allow 't' to match TOAST tables too */ if (showSystem || pattern) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ","); + appendPQExpBufferStr(&buf, RELKIND_TOASTVALUE_STR ","); } if (showViews) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ","); + appendPQExpBufferStr(&buf, RELKIND_VIEW_STR ","); if (showMatViews) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ","); + appendPQExpBufferStr(&buf, RELKIND_MATVIEW_STR ","); if (showIndexes) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) "," - CppAsString2(RELKIND_PARTITIONED_INDEX) ","); + appendPQExpBufferStr(&buf, RELKIND_INDEX_STR "," + RELKIND_PARTITIONED_INDEX_STR ","); if (showSeq) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ","); + appendPQExpBufferStr(&buf, RELKIND_SEQUENCE_STR ","); if (showSystem || pattern) appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */ if (showForeign) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ","); + appendPQExpBufferStr(&buf, RELKIND_FOREIGN_TABLE_STR ","); appendPQExpBufferStr(&buf, "''"); /* dummy */ appendPQExpBufferStr(&buf, ")\n"); @@ -4348,8 +4348,8 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) { appendPQExpBuffer(&buf, ",\n CASE c.relkind" - " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" - " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" + " WHEN " RELKIND_PARTITIONED_TABLE_STR " THEN '%s'" + " WHEN " RELKIND_PARTITIONED_INDEX_STR " THEN '%s'" " END as \"%s\"", gettext_noop("partitioned table"), gettext_noop("partitioned index"), @@ -4449,9 +4449,9 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); if (showTables) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ","); + appendPQExpBufferStr(&buf, RELKIND_PARTITIONED_TABLE_STR ","); if (showIndexes) - appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ","); + appendPQExpBufferStr(&buf, RELKIND_PARTITIONED_INDEX_STR ","); appendPQExpBufferStr(&buf, "''"); /* dummy */ appendPQExpBufferStr(&buf, ")\n"); diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c index 8b91bc00062..5434a1273b2 100644 --- a/src/bin/psql/tab-complete.in.c +++ b/src/bin/psql/tab-complete.in.c @@ -146,7 +146,7 @@ typedef struct SchemaQuery * Selection condition --- only rows meeting this condition are candidates * to display. If catname mentions multiple tables, include the necessary * join condition here. For example, this might look like "c.relkind = " - * CppAsString2(RELKIND_RELATION). Write NULL (not an empty string) if + * RELKIND_RELATION_STR. Write NULL (not an empty string) if * not needed. */ const char *selcondition; @@ -591,7 +591,7 @@ static const SchemaQuery Query_for_list_of_datatypes = { .catname = "pg_catalog.pg_type t", /* selcondition --- ignore table rowtypes and array types */ .selcondition = "(t.typrelid = 0 " - " OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE) + " OR (SELECT c.relkind = " RELKIND_COMPOSITE_TYPE_STR " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) " "AND t.typname !~ '^_'", .viscondition = "pg_catalog.pg_type_is_visible(t.oid)", @@ -603,7 +603,7 @@ static const SchemaQuery Query_for_list_of_datatypes = { static const SchemaQuery Query_for_list_of_composite_datatypes = { .catname = "pg_catalog.pg_type t", /* selcondition --- only get composite types */ - .selcondition = "(SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE) + .selcondition = "(SELECT c.relkind = " RELKIND_COMPOSITE_TYPE_STR " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid) " "AND t.typname !~ '^_'", .viscondition = "pg_catalog.pg_type_is_visible(t.oid)", @@ -679,7 +679,7 @@ static const SchemaQuery Query_for_list_of_routines = { static const SchemaQuery Query_for_list_of_sequences = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")", + .selcondition = "c.relkind IN (" RELKIND_SEQUENCE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -687,7 +687,7 @@ static const SchemaQuery Query_for_list_of_sequences = { static const SchemaQuery Query_for_list_of_foreign_tables = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")", + .selcondition = "c.relkind IN (" RELKIND_FOREIGN_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -696,8 +696,8 @@ static const SchemaQuery Query_for_list_of_foreign_tables = { static const SchemaQuery Query_for_list_of_tables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -705,7 +705,7 @@ static const SchemaQuery Query_for_list_of_tables = { static const SchemaQuery Query_for_list_of_partitioned_tables = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + .selcondition = "c.relkind IN (" RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -714,8 +714,8 @@ static const SchemaQuery Query_for_list_of_partitioned_tables = { static const SchemaQuery Query_for_list_of_tables_for_constraint = { .catname = "pg_catalog.pg_class c, pg_catalog.pg_constraint con", .selcondition = "c.oid=con.conrelid and c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + RELKIND_RELATION_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -783,7 +783,7 @@ static const SchemaQuery Query_for_list_of_ts_templates = { static const SchemaQuery Query_for_list_of_views = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")", + .selcondition = "c.relkind IN (" RELKIND_VIEW_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -791,7 +791,7 @@ static const SchemaQuery Query_for_list_of_views = { static const SchemaQuery Query_for_list_of_matviews = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")", + .selcondition = "c.relkind IN (" RELKIND_MATVIEW_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -800,8 +800,8 @@ static const SchemaQuery Query_for_list_of_matviews = { static const SchemaQuery Query_for_list_of_indexes = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", " - CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + "c.relkind IN (" RELKIND_INDEX_STR ", " + RELKIND_PARTITIONED_INDEX_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -809,7 +809,7 @@ static const SchemaQuery Query_for_list_of_indexes = { static const SchemaQuery Query_for_list_of_partitioned_indexes = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX), + .selcondition = "c.relkind = " RELKIND_PARTITIONED_INDEX_STR, .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -827,8 +827,8 @@ static const SchemaQuery Query_for_list_of_relations = { /* partitioned relations */ static const SchemaQuery Query_for_list_of_partitioned_relations = { .catname = "pg_catalog.pg_class c", - .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) - ", " CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + .selcondition = "c.relkind IN (" RELKIND_PARTITIONED_TABLE_STR + ", " RELKIND_PARTITIONED_INDEX_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -845,10 +845,10 @@ static const SchemaQuery Query_for_list_of_operator_families = { static const SchemaQuery Query_for_list_of_updatables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_FOREIGN_TABLE) ", " - CppAsString2(RELKIND_VIEW) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_FOREIGN_TABLE_STR ", " + RELKIND_VIEW_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -858,9 +858,9 @@ static const SchemaQuery Query_for_list_of_updatables = { static const SchemaQuery Query_for_list_of_mergetargets = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_VIEW) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ") ", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_VIEW_STR ", " + RELKIND_PARTITIONED_TABLE_STR ") ", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -870,12 +870,12 @@ static const SchemaQuery Query_for_list_of_mergetargets = { static const SchemaQuery Query_for_list_of_selectables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_SEQUENCE) ", " - CppAsString2(RELKIND_VIEW) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_FOREIGN_TABLE) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_SEQUENCE_STR ", " + RELKIND_VIEW_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_FOREIGN_TABLE_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -885,9 +885,9 @@ static const SchemaQuery Query_for_list_of_selectables = { static const SchemaQuery Query_for_list_of_truncatables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_FOREIGN_TABLE) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_FOREIGN_TABLE_STR ", " + RELKIND_PARTITIONED_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -900,10 +900,10 @@ static const SchemaQuery Query_for_list_of_truncatables = { static const SchemaQuery Query_for_list_of_analyzables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_FOREIGN_TABLE) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_PARTITIONED_TABLE_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_FOREIGN_TABLE_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -921,9 +921,9 @@ static const SchemaQuery Query_for_list_of_analyzables = { static const SchemaQuery Query_for_list_of_indexables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ", " - CppAsString2(RELKIND_MATVIEW) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_PARTITIONED_TABLE_STR ", " + RELKIND_MATVIEW_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", @@ -939,9 +939,9 @@ static const SchemaQuery Query_for_list_of_indexables = { static const SchemaQuery Query_for_list_of_clusterables = { .catname = "pg_catalog.pg_class c", .selcondition = - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ", " - CppAsString2(RELKIND_MATVIEW) ")", + "c.relkind IN (" RELKIND_RELATION_STR ", " + RELKIND_PARTITIONED_TABLE_STR ", " + RELKIND_MATVIEW_STR ")", .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", .namespace = "c.relnamespace", .result = "c.relname", diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c index b15745256ff..e63dda7a7a1 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -651,8 +651,8 @@ get_parallel_tables_list(PGconn *conn, ReindexType type, " ON c.relnamespace = ns.oid\n" " WHERE ns.nspname != 'pg_catalog'\n" " AND c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ")\n" + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ")\n" " AND c.relpersistence != " CppAsString2(RELPERSISTENCE_TEMP) "\n" " ORDER BY c.relpages DESC;"); @@ -674,8 +674,8 @@ get_parallel_tables_list(PGconn *conn, ReindexType type, " JOIN pg_catalog.pg_namespace ns" " ON c.relnamespace = ns.oid\n" " WHERE c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ")\n" + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ")\n" " AND c.relpersistence != " CppAsString2(RELPERSISTENCE_TEMP) "\n" " AND ns.nspname IN ("); diff --git a/src/bin/scripts/vacuuming.c b/src/bin/scripts/vacuuming.c index faac9089a01..9c59cd31c50 100644 --- a/src/bin/scripts/vacuuming.c +++ b/src/bin/scripts/vacuuming.c @@ -598,8 +598,8 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, " JOIN pg_catalog.pg_namespace ns" " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n" " CROSS JOIN LATERAL (SELECT c.relkind IN (" - CppAsString2(RELKIND_PARTITIONED_TABLE) ", " - CppAsString2(RELKIND_PARTITIONED_INDEX) ")) as p (inherited)\n" + RELKIND_PARTITIONED_TABLE_STR ", " + RELKIND_PARTITIONED_INDEX_STR ")) as p (inherited)\n" " LEFT JOIN pg_catalog.pg_class t" " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n"); @@ -659,14 +659,14 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts, if (vacopts->mode == MODE_ANALYZE) appendPQExpBufferStr(&catalog_query, " AND c.relkind OPERATOR(pg_catalog.=) ANY (array[" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) "])\n"); + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR ", " + RELKIND_PARTITIONED_TABLE_STR "])\n"); else appendPQExpBufferStr(&catalog_query, " AND c.relkind OPERATOR(pg_catalog.=) ANY (array[" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) "])\n"); + RELKIND_RELATION_STR ", " + RELKIND_MATVIEW_STR "])\n"); } /* -- 2.47.3 --a5gwxv7edi5gnyjn Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0003-Initial-steps-to-making-relkind-an-enum.patch" ^ permalink raw reply [nested|flat] 3+ messages in thread
end of thread, other threads:[~2026-02-01 23:45 UTC | newest] Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2019-03-07 20:49 [PATCH 2/3] Add operator <->(box, point) to GiST box_ops Nikita Glukhov <[email protected]> 2023-09-02 06:32 [PATCH v5 4/7] Row pattern recognition patch (executor). Tatsuo Ishii <[email protected]> 2026-02-01 23:45 [PATCH 2/3] replace CppAsString2(RELKIND_x) with RELKIND_x_STR Álvaro Herrera <[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