Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User defined functions with keyword or built in function names throw ParseError for BigQuery dialect #1535

Closed
relud opened this issue May 3, 2023 · 0 comments

Comments

@relud
Copy link
Contributor

relud commented May 3, 2023

observed on both version 11.7.1 and commit e7111ba6afdb67ae7be52cf39384d7bcb86a8dac

Fully reproducible code snippet

sqlglot.parse_one("CREATE FUNCTION mydataset.extract(x ANY TYPE) AS (x); SELECT dataset.extract(1) AS y", read="bigquery")

traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.10/site-packages/sqlglot/__init__.py", line 150, in parse_one
    result = dialect.parse(sql, **opts)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/dialects/dialect.py", line 163, in parse
    return self.parser(**opts).parse(self.tokenize(sql), sql)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 836, in parse
    return self._parse(
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 899, in _parse
    expressions.append(parse_method(self))
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 1047, in _parse_statement
    expression = self._parse_set_operations(expression) if expression else self._parse_select()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 1824, in _parse_select
    expressions = self._parse_csv(self._parse_expression)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3974, in _parse_csv
    parse_result = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2622, in _parse_expression
    return self._parse_alias(self._parse_conjunction())
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2625, in _parse_conjunction
    return self._parse_tokens(self._parse_equality, self.CONJUNCTION)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3990, in _parse_tokens
    this = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2628, in _parse_equality
    return self._parse_tokens(self._parse_comparison, self.EQUALITY)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3990, in _parse_tokens
    this = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2631, in _parse_comparison
    return self._parse_tokens(self._parse_range, self.COMPARISON)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3990, in _parse_tokens
    this = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2634, in _parse_range
    this = self._parse_bitwise()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2726, in _parse_bitwise
    this = self._parse_term()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2749, in _parse_term
    return self._parse_tokens(self._parse_factor, self.TERM)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3990, in _parse_tokens
    this = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2752, in _parse_factor
    return self._parse_tokens(self._parse_unary, self.FACTOR)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3990, in _parse_tokens
    this = parse_method()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2757, in _parse_unary
    return self._parse_at_time_zone(self._parse_type())
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2766, in _parse_type
    this = self._parse_column()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 2935, in _parse_column
    field = self._parse_star() or self._parse_function() or self._parse_id_var()
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3047, in _parse_function
    this = parser(self)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 703, in <lambda>
    "EXTRACT": lambda self: self._parse_extract(),
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 3482, in _parse_extract
    self.raise_error("Expected FROM or comma after EXTRACT", self._prev)
  File "/usr/local/lib/python3.10/site-packages/sqlglot/parser.py", line 945, in raise_error
    raise error
sqlglot.errors.ParseError: Expected FROM or comma after EXTRACT. Line 1, Col: 79.
  CREATE FUNCTION mydataset.extract(x ANY TYPE) AS (x); SELECT dataset.extract(1) AS y

Official Documentation
https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions#sql-udf-structure

The next example creates the same function as a persistent UDF:

CREATE FUNCTION mydataset.AddFourAndDivide(x INT64, y INT64)
RETURNS FLOAT64
AS (
  (x + 4) / y
);

https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions#limitations

The following limitations apply to persistent user-defined functions:
[...]

  • When referencing a persistent UDF from another persistent UDF or a logical view, you must qualify the name with the dataset. For example:
    CREATE FUNCTION mydataset.referringFunction() AS (mydataset.referencedFunction());
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

No branches or pull requests

1 participant