Skip to content

Commit

Permalink
Feat!: extend ANALYZE common syntax to cover multiple dialects (#4591)
Browse files Browse the repository at this point in the history
* Extend ANALYZE common syntax to cover multiple dialects

* Support starrocks and redshift

* parse VALIDATE and SAMPLE statements

* Parse oracle ANALYZE LIST and ANALYZE DELETE

* Fix analyze list chained rows type hint

* Fix analyze with type hint

* Simplify generator logic (1)

* Simplify generator logic (2)

---------

Co-authored-by: Jo <[email protected]>
  • Loading branch information
zashroof and georgesittas authored Jan 14, 2025
1 parent b7ab3f1 commit e617d40
Show file tree
Hide file tree
Showing 17 changed files with 412 additions and 65 deletions.
61 changes: 58 additions & 3 deletions sqlglot/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4718,20 +4718,75 @@ def actions(self) -> t.List[Expression]:

class Analyze(Expression):
arg_types = {
"kind": True,
"kind": False,
"this": False,
"options": False,
"mode": False,
"partition": False,
"expression": True,
"expression": False,
"properties": False,
}


class ComputeStatistics(Expression):
class Statistics(Expression):
arg_types = {
"kind": True,
"option": False,
"this": False,
"expressions": False,
}


class Histogram(Expression):
arg_types = {
"this": True,
"expressions": True,
"expression": False,
"update_options": False,
}


class Sample(Expression):
arg_types = {
"kind": True,
"sample": True,
}


class AnalyzeListChainedRows(Expression):
arg_types = {
"expression": False,
}


class AnalyzeDelete(Expression):
arg_types = {
"kind": False,
}


class AnalyzeWith(Expression):
arg_types = {
"expressions": True,
}


class AnalyzeValidate(Expression):
arg_types = {
"kind": True,
"this": False,
"expression": False,
}


class AnalyzeColumns(Expression):
pass


class UsingData(Expression):
pass


class AddConstraint(Expression):
arg_types = {"expressions": True}

Expand Down
62 changes: 56 additions & 6 deletions sqlglot/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4656,22 +4656,72 @@ def unpivotcolumns_sql(self, expression: exp.UnpivotColumns) -> str:

return f"NAME {name} VALUE {values}"

def computestatistics_sql(self, expression: exp.ComputeStatistics) -> str:
def sample_sql(self, expression: exp.Sample) -> str:
kind = self.sql(expression, "kind")
sample = self.sql(expression, "sample")
return f"SAMPLE {sample} {kind}"

def statistics_sql(self, expression: exp.Statistics) -> str:
kind = self.sql(expression, "kind")
option = self.sql(expression, "option")
option = f" {option}" if option else ""
this = self.sql(expression, "this")
this = f" {this}" if this else ""
columns = self.expressions(expression)
columns = f" {columns}" if columns else ""
return f"COMPUTE STATISTICS {this}{columns}"
return f"{kind}{option} STATISTICS{this}{columns}"

def histogram_sql(self, expression: exp.Histogram) -> str:
this = self.sql(expression, "this")
columns = self.expressions(expression)
inner_expression = self.sql(expression, "expression")
inner_expression = f" {inner_expression}" if inner_expression else ""
update_options = self.sql(expression, "update_options")
update_options = f" {update_options} UPDATE" if update_options else ""
return f"{this} HISTOGRAM ON {columns}{inner_expression}{update_options}"

def usingdata_sql(self, expression: exp.UsingData) -> str:
data = self.sql(expression, "this")
return f"USING DATA {data}"

def analyzecolumns_sql(self, expression: exp.AnalyzeColumns) -> str:
return self.sql(expression, "this")

def analyzedelete_sql(self, expression: exp.AnalyzeDelete) -> str:
kind = self.sql(expression, "kind")
kind = f" {kind}" if kind else ""
return f"DELETE{kind} STATISTICS"

def analyzewith_sql(self, expression: exp.AnalyzeWith) -> str:
return self.expressions(expression, prefix="WITH ", sep=" ")

def analyzelistchainedrows_sql(self, expression: exp.AnalyzeListChainedRows) -> str:
inner_expression = self.sql(expression, "expression")
return f"LIST CHAINED ROWS{inner_expression}"

def analyzevalidate_sql(self, expression: exp.AnalyzeValidate) -> str:
kind = self.sql(expression, "kind")
this = self.sql(expression, "this")
this = f" {this}" if this else ""
inner_expression = self.sql(expression, "expression")
return f"VALIDATE {kind}{this}{inner_expression}"

def analyze_sql(self, expression: exp.Analyze) -> str:
options = self.expressions(expression, key="options", sep=" ")
options = f" {options}" if options else ""
kind = self.sql(expression, "kind")
kind = f" {kind}" if kind else ""
this = self.sql(expression, "this")
this = f" {this}" if this else ""
if this and kind == "TABLES":
this = f" FROM{this}"
mode = self.sql(expression, "mode")
mode = f" {mode}" if mode else ""
properties = self.sql(expression, "properties")
properties = f" {properties}" if properties else ""
partition = self.sql(expression, "partition")
partition = f" {partition}" if partition else ""
inner_expression = f" {self.sql(expression, 'expression')}"
return f"ANALYZE {kind}{this}{partition}{inner_expression}"
inner_expression = self.sql(expression, "expression")
inner_expression = f" {inner_expression}" if inner_expression else ""
return f"ANALYZE{options}{kind}{this}{partition}{mode}{inner_expression}{properties}"

def xmltable_sql(self, expression: exp.XMLTable) -> str:
this = self.sql(expression, "this")
Expand Down
Loading

0 comments on commit e617d40

Please sign in to comment.