mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Redesign tablesample method API, and do extensive code review.
The original implementation of TABLESAMPLE modeled the tablesample method API on index access methods, which wasn't a good choice because, without specialized DDL commands, there's no way to build an extension that can implement a TSM. (Raw inserts into system catalogs are not an acceptable thing to do, because we can't undo them during DROP EXTENSION, nor will pg_upgrade behave sanely.) Instead adopt an API more like procedural language handlers or foreign data wrappers, wherein the only SQL-level support object needed is a single handler function identified by having a special return type. This lets us get rid of the supporting catalog altogether, so that no custom DDL support is needed for the feature. Adjust the API so that it can support non-constant tablesample arguments (the original coding assumed we could evaluate the argument expressions at ExecInitSampleScan time, which is undesirable even if it weren't outright unsafe), and discourage sampling methods from looking at invisible tuples. Make sure that the BERNOULLI and SYSTEM methods are genuinely repeatable within and across queries, as required by the SQL standard, and deal more honestly with methods that can't support that requirement. Make a full code-review pass over the tablesample additions, and fix assorted bugs, omissions, infelicities, and cosmetic issues (such as failure to put the added code stanzas in a consistent ordering). Improve EXPLAIN's output of tablesample plans, too. Back-patch to 9.5 so that we don't have to support the original API in production.
This commit is contained in:
@ -359,6 +359,27 @@ _copySeqScan(const SeqScan *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copySampleScan
|
||||
*/
|
||||
static SampleScan *
|
||||
_copySampleScan(const SampleScan *from)
|
||||
{
|
||||
SampleScan *newnode = makeNode(SampleScan);
|
||||
|
||||
/*
|
||||
* copy node superclass fields
|
||||
*/
|
||||
CopyScanFields((const Scan *) from, (Scan *) newnode);
|
||||
|
||||
/*
|
||||
* copy remainder of node
|
||||
*/
|
||||
COPY_NODE_FIELD(tablesample);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copyIndexScan
|
||||
*/
|
||||
@ -641,22 +662,6 @@ _copyCustomScan(const CustomScan *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* _copySampleScan
|
||||
*/
|
||||
static SampleScan *
|
||||
_copySampleScan(const SampleScan *from)
|
||||
{
|
||||
SampleScan *newnode = makeNode(SampleScan);
|
||||
|
||||
/*
|
||||
* copy node superclass fields
|
||||
*/
|
||||
CopyScanFields((const Scan *) from, (Scan *) newnode);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* CopyJoinFields
|
||||
*
|
||||
@ -2143,6 +2148,18 @@ _copyRangeTblFunction(const RangeTblFunction *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static TableSampleClause *
|
||||
_copyTableSampleClause(const TableSampleClause *from)
|
||||
{
|
||||
TableSampleClause *newnode = makeNode(TableSampleClause);
|
||||
|
||||
COPY_SCALAR_FIELD(tsmhandler);
|
||||
COPY_NODE_FIELD(args);
|
||||
COPY_NODE_FIELD(repeatable);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static WithCheckOption *
|
||||
_copyWithCheckOption(const WithCheckOption *from)
|
||||
{
|
||||
@ -2271,40 +2288,6 @@ _copyCommonTableExpr(const CommonTableExpr *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static RangeTableSample *
|
||||
_copyRangeTableSample(const RangeTableSample *from)
|
||||
{
|
||||
RangeTableSample *newnode = makeNode(RangeTableSample);
|
||||
|
||||
COPY_NODE_FIELD(relation);
|
||||
COPY_STRING_FIELD(method);
|
||||
COPY_NODE_FIELD(repeatable);
|
||||
COPY_NODE_FIELD(args);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static TableSampleClause *
|
||||
_copyTableSampleClause(const TableSampleClause *from)
|
||||
{
|
||||
TableSampleClause *newnode = makeNode(TableSampleClause);
|
||||
|
||||
COPY_SCALAR_FIELD(tsmid);
|
||||
COPY_SCALAR_FIELD(tsmseqscan);
|
||||
COPY_SCALAR_FIELD(tsmpagemode);
|
||||
COPY_SCALAR_FIELD(tsminit);
|
||||
COPY_SCALAR_FIELD(tsmnextblock);
|
||||
COPY_SCALAR_FIELD(tsmnexttuple);
|
||||
COPY_SCALAR_FIELD(tsmexaminetuple);
|
||||
COPY_SCALAR_FIELD(tsmend);
|
||||
COPY_SCALAR_FIELD(tsmreset);
|
||||
COPY_SCALAR_FIELD(tsmcost);
|
||||
COPY_NODE_FIELD(repeatable);
|
||||
COPY_NODE_FIELD(args);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static A_Expr *
|
||||
_copyAExpr(const A_Expr *from)
|
||||
{
|
||||
@ -2532,6 +2515,20 @@ _copyRangeFunction(const RangeFunction *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static RangeTableSample *
|
||||
_copyRangeTableSample(const RangeTableSample *from)
|
||||
{
|
||||
RangeTableSample *newnode = makeNode(RangeTableSample);
|
||||
|
||||
COPY_NODE_FIELD(relation);
|
||||
COPY_NODE_FIELD(method);
|
||||
COPY_NODE_FIELD(args);
|
||||
COPY_NODE_FIELD(repeatable);
|
||||
COPY_LOCATION_FIELD(location);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static TypeCast *
|
||||
_copyTypeCast(const TypeCast *from)
|
||||
{
|
||||
@ -4237,6 +4234,9 @@ copyObject(const void *from)
|
||||
case T_SeqScan:
|
||||
retval = _copySeqScan(from);
|
||||
break;
|
||||
case T_SampleScan:
|
||||
retval = _copySampleScan(from);
|
||||
break;
|
||||
case T_IndexScan:
|
||||
retval = _copyIndexScan(from);
|
||||
break;
|
||||
@ -4273,9 +4273,6 @@ copyObject(const void *from)
|
||||
case T_CustomScan:
|
||||
retval = _copyCustomScan(from);
|
||||
break;
|
||||
case T_SampleScan:
|
||||
retval = _copySampleScan(from);
|
||||
break;
|
||||
case T_Join:
|
||||
retval = _copyJoin(from);
|
||||
break;
|
||||
@ -4897,6 +4894,9 @@ copyObject(const void *from)
|
||||
case T_RangeFunction:
|
||||
retval = _copyRangeFunction(from);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
retval = _copyRangeTableSample(from);
|
||||
break;
|
||||
case T_TypeName:
|
||||
retval = _copyTypeName(from);
|
||||
break;
|
||||
@ -4921,6 +4921,9 @@ copyObject(const void *from)
|
||||
case T_RangeTblFunction:
|
||||
retval = _copyRangeTblFunction(from);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
retval = _copyTableSampleClause(from);
|
||||
break;
|
||||
case T_WithCheckOption:
|
||||
retval = _copyWithCheckOption(from);
|
||||
break;
|
||||
@ -4948,12 +4951,6 @@ copyObject(const void *from)
|
||||
case T_CommonTableExpr:
|
||||
retval = _copyCommonTableExpr(from);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
retval = _copyRangeTableSample(from);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
retval = _copyTableSampleClause(from);
|
||||
break;
|
||||
case T_FuncWithArgs:
|
||||
retval = _copyFuncWithArgs(from);
|
||||
break;
|
||||
|
@ -2290,6 +2290,18 @@ _equalRangeFunction(const RangeFunction *a, const RangeFunction *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalRangeTableSample(const RangeTableSample *a, const RangeTableSample *b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(relation);
|
||||
COMPARE_NODE_FIELD(method);
|
||||
COMPARE_NODE_FIELD(args);
|
||||
COMPARE_NODE_FIELD(repeatable);
|
||||
COMPARE_LOCATION_FIELD(location);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalIndexElem(const IndexElem *a, const IndexElem *b)
|
||||
{
|
||||
@ -2428,6 +2440,16 @@ _equalRangeTblFunction(const RangeTblFunction *a, const RangeTblFunction *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalTableSampleClause(const TableSampleClause *a, const TableSampleClause *b)
|
||||
{
|
||||
COMPARE_SCALAR_FIELD(tsmhandler);
|
||||
COMPARE_NODE_FIELD(args);
|
||||
COMPARE_NODE_FIELD(repeatable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalWithCheckOption(const WithCheckOption *a, const WithCheckOption *b)
|
||||
{
|
||||
@ -2538,36 +2560,6 @@ _equalCommonTableExpr(const CommonTableExpr *a, const CommonTableExpr *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalRangeTableSample(const RangeTableSample *a, const RangeTableSample *b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(relation);
|
||||
COMPARE_STRING_FIELD(method);
|
||||
COMPARE_NODE_FIELD(repeatable);
|
||||
COMPARE_NODE_FIELD(args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalTableSampleClause(const TableSampleClause *a, const TableSampleClause *b)
|
||||
{
|
||||
COMPARE_SCALAR_FIELD(tsmid);
|
||||
COMPARE_SCALAR_FIELD(tsmseqscan);
|
||||
COMPARE_SCALAR_FIELD(tsmpagemode);
|
||||
COMPARE_SCALAR_FIELD(tsminit);
|
||||
COMPARE_SCALAR_FIELD(tsmnextblock);
|
||||
COMPARE_SCALAR_FIELD(tsmnexttuple);
|
||||
COMPARE_SCALAR_FIELD(tsmexaminetuple);
|
||||
COMPARE_SCALAR_FIELD(tsmend);
|
||||
COMPARE_SCALAR_FIELD(tsmreset);
|
||||
COMPARE_SCALAR_FIELD(tsmcost);
|
||||
COMPARE_NODE_FIELD(repeatable);
|
||||
COMPARE_NODE_FIELD(args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalXmlSerialize(const XmlSerialize *a, const XmlSerialize *b)
|
||||
{
|
||||
@ -3260,6 +3252,9 @@ equal(const void *a, const void *b)
|
||||
case T_RangeFunction:
|
||||
retval = _equalRangeFunction(a, b);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
retval = _equalRangeTableSample(a, b);
|
||||
break;
|
||||
case T_TypeName:
|
||||
retval = _equalTypeName(a, b);
|
||||
break;
|
||||
@ -3284,6 +3279,9 @@ equal(const void *a, const void *b)
|
||||
case T_RangeTblFunction:
|
||||
retval = _equalRangeTblFunction(a, b);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
retval = _equalTableSampleClause(a, b);
|
||||
break;
|
||||
case T_WithCheckOption:
|
||||
retval = _equalWithCheckOption(a, b);
|
||||
break;
|
||||
@ -3311,12 +3309,6 @@ equal(const void *a, const void *b)
|
||||
case T_CommonTableExpr:
|
||||
retval = _equalCommonTableExpr(a, b);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
retval = _equalRangeTableSample(a, b);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
retval = _equalTableSampleClause(a, b);
|
||||
break;
|
||||
case T_FuncWithArgs:
|
||||
retval = _equalFuncWithArgs(a, b);
|
||||
break;
|
||||
|
@ -1486,6 +1486,9 @@ exprLocation(const Node *expr)
|
||||
case T_WindowDef:
|
||||
loc = ((const WindowDef *) expr)->location;
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
loc = ((const RangeTableSample *) expr)->location;
|
||||
break;
|
||||
case T_TypeName:
|
||||
loc = ((const TypeName *) expr)->location;
|
||||
break;
|
||||
@ -1995,6 +1998,17 @@ expression_tree_walker(Node *node,
|
||||
return walker(((PlaceHolderInfo *) node)->ph_var, context);
|
||||
case T_RangeTblFunction:
|
||||
return walker(((RangeTblFunction *) node)->funcexpr, context);
|
||||
case T_TableSampleClause:
|
||||
{
|
||||
TableSampleClause *tsc = (TableSampleClause *) node;
|
||||
|
||||
if (expression_tree_walker((Node *) tsc->args,
|
||||
walker, context))
|
||||
return true;
|
||||
if (walker((Node *) tsc->repeatable, context))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized node type: %d",
|
||||
(int) nodeTag(node));
|
||||
@ -2082,13 +2096,8 @@ range_table_walker(List *rtable,
|
||||
switch (rte->rtekind)
|
||||
{
|
||||
case RTE_RELATION:
|
||||
if (rte->tablesample)
|
||||
{
|
||||
if (walker(rte->tablesample->args, context))
|
||||
return true;
|
||||
if (walker(rte->tablesample->repeatable, context))
|
||||
return true;
|
||||
}
|
||||
if (walker(rte->tablesample, context))
|
||||
return true;
|
||||
break;
|
||||
case RTE_CTE:
|
||||
/* nothing to do */
|
||||
@ -2782,6 +2791,17 @@ expression_tree_mutator(Node *node,
|
||||
return (Node *) newnode;
|
||||
}
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
{
|
||||
TableSampleClause *tsc = (TableSampleClause *) node;
|
||||
TableSampleClause *newnode;
|
||||
|
||||
FLATCOPY(newnode, tsc, TableSampleClause);
|
||||
MUTATE(newnode->args, tsc->args, List *);
|
||||
MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
|
||||
return (Node *) newnode;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized node type: %d",
|
||||
(int) nodeTag(node));
|
||||
@ -2868,20 +2888,12 @@ range_table_mutator(List *rtable,
|
||||
switch (rte->rtekind)
|
||||
{
|
||||
case RTE_RELATION:
|
||||
if (rte->tablesample)
|
||||
{
|
||||
CHECKFLATCOPY(newrte->tablesample, rte->tablesample,
|
||||
TableSampleClause);
|
||||
MUTATE(newrte->tablesample->args,
|
||||
newrte->tablesample->args,
|
||||
List *);
|
||||
MUTATE(newrte->tablesample->repeatable,
|
||||
newrte->tablesample->repeatable,
|
||||
Node *);
|
||||
}
|
||||
MUTATE(newrte->tablesample, rte->tablesample,
|
||||
TableSampleClause *);
|
||||
/* we don't bother to copy eref, aliases, etc; OK? */
|
||||
break;
|
||||
case RTE_CTE:
|
||||
/* we don't bother to copy eref, aliases, etc; OK? */
|
||||
/* nothing to do */
|
||||
break;
|
||||
case RTE_SUBQUERY:
|
||||
if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
|
||||
@ -3316,6 +3328,19 @@ raw_expression_tree_walker(Node *node,
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
{
|
||||
RangeTableSample *rts = (RangeTableSample *) node;
|
||||
|
||||
if (walker(rts->relation, context))
|
||||
return true;
|
||||
/* method name is deemed uninteresting */
|
||||
if (walker(rts->args, context))
|
||||
return true;
|
||||
if (walker(rts->repeatable, context))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case T_TypeName:
|
||||
{
|
||||
TypeName *tn = (TypeName *) node;
|
||||
@ -3380,18 +3405,6 @@ raw_expression_tree_walker(Node *node,
|
||||
break;
|
||||
case T_CommonTableExpr:
|
||||
return walker(((CommonTableExpr *) node)->ctequery, context);
|
||||
case T_RangeTableSample:
|
||||
{
|
||||
RangeTableSample *rts = (RangeTableSample *) node;
|
||||
|
||||
if (walker(rts->relation, context))
|
||||
return true;
|
||||
if (walker(rts->repeatable, context))
|
||||
return true;
|
||||
if (walker(rts->args, context))
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized node type: %d",
|
||||
(int) nodeTag(node));
|
||||
|
@ -444,6 +444,16 @@ _outSeqScan(StringInfo str, const SeqScan *node)
|
||||
_outScanInfo(str, (const Scan *) node);
|
||||
}
|
||||
|
||||
static void
|
||||
_outSampleScan(StringInfo str, const SampleScan *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("SAMPLESCAN");
|
||||
|
||||
_outScanInfo(str, (const Scan *) node);
|
||||
|
||||
WRITE_NODE_FIELD(tablesample);
|
||||
}
|
||||
|
||||
static void
|
||||
_outIndexScan(StringInfo str, const IndexScan *node)
|
||||
{
|
||||
@ -591,14 +601,6 @@ _outCustomScan(StringInfo str, const CustomScan *node)
|
||||
node->methods->TextOutCustomScan(str, node);
|
||||
}
|
||||
|
||||
static void
|
||||
_outSampleScan(StringInfo str, const SampleScan *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("SAMPLESCAN");
|
||||
|
||||
_outScanInfo(str, (const Scan *) node);
|
||||
}
|
||||
|
||||
static void
|
||||
_outJoin(StringInfo str, const Join *node)
|
||||
{
|
||||
@ -2478,36 +2480,6 @@ _outCommonTableExpr(StringInfo str, const CommonTableExpr *node)
|
||||
WRITE_NODE_FIELD(ctecolcollations);
|
||||
}
|
||||
|
||||
static void
|
||||
_outRangeTableSample(StringInfo str, const RangeTableSample *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("RANGETABLESAMPLE");
|
||||
|
||||
WRITE_NODE_FIELD(relation);
|
||||
WRITE_STRING_FIELD(method);
|
||||
WRITE_NODE_FIELD(repeatable);
|
||||
WRITE_NODE_FIELD(args);
|
||||
}
|
||||
|
||||
static void
|
||||
_outTableSampleClause(StringInfo str, const TableSampleClause *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("TABLESAMPLECLAUSE");
|
||||
|
||||
WRITE_OID_FIELD(tsmid);
|
||||
WRITE_BOOL_FIELD(tsmseqscan);
|
||||
WRITE_BOOL_FIELD(tsmpagemode);
|
||||
WRITE_OID_FIELD(tsminit);
|
||||
WRITE_OID_FIELD(tsmnextblock);
|
||||
WRITE_OID_FIELD(tsmnexttuple);
|
||||
WRITE_OID_FIELD(tsmexaminetuple);
|
||||
WRITE_OID_FIELD(tsmend);
|
||||
WRITE_OID_FIELD(tsmreset);
|
||||
WRITE_OID_FIELD(tsmcost);
|
||||
WRITE_NODE_FIELD(repeatable);
|
||||
WRITE_NODE_FIELD(args);
|
||||
}
|
||||
|
||||
static void
|
||||
_outSetOperationStmt(StringInfo str, const SetOperationStmt *node)
|
||||
{
|
||||
@ -2594,6 +2566,16 @@ _outRangeTblFunction(StringInfo str, const RangeTblFunction *node)
|
||||
WRITE_BITMAPSET_FIELD(funcparams);
|
||||
}
|
||||
|
||||
static void
|
||||
_outTableSampleClause(StringInfo str, const TableSampleClause *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("TABLESAMPLECLAUSE");
|
||||
|
||||
WRITE_OID_FIELD(tsmhandler);
|
||||
WRITE_NODE_FIELD(args);
|
||||
WRITE_NODE_FIELD(repeatable);
|
||||
}
|
||||
|
||||
static void
|
||||
_outAExpr(StringInfo str, const A_Expr *node)
|
||||
{
|
||||
@ -2845,6 +2827,18 @@ _outRangeFunction(StringInfo str, const RangeFunction *node)
|
||||
WRITE_NODE_FIELD(coldeflist);
|
||||
}
|
||||
|
||||
static void
|
||||
_outRangeTableSample(StringInfo str, const RangeTableSample *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("RANGETABLESAMPLE");
|
||||
|
||||
WRITE_NODE_FIELD(relation);
|
||||
WRITE_NODE_FIELD(method);
|
||||
WRITE_NODE_FIELD(args);
|
||||
WRITE_NODE_FIELD(repeatable);
|
||||
WRITE_LOCATION_FIELD(location);
|
||||
}
|
||||
|
||||
static void
|
||||
_outConstraint(StringInfo str, const Constraint *node)
|
||||
{
|
||||
@ -3002,6 +2996,9 @@ _outNode(StringInfo str, const void *obj)
|
||||
case T_SeqScan:
|
||||
_outSeqScan(str, obj);
|
||||
break;
|
||||
case T_SampleScan:
|
||||
_outSampleScan(str, obj);
|
||||
break;
|
||||
case T_IndexScan:
|
||||
_outIndexScan(str, obj);
|
||||
break;
|
||||
@ -3038,9 +3035,6 @@ _outNode(StringInfo str, const void *obj)
|
||||
case T_CustomScan:
|
||||
_outCustomScan(str, obj);
|
||||
break;
|
||||
case T_SampleScan:
|
||||
_outSampleScan(str, obj);
|
||||
break;
|
||||
case T_Join:
|
||||
_outJoin(str, obj);
|
||||
break;
|
||||
@ -3393,12 +3387,6 @@ _outNode(StringInfo str, const void *obj)
|
||||
case T_CommonTableExpr:
|
||||
_outCommonTableExpr(str, obj);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
_outRangeTableSample(str, obj);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
_outTableSampleClause(str, obj);
|
||||
break;
|
||||
case T_SetOperationStmt:
|
||||
_outSetOperationStmt(str, obj);
|
||||
break;
|
||||
@ -3408,6 +3396,9 @@ _outNode(StringInfo str, const void *obj)
|
||||
case T_RangeTblFunction:
|
||||
_outRangeTblFunction(str, obj);
|
||||
break;
|
||||
case T_TableSampleClause:
|
||||
_outTableSampleClause(str, obj);
|
||||
break;
|
||||
case T_A_Expr:
|
||||
_outAExpr(str, obj);
|
||||
break;
|
||||
@ -3450,6 +3441,9 @@ _outNode(StringInfo str, const void *obj)
|
||||
case T_RangeFunction:
|
||||
_outRangeFunction(str, obj);
|
||||
break;
|
||||
case T_RangeTableSample:
|
||||
_outRangeTableSample(str, obj);
|
||||
break;
|
||||
case T_Constraint:
|
||||
_outConstraint(str, obj);
|
||||
break;
|
||||
|
@ -367,46 +367,6 @@ _readCommonTableExpr(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readRangeTableSample
|
||||
*/
|
||||
static RangeTableSample *
|
||||
_readRangeTableSample(void)
|
||||
{
|
||||
READ_LOCALS(RangeTableSample);
|
||||
|
||||
READ_NODE_FIELD(relation);
|
||||
READ_STRING_FIELD(method);
|
||||
READ_NODE_FIELD(repeatable);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readTableSampleClause
|
||||
*/
|
||||
static TableSampleClause *
|
||||
_readTableSampleClause(void)
|
||||
{
|
||||
READ_LOCALS(TableSampleClause);
|
||||
|
||||
READ_OID_FIELD(tsmid);
|
||||
READ_BOOL_FIELD(tsmseqscan);
|
||||
READ_BOOL_FIELD(tsmpagemode);
|
||||
READ_OID_FIELD(tsminit);
|
||||
READ_OID_FIELD(tsmnextblock);
|
||||
READ_OID_FIELD(tsmnexttuple);
|
||||
READ_OID_FIELD(tsmexaminetuple);
|
||||
READ_OID_FIELD(tsmend);
|
||||
READ_OID_FIELD(tsmreset);
|
||||
READ_OID_FIELD(tsmcost);
|
||||
READ_NODE_FIELD(repeatable);
|
||||
READ_NODE_FIELD(args);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readSetOperationStmt
|
||||
*/
|
||||
@ -1391,6 +1351,21 @@ _readRangeTblFunction(void)
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
/*
|
||||
* _readTableSampleClause
|
||||
*/
|
||||
static TableSampleClause *
|
||||
_readTableSampleClause(void)
|
||||
{
|
||||
READ_LOCALS(TableSampleClause);
|
||||
|
||||
READ_OID_FIELD(tsmhandler);
|
||||
READ_NODE_FIELD(args);
|
||||
READ_NODE_FIELD(repeatable);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* parseNodeString
|
||||
@ -1426,10 +1401,6 @@ parseNodeString(void)
|
||||
return_value = _readRowMarkClause();
|
||||
else if (MATCH("COMMONTABLEEXPR", 15))
|
||||
return_value = _readCommonTableExpr();
|
||||
else if (MATCH("RANGETABLESAMPLE", 16))
|
||||
return_value = _readRangeTableSample();
|
||||
else if (MATCH("TABLESAMPLECLAUSE", 17))
|
||||
return_value = _readTableSampleClause();
|
||||
else if (MATCH("SETOPERATIONSTMT", 16))
|
||||
return_value = _readSetOperationStmt();
|
||||
else if (MATCH("ALIAS", 5))
|
||||
@ -1528,6 +1499,8 @@ parseNodeString(void)
|
||||
return_value = _readRangeTblEntry();
|
||||
else if (MATCH("RANGETBLFUNCTION", 16))
|
||||
return_value = _readRangeTblFunction();
|
||||
else if (MATCH("TABLESAMPLECLAUSE", 17))
|
||||
return_value = _readTableSampleClause();
|
||||
else if (MATCH("NOTIFY", 6))
|
||||
return_value = _readNotifyStmt();
|
||||
else if (MATCH("DECLARECURSOR", 13))
|
||||
|
Reference in New Issue
Block a user