Skip to content

refactor(bigframes): Introduce GoogleSqlScalarOp#17037

Merged
tswast merged 12 commits into
mainfrom
tbergeron_googlesql_op
May 12, 2026
Merged

refactor(bigframes): Introduce GoogleSqlScalarOp#17037
tswast merged 12 commits into
mainfrom
tbergeron_googlesql_op

Conversation

@TrevorBergeron
Copy link
Copy Markdown
Contributor

Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

@TrevorBergeron TrevorBergeron requested review from a team as code owners May 12, 2026 00:58
@TrevorBergeron TrevorBergeron requested review from tswast and removed request for a team May 12, 2026 00:58
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces GoogleSqlScalarOp to provide a more direct mapping between BigFrames operations and GoogleSQL functions, refactoring several geography and mathematical operations to use this new infrastructure. It also adds support for omitted optional arguments across the expression and compilation layers for both Ibis and sqlglot. Feedback identifies several critical implementation errors in the Ibis compiler registry, including incorrect list methods, return type mismatches, and logic errors in argument indexing. Additionally, there are issues with missing imports, incorrect type hints, and consistent typos in the 'omitted' property across the codebase.

Comment thread packages/bigframes/bigframes/core/compile/ibis_compiler/scalar_op_registry.py Outdated
Comment thread packages/bigframes/bigframes/operations/googlesql.py Outdated
Comment thread packages/bigframes/bigframes/operations/googlesql.py Outdated
Comment thread packages/bigframes/third_party/bigframes_vendored/ibis/expr/operations/generic.py Outdated
Comment thread packages/bigframes/bigframes/operations/googlesql.py Outdated
Comment thread packages/bigframes/third_party/bigframes_vendored/ibis/expr/operations/core.py Outdated
Copy link
Copy Markdown
Contributor

@tswast tswast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see some (tested) examples of the PREFIX and INFIX calling modes to know that these work rather than discovering bugs later. Alternatively, we can raise notimplemented for these cases and add those examples in a follow-up.

return sg.parse_one(f"{op.sql_name} {operands[0].expr.sql(dialect='bigquery')}", dialect="bigquery")
elif op.calling_convention == CallingConvention.INFIX:
assert len(operands) == 2, 'infix op expects exactly 2 args'
return sg.parse_one(f"{operands[0].expr.sql(dialect='bigquery')} {op.sql_name} {operands[1].expr.sql(dialect='bigquery')}", dialect="bigquery")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any way we can avoid the "parse" calls?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert the changes to this file. The typing module is the one exception to the "import modules not classes" rule.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

def googlesql_scalar_op_impl(*operands: ibis_types.Value, op: ops.GoogleSqlScalarOp):
final_operands = []
arg_templates = []
if op.calling_convention == CallingConvention.FUNCTION:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readability nit: could we define helper methods for each of the calling_convertion branch? The goal is to reduce function length and levels of nesting.

E.g.

if op.calling_convention == CallingConvention.FUNCTION:
  _compile_function_sql_scalar_op(...)
else if op.calling_convention == CallingConvention.PREFIX:
  _compile_prefix_sql_scalar_op(...)
...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed calling_convention entirely - will handle operators in specialized logic later



@dataclasses.dataclass(frozen=True)
class Omitted(Expression):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readability nit: Maybe use a noun for the class name, such as "OmittedArg"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done



@public
class Omitted(Value):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, "OmittedArg" ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@TrevorBergeron TrevorBergeron requested review from sycai and tswast May 12, 2026 19:48
inputs = tuple(
TypedExpr(self.compile_expression(sub_expr), sub_expr.output_type)
if not isinstance(sub_expr, ex.OmittedArg)
else TypedExpr(sge.Null(), None, is_omitted=True)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing that this could cause problems at some point, but hopefully we'll catch that when we encounter such a case.

@tswast tswast merged commit a10a813 into main May 12, 2026
31 checks passed
@tswast tswast deleted the tbergeron_googlesql_op branch May 12, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants