Convert converts the JSON statement into its output form.
()
| 344 | |
| 345 | // Convert converts the JSON statement into its output form. |
| 346 | func (stmt *plpgSQL_stmt_case) Convert() (block Block, err error) { |
| 347 | // If the CASE statement has a main expression, start by assigning it to a variable so |
| 348 | // we can evaluate it once and only once. |
| 349 | if stmt.Expression.Expression.Query != "" { |
| 350 | // TODO: pg_query_go creates the definitions for these variables, and |
| 351 | // ideally users shouldn't be able to reference them. We could |
| 352 | // update all the references to them (i.e. declaration, assignment, |
| 353 | // and WHEN block exprs) to change the name to include a \0 char to |
| 354 | // prevent users from referencing them or colliding with them. |
| 355 | block.Body = append(block.Body, Assignment{ |
| 356 | VariableName: fmt.Sprintf("__Case__Variable_%d__", stmt.VarNo), |
| 357 | Expression: stmt.Expression.Expression.Query, |
| 358 | }) |
| 359 | } |
| 360 | |
| 361 | // Record indexes of all the GOTO ops that jump to the very end of the case block so we |
| 362 | // can update them later and plug in the correct offsets after we know the final size. |
| 363 | var gotoEndOpsIndexes []int |
| 364 | |
| 365 | // Add operations for each WHEN statement... |
| 366 | for _, stmt := range stmt.WhenList { |
| 367 | when := stmt.When |
| 368 | if when == nil { |
| 369 | return Block{}, fmt.Errorf("case statement WHEN clause is nil") |
| 370 | } |
| 371 | |
| 372 | // TODO: The generated expressions from pg_query_go uses double quotes |
| 373 | // around the variable name, which is valid for Postgres, but |
| 374 | // our engine doesn't currently resolve double-quoted strings to |
| 375 | // variables, so for now, we just extract the double quotes. |
| 376 | expressionString := when.Expression.Expression.Query |
| 377 | expressionString = strings.ReplaceAll(expressionString, `"`, "") |
| 378 | |
| 379 | convertedWhenBodyStatements, err := jsonConvertStatements(when.Body) |
| 380 | if err != nil { |
| 381 | return Block{}, err |
| 382 | } |
| 383 | |
| 384 | block.Body = append(block.Body, |
| 385 | If{ |
| 386 | Condition: expressionString, |
| 387 | GotoOffset: 2, |
| 388 | }, |
| 389 | Goto{ |
| 390 | // This GOTO jumps to the next WHEN block, so step over all the statements |
| 391 | // from this WHEN block, plus 1 for the GOTO op we add at the end of each |
| 392 | // block, and plus 1 more to move to the next statement. |
| 393 | Offset: int32(len(convertedWhenBodyStatements) + 1 + 1), |
| 394 | }) |
| 395 | block.Body = append(block.Body, convertedWhenBodyStatements...) |
| 396 | |
| 397 | // Add a GOTO op to jump to the end of the entire CASE block, and record its position |
| 398 | // in the statement block so we can update it later. |
| 399 | block.Body = append(block.Body, Goto{}) |
| 400 | gotoEndOpsIndexes = append(gotoEndOpsIndexes, len(block.Body)-1) |
| 401 | } |
| 402 | |
| 403 | if stmt.HasElse { |
nothing calls this directly
no test coverage detected