How to make a OpExpr check compatible among different versions

Started by Andy Fanalmost 6 years ago3 messages
#1Andy Fan
zhihui.fan1213@gmail.com

During one of my works for logical rewrite, I want to check if the expr is
a given Expr.

so the simplest way is:
if (expr->opno == 418 && nodeTag(linitial(expr->args)) == T_xxx &&
nodeTag(lsecond(expr->args)) == T_yyyy )
{
..
}

if we write code like above, we may have issues if the oid changed in the
future version.
so what would be your suggestion?

Thanks

#2Peter Eisentraut
peter.eisentraut@2ndquadrant.com
In reply to: Andy Fan (#1)
Re: How to make a OpExpr check compatible among different versions

On 2020-01-13 08:29, Andy Fan wrote:

During one of my works for logical rewrite,  I want to check if the expr
is a given Expr.

so the simplest way is:
if (expr->opno == 418 && nodeTag(linitial(expr->args)) == T_xxx  &&
nodeTag(lsecond(expr->args)) == T_yyyy )
{
 ..
}

if we write code like above,  we may have issues if the oid changed in
the future version.

Generally, you would do this by using a preprocessor symbol. For
example, instead of hardcoding the OID of the text type, you would use
the symbol TEXTOID instead. Symbols like that exist for many catalog
objects that one might reasonably need to hardcode.

However, hardcoding an OID reference to an operator looks like a design
mistake to me. Operators should normally be looked up via operator
classes or similar structures that convey the meaning of the operator.

Also, instead of nodeTag() == T_xxx you should use the IsA() macro.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

#3Andy Fan
zhihui.fan1213@gmail.com
In reply to: Peter Eisentraut (#2)
Re: How to make a OpExpr check compatible among different versions

On Mon, Jan 13, 2020 at 4:09 PM Peter Eisentraut <
peter.eisentraut@2ndquadrant.com> wrote:

On 2020-01-13 08:29, Andy Fan wrote:

During one of my works for logical rewrite, I want to check if the expr
is a given Expr.

so the simplest way is:
if (expr->opno == 418 && nodeTag(linitial(expr->args)) == T_xxx &&
nodeTag(lsecond(expr->args)) == T_yyyy )
{
..
}

if we write code like above, we may have issues if the oid changed in
the future version.

Generally, you would do this by using a preprocessor symbol. For
example, instead of hardcoding the OID of the text type, you would use
the symbol TEXTOID instead. Symbols like that exist for many catalog
objects that one might reasonably need to hardcode.

However, hardcoding an OID reference to an operator looks like a design
mistake to me. Operators should normally be looked up via operator
classes or similar structures that convey the meaning of the operator.

Yes, I just realized this. Thanks for your point!

Show quoted text

Also, instead of nodeTag() == T_xxx you should use the IsA() macro.

Thank you for this as well.

--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services