Skip to content

Commit c545a8c

Browse files
committed
feat(parser): parse CALLED ON NULL INPUT as a property instead of Command
1 parent 91a781b commit c545a8c

6 files changed

Lines changed: 23 additions & 3 deletions

File tree

sqlglot/expressions/properties.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class BlockCompressionProperty(Property):
6363
}
6464

6565

66+
class CalledOnNullInputProperty(Property):
67+
arg_types = {}
68+
69+
6670
class CatalogProperty(Property):
6771
arg_types = {}
6872

sqlglot/generator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class Generator:
149149
exp.CaseSpecificColumnConstraint: lambda _, e: (
150150
f"{'NOT ' if e.args.get('not_') else ''}CASESPECIFIC"
151151
),
152+
exp.CalledOnNullInputProperty: lambda *_: "CALLED ON NULL INPUT",
152153
exp.Ceil: lambda self, e: self.ceil_floor(e),
153154
exp.CharacterSetColumnConstraint: lambda self, e: f"CHARACTER SET {self.sql(e, 'this')}",
154155
exp.CharacterSetProperty: lambda self, e: (
@@ -677,6 +678,7 @@ class Generator:
677678
exp.AutoRefreshProperty: exp.Properties.Location.POST_SCHEMA,
678679
exp.BackupProperty: exp.Properties.Location.POST_SCHEMA,
679680
exp.BlockCompressionProperty: exp.Properties.Location.POST_NAME,
681+
exp.CalledOnNullInputProperty: exp.Properties.Location.POST_SCHEMA,
680682
exp.CatalogProperty: exp.Properties.Location.POST_CREATE,
681683
exp.CharacterSetProperty: exp.Properties.Location.POST_SCHEMA,
682684
exp.ChecksumProperty: exp.Properties.Location.POST_NAME,

sqlglot/parser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,7 @@ class Parser:
12361236
exp.BackupProperty(this=self._parse_var(any_token=True))
12371237
),
12381238
"BLOCKCOMPRESSION": lambda self: self._parse_blockcompression(),
1239+
"CALLED": lambda self: self._parse_called_on_null_input_property(),
12391240
"CHARSET": lambda self, **kwargs: self._parse_character_set(**kwargs),
12401241
"CHARACTER SET": lambda self, **kwargs: self._parse_character_set(**kwargs),
12411242
"CHECKSUM": lambda self: self._parse_checksum(),
@@ -2900,6 +2901,14 @@ def _parse_settings_property(self) -> exp.SettingsProperty:
29002901
exp.SettingsProperty(expressions=self._parse_csv(self._parse_assignment))
29012902
)
29022903

2904+
def _parse_called_on_null_input_property(self) -> exp.CalledOnNullInputProperty | None:
2905+
index = self._index
2906+
if self._match_text_seq("ON", "NULL", "INPUT"):
2907+
return self.expression(exp.CalledOnNullInputProperty())
2908+
2909+
self._retreat(index - 1)
2910+
return None
2911+
29032912
def _parse_volatile_property(self) -> exp.VolatileProperty | exp.StabilityProperty:
29042913
if self._index >= 2:
29052914
pre_volatile_token = self._tokens[self._index - 2]

tests/dialects/test_postgres.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,8 +1292,8 @@ def test_ddl(self):
12921292
)
12931293
self.validate_identity(
12941294
"CREATE FUNCTION add(integer, integer) RETURNS integer AS 'select $1 + $2;' LANGUAGE SQL IMMUTABLE CALLED ON NULL INPUT",
1295-
check_command_warning=True,
1296-
)
1295+
"CREATE FUNCTION add(integer, integer) RETURNS INT LANGUAGE SQL IMMUTABLE CALLED ON NULL INPUT AS 'select $1 + $2;'",
1296+
).assert_is(exp.Create)
12971297
self.validate_identity(
12981298
"CREATE CONSTRAINT TRIGGER my_trigger AFTER INSERT OR DELETE OR UPDATE OF col_a, col_b ON public.my_table DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION DO_STH()"
12991299
)

tests/dialects/test_snowflake.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4322,7 +4322,7 @@ def test_ddl(self):
43224322
)
43234323
self.validate_identity(
43244324
"""CREATE OR REPLACE FUNCTION ibis_udfs.public.object_values("obj" OBJECT) RETURNS ARRAY LANGUAGE JAVASCRIPT RETURNS NULL ON NULL INPUT AS ' return Object.values(obj) '"""
4325-
)
4325+
).assert_is(exp.Create)
43264326
self.validate_identity(
43274327
"""CREATE OR REPLACE FUNCTION ibis_udfs.public.object_values("obj" OBJECT) RETURNS ARRAY LANGUAGE JAVASCRIPT STRICT AS ' return Object.values(obj) '"""
43284328
)
@@ -4427,6 +4427,10 @@ def test_user_defined_functions(self):
44274427
"snowflake": "CREATE FUNCTION a() RETURNS INT IMMUTABLE AS 'SELECT 1'",
44284428
},
44294429
)
4430+
self.validate_identity(
4431+
"CREATE FUNCTION a(x FLOAT) RETURNS FLOAT LANGUAGE SQL CALLED ON NULL INPUT AS $$ RETURN x * 2; $$",
4432+
"CREATE FUNCTION a(x DOUBLE) RETURNS DOUBLE LANGUAGE SQL CALLED ON NULL INPUT AS ' RETURN x * 2; '",
4433+
).assert_is(exp.Create)
44304434

44314435
self.validate_identity(
44324436
"CREATE OR REPLACE FUNCTION repro_fn() RETURNS INT LANGUAGE PYTHON HANDLER = 'fn' RUNTIME_VERSION='3.11' PACKAGES=() AS '\\ndef fn():\\n return 1\\n'"

tests/fixtures/identity.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ CREATE FUNCTION a.b(x INT) RETURNS INT AS RETURN x + 1
632632
CREATE FUNCTION a.b(x TEXT) RETURNS TEXT CONTAINS SQL AS RETURN x
633633
CREATE FUNCTION a.b(x TEXT) RETURNS TEXT LANGUAGE SQL MODIFIES SQL DATA AS RETURN x
634634
CREATE FUNCTION a.b(x TEXT) LANGUAGE SQL READS SQL DATA RETURNS TEXT AS RETURN x
635+
CREATE FUNCTION a(x INT) RETURNS INT LANGUAGE SQL CALLED ON NULL INPUT AS 'SELECT 1'
635636
CREATE FUNCTION a.b.c()
636637
CREATE INDEX abc ON t(a)
637638
CREATE INDEX "abc" ON t(a)

0 commit comments

Comments
 (0)