diff --git a/packages/bigframes/bigframes/bigquery/__init__.py b/packages/bigframes/bigframes/bigquery/__init__.py index d3fb8701df20..99a47d218691 100644 --- a/packages/bigframes/bigframes/bigquery/__init__.py +++ b/packages/bigframes/bigframes/bigquery/__init__.py @@ -114,6 +114,18 @@ flatten, generate_array, ) +from bigframes.operations.googlesql.global_namespace.bit import ( + bit_count, +) +from bigframes.operations.googlesql.global_namespace.conversion import ( + bool_, + double, + float64, + int64, + parse_bignumeric, + parse_numeric, + string, +) _functions = [ # approximate aggregate ops @@ -134,6 +146,16 @@ array_to_string, flatten, generate_array, + # bit ops + bit_count, + # conversion ops + bool_, + double, + float64, + int64, + parse_bignumeric, + parse_numeric, + string, # datetime ops unix_micros, unix_millis, @@ -208,6 +230,16 @@ "array_to_string", "flatten", "generate_array", + # bit ops + "bit_count", + # conversion ops + "bool_", + "double", + "float64", + "int64", + "parse_bignumeric", + "parse_numeric", + "string", # datetime ops "unix_micros", "unix_millis", diff --git a/packages/bigframes/bigframes/extensions/core/series_accessor.py b/packages/bigframes/bigframes/extensions/core/series_accessor.py index 4c0f261b83cd..96d0eb8d045e 100644 --- a/packages/bigframes/bigframes/extensions/core/series_accessor.py +++ b/packages/bigframes/bigframes/extensions/core/series_accessor.py @@ -598,6 +598,160 @@ def flatten( ) return self._to_series(cast(series.Series, result)) + def bool_( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON boolean to a SQL BOOL value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + bool_ as bool__impl, + ) + + bf_series = self._bf_from_series(session) + result = bool__impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def double( + self, + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL FLOAT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + double as double_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + wide_number_mode, + ) + + bf_series = self._bf_from_series(session) + result = double_impl( + bf_series, + wide_number_mode, + ) + return self._to_series(cast(series.Series, result)) + + def float64( + self, + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL FLOAT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + float64 as float64_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + wide_number_mode, + ) + + bf_series = self._bf_from_series(session) + result = float64_impl( + bf_series, + wide_number_mode, + ) + return self._to_series(cast(series.Series, result)) + + def int64( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a JSON number to a SQL INT64 value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + int64 as int64_impl, + ) + + bf_series = self._bf_from_series(session) + result = int64_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def parse_bignumeric( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a STRING to a BIGNUMERIC value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + parse_bignumeric as parse_bignumeric_impl, + ) + + bf_series = self._bf_from_series(session) + result = parse_bignumeric_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def parse_numeric( + self, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a STRING to a NUMERIC value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + parse_numeric as parse_numeric_impl, + ) + + bf_series = self._bf_from_series(session) + result = parse_numeric_impl( + bf_series, + ) + return self._to_series(cast(series.Series, result)) + + def string( + self, + timezone: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, + *, + session: Optional[bigframes.session.Session] = None, + ) -> S: + """Converts a value to a STRING value.""" + from bigframes.operations.googlesql.global_namespace.conversion import ( + string as string_impl, + ) + + # Resolve session from other arguments if not passed + if session is None: + import bigframes.core.googlesql as googlesql + + session = googlesql._find_session( + timezone, + ) + + bf_series = self._bf_from_series(session) + result = string_impl( + bf_series, + timezone, + ) + return self._to_series(cast(series.Series, result)) + class AeadSeriesAccessor(AbstractBigQuerySeriesAccessor[S]): """Series accessor for BigQuery aead functions.""" diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py new file mode 100644 index 000000000000..e0c22dfc2990 --- /dev/null +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/bit.py @@ -0,0 +1,48 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/bit.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +from __future__ import annotations + +from typing import Any, Literal, Union + +import bigframes.core.col +import bigframes.core.googlesql +import bigframes.core.sentinels as sentinels +import bigframes.series as series +from bigframes import dtypes +from bigframes.operations import googlesql + +_BIT_COUNT_OP = googlesql.GoogleSqlScalarOp( + "BIT_COUNT", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.INT_DTYPE, +) + + +def bit_count( + expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Any, Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], bytes, int], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _BIT_COUNT_OP, + expression, + ) diff --git a/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py b/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py new file mode 100644 index 000000000000..cea4e45d836b --- /dev/null +++ b/packages/bigframes/bigframes/operations/googlesql/global_namespace/conversion.py @@ -0,0 +1,193 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/conversion.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +from __future__ import annotations + +import datetime +from typing import Literal, Union + +import bigframes.core.col +import bigframes.core.googlesql +import bigframes.core.sentinels as sentinels +import bigframes.series as series +from bigframes import dtypes +from bigframes.operations import googlesql + +_BOOL_OP = googlesql.GoogleSqlScalarOp( + "BOOL", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.BOOL_DTYPE, +) +_DOUBLE_OP = googlesql.GoogleSqlScalarOp( + "DOUBLE", + args=( + googlesql.ArgSpec(), + googlesql.ArgSpec(arg_name="wide_number_mode", optional=True), + ), + signature=lambda *args: dtypes.FLOAT_DTYPE, +) +_FLOAT64_OP = googlesql.GoogleSqlScalarOp( + "FLOAT64", + args=( + googlesql.ArgSpec(), + googlesql.ArgSpec(arg_name="wide_number_mode", optional=True), + ), + signature=lambda *args: dtypes.FLOAT_DTYPE, +) +_INT64_OP = googlesql.GoogleSqlScalarOp( + "INT64", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.INT_DTYPE, +) +_PARSE_BIGNUMERIC_OP = googlesql.GoogleSqlScalarOp( + "PARSE_BIGNUMERIC", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.BIGNUMERIC_DTYPE, +) +_PARSE_NUMERIC_OP = googlesql.GoogleSqlScalarOp( + "PARSE_NUMERIC", + args=(googlesql.ArgSpec(),), + signature=lambda *args: dtypes.NUMERIC_DTYPE, +) +_STRING_OP = googlesql.GoogleSqlScalarOp( + "STRING", + args=(googlesql.ArgSpec(), googlesql.ArgSpec(optional=True)), + signature=lambda *args: dtypes.STRING_DTYPE, +) + + +def bool_( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON boolean to a SQL BOOL value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _BOOL_OP, + json_string_expression, + ) + + +def double( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL FLOAT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _DOUBLE_OP, + json_string_expression, + wide_number_mode, + ) + + +def float64( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], + wide_number_mode: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL FLOAT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _FLOAT64_OP, + json_string_expression, + wide_number_mode, + ) + + +def int64( + json_string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a JSON number to a SQL INT64 value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _INT64_OP, + json_string_expression, + ) + + +def parse_bignumeric( + string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a STRING to a BIGNUMERIC value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _PARSE_BIGNUMERIC_OP, + string_expression, + ) + + +def parse_numeric( + string_expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ], +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a STRING to a NUMERIC value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _PARSE_NUMERIC_OP, + string_expression, + ) + + +def string( + expression: Union[ + series.Series, + bigframes.core.col.Expression, + Union[ + Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], + datetime.date, + datetime.datetime, + datetime.time, + str, + ], + ], + timezone: Union[ + series.Series, + bigframes.core.col.Expression, + Union[Literal[sentinels.Sentinel.ARGUMENT_DEFAULT], str], + ] = sentinels.Sentinel.ARGUMENT_DEFAULT, +) -> Union[series.Series, bigframes.core.col.Expression]: + """Converts a value to a STRING value.""" + return bigframes.core.googlesql.apply_googlesql_scalar_op( + _STRING_OP, + expression, + timezone, + ) diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml new file mode 100644 index 000000000000..3c2953133e49 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/bit.yaml @@ -0,0 +1,26 @@ +urn: extension:google:bq_scalar_functions +scalar_functions: + - name: "bit_count" + description: "The input, `expression`, must be an integer or `BYTES`. Returns the number of bits that are set in the input expression. For signed integers, this is the number of bits in two's complement form." + impls: + # Signature: bit_count:i32 + - args: + - name: "expression" + value: i32 + optional: false + keyword_only: false + return: i64 + # Signature: bit_count:i64 + - args: + - name: "expression" + value: i64 + optional: false + keyword_only: false + return: i64 + # Signature: bit_count:vbin + - args: + - name: "expression" + value: binary + optional: false + keyword_only: false + return: i64 diff --git a/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml b/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml new file mode 100644 index 000000000000..c39724427de4 --- /dev/null +++ b/packages/bigframes/scripts/data/sql-functions/global_namespace/conversion.yaml @@ -0,0 +1,119 @@ +urn: extension:google:bq_scalar_functions +scalar_functions: + - name: "bool" + description: "Converts a JSON boolean to a SQL BOOL value." + series_accessor_arg: json_string_expression + impls: + # Signature: bool:str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + return: boolean + - name: "double" + description: "Converts a JSON number to a SQL FLOAT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: double:str_str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + - name: "wide_number_mode" + value: string + optional: true + keyword_only: true + return: fp64 + - name: "float64" + description: "Converts a JSON number to a SQL FLOAT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: float64:str_str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + - name: "wide_number_mode" + value: string + optional: true + keyword_only: true + return: fp64 + - name: "int64" + description: "Converts a JSON number to a SQL INT64 value." + series_accessor_arg: json_string_expression + impls: + # Signature: int64:str + - args: + - name: "json_string_expression" + value: string + optional: false + keyword_only: false + return: i64 + - name: "parse_bignumeric" + description: "Converts a STRING to a BIGNUMERIC value." + series_accessor_arg: string_expression + impls: + # Signature: parse_bignumeric:str + - args: + - name: "string_expression" + value: string + optional: false + keyword_only: false + return: decimal<76,38> + - name: "parse_numeric" + description: "Converts a STRING to a NUMERIC value." + series_accessor_arg: string_expression + impls: + # Signature: parse_numeric:str + - args: + - name: "string_expression" + value: string + optional: false + keyword_only: false + return: decimal<38,9> + - name: "string" + description: "Converts a value to a STRING value." + series_accessor_arg: expression + impls: + # Signature: string:pts_str + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + - name: "timezone" + value: string + optional: true + keyword_only: false + return: string + # Signature: string:date + - args: + - name: "expression" + value: date + optional: false + keyword_only: false + return: string + # Signature: string:pt + - args: + - name: "expression" + value: time + optional: false + keyword_only: false + return: string + # Signature: string:pts + - args: + - name: "expression" + value: timestamp + optional: false + keyword_only: false + return: string + # Signature: string:str + - args: + - name: "expression" + value: string + optional: false + keyword_only: false + return: string diff --git a/packages/bigframes/scripts/generate_bigframes_bigquery.py b/packages/bigframes/scripts/generate_bigframes_bigquery.py index 124604354205..bb232a6cdf8c 100755 --- a/packages/bigframes/scripts/generate_bigframes_bigquery.py +++ b/packages/bigframes/scripts/generate_bigframes_bigquery.py @@ -77,6 +77,7 @@ "datetime": "dtypes.DATETIME_DTYPE", "timestamp": "dtypes.TIMESTAMP_DTYPE", "decimal<38,9>": "dtypes.NUMERIC_DTYPE", + "decimal<76,38>": "dtypes.BIGNUMERIC_DTYPE", } PY_TYPE_MAP = { @@ -96,6 +97,7 @@ "timestamp": "datetime.datetime", "struct": "dict", "decimal<38,9>": "decimal.Decimal", + "decimal<76,38>": "decimal.Decimal", } YAML_TYPE_TO_COL = { @@ -113,6 +115,78 @@ "datetime": "datetime_col", "timestamp": "timestamp_col", "decimal<38,9>": "numeric_col", + "decimal<76,38>": "bignumeric_col", +} + +_PYTHON_BUILTINS = { + "abs", + "all", + "any", + "ascii", + "bin", + "bool", + "breakpoint", + "bytearray", + "bytes", + "callable", + "chr", + "classmethod", + "compile", + "complex", + "delattr", + "dict", + "dir", + "divmod", + "enumerate", + "eval", + "exec", + "filter", + "float", + "format", + "frozenset", + "getattr", + "globals", + "hasattr", + "hash", + "help", + "hex", + "id", + "input", + "int", + "isinstance", + "issubclass", + "iter", + "len", + "list", + "locals", + "map", + "max", + "memoryview", + "min", + "next", + "object", + "oct", + "open", + "ord", + "pow", + "print", + "property", + "range", + "repr", + "reversed", + "round", + "set", + "setattr", + "slice", + "sorted", + "staticmethod", + "str", + "sum", + "super", + "tuple", + "type", + "vars", + "zip", } @@ -311,7 +385,11 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= if not is_global and python_name.startswith(module_name + "_"): python_name = python_name[len(module_name) + 1 :] - internal_op_name = f"_{python_name.upper()}_OP" + op_base_name = python_name + if python_name in _PYTHON_BUILTINS: + python_name = python_name + "_" + + internal_op_name = f"_{op_base_name.upper()}_OP" # Aggregate args across impls args_by_name, arg_order = _collect_args(func_data["impls"]) @@ -324,7 +402,7 @@ def parse_scalar_functions(data, module_name, signature_def_template, is_global= # Determine return dtype sig_name, sig_def = _generate_signature_def( - python_name, + op_base_name, func_data["impls"], sql_name, signature_def_template, diff --git a/packages/bigframes/scripts/templates/test_operation.py.j2 b/packages/bigframes/scripts/templates/test_operation.py.j2 index 21db9cbfc8ba..6aee365cdedb 100644 --- a/packages/bigframes/scripts/templates/test_operation.py.j2 +++ b/packages/bigframes/scripts/templates/test_operation.py.j2 @@ -31,7 +31,7 @@ def test_{{ func.name }}_expression(): # Verify the internal expression structure expr = result._value assert isinstance(expr, ex.OpExpression) - assert expr.op == {{ short_name }}_op._{{ func.name | upper }}_OP + assert expr.op == {{ short_name }}_op.{{ func.op_name }} # Verify arguments are free variables matching the names assert len(expr.inputs) == {{ func.args | length }} diff --git a/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py new file mode 100644 index 000000000000..2cccafc0643d --- /dev/null +++ b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_bit.py @@ -0,0 +1,43 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/bit.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +import bigframes.bigquery as bbq +import bigframes.core.col +import bigframes.core.expression as ex +import bigframes.operations.googlesql.global_namespace.bit as bit_op +import bigframes.pandas as bpd + + +def test_bit_count_expression(): + # Call the function with col() expressions + result = bbq.bit_count( + bpd.col("expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == bit_op._BIT_COUNT_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "expression" diff --git a/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py new file mode 100644 index 000000000000..84dfc02465cc --- /dev/null +++ b/packages/bigframes/tests/unit/bigquery/generated/global_namespace/test_conversion.py @@ -0,0 +1,172 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# DO NOT MODIFY THIS FILE DIRECTLY. +# This file was generated from: scripts/data/sql-functions/global_namespace/conversion.yaml +# by the script: scripts/generate_bigframes_bigquery.py + +import bigframes.bigquery as bbq +import bigframes.core.col +import bigframes.core.expression as ex +import bigframes.operations.googlesql.global_namespace.conversion as conversion_op +import bigframes.pandas as bpd + + +def test_bool__expression(): + # Call the function with col() expressions + result = bbq.bool_( + bpd.col("json_string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._BOOL_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + + +def test_double_expression(): + # Call the function with col() expressions + result = bbq.double( + bpd.col("json_string_expression"), + bpd.col("wide_number_mode"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._DOUBLE_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "wide_number_mode" + + +def test_float64_expression(): + # Call the function with col() expressions + result = bbq.float64( + bpd.col("json_string_expression"), + bpd.col("wide_number_mode"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._FLOAT64_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "wide_number_mode" + + +def test_int64_expression(): + # Call the function with col() expressions + result = bbq.int64( + bpd.col("json_string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._INT64_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "json_string_expression" + + +def test_parse_bignumeric_expression(): + # Call the function with col() expressions + result = bbq.parse_bignumeric( + bpd.col("string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._PARSE_BIGNUMERIC_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "string_expression" + + +def test_parse_numeric_expression(): + # Call the function with col() expressions + result = bbq.parse_numeric( + bpd.col("string_expression"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._PARSE_NUMERIC_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 1 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "string_expression" + + +def test_string_expression(): + # Call the function with col() expressions + result = bbq.string( + bpd.col("expression"), + bpd.col("timezone"), + ) + + # Verify result is a col Expression + assert isinstance(result, bigframes.core.col.Expression) + + # Verify the internal expression structure + expr = result._value + assert isinstance(expr, ex.OpExpression) + assert expr.op == conversion_op._STRING_OP + + # Verify arguments are free variables matching the names + assert len(expr.inputs) == 2 + assert isinstance(expr.inputs[0], ex.UnboundVariableExpression) + assert expr.inputs[0].id == "expression" + assert isinstance(expr.inputs[1], ex.UnboundVariableExpression) + assert expr.inputs[1].id == "timezone"