MCPcopy Create free account
hub / github.com/dolthub/doltgresql / Convert

Method Convert

server/plpgsql/json.go:644–707  ·  view source on GitHub ↗

Convert converts the JSON statement into its output form.

()

Source from the content-addressed store, hash-verified

642
643// Convert converts the JSON statement into its output form.
644func (stmt *plpgSQL_stmt_if) Convert() (Block, error) {
645 // We store all GOTOs that will need to go to the end of the block. Since we can't know that ahead of time, we store
646 // their indexes and set them at the end of the function.
647 type gotoEndIndex struct {
648 BodyIndex int
649 GotoIndex int32
650 }
651 var gotoEndIndexes []gotoEndIndex
652 returnBlock := Block{
653 Body: []Statement{
654 If{
655 Condition: stmt.Condition.Expression.Query,
656 GotoOffset: 2, // The operation following the conditional skips the THEN statements, so we're skipping that
657 },
658 },
659 }
660 // We'll parse our THEN statements, but we won't add them to the block just yet as we need their operation sizes
661 thenStmts, err := jsonConvertStatements(stmt.Then)
662 if err != nil {
663 return Block{}, err
664 }
665 // When the condition is false, we want to skip our THEN block, so we do that (plus the GOTO which finishes the THEN block)
666 returnBlock.Body = append(returnBlock.Body, Goto{Offset: OperationSizeForStatements(thenStmts) + 2})
667 // Then we'll append our THEN block
668 returnBlock.Body = append(returnBlock.Body, thenStmts...)
669 // Then we want to append the GOTO that finishes the THEN block, but we don't know the end just yet, so we'll save
670 // its index and fill it in later
671 gotoEndIndexes = append(gotoEndIndexes, gotoEndIndex{
672 BodyIndex: len(returnBlock.Body),
673 GotoIndex: OperationSizeForStatements(returnBlock.Body),
674 })
675 returnBlock.Body = append(returnBlock.Body, Goto{})
676 // We repeat the same process for each ELSIF statement (refer to the comments above)
677 for _, elseIf := range stmt.ElseIf {
678 returnBlock.Body = append(returnBlock.Body, If{
679 Condition: elseIf.ElseIf.Condition.Expression.Query,
680 GotoOffset: 2, // Same rules as skipping our THEN statement above
681 })
682 elseIfStmts, err := jsonConvertStatements(elseIf.ElseIf.Then)
683 if err != nil {
684 return Block{}, err
685 }
686 returnBlock.Body = append(returnBlock.Body, Goto{Offset: OperationSizeForStatements(elseIfStmts) + 2})
687 returnBlock.Body = append(returnBlock.Body, elseIfStmts...)
688 gotoEndIndexes = append(gotoEndIndexes, gotoEndIndex{
689 BodyIndex: len(returnBlock.Body),
690 GotoIndex: OperationSizeForStatements(returnBlock.Body),
691 })
692 returnBlock.Body = append(returnBlock.Body, Goto{})
693 }
694 // Finally we handle our ELSE statements. We don't have a condition to check, so we don't have to append any
695 // additional GOTOs.
696 elseStmts, err := jsonConvertStatements(stmt.Else)
697 if err != nil {
698 return Block{}, err
699 }
700 returnBlock.Body = append(returnBlock.Body, elseStmts...)
701 // Now we'll set all of our GOTOs so that they skip to the end of the block.

Callers 1

jsonConvertStatementFunction · 0.45

Calls 2

jsonConvertStatementsFunction · 0.85

Tested by

no test coverage detected