pg_graphql的工作原理

pg_graphql的工作原理

💡 原文英文,约2000词,阅读约需8分钟。
📝

内容提要

pg_graphql是一个Postgres扩展,将SQL模式转换为GraphQL模式。它通过graphql.resolve(...)函数处理GraphQL请求,涉及令牌化、解析、验证和执行等步骤。查询字符串被转换为抽象语法树(AST),并进行多种验证以确保查询有效。pg_graphql还通过反射获取GraphQL模式信息,最终生成SQL并返回JSON响应。

🔎

延伸解读

令牌化与解析:查询如何变成AST

pg_graphql首先对GraphQL查询字符串进行令牌化,将其转换为词法标记,然后由解析器组织成抽象语法树(AST)。令牌化基于词法语法,例如识别Name、标点等,并忽略空白和逗号。解析器根据语法规则构建AST,期望得到可执行文档。这一过程确保查询在结构上符合GraphQL语法,但生成的AST可能仍包含语义错误,需进一步验证。

验证阶段:确保查询可执行

解析后,pg_graphql会验证AST,检查其是否符合GraphQL规范。验证包括操作名称唯一性、字段是否存在于目标类型、字面量类型是否匹配、参数名是否允许等。这些验证需要反射的GraphQL模式信息,例如字段定义。验证失败会返回错误,防止无效查询进入执行阶段。验证代码分布在多个文件中,如resolve.rs和parser_util.rs。

模式反射与缓存:性能优化关键

pg_graphql通过读取系统目录构建GraphQL模式,load_sql_context函数将信息加载到Context对象。该函数使用cached属性进行记忆化,仅当Config(搜索路径、角色、模式版本)变化时重新加载。模式版本由触发器更新,确保模式变更时刷新。Context被包装为__Schema,用于内省、验证和转译。这种缓存机制提升了性能,避免了每次查询都重新加载模式。

转译与执行:从AST到SQL的安全转换

转译分两步:首先根据AST和__Schema构建builder对象,然后转换为SQL。builder对象包含生成SQL所需信息,并实现QueryEntrypoint trait。to_sql方法生成SQL,并使用quote_ident和quote_literal防止SQL注入。生成的SQL执行后返回jsonb对象,反序列化为pgrx::JsonB,最终作为JSON响应返回客户端。这一过程确保了查询的安全性和正确性。

❓

Q&A

pg_graphql是什么?

pg_graphql是一个Postgres扩展,将SQL模式转换为GraphQL模式。

pg_graphql如何处理GraphQL请求?

pg_graphql通过graphql.resolve(...)函数处理请求,涉及令牌化、解析、验证和执行等步骤。

令牌化在pg_graphql中有什么作用?

令牌化将查询字符串转换为有效的词法标记,以便后续解析。

pg_graphql如何验证GraphQL查询的有效性?

pg_graphql在执行之前会验证抽象语法树(AST),确保查询符合GraphQL规范。

pg_graphql是如何生成SQL的?

pg_graphql通过将抽象语法树(AST)转译为SQL,最终生成SQL查询。

pg_graphql的性能如何优化?

pg_graphql通过缓存机制提高性能,避免重复读取系统目录中的信息。

🏷️

标签

➡️

继续阅读