sqlglot
sqlglot copied to clipboard
[draft] - Noklam/fix alter table alter column drop not null
fix: #3534 Context:
class AlterColumn(Expression):
arg_types = {
"this": True,
"dtype": False,
"collate": False,
"using": False,
"default": False,
"drop": False,
"comment": False,
}
The existing AlterColumn expression seems to assume only SET DEFAULT and NOT DEFAULT is possible. Therefore is drop is True is sufficient to represent DROP DEFAULT and when default is not null it means set default. This seems to be insufficient to handle statement like DROP NOT NULL and SET NOT NULL
Few questions:
- there are many
_match_xxxfunctions, is_match_text_seqthe most suitable one? - I don't know if I should use things like
_parse_not_constraintshere. - I figured I should edit the
AlterColumnexpression, but I am not sure how to add a new type forSET NOT NULLandDROP NOT NULL. I found there areNotNullColumnConstrains. I take a look at other expression and I thought adding a new optional arg_typeexpressionseems to best fit.
Test
Reuse the original issue example.
from sqlglot import parse_one
query = """
ALTER TABLE DB_NAME.SCHMA_NAME.TBL_NAME
ALTER COLUMN MY_COLUMN DROP NOT NULL ;
"""
parsed = parse_one(query, read='snowflake')
This gives me:
AlterTable(
this=Table(
this=Identifier(this=TBL_NAME, quoted=False),
db=Identifier(this=SCHMA_NAME, quoted=False),
catalog=Identifier(this=DB_NAME, quoted=False)),
actions=[
AlterColumn(
this=Identifier(this=MY_COLUMN, quoted=False),
drop=True,
expression=<class 'sqlglot.expressions.NotNullColumnConstraint'>)])
But on the transpile step I get error that I cannot understand and would appreciate some help:
a =parsed.sql(dialect="duckdb")
Details
Traceback (most recent call last): File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/nok.py", line 26, in <module> a =parsed.sql(dialect="duckdb") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/sqlglot/expressions.py", line 597, in sql return Dialect.get_or_raise(dialect).generate(self, **opts) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/sqlglot/dialects/dialect.py", line 520, in generate return self.generator(**opts).generate(expression, copy=copy) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/sqlglot/generator.py", line 615, in generate expression = expression.copy() ^^^^^^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/sqlglot/expressions.py", line 302, in copy return deepcopy(self) ^^^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/miniconda3/lib/python3.11/copy.py", line 153, in deepcopy y = copier(memo) ^^^^^^^^^^^^ File "/Users/Nok_Lam_Chan/Documents/GitHub/sqlglot/sqlglot/expressions.py", line 282, in __deepcopy__ stack.append((vs, vs.__class__())) ^^^^^^^^^^^^^^ TypeError: _Expression.__new__() missing 3 required positional arguments: 'clsname', 'bases', and 'attrs'