mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
Code review for NextValueExpr expression node type.
Add missing infrastructure for this node type, notably in ruleutils.c where its lack could demonstrably cause EXPLAIN to fail. Add outfuncs/readfuncs support. (outfuncs support is useful today for debugging purposes. The readfuncs support may never be needed, since at present it would only matter for parallel query and NextValueExpr should never appear in a parallelizable query; but it seems like a bad idea to have a primnode type that isn't fully supported here.) Teach planner infrastructure that NextValueExpr is a volatile, parallel-unsafe, non-leaky expression node with cost cpu_operator_cost. Given its limited scope of usage, there *might* be no live bug today from the lack of that knowledge, but it's certainly going to bite us on the rear someday. Teach pg_stat_statements about the new node type, too. While at it, also teach cost_qual_eval() that MinMaxExpr, SQLValueFunction, XmlExpr, and CoerceToDomain should be charged as cpu_operator_cost. Failing to do this for SQLValueFunction was an oversight in my commit 0bb51aa96. The others are longer-standing oversights, but no time like the present to fix them. (In principle, CoerceToDomain could have cost much higher than this, but it doesn't presently seem worth trying to examine the domain's constraints here.) Modify execExprInterp.c to execute NextValueExpr as an out-of-line function; it seems quite unlikely to me that it's worth insisting that it be inlined in all expression eval methods. Besides, providing the out-of-line function doesn't stop anyone from inlining if they want to. Adjust some places where NextValueExpr support had been inserted with the aid of a dartboard rather than keeping it in the same order as elsewhere. Discussion: https://postgr.es/m/23862.1499981661@sss.pgh.pa.us
This commit is contained in:
parent
c95275fc20
commit
decb08ebdf
@ -2763,6 +2763,14 @@ JumbleExpr(pgssJumbleState *jstate, Node *node)
|
|||||||
APP_JUMB(ce->cursor_param);
|
APP_JUMB(ce->cursor_param);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case T_NextValueExpr:
|
||||||
|
{
|
||||||
|
NextValueExpr *nve = (NextValueExpr *) node;
|
||||||
|
|
||||||
|
APP_JUMB(nve->seqid);
|
||||||
|
APP_JUMB(nve->typeId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case T_InferenceElem:
|
case T_InferenceElem:
|
||||||
{
|
{
|
||||||
InferenceElem *ie = (InferenceElem *) node;
|
InferenceElem *ie = (InferenceElem *) node;
|
||||||
|
@ -1791,6 +1791,13 @@ find_expr_references_walker(Node *node,
|
|||||||
add_object_address(OCLASS_TYPE, cd->resulttype, 0,
|
add_object_address(OCLASS_TYPE, cd->resulttype, 0,
|
||||||
context->addrs);
|
context->addrs);
|
||||||
}
|
}
|
||||||
|
else if (IsA(node, NextValueExpr))
|
||||||
|
{
|
||||||
|
NextValueExpr *nve = (NextValueExpr *) node;
|
||||||
|
|
||||||
|
add_object_address(OCLASS_CLASS, nve->seqid, 0,
|
||||||
|
context->addrs);
|
||||||
|
}
|
||||||
else if (IsA(node, OnConflictExpr))
|
else if (IsA(node, OnConflictExpr))
|
||||||
{
|
{
|
||||||
OnConflictExpr *onconflict = (OnConflictExpr *) node;
|
OnConflictExpr *onconflict = (OnConflictExpr *) node;
|
||||||
@ -1942,13 +1949,6 @@ find_expr_references_walker(Node *node,
|
|||||||
context->addrs);
|
context->addrs);
|
||||||
/* fall through to examine arguments */
|
/* fall through to examine arguments */
|
||||||
}
|
}
|
||||||
else if (IsA(node, NextValueExpr))
|
|
||||||
{
|
|
||||||
NextValueExpr *nve = (NextValueExpr *) node;
|
|
||||||
|
|
||||||
add_object_address(OCLASS_CLASS, nve->seqid, 0,
|
|
||||||
context->addrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return expression_tree_walker(node, find_expr_references_walker,
|
return expression_tree_walker(node, find_expr_references_walker,
|
||||||
(void *) context);
|
(void *) context);
|
||||||
|
@ -1232,21 +1232,11 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
|
|||||||
|
|
||||||
EEO_CASE(EEOP_NEXTVALUEEXPR)
|
EEO_CASE(EEOP_NEXTVALUEEXPR)
|
||||||
{
|
{
|
||||||
switch (op->d.nextvalueexpr.seqtypid)
|
/*
|
||||||
{
|
* Doesn't seem worthwhile to have an inline implementation
|
||||||
case INT2OID:
|
* efficiency-wise.
|
||||||
*op->resvalue = Int16GetDatum((int16) nextval_internal(op->d.nextvalueexpr.seqid, false));
|
*/
|
||||||
break;
|
ExecEvalNextValueExpr(state, op);
|
||||||
case INT4OID:
|
|
||||||
*op->resvalue = Int32GetDatum((int32) nextval_internal(op->d.nextvalueexpr.seqid, false));
|
|
||||||
break;
|
|
||||||
case INT8OID:
|
|
||||||
*op->resvalue = Int64GetDatum((int64) nextval_internal(op->d.nextvalueexpr.seqid, false));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "unsupported sequence type %u", op->d.nextvalueexpr.seqtypid);
|
|
||||||
}
|
|
||||||
*op->resnull = false;
|
|
||||||
|
|
||||||
EEO_NEXT();
|
EEO_NEXT();
|
||||||
}
|
}
|
||||||
@ -1989,6 +1979,32 @@ ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op)
|
|||||||
errmsg("WHERE CURRENT OF is not supported for this table type")));
|
errmsg("WHERE CURRENT OF is not supported for this table type")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluate NextValueExpr.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op)
|
||||||
|
{
|
||||||
|
int64 newval = nextval_internal(op->d.nextvalueexpr.seqid, false);
|
||||||
|
|
||||||
|
switch (op->d.nextvalueexpr.seqtypid)
|
||||||
|
{
|
||||||
|
case INT2OID:
|
||||||
|
*op->resvalue = Int16GetDatum((int16) newval);
|
||||||
|
break;
|
||||||
|
case INT4OID:
|
||||||
|
*op->resvalue = Int32GetDatum((int32) newval);
|
||||||
|
break;
|
||||||
|
case INT8OID:
|
||||||
|
*op->resvalue = Int64GetDatum((int64) newval);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unsupported sequence type %u",
|
||||||
|
op->d.nextvalueexpr.seqtypid);
|
||||||
|
}
|
||||||
|
*op->resnull = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evaluate NullTest / IS NULL for rows.
|
* Evaluate NullTest / IS NULL for rows.
|
||||||
*/
|
*/
|
||||||
|
@ -1642,10 +1642,10 @@ set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
|
|||||||
* for themselves, in case additional checks should be made, or because they
|
* for themselves, in case additional checks should be made, or because they
|
||||||
* have special rules about which parts of the tree need to be visited.
|
* have special rules about which parts of the tree need to be visited.
|
||||||
*
|
*
|
||||||
* Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, and CoerceToDomain
|
* Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
|
||||||
* nodes, because they do not contain SQL function OIDs. However, they can
|
* and NextValueExpr nodes, because they do not contain SQL function OIDs.
|
||||||
* invoke SQL-visible functions, so callers should take thought about how to
|
* However, they can invoke SQL-visible functions, so callers should take
|
||||||
* treat them.
|
* thought about how to treat them.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
check_functions_in_node(Node *node, check_function_callback checker,
|
check_functions_in_node(Node *node, check_function_callback checker,
|
||||||
@ -1865,12 +1865,12 @@ expression_tree_walker(Node *node,
|
|||||||
case T_Var:
|
case T_Var:
|
||||||
case T_Const:
|
case T_Const:
|
||||||
case T_Param:
|
case T_Param:
|
||||||
case T_CoerceToDomainValue:
|
|
||||||
case T_CaseTestExpr:
|
case T_CaseTestExpr:
|
||||||
|
case T_SQLValueFunction:
|
||||||
|
case T_CoerceToDomainValue:
|
||||||
case T_SetToDefault:
|
case T_SetToDefault:
|
||||||
case T_CurrentOfExpr:
|
case T_CurrentOfExpr:
|
||||||
case T_NextValueExpr:
|
case T_NextValueExpr:
|
||||||
case T_SQLValueFunction:
|
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
case T_SortGroupClause:
|
case T_SortGroupClause:
|
||||||
/* primitive node types with no expression subnodes */
|
/* primitive node types with no expression subnodes */
|
||||||
@ -2461,12 +2461,12 @@ expression_tree_mutator(Node *node,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_Param:
|
case T_Param:
|
||||||
case T_CoerceToDomainValue:
|
|
||||||
case T_CaseTestExpr:
|
case T_CaseTestExpr:
|
||||||
|
case T_SQLValueFunction:
|
||||||
|
case T_CoerceToDomainValue:
|
||||||
case T_SetToDefault:
|
case T_SetToDefault:
|
||||||
case T_CurrentOfExpr:
|
case T_CurrentOfExpr:
|
||||||
case T_NextValueExpr:
|
case T_NextValueExpr:
|
||||||
case T_SQLValueFunction:
|
|
||||||
case T_RangeTblRef:
|
case T_RangeTblRef:
|
||||||
case T_SortGroupClause:
|
case T_SortGroupClause:
|
||||||
return (Node *) copyObject(node);
|
return (Node *) copyObject(node);
|
||||||
|
@ -1610,6 +1610,15 @@ _outCurrentOfExpr(StringInfo str, const CurrentOfExpr *node)
|
|||||||
WRITE_INT_FIELD(cursor_param);
|
WRITE_INT_FIELD(cursor_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outNextValueExpr(StringInfo str, const NextValueExpr *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("NEXTVALUEEXPR");
|
||||||
|
|
||||||
|
WRITE_OID_FIELD(seqid);
|
||||||
|
WRITE_OID_FIELD(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outInferenceElem(StringInfo str, const InferenceElem *node)
|
_outInferenceElem(StringInfo str, const InferenceElem *node)
|
||||||
{
|
{
|
||||||
@ -3872,6 +3881,9 @@ outNode(StringInfo str, const void *obj)
|
|||||||
case T_CurrentOfExpr:
|
case T_CurrentOfExpr:
|
||||||
_outCurrentOfExpr(str, obj);
|
_outCurrentOfExpr(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_NextValueExpr:
|
||||||
|
_outNextValueExpr(str, obj);
|
||||||
|
break;
|
||||||
case T_InferenceElem:
|
case T_InferenceElem:
|
||||||
_outInferenceElem(str, obj);
|
_outInferenceElem(str, obj);
|
||||||
break;
|
break;
|
||||||
|
@ -1202,6 +1202,20 @@ _readCurrentOfExpr(void)
|
|||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _readNextValueExpr
|
||||||
|
*/
|
||||||
|
static NextValueExpr *
|
||||||
|
_readNextValueExpr(void)
|
||||||
|
{
|
||||||
|
READ_LOCALS(NextValueExpr);
|
||||||
|
|
||||||
|
READ_OID_FIELD(seqid);
|
||||||
|
READ_OID_FIELD(typeId);
|
||||||
|
|
||||||
|
READ_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _readInferenceElem
|
* _readInferenceElem
|
||||||
*/
|
*/
|
||||||
@ -2517,6 +2531,8 @@ parseNodeString(void)
|
|||||||
return_value = _readSetToDefault();
|
return_value = _readSetToDefault();
|
||||||
else if (MATCH("CURRENTOFEXPR", 13))
|
else if (MATCH("CURRENTOFEXPR", 13))
|
||||||
return_value = _readCurrentOfExpr();
|
return_value = _readCurrentOfExpr();
|
||||||
|
else if (MATCH("NEXTVALUEEXPR", 13))
|
||||||
|
return_value = _readNextValueExpr();
|
||||||
else if (MATCH("INFERENCEELEM", 13))
|
else if (MATCH("INFERENCEELEM", 13))
|
||||||
return_value = _readInferenceElem();
|
return_value = _readInferenceElem();
|
||||||
else if (MATCH("TARGETENTRY", 11))
|
else if (MATCH("TARGETENTRY", 11))
|
||||||
|
@ -3627,6 +3627,15 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
|
|||||||
cpu_operator_cost;
|
cpu_operator_cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (IsA(node, MinMaxExpr) ||
|
||||||
|
IsA(node, SQLValueFunction) ||
|
||||||
|
IsA(node, XmlExpr) ||
|
||||||
|
IsA(node, CoerceToDomain) ||
|
||||||
|
IsA(node, NextValueExpr))
|
||||||
|
{
|
||||||
|
/* Treat all these as having cost 1 */
|
||||||
|
context->total.per_tuple += cpu_operator_cost;
|
||||||
|
}
|
||||||
else if (IsA(node, CurrentOfExpr))
|
else if (IsA(node, CurrentOfExpr))
|
||||||
{
|
{
|
||||||
/* Report high cost to prevent selection of anything but TID scan */
|
/* Report high cost to prevent selection of anything but TID scan */
|
||||||
|
@ -902,6 +902,12 @@ contain_mutable_functions_walker(Node *node, void *context)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsA(node, NextValueExpr))
|
||||||
|
{
|
||||||
|
/* NextValueExpr is volatile */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It should be safe to treat MinMaxExpr as immutable, because it will
|
* It should be safe to treat MinMaxExpr as immutable, because it will
|
||||||
* depend on a non-cross-type btree comparison function, and those should
|
* depend on a non-cross-type btree comparison function, and those should
|
||||||
@ -969,6 +975,12 @@ contain_volatile_functions_walker(Node *node, void *context)
|
|||||||
context))
|
context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (IsA(node, NextValueExpr))
|
||||||
|
{
|
||||||
|
/* NextValueExpr is volatile */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See notes in contain_mutable_functions_walker about why we treat
|
* See notes in contain_mutable_functions_walker about why we treat
|
||||||
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
|
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
|
||||||
@ -1019,6 +1031,8 @@ contain_volatile_functions_not_nextval_walker(Node *node, void *context)
|
|||||||
* See notes in contain_mutable_functions_walker about why we treat
|
* See notes in contain_mutable_functions_walker about why we treat
|
||||||
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
|
* MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while
|
||||||
* SQLValueFunction is stable. Hence, none of them are of interest here.
|
* SQLValueFunction is stable. Hence, none of them are of interest here.
|
||||||
|
* Also, since we're intentionally ignoring nextval(), presumably we
|
||||||
|
* should ignore NextValueExpr.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Recurse to check arguments */
|
/* Recurse to check arguments */
|
||||||
@ -1146,7 +1160,7 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
|
|||||||
* contain a parallel-unsafe function; but useful constraints probably
|
* contain a parallel-unsafe function; but useful constraints probably
|
||||||
* never would have such, and assuming they do would cripple use of
|
* never would have such, and assuming they do would cripple use of
|
||||||
* parallel query in the presence of domain types.) SQLValueFunction
|
* parallel query in the presence of domain types.) SQLValueFunction
|
||||||
* should be safe in all cases.
|
* should be safe in all cases. NextValueExpr is parallel-unsafe.
|
||||||
*/
|
*/
|
||||||
if (IsA(node, CoerceToDomain))
|
if (IsA(node, CoerceToDomain))
|
||||||
{
|
{
|
||||||
@ -1154,6 +1168,12 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsA(node, NextValueExpr))
|
||||||
|
{
|
||||||
|
if (max_parallel_hazard_test(PROPARALLEL_UNSAFE, context))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As a notational convenience for callers, look through RestrictInfo.
|
* As a notational convenience for callers, look through RestrictInfo.
|
||||||
*/
|
*/
|
||||||
@ -1495,6 +1515,7 @@ contain_leaked_vars_walker(Node *node, void *context)
|
|||||||
case T_SQLValueFunction:
|
case T_SQLValueFunction:
|
||||||
case T_NullTest:
|
case T_NullTest:
|
||||||
case T_BooleanTest:
|
case T_BooleanTest:
|
||||||
|
case T_NextValueExpr:
|
||||||
case T_List:
|
case T_List:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7283,6 +7283,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
|
|||||||
case T_MinMaxExpr:
|
case T_MinMaxExpr:
|
||||||
case T_SQLValueFunction:
|
case T_SQLValueFunction:
|
||||||
case T_XmlExpr:
|
case T_XmlExpr:
|
||||||
|
case T_NextValueExpr:
|
||||||
case T_NullIfExpr:
|
case T_NullIfExpr:
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
case T_WindowFunc:
|
case T_WindowFunc:
|
||||||
@ -8612,6 +8613,22 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_NextValueExpr:
|
||||||
|
{
|
||||||
|
NextValueExpr *nvexpr = (NextValueExpr *) node;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This isn't exactly nextval(), but that seems close enough
|
||||||
|
* for EXPLAIN's purposes.
|
||||||
|
*/
|
||||||
|
appendStringInfoString(buf, "nextval(");
|
||||||
|
simple_quote_literal(buf,
|
||||||
|
generate_relation_name(nvexpr->seqid,
|
||||||
|
NIL));
|
||||||
|
appendStringInfoChar(buf, ')');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case T_InferenceElem:
|
case T_InferenceElem:
|
||||||
{
|
{
|
||||||
InferenceElem *iexpr = (InferenceElem *) node;
|
InferenceElem *iexpr = (InferenceElem *) node;
|
||||||
|
@ -362,7 +362,7 @@ typedef struct ExprEvalStep
|
|||||||
SQLValueFunction *svf;
|
SQLValueFunction *svf;
|
||||||
} sqlvaluefunction;
|
} sqlvaluefunction;
|
||||||
|
|
||||||
/* for EEOP_NEXTVALUEXPR */
|
/* for EEOP_NEXTVALUEEXPR */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
Oid seqid;
|
Oid seqid;
|
||||||
@ -615,6 +615,7 @@ extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op,
|
|||||||
ExprContext *econtext);
|
ExprContext *econtext);
|
||||||
extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
|
extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op);
|
||||||
extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
|
extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op);
|
||||||
|
extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op);
|
||||||
extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
|
extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op,
|
||||||
ExprContext *econtext);
|
ExprContext *econtext);
|
||||||
extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
|
extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op,
|
||||||
|
@ -183,6 +183,7 @@ typedef enum NodeTag
|
|||||||
T_CoerceToDomainValue,
|
T_CoerceToDomainValue,
|
||||||
T_SetToDefault,
|
T_SetToDefault,
|
||||||
T_CurrentOfExpr,
|
T_CurrentOfExpr,
|
||||||
|
T_NextValueExpr,
|
||||||
T_InferenceElem,
|
T_InferenceElem,
|
||||||
T_TargetEntry,
|
T_TargetEntry,
|
||||||
T_RangeTblRef,
|
T_RangeTblRef,
|
||||||
@ -190,7 +191,6 @@ typedef enum NodeTag
|
|||||||
T_FromExpr,
|
T_FromExpr,
|
||||||
T_OnConflictExpr,
|
T_OnConflictExpr,
|
||||||
T_IntoClause,
|
T_IntoClause,
|
||||||
T_NextValueExpr,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
|
* TAGS FOR EXPRESSION STATE NODES (execnodes.h)
|
||||||
|
@ -1279,6 +1279,20 @@ typedef struct CurrentOfExpr
|
|||||||
int cursor_param; /* refcursor parameter number, or 0 */
|
int cursor_param; /* refcursor parameter number, or 0 */
|
||||||
} CurrentOfExpr;
|
} CurrentOfExpr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NextValueExpr - get next value from sequence
|
||||||
|
*
|
||||||
|
* This has the same effect as calling the nextval() function, but it does not
|
||||||
|
* check permissions on the sequence. This is used for identity columns,
|
||||||
|
* where the sequence is an implicit dependency without its own permissions.
|
||||||
|
*/
|
||||||
|
typedef struct NextValueExpr
|
||||||
|
{
|
||||||
|
Expr xpr;
|
||||||
|
Oid seqid;
|
||||||
|
Oid typeId;
|
||||||
|
} NextValueExpr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InferenceElem - an element of a unique index inference specification
|
* InferenceElem - an element of a unique index inference specification
|
||||||
*
|
*
|
||||||
@ -1294,20 +1308,6 @@ typedef struct InferenceElem
|
|||||||
Oid inferopclass; /* OID of att opclass, or InvalidOid */
|
Oid inferopclass; /* OID of att opclass, or InvalidOid */
|
||||||
} InferenceElem;
|
} InferenceElem;
|
||||||
|
|
||||||
/*
|
|
||||||
* NextValueExpr - get next value from sequence
|
|
||||||
*
|
|
||||||
* This has the same effect as calling the nextval() function, but it does not
|
|
||||||
* check permissions on the sequence. This is used for identity columns,
|
|
||||||
* where the sequence is an implicit dependency without its own permissions.
|
|
||||||
*/
|
|
||||||
typedef struct NextValueExpr
|
|
||||||
{
|
|
||||||
Expr xpr;
|
|
||||||
Oid seqid;
|
|
||||||
Oid typeId;
|
|
||||||
} NextValueExpr;
|
|
||||||
|
|
||||||
/*--------------------
|
/*--------------------
|
||||||
* TargetEntry -
|
* TargetEntry -
|
||||||
* a target entry (used in query target lists)
|
* a target entry (used in query target lists)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user