We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] Transpiling built-in functions is not accurate.
**Before you file an issue**
- updated to 19.0.3

**Fully reproducible code snippet**
I am transpiling Oracle SQL to Postgres. There are multiple functions that fail when executed.
Here is an example.
`sql_in_oracle = "to_char(123)"`
`sqlglot.transpile(sql_in_oracle, read='oracle', write='postgres')`

Output: `['to_char(123)']`
Expected: `['123::text']` or whatever is valid in Postgres
Postgres supports `to_char(expr, format)`, but not `to_char(expr)`.

I have many functions that cannot be tranpiled correctly in my query list, such as,

Truncate datetime to day:
TRUNC(datetime) -- Valid Oracle
Output: TRUNC(datetime) -- Invalid Postgres
Expected: DATE_TRUNC('day', datetime) -- Valid postgres



**Official Documentation**
[sqlines](https://sqlines.com/oracle-to-postgresql) has an online tool I tried once. On its website, it lists many migration conversions for different databases. It might be a helpful resource for you to check out. Thanks.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sqlglot/dialects/oracle.py`
Content:
```
1 from __future__ import annotations
2 
3 import typing as t
4 
5 from sqlglot import exp, generator, parser, tokens, transforms
6 from sqlglot.dialects.dialect import Dialect, no_ilike_sql, rename_func, trim_sql
7 from sqlglot.helper import seq_get
8 from sqlglot.tokens import TokenType
9 
10 if t.TYPE_CHECKING:
11     from sqlglot._typing import E
12 
13 
14 def _parse_xml_table(self: Oracle.Parser) -> exp.XMLTable:
15     this = self._parse_string()
16 
17     passing = None
18     columns = None
19 
20     if self._match_text_seq("PASSING"):
21         # The BY VALUE keywords are optional and are provided for semantic clarity
22         self._match_text_seq("BY", "VALUE")
23         passing = self._parse_csv(self._parse_column)
24 
25     by_ref = self._match_text_seq("RETURNING", "SEQUENCE", "BY", "REF")
26 
27     if self._match_text_seq("COLUMNS"):
28         columns = self._parse_csv(self._parse_field_def)
29 
30     return self.expression(exp.XMLTable, this=this, passing=passing, columns=columns, by_ref=by_ref)
31 
32 
33 class Oracle(Dialect):
34     ALIAS_POST_TABLESAMPLE = True
35     LOCKING_READS_SUPPORTED = True
36 
37     # See section 8: https://docs.oracle.com/cd/A97630_01/server.920/a96540/sql_elements9a.htm
38     RESOLVES_IDENTIFIERS_AS_UPPERCASE = True
39     ALTER_TABLE_ADD_COLUMN_KEYWORD = False
40 
41     # https://docs.oracle.com/database/121/SQLRF/sql_elements004.htm#SQLRF00212
42     # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
43     TIME_MAPPING = {
44         "AM": "%p",  # Meridian indicator with or without periods
45         "A.M.": "%p",  # Meridian indicator with or without periods
46         "PM": "%p",  # Meridian indicator with or without periods
47         "P.M.": "%p",  # Meridian indicator with or without periods
48         "D": "%u",  # Day of week (1-7)
49         "DAY": "%A",  # name of day
50         "DD": "%d",  # day of month (1-31)
51         "DDD": "%j",  # day of year (1-366)
52         "DY": "%a",  # abbreviated name of day
53         "HH": "%I",  # Hour of day (1-12)
54         "HH12": "%I",  # alias for HH
55         "HH24": "%H",  # Hour of day (0-23)
56         "IW": "%V",  # Calendar week of year (1-52 or 1-53), as defined by the ISO 8601 standard
57         "MI": "%M",  # Minute (0-59)
58         "MM": "%m",  # Month (01-12; January = 01)
59         "MON": "%b",  # Abbreviated name of month
60         "MONTH": "%B",  # Name of month
61         "SS": "%S",  # Second (0-59)
62         "WW": "%W",  # Week of year (1-53)
63         "YY": "%y",  # 15
64         "YYYY": "%Y",  # 2015
65     }
66 
67     class Parser(parser.Parser):
68         WINDOW_BEFORE_PAREN_TOKENS = {TokenType.OVER, TokenType.KEEP}
69 
70         FUNCTIONS = {
71             **parser.Parser.FUNCTIONS,
72             "SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
73         }
74 
75         FUNCTION_PARSERS: t.Dict[str, t.Callable] = {
76             **parser.Parser.FUNCTION_PARSERS,
77             "JSON_ARRAY": lambda self: self._parse_json_array(
78                 exp.JSONArray,
79                 expressions=self._parse_csv(lambda: self._parse_format_json(self._parse_bitwise())),
80             ),
81             "JSON_ARRAYAGG": lambda self: self._parse_json_array(
82                 exp.JSONArrayAgg,
83                 this=self._parse_format_json(self._parse_bitwise()),
84                 order=self._parse_order(),
85             ),
86             "XMLTABLE": _parse_xml_table,
87         }
88 
89         TYPE_LITERAL_PARSERS = {
90             exp.DataType.Type.DATE: lambda self, this, _: self.expression(
91                 exp.DateStrToDate, this=this
92             )
93         }
94 
95         # SELECT UNIQUE .. is old-style Oracle syntax for SELECT DISTINCT ..
96         # Reference: https://stackoverflow.com/a/336455
97         DISTINCT_TOKENS = {TokenType.DISTINCT, TokenType.UNIQUE}
98 
99         def _parse_json_array(self, expr_type: t.Type[E], **kwargs) -> E:
100             return self.expression(
101                 expr_type,
102                 null_handling=self._parse_on_handling("NULL", "NULL", "ABSENT"),
103                 return_type=self._match_text_seq("RETURNING") and self._parse_type(),
104                 strict=self._match_text_seq("STRICT"),
105                 **kwargs,
106             )
107 
108         def _parse_column(self) -> t.Optional[exp.Expression]:
109             column = super()._parse_column()
110             if column:
111                 column.set("join_mark", self._match(TokenType.JOIN_MARKER))
112             return column
113 
114         def _parse_hint(self) -> t.Optional[exp.Hint]:
115             if self._match(TokenType.HINT):
116                 start = self._curr
117                 while self._curr and not self._match_pair(TokenType.STAR, TokenType.SLASH):
118                     self._advance()
119 
120                 if not self._curr:
121                     self.raise_error("Expected */ after HINT")
122 
123                 end = self._tokens[self._index - 3]
124                 return exp.Hint(expressions=[self._find_sql(start, end)])
125 
126             return None
127 
128     class Generator(generator.Generator):
129         LOCKING_READS_SUPPORTED = True
130         JOIN_HINTS = False
131         TABLE_HINTS = False
132         COLUMN_JOIN_MARKS_SUPPORTED = True
133         DATA_TYPE_SPECIFIERS_ALLOWED = True
134         ALTER_TABLE_ADD_COLUMN_KEYWORD = False
135 
136         LIMIT_FETCH = "FETCH"
137 
138         TYPE_MAPPING = {
139             **generator.Generator.TYPE_MAPPING,
140             exp.DataType.Type.TINYINT: "NUMBER",
141             exp.DataType.Type.SMALLINT: "NUMBER",
142             exp.DataType.Type.INT: "NUMBER",
143             exp.DataType.Type.BIGINT: "NUMBER",
144             exp.DataType.Type.DECIMAL: "NUMBER",
145             exp.DataType.Type.DOUBLE: "DOUBLE PRECISION",
146             exp.DataType.Type.VARCHAR: "VARCHAR2",
147             exp.DataType.Type.NVARCHAR: "NVARCHAR2",
148             exp.DataType.Type.NCHAR: "NCHAR",
149             exp.DataType.Type.TEXT: "CLOB",
150             exp.DataType.Type.BINARY: "BLOB",
151             exp.DataType.Type.VARBINARY: "BLOB",
152         }
153 
154         TRANSFORMS = {
155             **generator.Generator.TRANSFORMS,
156             exp.DateStrToDate: lambda self, e: self.func(
157                 "TO_DATE", e.this, exp.Literal.string("YYYY-MM-DD")
158             ),
159             exp.Group: transforms.preprocess([transforms.unalias_group]),
160             exp.ILike: no_ilike_sql,
161             exp.Select: transforms.preprocess(
162                 [
163                     transforms.eliminate_distinct_on,
164                     transforms.eliminate_qualify,
165                 ]
166             ),
167             exp.StrToTime: lambda self, e: f"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})",
168             exp.Subquery: lambda self, e: self.subquery_sql(e, sep=" "),
169             exp.Substring: rename_func("SUBSTR"),
170             exp.Table: lambda self, e: self.table_sql(e, sep=" "),
171             exp.TableSample: lambda self, e: self.tablesample_sql(e, sep=" "),
172             exp.TimeToStr: lambda self, e: f"TO_CHAR({self.sql(e, 'this')}, {self.format_time(e)})",
173             exp.ToChar: lambda self, e: self.function_fallback_sql(e),
174             exp.Trim: trim_sql,
175             exp.UnixToTime: lambda self, e: f"TO_DATE('1970-01-01','YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)",
176         }
177 
178         PROPERTIES_LOCATION = {
179             **generator.Generator.PROPERTIES_LOCATION,
180             exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
181         }
182 
183         def offset_sql(self, expression: exp.Offset) -> str:
184             return f"{super().offset_sql(expression)} ROWS"
185 
186         def xmltable_sql(self, expression: exp.XMLTable) -> str:
187             this = self.sql(expression, "this")
188             passing = self.expressions(expression, key="passing")
189             passing = f"{self.sep()}PASSING{self.seg(passing)}" if passing else ""
190             columns = self.expressions(expression, key="columns")
191             columns = f"{self.sep()}COLUMNS{self.seg(columns)}" if columns else ""
192             by_ref = (
193                 f"{self.sep()}RETURNING SEQUENCE BY REF" if expression.args.get("by_ref") else ""
194             )
195             return f"XMLTABLE({self.sep('')}{self.indent(this + passing + by_ref + columns)}{self.seg(')', sep='')}"
196 
197         def add_column_sql(self, expression: exp.AlterTable) -> str:
198             actions = self.expressions(expression, key="actions", flat=True)
199             if len(expression.args.get("actions", [])) > 1:
200                 return f"ADD ({actions})"
201             return f"ADD {actions}"
202 
203     class Tokenizer(tokens.Tokenizer):
204         VAR_SINGLE_TOKENS = {"@", "$", "#"}
205 
206         KEYWORDS = {
207             **tokens.Tokenizer.KEYWORDS,
208             "(+)": TokenType.JOIN_MARKER,
209             "BINARY_DOUBLE": TokenType.DOUBLE,
210             "BINARY_FLOAT": TokenType.FLOAT,
211             "COLUMNS": TokenType.COLUMN,
212             "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE,
213             "MINUS": TokenType.EXCEPT,
214             "NVARCHAR2": TokenType.NVARCHAR,
215             "SAMPLE": TokenType.TABLE_SAMPLE,
216             "START": TokenType.BEGIN,
217             "TOP": TokenType.TOP,
218             "VARCHAR2": TokenType.VARCHAR,
219         }
220
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sqlglot/dialects/oracle.py b/sqlglot/dialects/oracle.py
--- a/sqlglot/dialects/oracle.py
+++ b/sqlglot/dialects/oracle.py
@@ -3,7 +3,13 @@
 import typing as t
 
 from sqlglot import exp, generator, parser, tokens, transforms
-from sqlglot.dialects.dialect import Dialect, no_ilike_sql, rename_func, trim_sql
+from sqlglot.dialects.dialect import (
+    Dialect,
+    format_time_lambda,
+    no_ilike_sql,
+    rename_func,
+    trim_sql,
+)
 from sqlglot.helper import seq_get
 from sqlglot.tokens import TokenType
 
@@ -70,6 +76,7 @@
         FUNCTIONS = {
             **parser.Parser.FUNCTIONS,
             "SQUARE": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),
+            "TO_CHAR": format_time_lambda(exp.TimeToStr, "oracle", default=True),
         }
 
         FUNCTION_PARSERS: t.Dict[str, t.Callable] = {

{"golden_diff": "diff --git a/sqlglot/dialects/oracle.py b/sqlglot/dialects/oracle.py\n--- a/sqlglot/dialects/oracle.py\n+++ b/sqlglot/dialects/oracle.py\n@@ -3,7 +3,13 @@\n import typing as t\n \n from sqlglot import exp, generator, parser, tokens, transforms\n-from sqlglot.dialects.dialect import Dialect, no_ilike_sql, rename_func, trim_sql\n+from sqlglot.dialects.dialect import (\n+    Dialect,\n+    format_time_lambda,\n+    no_ilike_sql,\n+    rename_func,\n+    trim_sql,\n+)\n from sqlglot.helper import seq_get\n from sqlglot.tokens import TokenType\n \n@@ -70,6 +76,7 @@\n         FUNCTIONS = {\n             **parser.Parser.FUNCTIONS,\n             \"SQUARE\": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),\n+            \"TO_CHAR\": format_time_lambda(exp.TimeToStr, \"oracle\", default=True),\n         }\n \n         FUNCTION_PARSERS: t.Dict[str, t.Callable] = {\n", "issue": "[Bug] Transpiling built-in functions is not accurate.\n**Before you file an issue**\r\n- updated to 19.0.3\r\n\r\n**Fully reproducible code snippet**\r\nI am transpiling Oracle SQL to Postgres. There are multiple functions that fail when executed.\r\nHere is an example.\r\n`sql_in_oracle = \"to_char(123)\"`\r\n`sqlglot.transpile(sql_in_oracle, read='oracle', write='postgres')`\r\n\r\nOutput: `['to_char(123)']`\r\nExpected: `['123::text']` or whatever is valid in Postgres\r\nPostgres supports `to_char(expr, format)`, but not `to_char(expr)`.\r\n\r\nI have many functions that cannot be tranpiled correctly in my query list, such as,\r\n\r\nTruncate\u00a0datetime\u00a0to day:\r\nTRUNC(datetime) -- Valid Oracle\r\nOutput: TRUNC(datetime) -- Invalid Postgres\r\nExpected: DATE_TRUNC('day',\u00a0datetime) -- Valid postgres\r\n\r\n\r\n\r\n**Official Documentation**\r\n[sqlines](https://sqlines.com/oracle-to-postgresql) has an online tool I tried once. On its website, it lists many migration conversions for different databases. It might be a helpful resource for you to check out. Thanks.\n", "before_files": [{"content": "from __future__ import annotations\n\nimport typing as t\n\nfrom sqlglot import exp, generator, parser, tokens, transforms\nfrom sqlglot.dialects.dialect import Dialect, no_ilike_sql, rename_func, trim_sql\nfrom sqlglot.helper import seq_get\nfrom sqlglot.tokens import TokenType\n\nif t.TYPE_CHECKING:\n    from sqlglot._typing import E\n\n\ndef _parse_xml_table(self: Oracle.Parser) -> exp.XMLTable:\n    this = self._parse_string()\n\n    passing = None\n    columns = None\n\n    if self._match_text_seq(\"PASSING\"):\n        # The BY VALUE keywords are optional and are provided for semantic clarity\n        self._match_text_seq(\"BY\", \"VALUE\")\n        passing = self._parse_csv(self._parse_column)\n\n    by_ref = self._match_text_seq(\"RETURNING\", \"SEQUENCE\", \"BY\", \"REF\")\n\n    if self._match_text_seq(\"COLUMNS\"):\n        columns = self._parse_csv(self._parse_field_def)\n\n    return self.expression(exp.XMLTable, this=this, passing=passing, columns=columns, by_ref=by_ref)\n\n\nclass Oracle(Dialect):\n    ALIAS_POST_TABLESAMPLE = True\n    LOCKING_READS_SUPPORTED = True\n\n    # See section 8: https://docs.oracle.com/cd/A97630_01/server.920/a96540/sql_elements9a.htm\n    RESOLVES_IDENTIFIERS_AS_UPPERCASE = True\n    ALTER_TABLE_ADD_COLUMN_KEYWORD = False\n\n    # https://docs.oracle.com/database/121/SQLRF/sql_elements004.htm#SQLRF00212\n    # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes\n    TIME_MAPPING = {\n        \"AM\": \"%p\",  # Meridian indicator with or without periods\n        \"A.M.\": \"%p\",  # Meridian indicator with or without periods\n        \"PM\": \"%p\",  # Meridian indicator with or without periods\n        \"P.M.\": \"%p\",  # Meridian indicator with or without periods\n        \"D\": \"%u\",  # Day of week (1-7)\n        \"DAY\": \"%A\",  # name of day\n        \"DD\": \"%d\",  # day of month (1-31)\n        \"DDD\": \"%j\",  # day of year (1-366)\n        \"DY\": \"%a\",  # abbreviated name of day\n        \"HH\": \"%I\",  # Hour of day (1-12)\n        \"HH12\": \"%I\",  # alias for HH\n        \"HH24\": \"%H\",  # Hour of day (0-23)\n        \"IW\": \"%V\",  # Calendar week of year (1-52 or 1-53), as defined by the ISO 8601 standard\n        \"MI\": \"%M\",  # Minute (0-59)\n        \"MM\": \"%m\",  # Month (01-12; January = 01)\n        \"MON\": \"%b\",  # Abbreviated name of month\n        \"MONTH\": \"%B\",  # Name of month\n        \"SS\": \"%S\",  # Second (0-59)\n        \"WW\": \"%W\",  # Week of year (1-53)\n        \"YY\": \"%y\",  # 15\n        \"YYYY\": \"%Y\",  # 2015\n    }\n\n    class Parser(parser.Parser):\n        WINDOW_BEFORE_PAREN_TOKENS = {TokenType.OVER, TokenType.KEEP}\n\n        FUNCTIONS = {\n            **parser.Parser.FUNCTIONS,\n            \"SQUARE\": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),\n        }\n\n        FUNCTION_PARSERS: t.Dict[str, t.Callable] = {\n            **parser.Parser.FUNCTION_PARSERS,\n            \"JSON_ARRAY\": lambda self: self._parse_json_array(\n                exp.JSONArray,\n                expressions=self._parse_csv(lambda: self._parse_format_json(self._parse_bitwise())),\n            ),\n            \"JSON_ARRAYAGG\": lambda self: self._parse_json_array(\n                exp.JSONArrayAgg,\n                this=self._parse_format_json(self._parse_bitwise()),\n                order=self._parse_order(),\n            ),\n            \"XMLTABLE\": _parse_xml_table,\n        }\n\n        TYPE_LITERAL_PARSERS = {\n            exp.DataType.Type.DATE: lambda self, this, _: self.expression(\n                exp.DateStrToDate, this=this\n            )\n        }\n\n        # SELECT UNIQUE .. is old-style Oracle syntax for SELECT DISTINCT ..\n        # Reference: https://stackoverflow.com/a/336455\n        DISTINCT_TOKENS = {TokenType.DISTINCT, TokenType.UNIQUE}\n\n        def _parse_json_array(self, expr_type: t.Type[E], **kwargs) -> E:\n            return self.expression(\n                expr_type,\n                null_handling=self._parse_on_handling(\"NULL\", \"NULL\", \"ABSENT\"),\n                return_type=self._match_text_seq(\"RETURNING\") and self._parse_type(),\n                strict=self._match_text_seq(\"STRICT\"),\n                **kwargs,\n            )\n\n        def _parse_column(self) -> t.Optional[exp.Expression]:\n            column = super()._parse_column()\n            if column:\n                column.set(\"join_mark\", self._match(TokenType.JOIN_MARKER))\n            return column\n\n        def _parse_hint(self) -> t.Optional[exp.Hint]:\n            if self._match(TokenType.HINT):\n                start = self._curr\n                while self._curr and not self._match_pair(TokenType.STAR, TokenType.SLASH):\n                    self._advance()\n\n                if not self._curr:\n                    self.raise_error(\"Expected */ after HINT\")\n\n                end = self._tokens[self._index - 3]\n                return exp.Hint(expressions=[self._find_sql(start, end)])\n\n            return None\n\n    class Generator(generator.Generator):\n        LOCKING_READS_SUPPORTED = True\n        JOIN_HINTS = False\n        TABLE_HINTS = False\n        COLUMN_JOIN_MARKS_SUPPORTED = True\n        DATA_TYPE_SPECIFIERS_ALLOWED = True\n        ALTER_TABLE_ADD_COLUMN_KEYWORD = False\n\n        LIMIT_FETCH = \"FETCH\"\n\n        TYPE_MAPPING = {\n            **generator.Generator.TYPE_MAPPING,\n            exp.DataType.Type.TINYINT: \"NUMBER\",\n            exp.DataType.Type.SMALLINT: \"NUMBER\",\n            exp.DataType.Type.INT: \"NUMBER\",\n            exp.DataType.Type.BIGINT: \"NUMBER\",\n            exp.DataType.Type.DECIMAL: \"NUMBER\",\n            exp.DataType.Type.DOUBLE: \"DOUBLE PRECISION\",\n            exp.DataType.Type.VARCHAR: \"VARCHAR2\",\n            exp.DataType.Type.NVARCHAR: \"NVARCHAR2\",\n            exp.DataType.Type.NCHAR: \"NCHAR\",\n            exp.DataType.Type.TEXT: \"CLOB\",\n            exp.DataType.Type.BINARY: \"BLOB\",\n            exp.DataType.Type.VARBINARY: \"BLOB\",\n        }\n\n        TRANSFORMS = {\n            **generator.Generator.TRANSFORMS,\n            exp.DateStrToDate: lambda self, e: self.func(\n                \"TO_DATE\", e.this, exp.Literal.string(\"YYYY-MM-DD\")\n            ),\n            exp.Group: transforms.preprocess([transforms.unalias_group]),\n            exp.ILike: no_ilike_sql,\n            exp.Select: transforms.preprocess(\n                [\n                    transforms.eliminate_distinct_on,\n                    transforms.eliminate_qualify,\n                ]\n            ),\n            exp.StrToTime: lambda self, e: f\"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})\",\n            exp.Subquery: lambda self, e: self.subquery_sql(e, sep=\" \"),\n            exp.Substring: rename_func(\"SUBSTR\"),\n            exp.Table: lambda self, e: self.table_sql(e, sep=\" \"),\n            exp.TableSample: lambda self, e: self.tablesample_sql(e, sep=\" \"),\n            exp.TimeToStr: lambda self, e: f\"TO_CHAR({self.sql(e, 'this')}, {self.format_time(e)})\",\n            exp.ToChar: lambda self, e: self.function_fallback_sql(e),\n            exp.Trim: trim_sql,\n            exp.UnixToTime: lambda self, e: f\"TO_DATE('1970-01-01','YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)\",\n        }\n\n        PROPERTIES_LOCATION = {\n            **generator.Generator.PROPERTIES_LOCATION,\n            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,\n        }\n\n        def offset_sql(self, expression: exp.Offset) -> str:\n            return f\"{super().offset_sql(expression)} ROWS\"\n\n        def xmltable_sql(self, expression: exp.XMLTable) -> str:\n            this = self.sql(expression, \"this\")\n            passing = self.expressions(expression, key=\"passing\")\n            passing = f\"{self.sep()}PASSING{self.seg(passing)}\" if passing else \"\"\n            columns = self.expressions(expression, key=\"columns\")\n            columns = f\"{self.sep()}COLUMNS{self.seg(columns)}\" if columns else \"\"\n            by_ref = (\n                f\"{self.sep()}RETURNING SEQUENCE BY REF\" if expression.args.get(\"by_ref\") else \"\"\n            )\n            return f\"XMLTABLE({self.sep('')}{self.indent(this + passing + by_ref + columns)}{self.seg(')', sep='')}\"\n\n        def add_column_sql(self, expression: exp.AlterTable) -> str:\n            actions = self.expressions(expression, key=\"actions\", flat=True)\n            if len(expression.args.get(\"actions\", [])) > 1:\n                return f\"ADD ({actions})\"\n            return f\"ADD {actions}\"\n\n    class Tokenizer(tokens.Tokenizer):\n        VAR_SINGLE_TOKENS = {\"@\", \"$\", \"#\"}\n\n        KEYWORDS = {\n            **tokens.Tokenizer.KEYWORDS,\n            \"(+)\": TokenType.JOIN_MARKER,\n            \"BINARY_DOUBLE\": TokenType.DOUBLE,\n            \"BINARY_FLOAT\": TokenType.FLOAT,\n            \"COLUMNS\": TokenType.COLUMN,\n            \"MATCH_RECOGNIZE\": TokenType.MATCH_RECOGNIZE,\n            \"MINUS\": TokenType.EXCEPT,\n            \"NVARCHAR2\": TokenType.NVARCHAR,\n            \"SAMPLE\": TokenType.TABLE_SAMPLE,\n            \"START\": TokenType.BEGIN,\n            \"TOP\": TokenType.TOP,\n            \"VARCHAR2\": TokenType.VARCHAR,\n        }\n", "path": "sqlglot/dialects/oracle.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport typing as t\n\nfrom sqlglot import exp, generator, parser, tokens, transforms\nfrom sqlglot.dialects.dialect import (\n    Dialect,\n    format_time_lambda,\n    no_ilike_sql,\n    rename_func,\n    trim_sql,\n)\nfrom sqlglot.helper import seq_get\nfrom sqlglot.tokens import TokenType\n\nif t.TYPE_CHECKING:\n    from sqlglot._typing import E\n\n\ndef _parse_xml_table(self: Oracle.Parser) -> exp.XMLTable:\n    this = self._parse_string()\n\n    passing = None\n    columns = None\n\n    if self._match_text_seq(\"PASSING\"):\n        # The BY VALUE keywords are optional and are provided for semantic clarity\n        self._match_text_seq(\"BY\", \"VALUE\")\n        passing = self._parse_csv(self._parse_column)\n\n    by_ref = self._match_text_seq(\"RETURNING\", \"SEQUENCE\", \"BY\", \"REF\")\n\n    if self._match_text_seq(\"COLUMNS\"):\n        columns = self._parse_csv(self._parse_field_def)\n\n    return self.expression(exp.XMLTable, this=this, passing=passing, columns=columns, by_ref=by_ref)\n\n\nclass Oracle(Dialect):\n    ALIAS_POST_TABLESAMPLE = True\n    LOCKING_READS_SUPPORTED = True\n\n    # See section 8: https://docs.oracle.com/cd/A97630_01/server.920/a96540/sql_elements9a.htm\n    RESOLVES_IDENTIFIERS_AS_UPPERCASE = True\n    ALTER_TABLE_ADD_COLUMN_KEYWORD = False\n\n    # https://docs.oracle.com/database/121/SQLRF/sql_elements004.htm#SQLRF00212\n    # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes\n    TIME_MAPPING = {\n        \"AM\": \"%p\",  # Meridian indicator with or without periods\n        \"A.M.\": \"%p\",  # Meridian indicator with or without periods\n        \"PM\": \"%p\",  # Meridian indicator with or without periods\n        \"P.M.\": \"%p\",  # Meridian indicator with or without periods\n        \"D\": \"%u\",  # Day of week (1-7)\n        \"DAY\": \"%A\",  # name of day\n        \"DD\": \"%d\",  # day of month (1-31)\n        \"DDD\": \"%j\",  # day of year (1-366)\n        \"DY\": \"%a\",  # abbreviated name of day\n        \"HH\": \"%I\",  # Hour of day (1-12)\n        \"HH12\": \"%I\",  # alias for HH\n        \"HH24\": \"%H\",  # Hour of day (0-23)\n        \"IW\": \"%V\",  # Calendar week of year (1-52 or 1-53), as defined by the ISO 8601 standard\n        \"MI\": \"%M\",  # Minute (0-59)\n        \"MM\": \"%m\",  # Month (01-12; January = 01)\n        \"MON\": \"%b\",  # Abbreviated name of month\n        \"MONTH\": \"%B\",  # Name of month\n        \"SS\": \"%S\",  # Second (0-59)\n        \"WW\": \"%W\",  # Week of year (1-53)\n        \"YY\": \"%y\",  # 15\n        \"YYYY\": \"%Y\",  # 2015\n    }\n\n    class Parser(parser.Parser):\n        WINDOW_BEFORE_PAREN_TOKENS = {TokenType.OVER, TokenType.KEEP}\n\n        FUNCTIONS = {\n            **parser.Parser.FUNCTIONS,\n            \"SQUARE\": lambda args: exp.Pow(this=seq_get(args, 0), expression=exp.Literal.number(2)),\n            \"TO_CHAR\": format_time_lambda(exp.TimeToStr, \"oracle\", default=True),\n        }\n\n        FUNCTION_PARSERS: t.Dict[str, t.Callable] = {\n            **parser.Parser.FUNCTION_PARSERS,\n            \"JSON_ARRAY\": lambda self: self._parse_json_array(\n                exp.JSONArray,\n                expressions=self._parse_csv(lambda: self._parse_format_json(self._parse_bitwise())),\n            ),\n            \"JSON_ARRAYAGG\": lambda self: self._parse_json_array(\n                exp.JSONArrayAgg,\n                this=self._parse_format_json(self._parse_bitwise()),\n                order=self._parse_order(),\n            ),\n            \"XMLTABLE\": _parse_xml_table,\n        }\n\n        TYPE_LITERAL_PARSERS = {\n            exp.DataType.Type.DATE: lambda self, this, _: self.expression(\n                exp.DateStrToDate, this=this\n            )\n        }\n\n        # SELECT UNIQUE .. is old-style Oracle syntax for SELECT DISTINCT ..\n        # Reference: https://stackoverflow.com/a/336455\n        DISTINCT_TOKENS = {TokenType.DISTINCT, TokenType.UNIQUE}\n\n        def _parse_json_array(self, expr_type: t.Type[E], **kwargs) -> E:\n            return self.expression(\n                expr_type,\n                null_handling=self._parse_on_handling(\"NULL\", \"NULL\", \"ABSENT\"),\n                return_type=self._match_text_seq(\"RETURNING\") and self._parse_type(),\n                strict=self._match_text_seq(\"STRICT\"),\n                **kwargs,\n            )\n\n        def _parse_column(self) -> t.Optional[exp.Expression]:\n            column = super()._parse_column()\n            if column:\n                column.set(\"join_mark\", self._match(TokenType.JOIN_MARKER))\n            return column\n\n        def _parse_hint(self) -> t.Optional[exp.Hint]:\n            if self._match(TokenType.HINT):\n                start = self._curr\n                while self._curr and not self._match_pair(TokenType.STAR, TokenType.SLASH):\n                    self._advance()\n\n                if not self._curr:\n                    self.raise_error(\"Expected */ after HINT\")\n\n                end = self._tokens[self._index - 3]\n                return exp.Hint(expressions=[self._find_sql(start, end)])\n\n            return None\n\n    class Generator(generator.Generator):\n        LOCKING_READS_SUPPORTED = True\n        JOIN_HINTS = False\n        TABLE_HINTS = False\n        COLUMN_JOIN_MARKS_SUPPORTED = True\n        DATA_TYPE_SPECIFIERS_ALLOWED = True\n        ALTER_TABLE_ADD_COLUMN_KEYWORD = False\n\n        LIMIT_FETCH = \"FETCH\"\n\n        TYPE_MAPPING = {\n            **generator.Generator.TYPE_MAPPING,\n            exp.DataType.Type.TINYINT: \"NUMBER\",\n            exp.DataType.Type.SMALLINT: \"NUMBER\",\n            exp.DataType.Type.INT: \"NUMBER\",\n            exp.DataType.Type.BIGINT: \"NUMBER\",\n            exp.DataType.Type.DECIMAL: \"NUMBER\",\n            exp.DataType.Type.DOUBLE: \"DOUBLE PRECISION\",\n            exp.DataType.Type.VARCHAR: \"VARCHAR2\",\n            exp.DataType.Type.NVARCHAR: \"NVARCHAR2\",\n            exp.DataType.Type.NCHAR: \"NCHAR\",\n            exp.DataType.Type.TEXT: \"CLOB\",\n            exp.DataType.Type.BINARY: \"BLOB\",\n            exp.DataType.Type.VARBINARY: \"BLOB\",\n        }\n\n        TRANSFORMS = {\n            **generator.Generator.TRANSFORMS,\n            exp.DateStrToDate: lambda self, e: self.func(\n                \"TO_DATE\", e.this, exp.Literal.string(\"YYYY-MM-DD\")\n            ),\n            exp.Group: transforms.preprocess([transforms.unalias_group]),\n            exp.ILike: no_ilike_sql,\n            exp.Select: transforms.preprocess(\n                [\n                    transforms.eliminate_distinct_on,\n                    transforms.eliminate_qualify,\n                ]\n            ),\n            exp.StrToTime: lambda self, e: f\"TO_TIMESTAMP({self.sql(e, 'this')}, {self.format_time(e)})\",\n            exp.Subquery: lambda self, e: self.subquery_sql(e, sep=\" \"),\n            exp.Substring: rename_func(\"SUBSTR\"),\n            exp.Table: lambda self, e: self.table_sql(e, sep=\" \"),\n            exp.TableSample: lambda self, e: self.tablesample_sql(e, sep=\" \"),\n            exp.TimeToStr: lambda self, e: f\"TO_CHAR({self.sql(e, 'this')}, {self.format_time(e)})\",\n            exp.ToChar: lambda self, e: self.function_fallback_sql(e),\n            exp.Trim: trim_sql,\n            exp.UnixToTime: lambda self, e: f\"TO_DATE('1970-01-01','YYYY-MM-DD') + ({self.sql(e, 'this')} / 86400)\",\n        }\n\n        PROPERTIES_LOCATION = {\n            **generator.Generator.PROPERTIES_LOCATION,\n            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,\n        }\n\n        def offset_sql(self, expression: exp.Offset) -> str:\n            return f\"{super().offset_sql(expression)} ROWS\"\n\n        def xmltable_sql(self, expression: exp.XMLTable) -> str:\n            this = self.sql(expression, \"this\")\n            passing = self.expressions(expression, key=\"passing\")\n            passing = f\"{self.sep()}PASSING{self.seg(passing)}\" if passing else \"\"\n            columns = self.expressions(expression, key=\"columns\")\n            columns = f\"{self.sep()}COLUMNS{self.seg(columns)}\" if columns else \"\"\n            by_ref = (\n                f\"{self.sep()}RETURNING SEQUENCE BY REF\" if expression.args.get(\"by_ref\") else \"\"\n            )\n            return f\"XMLTABLE({self.sep('')}{self.indent(this + passing + by_ref + columns)}{self.seg(')', sep='')}\"\n\n        def add_column_sql(self, expression: exp.AlterTable) -> str:\n            actions = self.expressions(expression, key=\"actions\", flat=True)\n            if len(expression.args.get(\"actions\", [])) > 1:\n                return f\"ADD ({actions})\"\n            return f\"ADD {actions}\"\n\n    class Tokenizer(tokens.Tokenizer):\n        VAR_SINGLE_TOKENS = {\"@\", \"$\", \"#\"}\n\n        KEYWORDS = {\n            **tokens.Tokenizer.KEYWORDS,\n            \"(+)\": TokenType.JOIN_MARKER,\n            \"BINARY_DOUBLE\": TokenType.DOUBLE,\n            \"BINARY_FLOAT\": TokenType.FLOAT,\n            \"COLUMNS\": TokenType.COLUMN,\n            \"MATCH_RECOGNIZE\": TokenType.MATCH_RECOGNIZE,\n            \"MINUS\": TokenType.EXCEPT,\n            \"NVARCHAR2\": TokenType.NVARCHAR,\n            \"SAMPLE\": TokenType.TABLE_SAMPLE,\n            \"START\": TokenType.BEGIN,\n            \"TOP\": TokenType.TOP,\n            \"VARCHAR2\": TokenType.VARCHAR,\n        }\n", "path": "sqlglot/dialects/oracle.py"}]}