一、背景
postgreSQL命令的词法分析和语法分析是由Unix工具Yacc和Lex制作的。使用的是 Bison 和
Flex。
前面已经分析了 词法分析器代码
这次介绍语法分析器代码
二、代码分析
由于词法分析器代码较多,文章只对其中部分做重点解说。
- 语法分析器gram.y ——定义段
/* src/backend/parser/gram.y */
/* 定义段 */
%{
#include "postgres.h"
#include
#include
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "catalog/pg_trigger.h"
#include "commands/defrem.h"
#include "commands/trigger.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/gramparse.h"
#include "parser/parser.h"
#include "parser/parse_expr.h"
#include "storage/lmgr.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/numeric.h"
#include "utils/xml.h"
...
/* 定义 宏、函数*/
...
%}
...
/* 改变YYSTYPE的类型 */
%union
{
core_YYSTYPE core_yystype;
/* these fields must match core_YYSTYPE: */
int ival;
char *str;
const char *keyword;
char chr;
bool boolean;
JoinType jtype;
DropBehavior dbehavior;
OnCommitAction oncommit;
List *list;
Node *node;
Value *value;
ObjectType objtype;
TypeName *typnam;
FunctionParameter *fun_param;
FunctionParameterMode fun_param_mode;
ObjectWithArgs *objwithargs;
DefElem *defelt;
SortBy *sortby;
WindowDef *windef;
JoinExpr *jexpr;
IndexElem *ielem;
Alias *alias;
RangeVar *range;
IntoClause *into;
WithClause *with;
InferClause *infer;
OnConflictClause *onconflict;
A_Indices *aind;
ResTarget *target;
struct PrivTarget *privtarget;
AccessPriv *accesspriv;
struct ImportQual *importqual;
InsertStmt *istmt;
VariableSetStmt *vsetstmt;
PartitionElem *partelem;
PartitionSpec *partspec;
PartitionBoundSpec *partboundspec;
RoleSpec *rolespec;
}
/* 用%type 方式声明非终结符的类型,绑定到 node */
%type stmt schema_stmt
AlterEventTrigStmt AlterCollationStmt
AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt
AlterFdwStmt AlterForeignServerStmt AlterGroupStmt
AlterObjectDependsStmt AlterObjectSchemaStmt AlterOwnerStmt
AlterOperatorStmt AlterSeqStmt AlterSystemStmt AlterTableStmt
AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt
AlterCompositeTypeStmt AlterUserMappingStmt
AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt
AlterDefaultPrivilegesStmt DefACLAction
AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
CreateDomainStmt CreateExtensionStmt CreateGroupStmt CreateOpClassStmt
CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt
CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt
CreateAssertStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt
CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt
DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
DropAssertStmt DropCastStmt DropRoleStmt
DropdbStmt DropTableSpaceStmt
DropTransformStmt
DropUserMappingStmt ExplainStmt FetchStmt
GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt
ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
RuleActionStmt RuleActionStmtOrEmpty RuleStmt
SecLabelStmt SelectStmt TransactionStmt TruncateStmt
UnlistenStmt UpdateStmt VacuumStmt
VariableResetStmt VariableSetStmt VariableShowStmt
ViewStmt CheckPointStmt CreateConversionStmt
DeallocateStmt PrepareStmt ExecuteStmt
DropOwnedStmt ReassignOwnedStmt
AlterTSConfigurationStmt AlterTSDictionaryStmt
CreateMatViewStmt RefreshMatViewStmt CreateAmStmt
CreatePublicationStmt AlterPublicationStmt
CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt
%type select_no_parens select_with_parens select_clause
simple_select values_clause
%type alter_column_default opclass_item opclass_drop alter_using
%type add_drop opt_asc_desc opt_nulls_order
%type alter_table_cmd alter_type_cmd opt_collate_clause
replica_identity partition_cmd index_partition_cmd
%type alter_table_cmds alter_type_cmds
%type alter_identity_column_option_list
%type alter_identity_column_option
%type opt_drop_behavior
%type createdb_opt_list createdb_opt_items copy_opt_list
transaction_mode_list
create_extension_opt_list alter_extension_opt_list
%type createdb_opt_item copy_opt_item
transaction_mode_item
create_extension_opt_item alter_extension_opt_item
%type opt_lock lock_type cast_context
%type vacuum_option_list vacuum_option_elem
analyze_option_list analyze_option_elem
%type opt_or_replace
opt_grant_grant_option opt_grant_admin_option
opt_nowait opt_if_exists opt_with_data
%type opt_nowait_or_skip
%type OptRoleList AlterOptRoleList
%type CreateOptRoleElem AlterOptRoleElem
%type opt_type
%type foreign_server_version opt_foreign_server_version
%type opt_in_database
%type OptSchemaName
%type OptSchemaEltList
%type TriggerForSpec TriggerForType
%type TriggerActionTime
%type TriggerEvents TriggerOneEvent
%type TriggerFuncArg
%type TriggerWhen
%type TransitionRelName
%type TransitionRowOrTable TransitionOldOrNew
%type TriggerTransition
%type event_trigger_when_list event_trigger_value_list
%type event_trigger_when_item
%type enable_trigger
%type copy_file_name
database_name access_method_clause access_method attr_name
name cursor_name file_name
index_name opt_index_name cluster_index_specification
%type func_name handler_name qual_Op qual_all_Op subquery_Op
opt_class opt_inline_handler opt_validator validator_clause
opt_collate
%type qualified_name insert_target OptConstrFromTable
%type all_Op MathOp
%type row_security_cmd RowSecurityDefaultForCmd
%type RowSecurityDefaultPermissive
%type RowSecurityOptionalWithCheck RowSecurityOptionalExpr
%type RowSecurityDefaultToRole RowSecurityOptionalToRole
%type iso_level opt_encoding
%type grantee
%type grantee_list
%type privilege
%type privileges privilege_list
%type privilege_target
%type function_with_argtypes aggregate_with_argtypes operator_with_argtypes
%type function_with_argtypes_list aggregate_with_argtypes_list operator_with_argtypes_list
%type defacl_privilege_target
%type DefACLOption
%type DefACLOptionList
%type import_qualification_type
%type import_qualification
%type vacuum_relation
/* 用%type 方式声明非终结符的类型,绑定到 list*/
%type stmtblock stmtmulti
OptTableElementList TableElementList OptInherit definition
OptTypedTableElementList TypedTableElementList
reloptions opt_reloptions
OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list
func_args_with_defaults func_args_with_defaults_list
aggr_args aggr_args_list
func_as createfunc_opt_list alterfunc_opt_list
old_aggr_definition old_aggr_list
oper_argtypes RuleActionList RuleActionMulti
opt_column_list columnList opt_name_list
sort_clause opt_sort_clause sortby_list index_params
opt_include opt_c_include index_including_params
name_list role_list from_clause from_list opt_array_bounds
qualified_name_list any_name any_name_list type_name_list
any_operator expr_list attrs
target_list opt_target_list insert_column_list set_target_list
set_clause_list set_clause
def_list operator_def_list indirection opt_indirection
reloption_list group_clause TriggerFuncArgs select_limit
opt_select_limit opclass_item_list opclass_drop_list
opclass_purpose opt_opfamily transaction_mode_list_or_empty
OptTableFuncElementList TableFuncElementList opt_type_modifiers
prep_type_clause
execute_param_clause using_clause returning_clause
opt_enum_val_list enum_val_list table_func_column_list
create_generic_options alter_generic_options
relation_expr_list dostmt_opt_list
transform_element_list transform_type_list
TriggerTransitions TriggerReferencing
publication_name_list
vacuum_relation_list opt_vacuum_relation_list
%type group_by_list
%type group_by_item empty_grouping_set rollup_clause cube_clause
%type grouping_sets_clause
%type opt_publication_for_tables publication_for_tables
%type publication_name_item
%type opt_fdw_options fdw_options
%type fdw_option
%type OptTempTableName
%type into_clause create_as_target create_mv_target
%type createfunc_opt_item common_func_opt_item dostmt_opt_item
%type func_arg func_arg_with_default table_func_column aggr_arg
%type arg_class
%type func_return func_type
%type opt_trusted opt_restart_seqs
%type OptTemp
%type OptNoLog
%type OnCommitOption
%type for_locking_strength
%type for_locking_item
%type for_locking_clause opt_for_locking_clause for_locking_items
%type locked_rels_list
%type all_or_distinct
%type join_outer join_qual
%type join_type
%type extract_list overlay_list position_list
%type substr_list trim_list
%type opt_interval interval_second
%type overlay_placing substr_from substr_for
%type opt_instead
%type opt_unique opt_concurrently opt_verbose opt_full
%type opt_freeze opt_analyze opt_default opt_recheck
%type opt_binary opt_oids copy_delimiter
%type copy_from opt_program
%type opt_column event cursor_options opt_hold opt_set_data
%type drop_type_any_name drop_type_name drop_type_name_on_any_name
comment_type_any_name comment_type_name
security_label_type_any_name security_label_type_name
%type fetch_args limit_clause select_limit_value
offset_clause select_offset_value
select_fetch_first_value I_or_F_const
%type row_or_rows first_or_next
%type OptSeqOptList SeqOptList OptParenthesizedSeqOptList
%type SeqOptElem
%type insert_rest
%type opt_conf_expr
%type opt_on_conflict
%type generic_set set_rest set_rest_more generic_reset reset_rest
SetResetClause FunctionSetResetClause
%type TableElement TypedTableElement ConstraintElem TableFuncElement
%type columnDef columnOptions
%type def_elem reloption_elem old_aggr_elem operator_def_elem
%type def_arg columnElem where_clause where_or_current_clause
a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound
columnref in_expr having_clause func_table xmltable array_expr
ExclusionWhereClause operator_def_arg
%type rowsfrom_item rowsfrom_list opt_col_def_list
%type opt_ordinality
%type ExclusionConstraintList ExclusionConstraintElem
%type func_arg_list
%type func_arg_expr
%type row explicit_row implicit_row type_list array_expr_list
%type case_expr case_arg when_clause case_default
%type when_clause_list
%type sub_type
%type NumericOnly
%type NumericOnly_list
%type alias_clause opt_alias_clause
%type func_alias_clause
%type sortby
%type index_elem
%type table_ref
%type joined_table
%type relation_expr
%type relation_expr_opt_alias
%type tablesample_clause opt_repeatable_clause
%type target_el set_target insert_column_item
%type generic_option_name
%type generic_option_arg
%type generic_option_elem alter_generic_option_elem
%type generic_option_list alter_generic_option_list
%type explain_option_name
%type explain_option_arg
%type explain_option_elem
%type explain_option_list
%type reindex_target_type reindex_target_multitable
%type reindex_option_list reindex_option_elem
%type copy_generic_opt_arg copy_generic_opt_arg_list_item
%type copy_generic_opt_elem
%type copy_generic_opt_list copy_generic_opt_arg_list
%type copy_options
%type Typename SimpleTypename ConstTypename
GenericType Numeric opt_float
Character ConstCharacter
CharacterWithLength CharacterWithoutLength
ConstDatetime ConstInterval
Bit ConstBit BitWithLength BitWithoutLength
%type character
%type extract_arg
%type opt_varying opt_timezone opt_no_inherit
%type Iconst SignedIconst
%type Sconst comment_text notify_payload
%type RoleId opt_boolean_or_string
%type var_list
%type ColId ColLabel var_name type_function_name param_name
%type NonReservedWord NonReservedWord_or_Sconst
%type createdb_opt_name
%type var_value zone_value
%type auth_ident RoleSpec opt_granted_by
%type unreserved_keyword type_func_name_keyword
%type col_name_keyword reserved_keyword
%type TableConstraint TableLikeClause
%type TableLikeOptionList TableLikeOption
%type ColQualList
%type ColConstraint ColConstraintElem ConstraintAttr
%type key_actions key_delete key_match key_update key_action
%type ConstraintAttributeSpec ConstraintAttributeElem
%type ExistingIndex
%type constraints_set_list
%type constraints_set_mode
%type OptTableSpace OptConsTableSpace
%type OptTableSpaceOwner
%type opt_check_option
%type opt_provider security_label
%type xml_attribute_el
%type xml_attribute_list xml_attributes
%type xml_root_version opt_xml_root_standalone
%type xmlexists_argument
%type document_or_content
%type xml_whitespace_option
%type xmltable_column_list xmltable_column_option_list
%type xmltable_column_el
%type xmltable_column_option_el
%type xml_namespace_list
%type xml_namespace_el
%type func_application func_expr_common_subexpr
%type func_expr func_expr_windowless
%type common_table_expr
%type with_clause opt_with_clause
%type cte_list
%type within_group_clause
%type filter_clause
%type window_clause window_definition_list opt_partition_clause
%type window_definition over_clause window_specification
opt_frame_clause frame_extent frame_bound
%type opt_window_exclusion_clause
%type opt_existing_window_name
%type opt_if_not_exists
%type generated_when override_kind
%type PartitionSpec OptPartitionSpec
%type part_strategy
%type part_elem
%type part_params
%type PartitionBoundSpec
%type partbound_datum PartitionRangeDatum
%type hash_partbound partbound_datum_list range_datum_list
%type hash_partbound_elem
/* 用%token<>方式声明yacc记号 */
%token IDENT FCONST SCONST BCONST XCONST Op
%token ICONST PARAM
%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
%token LESS_EQUALS GREATER_EQUALS NOT_EQUALS
/*
* If you want to make any keyword changes, update the keyword table in
* src/include/parser/kwlist.h and add new keywords to the appropriate one
* of the reserved-or-not-so-reserved keyword lists, below; search
* this file for "Keyword category lists".
*/
/* ordinary key words in alphabetical order */
%token ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION
BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
BOOLEAN_P BOTH BY
CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONFLICT CONNECTION CONSTRAINT
CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE
CROSS CSV CUBE CURRENT_P
CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DESC
DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P
DOUBLE_P DROP
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EVENT EXCEPT
EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
EXTENSION EXTERNAL EXTRACT
FALSE_P FAMILY FETCH FILTER FIRST_P FLOAT_P FOLLOWING FOR
FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS
GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS
HANDLER HAVING HEADER_P HOLD HOUR_P
IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IMPORT_P IN_P INCLUDE
INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
JOIN
KEY
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED
MAPPING MATCH MATERIALIZED MAXVALUE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE
NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NONE
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
NULLS_P NUMERIC
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OPTIONS OR
ORDER ORDINALITY OTHERS OUT_P OUTER_P
OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
PARALLEL PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POLICY
POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
QUOTE
RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REFERENCING
REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA
RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
ROUTINE ROUTINES ROW ROWS RULE
SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P
START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P
SUBSCRIPTION SUBSTRING SYMMETRIC SYSID SYSTEM_P
TABLE TABLES TABLESAMPLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN
TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM
TREAT TRIGGER TRIM TRUE_P
TRUNCATE TRUSTED TYPE_P TYPES_P
UNBOUNDED UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED
UNTIL UPDATE USER USING
VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
VERBOSE VERSION_P VIEW VIEWS VOLATILE
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLNAMESPACES
XMLPARSE XMLPI XMLROOT XMLSERIALIZE XMLTABLE
YEAR_P YES_P
ZONE
%token NOT_LA NULLS_LA WITH_LA
/* 预定义操作符的左右相关,并排序优先级 */
%nonassoc SET /* see relation_expr_opt_alias */
%left UNION EXCEPT
%left INTERSECT
%left OR
%left AND
%right NOT
%nonassoc IS ISNULL NOTNULL /* IS sets precedence for IS NULL, etc */
%nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS
%nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA
%nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */
%left POSTFIXOP /* dummy for postfix Op rules */
/*
* To support target_el without AS, we must give IDENT an explicit priority
* between POSTFIXOP and Op. We can safely assign the same priority to
* various unreserved keywords as needed to resolve ambiguities (this can't
* have any bad effects since obviously the keywords will still behave the
* same as if they weren't keywords). We need to do this:
* for PARTITION, RANGE, ROWS, GROUPS to support opt_existing_window_name;
* for RANGE, ROWS, GROUPS so that they can follow a_expr without creating
* postfix-operator problems;
* for GENERATED so that it can follow b_expr;
* and for NULL so that it can follow b_expr in ColQualList without creating
* postfix-operator problems.
*
* To support CUBE and ROLLUP in GROUP BY without reserving them, we give them
* an explicit priority lower than '(', so that a rule with CUBE '(' will shift
* rather than reducing a conflicting rule that takes CUBE as a function name.
* Using the same precedence as IDENT seems right for the reasons given above.
*
* The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
* are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
* there is no principled way to distinguish these from the productions
* a_expr PRECEDING/FOLLOWING. We hack this up by giving UNBOUNDED slightly
* lower precedence than PRECEDING and FOLLOWING. At present this doesn't
* appear to cause UNBOUNDED to be treated differently from other unreserved
* keywords anywhere else in the grammar, but it's definitely risky. We can
* blame any funny behavior of UNBOUNDED on the SQL standard, though.
*/
%nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */
%nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP
%left Op OPERATOR /* multi-character ops and user-defined operators */
%left '+' '-'
%left '*' '/' '%'
%left '^'
/* Unary Operators */
%left AT /* sets precedence for AT TIME ZONE */
%left COLLATE
%right UMINUS
%left '[' ']'
%left '(' ')'
%left TYPECAST
%left '.'
/*
* These might seem to be low-precedence, but actually they are not part
* of the arithmetic hierarchy at all in their use as JOIN operators.
* We make them high-precedence to support their use as function names.
* They wouldn't be given a precedence at all, were it not that we need
* left-associativity among the JOIN rules themselves.
*/
%left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
%right PRESERVE STRIP_P
%%
- 语法分析器gram.y ——规则段
/* 规则段 */
/*
* 整个字符串的parse.
*/
stmtblock: stmtmulti
{
pg_yyget_extra(yyscanner)->parsetree = $1;
}
;
/*
* At top level, we wrap each stmt with a RawStmt node carrying start location
* and length of the stmt's text. Notice that the start loc/len are driven
* entirely from semicolon locations (@2). It would seem natural to use
* @1 or @3 to get the true start location of a stmt, but that doesn't work
* for statements that can start with empty nonterminals (opt_with_clause is
* the main offender here); as noted in the comments for YYLLOC_DEFAULT,
* we'd get -1 for the location in such cases.
* We also take care to discard empty statements entirely.
*/
/* 使用左递归形式,处理含有多个SQL */
stmtmulti: stmtmulti ';' stmt
{
if ($1 != NIL)
{
/* update length of previous stmt */
updateRawStmtEnd(llast_node(RawStmt, $1), @2);
}
if ($3 != NULL)
$$ = lappend($1, makeRawStmt($3, @2 + 1));
else
$$ = $1;
}
| stmt
{
if ($1 != NULL)
$$ = list_make1(makeRawStmt($1, 0));
else
$$ = NIL;
}
;
/* 定义stmt的语法树,支持124中SQL的语法分析*/
stmt :
AlterEventTrigStmt
| AlterCollationStmt
| AlterDatabaseStmt
| AlterDatabaseSetStmt
| AlterDefaultPrivilegesStmt
| AlterDomainStmt
| AlterEnumStmt
| AlterExtensionStmt
| AlterExtensionContentsStmt
| AlterFdwStmt
| AlterForeignServerStmt
| AlterForeignTableStmt
| AlterFunctionStmt
| AlterGroupStmt
| AlterObjectDependsStmt
| AlterObjectSchemaStmt
| AlterOwnerStmt
| AlterOperatorStmt
| AlterPolicyStmt
| AlterSeqStmt
| AlterSystemStmt
| AlterTableStmt
| AlterTblSpcStmt
| AlterCompositeTypeStmt
| AlterPublicationStmt
| AlterRoleSetStmt
| AlterRoleStmt
| AlterSubscriptionStmt
| AlterTSConfigurationStmt
| AlterTSDictionaryStmt
| AlterUserMappingStmt
| AnalyzeStmt
| CallStmt
| CheckPointStmt
| ClosePortalStmt
| ClusterStmt
| CommentStmt
| ConstraintsSetStmt
| CopyStmt
| CreateAmStmt
| CreateAsStmt
| CreateAssertStmt
| CreateCastStmt
| CreateConversionStmt
| CreateDomainStmt
| CreateExtensionStmt
| CreateFdwStmt
| CreateForeignServerStmt
| CreateForeignTableStmt
| CreateFunctionStmt
| CreateGroupStmt
| CreateMatViewStmt
| CreateOpClassStmt
| CreateOpFamilyStmt
| CreatePublicationStmt
| AlterOpFamilyStmt
| CreatePolicyStmt
| CreatePLangStmt
| CreateSchemaStmt
| CreateSeqStmt
| CreateStmt
| CreateSubscriptionStmt
| CreateStatsStmt
| CreateTableSpaceStmt
| CreateTransformStmt
| CreateTrigStmt
| CreateEventTrigStmt
| CreateRoleStmt
| CreateUserStmt
| CreateUserMappingStmt
| CreatedbStmt
| DeallocateStmt
| DeclareCursorStmt
| DefineStmt
| DeleteStmt /*删除数据SQL*/
| DiscardStmt
| DoStmt
| DropAssertStmt
| DropCastStmt
| DropOpClassStmt
| DropOpFamilyStmt
| DropOwnedStmt
| DropPLangStmt
| DropStmt
| DropSubscriptionStmt
| DropTableSpaceStmt
| DropTransformStmt
| DropRoleStmt
| DropUserMappingStmt
| DropdbStmt
| ExecuteStmt
| ExplainStmt
| FetchStmt
| GrantStmt
| GrantRoleStmt
| ImportForeignSchemaStmt
| IndexStmt
| InsertStmt /*插入数据SQL*/
| ListenStmt
| RefreshMatViewStmt
| LoadStmt
| LockStmt
| NotifyStmt
| PrepareStmt
| ReassignOwnedStmt
| ReindexStmt
| RemoveAggrStmt
| RemoveFuncStmt
| RemoveOperStmt
| RenameStmt
| RevokeStmt
| RevokeRoleStmt
| RuleStmt
| SecLabelStmt
| SelectStmt /*查询数据SQL*/
| TransactionStmt
| TruncateStmt
| UnlistenStmt
| UpdateStmt /*修改数据SQL*/
| VacuumStmt
| VariableResetStmt
| VariableSetStmt
| VariableShowStmt
| ViewStmt
| /*EMPTY*/
{ $$ = NULL; }
;
...
/* 数据查询的SQL*/
/*****************************************************************************
*
* QUERY:
* SELECT STATEMENTS
*
*****************************************************************************/
/* A complete SELECT statement looks like this.
*
* The rule returns either a single SelectStmt node or a tree of them,
* representing a set-operation tree.
*
* There is an ambiguity when a sub-SELECT is within an a_expr and there
* are excess parentheses: do the parentheses belong to the sub-SELECT or
* to the surrounding a_expr? We don't really care, but bison wants to know.
* To resolve the ambiguity, we are careful to define the grammar so that
* the decision is staved off as long as possible: as long as we can keep
* absorbing parentheses into the sub-SELECT, we will do so, and only when
* it's no longer possible to do that will we decide that parens belong to
* the expression. For example, in "SELECT (((SELECT 2)) + 3)" the extra
* parentheses are treated as part of the sub-select. The necessity of doing
* it that way is shown by "SELECT (((SELECT 2)) UNION SELECT 2)". Had we
* parsed "((SELECT 2))" as an a_expr, it'd be too late to go back to the
* SELECT viewpoint when we see the UNION.
*
* This approach is implemented by defining a nonterminal select_with_parens,
* which represents a SELECT with at least one outer layer of parentheses,
* and being careful to use select_with_parens, never '(' SelectStmt ')',
* in the expression grammar. We will then have shift-reduce conflicts
* which we can resolve in favor of always treating '('
- 语法分析器gram.y ——用户子程序段(未完成)
/* 用户子程序段 */
总结
本文居于查询SQL的语法结构,分析postgreSQL的语法分析器代码。
如果你想修改postgresql的语法,你要关注下两个文件“gram.y”和“kwlist.h”。简要地说就是将新添加的关键字添加到kwlist.h中,同时修改gram.y文件中的语法规则,然后重新编译即可。