Skip to content

Commit

Permalink
Feat(executor): add support for TRIM, fix TRIM CSV-style parsing order (
Browse files Browse the repository at this point in the history
#2342)

* Feat(executor): add support for TRIM, fix TRIM CSV-style parsing order

* Define trim inline using a lambda

* Comment cleanup
  • Loading branch information
georgesittas authored Sep 28, 2023
1 parent 090724d commit e2c8366
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
2 changes: 2 additions & 0 deletions sqlglot/dialects/spark2.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ def _unqualify_pivot_columns(expression: exp.Expression) -> exp.Expression:

class Spark2(Hive):
class Parser(Hive.Parser):
TRIM_PATTERN_FIRST = True

FUNCTIONS = {
**Hive.Parser.FUNCTIONS,
"AGGREGATE": exp.Reduce.from_arg_list,
Expand Down
1 change: 1 addition & 0 deletions sqlglot/executor/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,5 @@ def interval(this, unit):
"CURRENTTIME": datetime.datetime.now,
"CURRENTDATE": datetime.date.today,
"STRFTIME": null_if_any(lambda fmt, arg: datetime.datetime.fromisoformat(arg).strftime(fmt)),
"TRIM": null_if_any(lambda this, e=None: this.strip(e)),
}
17 changes: 11 additions & 6 deletions sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,9 +889,12 @@ class Parser(metaclass=_Parser):
# Whether or not the table sample clause expects CSV syntax
TABLESAMPLE_CSV = False

# Whether or not the SET command needs a delimiter (e.g. "=") for assignments.
# Whether or not the SET command needs a delimiter (e.g. "=") for assignments
SET_REQUIRES_ASSIGNMENT_DELIMITER = True

# Whether the TRIM function expects the characters to trim as its first argument
TRIM_PATTERN_FIRST = False

__slots__ = (
"error_level",
"error_message_context",
Expand Down Expand Up @@ -4411,16 +4414,18 @@ def _parse_trim(self) -> exp.Trim:

position = None
collation = None
expression = None

if self._match_texts(self.TRIM_TYPES):
position = self._prev.text.upper()

expression = self._parse_bitwise()
this = self._parse_bitwise()
if self._match_set((TokenType.FROM, TokenType.COMMA)):
this = self._parse_bitwise()
else:
this = expression
expression = None
invert_order = self._prev.token_type == TokenType.FROM or self.TRIM_PATTERN_FIRST
expression = self._parse_bitwise()

if invert_order:
this, expression = expression, this

if self._match(TokenType.COLLATE):
collation = self._parse_bitwise()
Expand Down
12 changes: 12 additions & 0 deletions tests/dialects/test_bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ def test_bigquery(self):
self.validate_all('x <> """"""', write={"bigquery": "x <> ''"})
self.validate_all("x <> ''''''", write={"bigquery": "x <> ''"})
self.validate_all("CAST(x AS DATETIME)", read={"": "x::timestamp"})
self.validate_all(
"TRIM(item, '*')",
read={
"snowflake": "TRIM(item, '*')",
"spark": "TRIM('*', item)",
},
write={
"bigquery": "TRIM(item, '*')",
"snowflake": "TRIM(item, '*')",
"spark": "TRIM('*' FROM item)",
},
)
self.validate_all(
"CREATE OR REPLACE TABLE `a.b.c` COPY `a.b.d`",
write={
Expand Down
2 changes: 2 additions & 0 deletions tests/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,8 @@ def test_scalar_functions(self):
("LEFT('12345', 3)", "123"),
("RIGHT('12345', 3)", "345"),
("DATEDIFF('2022-01-03'::date, '2022-01-01'::TIMESTAMP::DATE)", 2),
("TRIM(' foo ')", "foo"),
("TRIM('afoob', 'ab')", "foo"),
]:
with self.subTest(sql):
result = execute(f"SELECT {sql}")
Expand Down

0 comments on commit e2c8366

Please sign in to comment.