-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reporting CTE Materialized clause and Sql body in Function #2165
base: main
Are you sure you want to change the base?
Conversation
047fb53
to
fc1b227
Compare
@@ -566,6 +566,19 @@ func NewForeignKeyReferencesPartitionedTableIssue(objectType string, objectName | |||
return newQueryIssue(foreignKeyReferencesPartitionedTableIssue, objectType, objectName, SqlStatement, details) | |||
} | |||
|
|||
var sqlBodyInFunctionIssue = issue.Issue{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please define a Description for each issue moving forward.
Type: CTE_WITH_MATERIALIZED_CLAUSE, | ||
Name: CTE_WITH_MATERIALIZED_CLAUSE_NAME, | ||
Impact: constants.IMPACT_LEVEL_2, | ||
Description: "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly here.
if err != nil { | ||
return err | ||
} | ||
if cteNode.Ctematerialized != queryparser.CTE_MATERIALIZED_DEFAULT { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment here explaining that both MATERIALIZED, NOT MATERIALIZED flags were not supported..
} | ||
var issues []QueryIssue | ||
|
||
if function.HasSqlBody { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Can you use just
BEGIN
to start a function block? - If so, are both
BEGIN
andBEGIN ATOMIC
unsupported? sql_body could also just be a "return expression" from docs. Would that also be unsupported? https://www.postgresql.org/docs/current/sql-createfunction.html#:~:text=a%20new%20session.-,sql_body,is%20more%20compatible%20with%20the%20SQL%20standard%20and%20other%20SQL%20implementations.,-OverloadingI see in your test that that is also unsupported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use just BEGIN to start a function block?
yes BEGIN can also start a function block
If so, are both BEGIN and BEGIN ATOMIC unsupported?
No only BEGIN ATOMIC
is unsupported as its PG 15 feature
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but will function.HasSqlBody
be true even if the function has just BEGIN
? That would be a problem, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this HasSqlBody
is true only if the parser has populated the sql_body
field for function stmt, which is a new PG 15 feature for the BEGIN ATOMIC/RETURN expr
type of function block. So, in normal BEGIN cases, this can't be true.
) | ||
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref | ||
WHERE w2.key = 123;`: `syntax error at or near "NOT"`, | ||
`WITH moved_rows AS MATERIALIZED ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add a sql for NOT MATERIALIZED
as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes its there as first stmt
@@ -420,28 +412,44 @@ func ProtoAsSelectStmt(msg protoreflect.Message) (*pg_query.SelectStmt, error) { | |||
return selectStmtNode, nil | |||
} | |||
|
|||
func ProtoAsCTENode(msg protoreflect.Message) (*pg_query.CommonTableExpr, error) { | |||
protoMsg, ok := msg.Interface().(proto.Message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found out recently you don't need to do two steps.
You can convert it in one step directly.
msg.Interface().(*pg_query.xxx)
@@ -1070,7 +1070,7 @@ func fetchUnsupportedPGFeaturesFromSchemaReport(schemaAnalysisReport utils.Schem | |||
unsupportedFeatures = append(unsupportedFeatures, getUnsupportedFeaturesFromSchemaAnalysisReport(queryissue.JSONB_SUBSCRIPTING_NAME, "", queryissue.JSONB_SUBSCRIPTING, schemaAnalysisReport, false, "")) | |||
unsupportedFeatures = append(unsupportedFeatures, getUnsupportedFeaturesFromSchemaAnalysisReport(queryissue.FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE_NAME, "", queryissue.FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE, schemaAnalysisReport, false, "")) | |||
unsupportedFeatures = append(unsupportedFeatures, getUnsupportedFeaturesFromSchemaAnalysisReport(queryissue.JSON_TYPE_PREDICATE_NAME, "", queryissue.JSON_TYPE_PREDICATE, schemaAnalysisReport, false, "")) | |||
|
|||
unsupportedFeatures = append(unsupportedFeatures, getUnsupportedFeaturesFromSchemaAnalysisReport(queryissue.SQL_BODY_IN_FUNCTION_NAME, "", queryissue.SQL_BODY_IN_FUNCTION, schemaAnalysisReport, false, "")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about MATERIALIZED CTE issue? Can they not show up in DDLs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah CTE can be in CREATE VIEW, adding it here as well
@@ -918,6 +918,9 @@ sqlParsingLoop: | |||
} else if matches := dollarQuoteRegex.FindStringSubmatch(currLine); matches != nil { | |||
dollarQuoteFlag = 1 //denotes start of the code/body part | |||
codeBlockDelimiter = matches[0] | |||
} else if strings.Contains(currLine, "BEGIN ATOMIC") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also fixed in https://github.com/yugabyte/yb-voyager/pull/2201/files ?
Is that a prerequisite for this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes otherwise analyze-schema/assessment won't be able to report the case as our parser will not work
@@ -1021,6 +1021,7 @@ func (mv *FunctionProcessor) Process(parseTree *pg_query.ParseResult) (DDLObject | |||
SchemaName: funcSchemaName, | |||
FuncName: funcName, | |||
ReturnType: GetReturnTypeOfFunc(parseTree), | |||
HasSqlBody: funcNode.CreateFunctionStmt.GetSqlBody() != nil, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if funcNode.CreateFunctionStmt
is nil? Is that possible here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that is not possible if its function node, create function stmt can't be nil.
node, isPlPgSQLObject := getCreateFuncStmtNode(parseTree) | ||
return isPlPgSQLObject && (node.CreateFunctionStmt.SqlBody == nil) //TODO fix proper https://github.com/pganalyze/pg_query_go/issues/129 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how/where are we handling the case when node.CreateFunctionStmt.SqlBody != nil
in a plpgsql object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to handle this case because sqlBody
is only possible in language sql
, so language plpgsql
can't have sql_body
in parser.
docs- https://www.postgresql.org/docs/15/sql-createfunction.html#:~:text=The%20body%20of%20a%20LANGUAGE%20SQL%20function.%20This%20can%20either%20be%20a%20single%20statement
func IsPLPGSQLObject(parseTree *pg_query.ParseResult) bool { | ||
// CREATE FUNCTION is same parser NODE for FUNCTION/PROCEDURE | ||
_, isPlPgSQLObject := getCreateFuncStmtNode(parseTree) | ||
return isPlPgSQLObject | ||
node, isPlPgSQLObject := getCreateFuncStmtNode(parseTree) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
call it node, ok
now because isPlPgSqlObject has logic depending on the node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a nit. Let's wait for Sanyam's approval as well before merging.
Describe the changes in this pull request
Reports the CTE statements with
Materialized
clause as not supported. https://yugabyte.atlassian.net/browse/DB-14227Reports the presence of SQL body in Functions - PG15 docs
https://yugabyte.atlassian.net/browse/DB-14234
Describe if there are any user-facing changes
Added new feature
SQL body in Function
to report functions andModifying the Materialized option with CTE
in assessment.How was this pull request tested?
unit tests and end-to-end-tests
Does your PR have changes that can cause upgrade issues?