Skip to content

MySQL: Double-quoted string values break suggestions #167

@Allless

Description

@Allless

Using MySQL without a DB connection.
In MySQL, while not recommended, you can use double quotes for strings. Example: VALUES("Hello World").
Currently, if you have such a code, it will cause the language server to return a Not found statement error on a completion request.

To Reproduce

  • Start the sqls language server without configuration and DB connection
  • Check the LSP communication below, and imitate the same steps either programmatically or by running an LSP client.
    • It will provide the competition sometimes, depending on the cursor position. I'd recommend strictly following actions from the LSP communication to reproduce the issue.
  • See that you won't get any suggestions on competition requests.
  • See that you will get the Not found statement error

Versions (please complete the following information):

  • OS Version: Docker container. Based on frolvlad/alpine-glibc
  • sqls Version: v0.2.27

Additional context

LSP communication
[
  {
    "jsonrpc": "2.0",
    "id": 0,
    "method": "initialize",
    "params": {
      "processId": null,
      "clientInfo": {
        "name": "Monaco"
      },
      "locale": "en-US",
      "rootPath": "/project",
      "rootUri": "file:///project",
      "capabilities": {
        "workspace": {
          "applyEdit": true,
          "workspaceEdit": {
            "documentChanges": true,
            "resourceOperations": [
              "create",
              "rename",
              "delete"
            ],
            "failureHandling": "textOnlyTransactional",
            "normalizesLineEndings": true,
            "changeAnnotationSupport": {
              "groupsOnLabel": true
            }
          },
          "didChangeConfiguration": {
            "dynamicRegistration": true
          },
          "didChangeWatchedFiles": {
            "dynamicRegistration": true
          },
          "symbol": {
            "dynamicRegistration": true,
            "symbolKind": {
              "valueSet": [
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9,
                10,
                11,
                12,
                13,
                14,
                15,
                16,
                17,
                18,
                19,
                20,
                21,
                22,
                23,
                24,
                25,
                26
              ]
            },
            "tagSupport": {
              "valueSet": [
                1
              ]
            }
          },
          "codeLens": {
            "refreshSupport": true
          },
          "executeCommand": {
            "dynamicRegistration": true
          },
          "configuration": true,
          "workspaceFolders": true,
          "semanticTokens": {
            "refreshSupport": true
          }
        },
        "textDocument": {
          "publishDiagnostics": {
            "relatedInformation": true,
            "versionSupport": false,
            "tagSupport": {
              "valueSet": [
                1,
                2
              ]
            },
            "codeDescriptionSupport": true,
            "dataSupport": true
          },
          "synchronization": {
            "dynamicRegistration": true,
            "willSave": true,
            "willSaveWaitUntil": true,
            "didSave": true
          },
          "completion": {
            "dynamicRegistration": true,
            "contextSupport": true,
            "completionItem": {
              "snippetSupport": true,
              "commitCharactersSupport": true,
              "documentationFormat": [
                "markdown",
                "plaintext"
              ],
              "deprecatedSupport": true,
              "preselectSupport": true,
              "tagSupport": {
                "valueSet": [
                  1
                ]
              },
              "insertReplaceSupport": true,
              "resolveSupport": {
                "properties": [
                  "documentation",
                  "detail",
                  "additionalTextEdits"
                ]
              },
              "insertTextModeSupport": {
                "valueSet": [
                  1,
                  2
                ]
              }
            },
            "completionItemKind": {
              "valueSet": [
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9,
                10,
                11,
                12,
                13,
                14,
                15,
                16,
                17,
                18,
                19,
                20,
                21,
                22,
                23,
                24,
                25
              ]
            }
          },
          "hover": {
            "dynamicRegistration": true,
            "contentFormat": [
              "markdown",
              "plaintext"
            ]
          },
          "signatureHelp": {
            "dynamicRegistration": true,
            "signatureInformation": {
              "documentationFormat": [
                "markdown",
                "plaintext"
              ],
              "parameterInformation": {
                "labelOffsetSupport": true
              },
              "activeParameterSupport": true
            },
            "contextSupport": true
          },
          "definition": {
            "dynamicRegistration": true,
            "linkSupport": true
          },
          "references": {
            "dynamicRegistration": true
          },
          "documentHighlight": {
            "dynamicRegistration": true
          },
          "documentSymbol": {
            "dynamicRegistration": true,
            "symbolKind": {
              "valueSet": [
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9,
                10,
                11,
                12,
                13,
                14,
                15,
                16,
                17,
                18,
                19,
                20,
                21,
                22,
                23,
                24,
                25,
                26
              ]
            },
            "hierarchicalDocumentSymbolSupport": true,
            "tagSupport": {
              "valueSet": [
                1
              ]
            },
            "labelSupport": true
          },
          "codeAction": {
            "dynamicRegistration": true,
            "isPreferredSupport": true,
            "disabledSupport": true,
            "dataSupport": true,
            "resolveSupport": {
              "properties": [
                "edit"
              ]
            },
            "codeActionLiteralSupport": {
              "codeActionKind": {
                "valueSet": [
                  "",
                  "quickfix",
                  "refactor",
                  "refactor.extract",
                  "refactor.inline",
                  "refactor.rewrite",
                  "source",
                  "source.organizeImports"
                ]
              }
            },
            "honorsChangeAnnotations": false
          },
          "codeLens": {
            "dynamicRegistration": true
          },
          "formatting": {
            "dynamicRegistration": true
          },
          "rangeFormatting": {
            "dynamicRegistration": true
          },
          "onTypeFormatting": {
            "dynamicRegistration": true
          },
          "rename": {
            "dynamicRegistration": true,
            "prepareSupport": true,
            "prepareSupportDefaultBehavior": 1,
            "honorsChangeAnnotations": true
          },
          "documentLink": {
            "dynamicRegistration": true,
            "tooltipSupport": true
          },
          "typeDefinition": {
            "dynamicRegistration": true,
            "linkSupport": true
          },
          "implementation": {
            "dynamicRegistration": true,
            "linkSupport": true
          },
          "colorProvider": {
            "dynamicRegistration": true
          },
          "foldingRange": {
            "dynamicRegistration": true,
            "rangeLimit": 5000,
            "lineFoldingOnly": true
          },
          "declaration": {
            "dynamicRegistration": true,
            "linkSupport": true
          },
          "semanticTokens": {
            "dynamicRegistration": true,
            "tokenTypes": [
              "namespace",
              "type",
              "class",
              "enum",
              "interface",
              "struct",
              "typeParameter",
              "parameter",
              "variable",
              "property",
              "enumMember",
              "event",
              "function",
              "method",
              "macro",
              "keyword",
              "modifier",
              "comment",
              "string",
              "number",
              "regexp",
              "operator"
            ],
            "tokenModifiers": [
              "declaration",
              "definition",
              "readonly",
              "static",
              "deprecated",
              "abstract",
              "async",
              "modification",
              "documentation",
              "defaultLibrary"
            ],
            "formats": [
              "relative"
            ],
            "requests": {
              "range": true,
              "full": {
                "delta": true
              }
            },
            "multilineTokenSupport": false,
            "overlappingTokenSupport": false
          },
          "callHierarchy": {
            "dynamicRegistration": true
          }
        },
        "window": {
          "showMessage": {
            "messageActionItem": {
              "additionalPropertiesSupport": true
            }
          },
          "showDocument": {
            "support": true
          },
          "workDoneProgress": true
        },
        "general": {
          "regularExpressions": {
            "engine": "ECMAScript",
            "version": "ES2020"
          },
          "markdown": {
            "parser": "marked",
            "version": "1.1.0"
          }
        }
      },
      "trace": "off",
      "workspaceFolders": [
        {
          "uri": "file:///project",
          "name": "file:///project"
        }
      ]
    }
  },
  {
    "method": "window/showMessage",
    "params": {
      "type": 1,
      "message": "no database connection"
    },
    "jsonrpc": "2.0"
  },
  {
    "id": 0,
    "result": {
      "capabilities": {
        "textDocumentSync": 1,
        "hoverProvider": true,
        "completionProvider": {
          "triggerCharacters": [
            "(",
            "."
          ]
        },
        "signatureHelpProvider": {
          "triggerCharacters": [
            "(",
            ","
          ],
          "retriggerCharacters": [
            "(",
            ","
          ]
        },
        "definitionProvider": true,
        "codeActionProvider": false,
        "documentFormattingProvider": true,
        "documentRangeFormattingProvider": true,
        "renameProvider": true
      }
    },
    "jsonrpc": "2.0"
  },
  {
    "jsonrpc": "2.0",
    "method": "initialized",
    "params": {}
  },
  {
    "jsonrpc": "2.0",
    "method": "textDocument/didOpen",
    "params": {
      "textDocument": {
        "uri": "file:///project/xsohwyw.sql",
        "languageId": "mysql",
        "version": 9,
        "text": "DROP TABLE IF EXISTS myTable;\nCREATE TABLE myTable(name varchar(20));\nINSERT INTO myTable VALUES(\"Hello World\");\nSELECT * FROM myTable;\n\n"
      }
    }
  },
  {
    "jsonrpc": "2.0",
    "method": "textDocument/didChange",
    "params": {
      "textDocument": {
        "uri": "file:///project/xsohwyw.sql",
        "version": 10
      },
      "contentChanges": [
        {
          "text": "DROP TABLE IF EXISTS myTable;\nCREATE TABLE myTable(name varchar(20));\nINSERT INTO myTable VALUES(\"Hello World\");\nSELECT * FROM myTable;\n\nA"
        }
      ]
    }
  },
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "textDocument/completion",
    "params": {
      "textDocument": {
        "uri": "file:///project/xsohwyw.sql"
      },
      "position": {
        "line": 5,
        "character": 1
      },
      "context": {
        "triggerKind": 1
      }
    }
  },
  {
    "id": 1,
    "error": {
      "code": 0,
      "message": "Not found statement, Node: \"DROP TABLE IF EXISTS myTable;\\nCREATE TABLE myTable(name varchar(20));\\nINSERT INTO myTable VALUES(\\\"Hello World\\\");\\nSELECT * FROM myTable;\\n\\nA\", Position: (5, 1)",
      "data": null
    },
    "jsonrpc": "2.0"
  },
  {
    "jsonrpc": "2.0",
    "id": 2,
    "method": "textDocument/hover",
    "params": {
      "textDocument": {
        "uri": "file:///project/xsohwyw.sql"
      },
      "position": {
        "line": 5,
        "character": 1
      }
    }
  },
  {
    "id": 2,
    "result": null,
    "jsonrpc": "2.0"
  }
]

Describe the solution you'd like
Add the possibility to configure the language server to identify double-quoted string values as valid. We could use the configuration file to specify the default behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions