diff --git a/.changeset/perfect-zebras-rest.md b/.changeset/perfect-zebras-rest.md new file mode 100644 index 0000000000..1916fe7731 --- /dev/null +++ b/.changeset/perfect-zebras-rest.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/explorer": patch +--- + +When accessing a new table in Explore tab, the SQL editor now encloses column names that are also PostgreSQL keywords in double quotes in order to prevent invalid queries. diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx index f7d19fbf86..69ca454bf9 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/Explorer.tsx @@ -12,6 +12,7 @@ import { indexerForChainId } from "../../../../utils/indexerForChainId"; import { SQLEditor } from "./SQLEditor"; import { TableSelector } from "./TableSelector"; import { TablesViewer } from "./TablesViewer"; +import { postgresKeywords } from "./consts"; export function Explorer() { const { worldAddress } = useParams(); @@ -31,7 +32,10 @@ export function Explorer() { if (indexer.type === "sqlite") { setQuery(`SELECT * FROM "${tableName}"`); } else { - setQuery(`SELECT ${Object.keys(table.schema).join(", ")} FROM ${tableName}`); + const columns = Object.keys(table.schema).map((column) => + postgresKeywords.includes(column.toLowerCase()) ? `"${column}"` : column, + ); + setQuery(`SELECT ${columns.join(", ")} FROM ${tableName}`); } } }, [chainId, setQuery, selectedTableId, table, worldAddress, prevSelectedTableId, query, indexer.type]); diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts index acbc6a9f10..74ecfa50ae 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/consts.ts @@ -41,3 +41,373 @@ export const monacoOptions: editor.IStandaloneEditorConstructionOptions = { automaticLayout: true, fixedOverflowWidgets: true, }; + +// Ref: https://www.postgresql.org/docs/8.1/sql-keywords-appendix.html +export const postgresKeywords = [ + "a", + "abort", + "absolute", + "access", + "action", + "add", + "admin", + "after", + "aggregate", + "all", + "also", + "alter", + "always", + "analyse", + "analyze", + "and", + "any", + "array", + "as", + "asc", + "assertion", + "assignment", + "asymmetric", + "at", + "authorization", + "backward", + "before", + "begin", + "between", + "bigint", + "binary", + "bit", + "boolean", + "both", + "by", + "cache", + "called", + "cascade", + "cascaded", + "case", + "cast", + "catalog", + "chain", + "char", + "character", + "characteristics", + "check", + "checkpoint", + "class", + "close", + "cluster", + "coalesce", + "collate", + "column", + "comment", + "commit", + "committed", + "configuration", + "connection", + "constraint", + "constraints", + "content", + "continue", + "conversion", + "copy", + "cost", + "create", + "cross", + "csv", + "current", + "current_catalog", + "current_date", + "current_role", + "current_time", + "current_timestamp", + "current_user", + "cursor", + "cycle", + "database", + "day", + "deallocate", + "dec", + "decimal", + "declare", + "default", + "defaults", + "deferrable", + "deferred", + "delete", + "delimiter", + "delimiters", + "desc", + "dictionary", + "disable", + "discard", + "distinct", + "do", + "document", + "domain", + "double", + "drop", + "each", + "else", + "enable", + "encoding", + "encrypted", + "end", + "escape", + "except", + "exclude", + "excluding", + "exclusive", + "execute", + "exists", + "explain", + "external", + "extract", + "false", + "family", + "fetch", + "first", + "float", + "following", + "for", + "force", + "foreign", + "forward", + "freeze", + "from", + "full", + "function", + "functions", + "global", + "grant", + "granted", + "greatest", + "group", + "handler", + "having", + "header", + "hold", + "hour", + "identity", + "if", + "ilike", + "immediate", + "immutable", + "implicit", + "in", + "including", + "increment", + "index", + "indexes", + "inherit", + "inherits", + "initially", + "inner", + "inout", + "input", + "insensitive", + "insert", + "instead", + "int", + "integer", + "intersect", + "interval", + "into", + "invoker", + "is", + "isnull", + "isolation", + "join", + "key", + "language", + "large", + "last", + "lateral", + "leading", + "least", + "left", + "level", + "like", + "limit", + "listen", + "load", + "local", + "localtime", + "localtimestamp", + "location", + "lock", + "mapping", + "match", + "maxvalue", + "minute", + "minvalue", + "mode", + "month", + "move", + "name", + "names", + "national", + "natural", + "nchar", + "new", + "next", + "no", + "none", + "not", + "nothing", + "notify", + "notnull", + "nowait", + "null", + "nullif", + "numeric", + "object", + "of", + "off", + "offset", + "oids", + "old", + "on", + "only", + "operator", + "option", + "options", + "or", + "order", + "out", + "outer", + "over", + "overlaps", + "overlay", + "owned", + "owner", + "parser", + "partial", + "partition", + "passing", + "password", + "placing", + "plans", + "position", + "preceding", + "precision", + "prepare", + "prepared", + "preserve", + "primary", + "prior", + "privileges", + "procedural", + "procedure", + "quote", + "range", + "read", + "real", + "reassign", + "recheck", + "recursive", + "ref", + "references", + "reindex", + "relative", + "release", + "rename", + "repeatable", + "replace", + "replica", + "reset", + "restart", + "restrict", + "returning", + "returns", + "revoke", + "right", + "role", + "rollback", + "row", + "rows", + "rule", + "savepoint", + "schema", + "scroll", + "search", + "second", + "security", + "select", + "sequence", + "sequences", + "serializable", + "server", + "session", + "session_user", + "set", + "setof", + "share", + "show", + "similar", + "simple", + "smallint", + "some", + "stable", + "standalone", + "start", + "statement", + "statistics", + "stdin", + "stdout", + "storage", + "strict", + "strip", + "substring", + "symmetric", + "sysid", + "system", + "table", + "tablespace", + "temp", + "template", + "temporary", + "text", + "then", + "time", + "timestamp", + "to", + "trailing", + "transaction", + "treat", + "trigger", + "trim", + "true", + "truncate", + "trusted", + "type", + "unbounded", + "uncommitted", + "unencrypted", + "union", + "unique", + "unknown", + "unlisten", + "until", + "update", + "vacuum", + "valid", + "validator", + "value", + "values", + "varchar", + "variadic", + "varying", + "verbose", + "version", + "view", + "volatile", + "when", + "where", + "whitespace", + "window", + "with", + "without", + "work", + "write", + "year", + "zone", +];