%glr-parser %token-table %{ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "connectivity/dbconversion.hxx" #include #include #include #if defined _MSC_VER #pragma warning(push) #pragma warning(disable: 4324) // structure was padded due to alignment specifier #pragma warning(disable: 4065) // switch statement contains 'default' but no 'case' labels #pragma warning(disable: 4702) // unreachable code #endif #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wwrite-strings" # pragma GCC diagnostic ignored "-Wunused-function" #endif inline connectivity::OSQLInternalNode* newNode(const sal_Char* pNewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0); inline connectivity::OSQLInternalNode* newNode(const OString& _newValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0); inline connectivity::OSQLInternalNode* newNode(const OUString& _newValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID = 0); // yyi is the internal number of the rule that is currently being reduced // This can be mapped to external rule number via the yyrmap. #if defined YYBISON && YYBISON >= 30800 #define SQL_NEW_RULE newNode("", SQLNodeType::Rule, yyr1[yyrule]) #define SQL_NEW_LISTRULE newNode("", SQLNodeType::ListRule, yyr1[yyrule]) #define SQL_NEW_COMMALISTRULE newNode("", SQLNodeType::CommaListRule, yyr1[yyrule]) #else #define SQL_NEW_RULE newNode("", SQLNodeType::Rule, yyr1[yyn]) #define SQL_NEW_LISTRULE newNode("", SQLNodeType::ListRule, yyr1[yyn]) #define SQL_NEW_COMMALISTRULE newNode("", SQLNodeType::CommaListRule, yyr1[yyn]) #endif extern connectivity::OSQLParser* xxx_pGLOBAL_SQLPARSER; #define YYERROR_VERBOSE #define SQLyyerror(s) \ { \ xxx_pGLOBAL_SQLPARSER->error(s); \ } using namespace connectivity; #define SQLyylex xxx_pGLOBAL_SQLPARSER->SQLlex %} /* symbolic tokens */ %union { connectivity::OSQLParseNode * pParseNode; } %type '(' ')' ',' ':' ';' '?' '[' ']' '{' '}' '.' 'K' 'M' 'G' 'T' 'P' %token SQL_TOKEN_STRING SQL_TOKEN_ACCESS_DATE SQL_TOKEN_INT SQL_TOKEN_REAL_NUM %token SQL_TOKEN_INTNUM SQL_TOKEN_APPROXNUM SQL_TOKEN_NOT SQL_TOKEN_NAME %nonassoc SQL_TOKEN_UMINUS /* literal keyword tokens */ %token SQL_TOKEN_ALL SQL_TOKEN_ALTER SQL_TOKEN_AMMSC SQL_TOKEN_ANY SQL_TOKEN_AS SQL_TOKEN_ASC SQL_TOKEN_AT SQL_TOKEN_AUTHORIZATION SQL_TOKEN_AVG %token SQL_TOKEN_BETWEEN SQL_TOKEN_BIT SQL_TOKEN_BOTH SQL_TOKEN_BY %token SQL_TOKEN_CAST SQL_TOKEN_CHARACTER SQL_TOKEN_CHECK SQL_TOKEN_COLLATE SQL_TOKEN_COMMIT SQL_TOKEN_CONTINUE SQL_TOKEN_CONVERT SQL_TOKEN_COUNT SQL_TOKEN_CREATE SQL_TOKEN_CROSS %token SQL_TOKEN_CURRENT SQL_TOKEN_CURSOR %token SQL_TOKEN_DATE SQL_TOKEN_DATEVALUE SQL_TOKEN_DAY SQL_TOKEN_DEC SQL_TOKEN_DECIMAL SQL_TOKEN_DECLARE SQL_TOKEN_DEFAULT SQL_TOKEN_DELETE SQL_TOKEN_DESC %token SQL_TOKEN_DISTINCT SQL_TOKEN_DOUBLE SQL_TOKEN_DROP %token SQL_TOKEN_ESCAPE SQL_TOKEN_EXCEPT SQL_TOKEN_EXISTS SQL_TOKEN_FALSE SQL_TOKEN_FETCH SQL_TOKEN_FLOAT SQL_TOKEN_FOR SQL_TOKEN_FOREIGN SQL_TOKEN_FOUND SQL_TOKEN_FROM SQL_TOKEN_FULL %token SQL_TOKEN_GRANT SQL_TOKEN_GROUP SQL_TOKEN_HAVING SQL_TOKEN_IN SQL_TOKEN_INDICATOR SQL_TOKEN_INNER SQL_TOKEN_INTEGER SQL_TOKEN_INTO SQL_TOKEN_IS SQL_TOKEN_INTERSECT %left SQL_TOKEN_JOIN %token SQL_TOKEN_KEY SQL_TOKEN_LEADING SQL_TOKEN_LIKE SQL_TOKEN_LOCAL SQL_TOKEN_LOWER %token SQL_TOKEN_MAX SQL_TOKEN_MIN SQL_TOKEN_NATURAL SQL_TOKEN_NCHAR SQL_TOKEN_NULL SQL_TOKEN_NUMERIC %token SQL_TOKEN_OCTET_LENGTH SQL_TOKEN_OF SQL_TOKEN_ON SQL_TOKEN_OPTION SQL_TOKEN_ORDER SQL_TOKEN_OUTER %token SQL_TOKEN_PRECISION SQL_TOKEN_PRIMARY SQL_TOKEN_PRIVILEGES SQL_TOKEN_PROCEDURE SQL_TOKEN_PUBLIC %token SQL_TOKEN_REAL SQL_TOKEN_REFERENCES SQL_TOKEN_ROLLBACK %token SQL_TOKEN_SCHEMA SQL_TOKEN_SELECT SQL_TOKEN_SET SQL_TOKEN_SIZE SQL_TOKEN_SMALLINT SQL_TOKEN_SOME SQL_TOKEN_SQLCODE SQL_TOKEN_SQLERROR SQL_TOKEN_SUM %token SQL_TOKEN_TABLE SQL_TOKEN_TIME SQL_TOKEN_TIMESTAMP SQL_TOKEN_TIMEZONE_HOUR SQL_TOKEN_TIMEZONE_MINUTE SQL_TOKEN_TO SQL_TOKEN_TRAILING SQL_TOKEN_TRANSLATE SQL_TOKEN_TRIM SQL_TOKEN_TRUE SQL_TOKEN_UNION %token SQL_TOKEN_UNIQUE SQL_TOKEN_UNKNOWN SQL_TOKEN_UPDATE SQL_TOKEN_UPPER SQL_TOKEN_USAGE SQL_TOKEN_USER SQL_TOKEN_USING SQL_TOKEN_VALUES SQL_TOKEN_VIEW %token SQL_TOKEN_WHERE SQL_TOKEN_WITH SQL_TOKEN_WORK SQL_TOKEN_ZONE /* ODBC KEYWORDS */ %token SQL_TOKEN_CALL SQL_TOKEN_D SQL_TOKEN_FN SQL_TOKEN_T SQL_TOKEN_TS SQL_TOKEN_OJ /* string functions */ %token SQL_TOKEN_ASCII SQL_TOKEN_BIT_LENGTH SQL_TOKEN_CHAR SQL_TOKEN_CHAR_LENGTH SQL_TOKEN_SQL_TOKEN_INTNUM %token SQL_TOKEN_CONCAT %token SQL_TOKEN_DIFFERENCE SQL_TOKEN_INSERT SQL_TOKEN_LCASE SQL_TOKEN_LEFT SQL_TOKEN_LENGTH SQL_TOKEN_LOCATE %token SQL_TOKEN_LOCATE_2 SQL_TOKEN_LTRIM SQL_TOKEN_POSITION SQL_TOKEN_REPEAT SQL_TOKEN_REPLACE %token SQL_TOKEN_RIGHT SQL_TOKEN_RTRIM SQL_TOKEN_SOUNDEX SQL_TOKEN_SPACE SQL_TOKEN_SUBSTRING SQL_TOKEN_UCASE /* time and date functions */ %token SQL_TOKEN_CURRENT_DATE SQL_TOKEN_CURRENT_TIME SQL_TOKEN_CURRENT_TIMESTAMP SQL_TOKEN_CURDATE SQL_TOKEN_CURTIME %token SQL_TOKEN_DAYNAME SQL_TOKEN_DAYOFMONTH SQL_TOKEN_DAYOFWEEK SQL_TOKEN_DAYOFYEAR SQL_TOKEN_EXTRACT %token SQL_TOKEN_HOUR SQL_TOKEN_MILLISECOND SQL_TOKEN_MINUTE SQL_TOKEN_MONTH SQL_TOKEN_MONTHNAME SQL_TOKEN_NOW SQL_TOKEN_QUARTER SQL_TOKEN_DATEDIFF %token SQL_TOKEN_SECOND SQL_TOKEN_TIMESTAMPADD SQL_TOKEN_TIMESTAMPDIFF SQL_TOKEN_TIMEVALUE SQL_TOKEN_WEEK SQL_TOKEN_WEEKDAY SQL_TOKEN_YEAR SQL_TOKEN_YEARDAY /* numeric functions */ %token SQL_TOKEN_ABS SQL_TOKEN_ACOS SQL_TOKEN_ASIN SQL_TOKEN_ATAN SQL_TOKEN_ATAN2 SQL_TOKEN_CEILING %token SQL_TOKEN_COS SQL_TOKEN_COT SQL_TOKEN_DEGREES SQL_TOKEN_EXP SQL_TOKEN_FLOOR SQL_TOKEN_LOGF SQL_TOKEN_LOG SQL_TOKEN_LN %token SQL_TOKEN_LOG10 SQL_TOKEN_MOD SQL_TOKEN_PI SQL_TOKEN_POWER SQL_TOKEN_RADIANS SQL_TOKEN_RAND SQL_TOKEN_ROUNDMAGIC %token SQL_TOKEN_ROUND SQL_TOKEN_SIGN SQL_TOKEN_SIN SQL_TOKEN_SQRT SQL_TOKEN_TAN SQL_TOKEN_TRUNCATE // computational operation %token SQL_TOKEN_EVERY SQL_TOKEN_INTERSECTION SQL_TOKEN_FUSION SQL_TOKEN_COLLECT SQL_TOKEN_VAR_POP SQL_TOKEN_VAR_SAMP %token SQL_TOKEN_STDDEV_SAMP SQL_TOKEN_STDDEV_POP %token SQL_TOKEN_RANK SQL_TOKEN_DENSE_RANK SQL_TOKEN_PERCENT_RANK SQL_TOKEN_CUME_DIST SQL_TOKEN_PERCENTILE_CONT SQL_TOKEN_PERCENTILE_DISC SQL_TOKEN_WITHIN SQL_TOKEN_ARRAY_AGG %token SQL_TOKEN_CASE SQL_TOKEN_THEN SQL_TOKEN_END SQL_TOKEN_NULLIF SQL_TOKEN_COALESCE SQL_TOKEN_WHEN SQL_TOKEN_ELSE %token SQL_TOKEN_BEFORE SQL_TOKEN_AFTER SQL_TOKEN_INSTEAD SQL_TOKEN_EACH SQL_TOKEN_REFERENCING SQL_TOKEN_BEGIN SQL_TOKEN_ATOMIC SQL_TOKEN_TRIGGER SQL_TOKEN_ROW SQL_TOKEN_STATEMENT %token SQL_TOKEN_NEW SQL_TOKEN_OLD %token SQL_TOKEN_VALUE SQL_TOKEN_CURRENT_CATALOG SQL_TOKEN_CURRENT_DEFAULT_TRANSFORM_GROUP SQL_TOKEN_CURRENT_PATH SQL_TOKEN_CURRENT_ROLE SQL_TOKEN_CURRENT_SCHEMA SQL_TOKEN_CURRENT_USER %token SQL_TOKEN_SESSION_USER SQL_TOKEN_SYSTEM_USER SQL_TOKEN_VARCHAR SQL_TOKEN_VARBINARY SQL_TOKEN_VARYING SQL_TOKEN_OBJECT SQL_TOKEN_NCLOB SQL_TOKEN_NATIONAL %token SQL_TOKEN_LARGE SQL_TOKEN_CLOB SQL_TOKEN_BLOB SQL_TOKEN_BIGINT SQL_TOKEN_BINARY SQL_TOKEN_WITHOUT SQL_TOKEN_BOOLEAN SQL_TOKEN_INTERVAL // window function %token SQL_TOKEN_OVER SQL_TOKEN_ROW_NUMBER SQL_TOKEN_NTILE SQL_TOKEN_LEAD SQL_TOKEN_LAG SQL_TOKEN_RESPECT SQL_TOKEN_IGNORE SQL_TOKEN_NULLS %token SQL_TOKEN_FIRST_VALUE SQL_TOKEN_LAST_VALUE SQL_TOKEN_NTH_VALUE SQL_TOKEN_FIRST SQL_TOKEN_LAST %token SQL_TOKEN_EXCLUDE SQL_TOKEN_OTHERS SQL_TOKEN_TIES SQL_TOKEN_FOLLOWING SQL_TOKEN_UNBOUNDED SQL_TOKEN_PRECEDING SQL_TOKEN_RANGE SQL_TOKEN_ROWS %token SQL_TOKEN_PARTITION SQL_TOKEN_WINDOW SQL_TOKEN_NO // LIMIT and OFFSEt %token SQL_TOKEN_LIMIT SQL_TOKEN_OFFSET SQL_TOKEN_NEXT SQL_TOKEN_ONLY /* operators */ %left SQL_TOKEN_NAME %left SQL_TOKEN_OR %left SQL_TOKEN_AND %left SQL_LESSEQ SQL_GREATEQ SQL_NOTEQUAL SQL_LESS SQL_GREAT SQL_EQUAL /* '<' '>' = <> < > <= >= != */ %left '+' '-' SQL_CONCAT %left '*' '/' %left SQL_TOKEN_NATURAL SQL_TOKEN_CROSS SQL_TOKEN_FULL SQL_TOKEN_LEFT SQL_TOKEN_RIGHT %left ')' %right '=' %right '.' %right '(' %token SQL_TOKEN_INVALIDSYMBOL /*%type sql_single_statement */ %type sql /*schema */ %type column_def_opt_list column_def_opt table_constraint_def column_commalist %type view_def opt_with_check_option opt_column_commalist privilege_def %type opt_with_grant_option privileges operation_commalist operation %type grantee_commalist grantee opt_order_by_clause ordering_spec_commalist %type ordering_spec opt_asc_desc manipulative_statement commit_statement %type /*delete_statement_positioned*/ delete_statement_searched fetch_statement %type insert_statement values_or_query_spec %type rollback_statement select_statement_into opt_all_distinct %type /*update_statement_positioned*/ assignment_commalist assignment %type update_statement_searched target_commalist target opt_where_clause %type select_statement selection table_exp from_clause table_ref_commalist table_ref %type where_clause opt_group_by_clause column_ref_commalist opt_having_clause %type search_condition predicate comparison_predicate comparison_predicate_part_2 between_predicate between_predicate_part_2 %type like_predicate opt_escape test_for_null null_predicate_part_2 in_predicate in_predicate_part_2 character_like_predicate_part_2 other_like_predicate_part_2 %type all_or_any_predicate any_all_some existence_test subquery quantified_comparison_predicate_part_2 %type scalar_exp_commalist parameter_ref literal parenthesized_boolean_value_expression %type column_ref data_type column cursor parameter range_variable user /*like_check*/ /* new rules at OJ */ %type derived_column as_clause table_name num_primary term num_value_exp %type value_exp_primary num_value_fct unsigned_value_spec cast_spec set_fct_spec scalar_subquery %type position_exp extract_exp length_exp general_value_spec %type general_set_fct set_fct_type query_exp non_join_query_exp joined_table %type non_join_query_term non_join_query_primary simple_table %type table_value_const_list row_value_constructor /*row_value_const_list*/ row_value_constructor_elem %type qualified_join value_exp query_term join_type outer_join_type join_condition boolean_term %type boolean_factor boolean_primary named_columns_join join_spec %type cast_operand cast_target factor datetime_value_exp /*interval_value_exp*/ datetime_term datetime_factor %type datetime_primary datetime_value_fct time_zone time_zone_specifier /*interval_term*/ interval_qualifier %type start_field non_second_datetime_field end_field single_datetime_field extract_field datetime_field time_zone_field %type char_length_exp octet_length_exp bit_length_exp select_sublist string_value_exp %type char_value_exp concatenation char_factor char_primary string_value_fct char_substring_fct fold %type form_conversion char_translation trim_fct trim_operands trim_spec bit_value_fct bit_substring_fct op_column_commalist %type /*bit_concatenation*/ bit_value_exp bit_factor bit_primary collate_clause char_value_fct unique_spec value_exp_commalist in_predicate_value unique_test update_source %type function_arg_commalist3 string_function_3Argument function_arg_commalist4 string_function_4Argument function_arg_commalist2 string_function_1Argument string_function_2Argument %type date_function_0Argument date_function_1Argument function_name12 function_name23 function_name1 function_name2 function_name3 function_name0 numeric_function_0Argument numeric_function_1Argument numeric_function_2Argument %type all query_primary sql_not for_length upper_lower comparison column_val cross_union /*opt_schema_element_list*/ %type /*op_authorization op_schema*/ nil_fkt schema_element base_table_def base_table_element base_table_element_commalist %type column_def odbc_fct_spec odbc_call_spec odbc_fct_type op_parameter union_statement %type op_odbc_call_parameter odbc_parameter_commalist odbc_parameter function_args_commalist function_arg %type catalog_name schema_name table_node numeric_function string_function function_name date_function table_primary_as_range_column opt_as %type ordered_set_function inverse_distribution_function hypothetical_set_function hypothetical_set_function_value_expression_list rank_function_type within_group_specification inverse_distribution_function_type array_aggregate_function inverse_distribution_function_argument %type case_expression else_clause result_expression result case_abbreviation case_specification searched_when_clause simple_when_clause searched_case simple_case %type when_operand_list when_operand case_operand %type trigger_definition trigger_name trigger_action_time trigger_event transition_table_or_variable_list triggered_action trigger_column_list triggered_when_clause triggered_SQL_statement SQL_procedure_statement old_transition_variable_name new_transition_variable_name %type op_referencing op_trigger_columnlist op_triggered_action_for opt_row trigger_for SQL_procedure_statement_list transition_table_or_variable old_transition_table_name new_transition_table_name transition_table_name %type searched_when_clause_list simple_when_clause_list predefined_type opt_char_set_spec opt_collate_clause character_string_type national_character_string_type %type binary_string_type numeric_type boolean_type datetime_type interval_type opt_paren_precision paren_char_length opt_paren_char_large_length paren_character_large_object_length %type large_object_length opt_multiplier character_large_object_type national_character_large_object_type binary_large_object_string_type opt_with_or_without_time_zone %type approximate_numeric_type exact_numeric_type opt_paren_precision_scale /* window function rules */ %type window_function window_function_type ntile_function number_of_tiles lead_or_lag_function lead_or_lag lead_or_lag_extent offset default_expression null_treatment %type first_or_last_value_function first_or_last_value nth_value_function nth_row from_first_or_last window_name_or_specification in_line_window_specification opt_lead_or_lag_function %type opt_null_treatment opt_from_first_or_last simple_value_specification dynamic_parameter_specification window_name window_clause window_definition_list window_definition %type new_window_name window_specification_details existing_window_name window_partition_clause window_partition_column_reference_list window_partition_column_reference window_frame_clause %type window_frame_units window_frame_extent window_frame_start window_frame_preceding window_frame_between window_frame_bound_1 window_frame_bound_2 window_frame_bound window_frame_following window_frame_exclusion %type opt_window_frame_clause opt_window_partition_clause opt_existing_window_name window_specification opt_window_frame_exclusion opt_window_clause opt_offset %type opt_fetch_first_row_count fetch_first_clause offset_row_count fetch_first_row_count first_or_next row_or_rows opt_result_offset_clause result_offset_clause /* LIMIT and OFFSET */ %type opt_limit_offset_clause limit_offset_clause opt_fetch_first_clause %% /* Return Parse Tree to OSQLParser * (the access over yyval after calling the parser fails, * */ sql_single_statement: sql { xxx_pGLOBAL_SQLPARSER->setParseTree( $1 ); } | sql ';' { xxx_pGLOBAL_SQLPARSER->setParseTree( $1 ); } ; /* schema definition language */ /* Note: other ``sql:sal_Unicode() rules appear later in the grammar */ sql: manipulative_statement | schema_element { $$ = SQL_NEW_RULE; $$->append($1); } ; /*** op_authorization: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_AUTHORIZATION user { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; op_schema: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_NAME | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); } ; schema: SQL_TOKEN_CREATE SQL_TOKEN_SCHEMA op_schema op_authorization opt_schema_element_list { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } ; opt_schema_element_list: {$$ = SQL_NEW_RULE;} | schema_glement_list ; schema_element_list: schema_element {$$ = SQL_NEW_LISTRULE; $$->append($1);} | schema_element_list schema_element {$1->append($2); $$ = $1;} ; */ schema_element: base_table_def | view_def | privilege_def | trigger_definition ; base_table_def: SQL_TOKEN_CREATE SQL_TOKEN_TABLE table_node '(' base_table_element_commalist ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation));} ; base_table_element_commalist: base_table_element {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | base_table_element_commalist ',' base_table_element {$1->append($3); $$ = $1;} ; base_table_element: column_def | table_constraint_def ; column_def: column data_type column_def_opt_list {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; column_def_opt_list: /* empty */ {$$ = SQL_NEW_LISTRULE;} | column_def_opt_list column_def_opt {$1->append($2); $$ = $1;} ; nil_fkt: datetime_value_fct ; unique_spec: SQL_TOKEN_UNIQUE | SQL_TOKEN_PRIMARY SQL_TOKEN_KEY { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; column_def_opt: SQL_TOKEN_NOT SQL_TOKEN_NULL {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | unique_spec | SQL_TOKEN_DEFAULT literal {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_DEFAULT SQL_TOKEN_NULL {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_DEFAULT SQL_TOKEN_USER {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_DEFAULT nil_fkt { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_CHECK | SQL_TOKEN_CHECK '(' search_condition ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation));} | SQL_TOKEN_REFERENCES table_node {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_REFERENCES table_node '(' column_commalist ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation));} ; table_constraint_def: unique_spec '(' column_commalist ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation));} | SQL_TOKEN_FOREIGN SQL_TOKEN_KEY '(' column_commalist ')' SQL_TOKEN_REFERENCES table_node {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($6); $$->append($7);} | SQL_TOKEN_FOREIGN SQL_TOKEN_KEY '(' column_commalist ')' SQL_TOKEN_REFERENCES table_node '(' column_commalist ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($6); $$->append($7); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($9); $$->append(newNode(")", SQLNodeType::Punctuation));} | SQL_TOKEN_CHECK '(' search_condition ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation));} ; op_column_commalist: /* empty */ {$$ = SQL_NEW_RULE;} | '(' column_commalist ')' {$$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; column_commalist: column_commalist ',' column {$1->append($3); $$ = $1;} | column {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} ; view_def: SQL_TOKEN_CREATE SQL_TOKEN_VIEW table_node opt_column_commalist SQL_TOKEN_AS select_statement opt_with_check_option {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7);} ; opt_with_check_option: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_WITH SQL_TOKEN_CHECK SQL_TOKEN_OPTION {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3);} ; opt_column_commalist: /* empty */ {$$ = SQL_NEW_RULE;} | '(' column_commalist ')' {$$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation));} ; privilege_def: SQL_TOKEN_GRANT privileges SQL_TOKEN_ON table_node SQL_TOKEN_TO grantee_commalist opt_with_grant_option {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7);} ; opt_with_grant_option: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_WITH SQL_TOKEN_GRANT SQL_TOKEN_OPTION {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3);} ; privileges: SQL_TOKEN_ALL SQL_TOKEN_PRIVILEGES {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | operation_commalist ; operation_commalist: operation {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | operation_commalist ',' operation {$1->append($3); $$ = $1;} ; operation: SQL_TOKEN_SELECT | SQL_TOKEN_INSERT opt_column_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_DELETE | SQL_TOKEN_UPDATE opt_column_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_REFERENCES opt_column_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | SQL_TOKEN_USAGE ; grantee_commalist: grantee {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | grantee_commalist ',' grantee {$1->append($3); $$ = $1;} ; grantee: SQL_TOKEN_PUBLIC | user ; /* module language */ opt_order_by_clause: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ORDER SQL_TOKEN_BY ordering_spec_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3);} ; ordering_spec_commalist: ordering_spec {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | ordering_spec_commalist ',' ordering_spec {$1->append($3); $$ = $1;} ; ordering_spec: /* SQL_TOKEN_INTNUM opt_asc_desc {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} */ predicate opt_asc_desc {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | row_value_constructor_elem opt_asc_desc {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; opt_asc_desc: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ASC | SQL_TOKEN_DESC ; /*** manipulative_statement_list: manipulative_statement {$$ = SQL_NEW_LISTRULE; $$->append($1);} | manipulative_statement_list manipulative_statement {$1->append($2); $$ = $1;} ; ***/ sql_not: /* vide */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_NOT ; /* manipulative statements */ manipulative_statement: commit_statement /* | delete_statement_positioned*/ | delete_statement_searched | fetch_statement | insert_statement | rollback_statement | select_statement_into /* | update_statement_positioned*/ | update_statement_searched | union_statement | '{' odbc_call_spec '}' { $$ = SQL_NEW_RULE; $$->append(newNode("{", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode("}", SQLNodeType::Punctuation)); } ; union_statement: select_statement | union_statement SQL_TOKEN_UNION all select_statement { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; commit_statement: SQL_TOKEN_COMMIT SQL_TOKEN_WORK {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; /* delete_statement_positioned: SQL_TOKEN_DELETE SQL_TOKEN_FROM table_node SQL_TOKEN_WHERE SQL_TOKEN_CURRENT SQL_TOKEN_OF cursor {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7);} ; */ delete_statement_searched: SQL_TOKEN_DELETE SQL_TOKEN_FROM table_node opt_where_clause {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4);} ; fetch_statement: SQL_TOKEN_FETCH cursor SQL_TOKEN_INTO target_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4);} ; insert_statement: SQL_TOKEN_INSERT SQL_TOKEN_INTO table_node opt_column_commalist query_exp {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5);} ; values_or_query_spec: SQL_TOKEN_VALUES '(' table_value_const_list ')' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; table_value_const_list: row_value_constructor {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | table_value_const_list ',' row_value_constructor {$1->append($3); $$ = $1;} ; /* row_value_const_list: row_value_constructor_elem {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | row_value_const_list ',' row_value_constructor_elem {$1->append($3); $$ = $1;} ; */ row_value_constructor: row_value_constructor_elem /* | '(' row_value_const_list ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } */ ; row_value_constructor_elem: value_exp /*[^')']*/ | SQL_TOKEN_DEFAULT ; rollback_statement: SQL_TOKEN_ROLLBACK SQL_TOKEN_WORK {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; /* INTO target_commalist herausgenommen */ select_statement_into: SQL_TOKEN_SELECT opt_all_distinct selection SQL_TOKEN_INTO target_commalist table_exp {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); } ; opt_all_distinct: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ALL | SQL_TOKEN_DISTINCT ; /* update_statement_positioned: SQL_TOKEN_UPDATE table_node SQL_TOKEN_SET assignment_commalist SQL_TOKEN_WHERE SQL_TOKEN_CURRENT SQL_TOKEN_OF cursor {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7); $$->append($8);} ; */ assignment_commalist: assignment {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | assignment_commalist ',' assignment {$1->append($3); $$ = $1;} ; assignment: column SQL_EQUAL update_source {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3);} ; update_source: value_exp | SQL_TOKEN_DEFAULT ; update_statement_searched: SQL_TOKEN_UPDATE table_node SQL_TOKEN_SET assignment_commalist opt_where_clause {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5);} ; target_commalist: target {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | target_commalist ',' target {$1->append($3); $$ = $1;} ; target: parameter_ref ; opt_where_clause: /* empty */ {$$ = SQL_NEW_RULE;} | where_clause ; /* query expressions */ query_term: non_join_query_term { $$ = SQL_NEW_RULE; $$->append($1); } ; /* SELECT STATEMENT */ select_statement: SQL_TOKEN_SELECT opt_all_distinct selection table_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; selection: '*' { $$ = SQL_NEW_RULE; $$->append(newNode("*", SQLNodeType::Punctuation)); } | scalar_exp_commalist ; opt_result_offset_clause: /* empty */ {$$ = SQL_NEW_RULE;} | result_offset_clause ; result_offset_clause: SQL_TOKEN_OFFSET offset_row_count row_or_rows { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; opt_fetch_first_row_count: /* empty */ {$$ = SQL_NEW_RULE;} | fetch_first_row_count ; first_or_next: SQL_TOKEN_FIRST | SQL_TOKEN_NEXT ; row_or_rows: SQL_TOKEN_ROW | SQL_TOKEN_ROWS ; opt_fetch_first_clause: /* empty */ {$$ = SQL_NEW_RULE;} | fetch_first_clause ; fetch_first_clause: SQL_TOKEN_FETCH first_or_next opt_fetch_first_row_count row_or_rows SQL_TOKEN_ONLY { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } ; offset_row_count: literal ; fetch_first_row_count: literal ; opt_limit_offset_clause: /* empty */ {$$ = SQL_NEW_RULE;} | limit_offset_clause ; opt_offset: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_OFFSET SQL_TOKEN_INTNUM { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; limit_offset_clause: SQL_TOKEN_LIMIT SQL_TOKEN_INTNUM opt_offset { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; table_exp: from_clause opt_where_clause opt_group_by_clause opt_having_clause opt_window_clause opt_order_by_clause opt_limit_offset_clause opt_result_offset_clause opt_fetch_first_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7); $$->append($8); $$->append($9); } ; from_clause: SQL_TOKEN_FROM table_ref_commalist { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; table_ref_commalist: table_ref { $$ = SQL_NEW_COMMALISTRULE; $$->append($1); } | table_ref_commalist ',' table_ref { $1->append($3); $$ = $1; } ; opt_as: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_AS ; opt_row: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ROW ; table_primary_as_range_column: {$$ = SQL_NEW_RULE;} | opt_as SQL_TOKEN_NAME op_column_commalist { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; table_ref: table_node table_primary_as_range_column { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | subquery range_variable op_column_commalist { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | joined_table | '{' SQL_TOKEN_OJ joined_table '}' { $$ = SQL_NEW_RULE; $$->append(newNode("{", SQLNodeType::Punctuation)); $$->append($2); $$->append($3); $$->append(newNode("}", SQLNodeType::Punctuation)); } | '(' joined_table ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; where_clause: SQL_TOKEN_WHERE search_condition {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; opt_group_by_clause: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_GROUP SQL_TOKEN_BY column_ref_commalist {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3);} ; column_ref_commalist: column_ref {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | set_fct_spec {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | column_ref_commalist ',' column_ref {$1->append($3); $$ = $1;} | column_ref_commalist ',' set_fct_spec {$1->append($3); $$ = $1;} ; opt_having_clause: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_HAVING search_condition {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; /* search conditions */ boolean_primary: predicate | '(' search_condition ')' { // boolean_primary: rule 2 $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } | row_value_constructor_elem /*[^')' ',']*/ { if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck())// boolean_primary: rule 3 { $$ = SQL_NEW_RULE; sal_Int16 nErg = 0; if ( SQL_ISTOKEN( $1, NULL)) { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); OSQLParseNode* pTFN = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::test_for_null)); pTFN->append(pColumnRef); OSQLParseNode* pNPP2 = new OSQLInternalNode("", SQLNodeType::Rule, OSQLParser::RuleID(OSQLParseNode::null_predicate_part_2)); pNPP2->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_IS)); pNPP2->append(new OSQLInternalNode("", SQLNodeType::Rule, OSQLParser::RuleID(OSQLParseNode::sql_not))); pNPP2->append(new OSQLInternalNode("", SQLNodeType::Keyword, SQL_TOKEN_NULL)); pTFN->append(pNPP2); $$->append(pTFN); nErg = 1; } else { nErg = xxx_pGLOBAL_SQLPARSER->buildComparsionRule($$,$1); } if(nErg == 1) { OSQLParseNode* pTemp = $$; $$ = pTemp->removeAt((sal_uInt32)0); delete pTemp; } else { delete $$; if(nErg) YYERROR; else YYABORT; } } else YYERROR; } ; parenthesized_boolean_value_expression: '(' search_condition ')' { // boolean_primary: rule 2 $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; boolean_factor: boolean_primary %dprec 2 | SQL_TOKEN_NOT boolean_primary %dprec 1 { // boolean_factor: rule 1 $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; boolean_term: boolean_factor | boolean_term SQL_TOKEN_AND boolean_factor { $$ = SQL_NEW_RULE; // boolean_term: rule 1 $$->append($1); $$->append($2); $$->append($3); } ; search_condition: boolean_term | search_condition SQL_TOKEN_OR boolean_term { $$ = SQL_NEW_RULE; // search_condition $$->append($1); $$->append($2); $$->append($3); } ; predicate: comparison_predicate %dprec 1 | between_predicate | all_or_any_predicate | existence_test | unique_test | test_for_null %dprec 2 | in_predicate | like_predicate ; comparison_predicate_part_2: comparison row_value_constructor { $$ = SQL_NEW_RULE; // comparison_predicate: rule 1 $$->append($1); $$->append($2); } comparison_predicate: row_value_constructor comparison row_value_constructor { $$ = SQL_NEW_RULE; // comparison_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); } | comparison row_value_constructor { if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // comparison_predicate: rule 2 { $$ = SQL_NEW_RULE; sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildPredicateRule($$,$2,$1); if(nErg == 1) { OSQLParseNode* pTemp = $$; $$ = pTemp->removeAt((sal_uInt32)0); delete pTemp; } else { delete $$; YYABORT; } } else { YYERROR; } } ; comparison: SQL_LESS | SQL_NOTEQUAL | SQL_EQUAL | SQL_GREAT | SQL_LESSEQ | SQL_GREATEQ | SQL_TOKEN_IS sql_not SQL_TOKEN_DISTINCT SQL_TOKEN_FROM { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_IS sql_not { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; between_predicate_part_2: sql_not SQL_TOKEN_BETWEEN row_value_constructor SQL_TOKEN_AND row_value_constructor { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // between_predicate: rule 2 { $$ = SQL_NEW_RULE; sal_Int16 nErg = xxx_pGLOBAL_SQLPARSER->buildPredicateRule($$,$3,$2,$5); if(nErg == 1) { OSQLParseNode* pTemp = $$; $$ = pTemp->removeAt((sal_uInt32)0); OSQLParseNode* pColumnRef = $$->removeAt((sal_uInt32)0); $$->insert(0,$1); OSQLParseNode* pBetween_predicate = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::between_predicate)); pBetween_predicate->append(pColumnRef); pBetween_predicate->append($$); $$ = pBetween_predicate; delete pTemp; delete $4; } else { delete $$; YYABORT; } } else { $$ = SQL_NEW_RULE; // between_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } } between_predicate: row_value_constructor between_predicate_part_2 { $$ = SQL_NEW_RULE; // between_predicate: rule 1 $$->append($1); $$->append($2); } | between_predicate_part_2 ; character_like_predicate_part_2: sql_not SQL_TOKEN_LIKE string_value_exp opt_escape { $$ = SQL_NEW_RULE; // like_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; other_like_predicate_part_2: sql_not SQL_TOKEN_LIKE value_exp_primary opt_escape { $$ = SQL_NEW_RULE; // like_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; like_predicate: row_value_constructor character_like_predicate_part_2 { $$ = SQL_NEW_RULE; // like_predicate: rule 1 $$->append($1); $$->append($2); } | row_value_constructor other_like_predicate_part_2 { $$ = SQL_NEW_RULE; // like_predicate: rule 3 $$->append($1); $$->append($2); } | character_like_predicate_part_2 { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // like_predicate: rule 5 { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); $$ = SQL_NEW_RULE; $$->append(pColumnRef); $$->append($1); OSQLParseNode* p2nd = $1->removeAt(2); OSQLParseNode* p3rd = $1->removeAt(2); if ( !xxx_pGLOBAL_SQLPARSER->buildLikeRule($1,p2nd,p3rd) ) { delete $$; YYABORT; } $1->append(p3rd); } else YYERROR; } | other_like_predicate_part_2 { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // like_predicate: rule 6 { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); $$ = SQL_NEW_RULE; $$->append(pColumnRef); $$->append($1); OSQLParseNode* p2nd = $1->removeAt(2); OSQLParseNode* p3rd = $1->removeAt(2); if ( !xxx_pGLOBAL_SQLPARSER->buildLikeRule($1,p2nd,p3rd) ) { delete $$; YYABORT; } $1->append(p3rd); } else YYERROR; } ; opt_escape: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ESCAPE string_value_exp {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} | '{' SQL_TOKEN_ESCAPE SQL_TOKEN_STRING '}' { $$ = SQL_NEW_RULE; $$->append(newNode("{", SQLNodeType::Punctuation)); $$->append($2); $$->append($3); $$->append(newNode("}", SQLNodeType::Punctuation)); } ; null_predicate_part_2: SQL_TOKEN_IS sql_not SQL_TOKEN_NULL { $$ = SQL_NEW_RULE; // test_for_null: rule 1 $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_IS sql_not SQL_TOKEN_UNKNOWN { $$ = SQL_NEW_RULE; // test_for_null: rule 1 $$->append($1); $$->append($2); $$->append($3); } ; test_for_null: row_value_constructor null_predicate_part_2 { $$ = SQL_NEW_RULE; // test_for_null: rule 1 $$->append($1); $$->append($2); } | null_predicate_part_2 { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck())// test_for_null: rule 2 { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); $$ = SQL_NEW_RULE; $$->append(pColumnRef); $$->append($1); } else YYERROR; } ; in_predicate_value: subquery {$$ = SQL_NEW_RULE; $$->append($1); } | '(' value_exp_commalist ')' {$$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; in_predicate_part_2: sql_not SQL_TOKEN_IN in_predicate_value { $$ = SQL_NEW_RULE;// in_predicate: rule 1 $$->append($1); $$->append($2); $$->append($3); } ; in_predicate: row_value_constructor in_predicate_part_2 { $$ = SQL_NEW_RULE;// in_predicate: rule 1 $$->append($1); $$->append($2); } | in_predicate_part_2 { if ( xxx_pGLOBAL_SQLPARSER->inPredicateCheck() )// in_predicate: rule 2 { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); $$ = SQL_NEW_RULE; $$->append(pColumnRef); $$->append($1); } else YYERROR; } ; quantified_comparison_predicate_part_2: comparison any_all_some subquery { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; all_or_any_predicate: row_value_constructor quantified_comparison_predicate_part_2 { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | quantified_comparison_predicate_part_2 { if(xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { OSQLParseNode* pColumnRef = newNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(newNode(xxx_pGLOBAL_SQLPARSER->getFieldName(),SQLNodeType::Name)); $$ = SQL_NEW_RULE; $$->append(pColumnRef); $$->append($1); } else YYERROR; } ; any_all_some: SQL_TOKEN_ANY | SQL_TOKEN_ALL | SQL_TOKEN_SOME ; existence_test: SQL_TOKEN_EXISTS subquery {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; unique_test: SQL_TOKEN_UNIQUE subquery {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2);} ; subquery: '(' query_exp ')' {$$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation));} ; /* scalar expressions */ scalar_exp_commalist: select_sublist { $$ = SQL_NEW_COMMALISTRULE; $$->append($1); } | scalar_exp_commalist ',' select_sublist { $1->append($3); $$ = $1; } ; select_sublist: /* table_node '.' '*' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append(newNode("*", SQLNodeType::Punctuation)); } */ derived_column ; parameter_ref: parameter ; /* op_like: '*' { $$ = newNode("*", SQLNodeType::Punctuation); } | '?' { $$ = newNode("?", SQLNodeType::Punctuation); } | op_like '*' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("*", SQLNodeType::Punctuation)); xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, sal_False); } | op_like '?' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("?", SQLNodeType::Punctuation)); xxx_pGLOBAL_SQLPARSER->reduceLiteral($$, sal_False); } ; */ literal: /* SQL_TOKEN_STRING | */SQL_TOKEN_INT | SQL_TOKEN_REAL_NUM | SQL_TOKEN_INTNUM | SQL_TOKEN_APPROXNUM | SQL_TOKEN_ACCESS_DATE /* rules for predicate check */ | literal SQL_TOKEN_STRING { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); OSQLParser::reduceLiteral($$, true); } else YYERROR; } | literal SQL_TOKEN_INT { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); OSQLParser::reduceLiteral($$, true); } else YYERROR; } | literal SQL_TOKEN_REAL_NUM { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); OSQLParser::reduceLiteral($$, true); } else YYERROR; } | literal SQL_TOKEN_APPROXNUM { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); OSQLParser::reduceLiteral($$, true); } else YYERROR; } ; /* miscellaneous */ as_clause: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_AS column { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | column ; position_exp: SQL_TOKEN_POSITION '(' value_exp SQL_TOKEN_IN value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_POSITION '(' value_exp_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; num_value_fct: position_exp | extract_exp | length_exp ; char_length_exp: SQL_TOKEN_CHAR_LENGTH '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_SQL_TOKEN_INTNUM '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; octet_length_exp: SQL_TOKEN_OCTET_LENGTH '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; bit_length_exp: SQL_TOKEN_BIT_LENGTH '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; length_exp: char_length_exp { $$ = SQL_NEW_RULE; $$->append($1); } | octet_length_exp { $$ = SQL_NEW_RULE; $$->append($1); } | bit_length_exp { $$ = SQL_NEW_RULE; $$->append($1); } ; datetime_field: non_second_datetime_field { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_SECOND { $$ = SQL_NEW_RULE; $$->append($1); } ; extract_field: time_zone_field | datetime_field | value_exp ; time_zone_field: SQL_TOKEN_TIMEZONE_HOUR { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_TIMEZONE_MINUTE { $$ = SQL_NEW_RULE; $$->append($1); } ; extract_exp: SQL_TOKEN_EXTRACT '(' extract_field SQL_TOKEN_FROM value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; unsigned_value_spec: general_value_spec | literal ; general_value_spec: parameter | SQL_TOKEN_USER | SQL_TOKEN_NULL | SQL_TOKEN_FALSE | SQL_TOKEN_TRUE | SQL_TOKEN_VALUE | SQL_TOKEN_CURRENT_CATALOG | SQL_TOKEN_CURRENT_DEFAULT_TRANSFORM_GROUP | SQL_TOKEN_CURRENT_PATH | SQL_TOKEN_CURRENT_ROLE | SQL_TOKEN_CURRENT_SCHEMA | SQL_TOKEN_CURRENT_USER | SQL_TOKEN_SESSION_USER | SQL_TOKEN_SYSTEM_USER ; set_fct_spec: general_set_fct | '{' odbc_fct_spec '}' { $$ = SQL_NEW_RULE; $$->append(newNode("{", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode("}", SQLNodeType::Punctuation)); } | function_name '(' ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name0 '(' ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name1 '(' function_arg ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name2 '(' function_arg_commalist2 ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name3 '(' function_arg_commalist3 ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | string_function_4Argument '(' function_arg_commalist4 ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name '(' function_args_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | function_name12 '(' function_args_commalist ')' { if ( $3->count() == 1 || $3->count() == 2 ) { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } else YYERROR; } | function_name23 '(' function_args_commalist ')' { if ( $3->count() == 2 || $3->count() == 3) { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } else YYERROR; } ; function_name0: date_function_0Argument | numeric_function_0Argument ; function_name1: string_function_1Argument | date_function_1Argument | numeric_function_1Argument ; function_name2: string_function_2Argument | numeric_function_2Argument ; function_name12: SQL_TOKEN_ROUND | SQL_TOKEN_WEEK | SQL_TOKEN_LOGF | SQL_TOKEN_LOG ; function_name23: SQL_TOKEN_LOCATE | SQL_TOKEN_DATEDIFF ; function_name3: string_function_3Argument ; function_name: string_function | date_function | numeric_function | SQL_TOKEN_NAME ; string_function_1Argument: SQL_TOKEN_LENGTH | SQL_TOKEN_ASCII | SQL_TOKEN_LCASE | SQL_TOKEN_LTRIM | SQL_TOKEN_RTRIM | SQL_TOKEN_SPACE | SQL_TOKEN_UCASE ; string_function_2Argument: SQL_TOKEN_REPEAT | SQL_TOKEN_LEFT | SQL_TOKEN_RIGHT ; string_function_3Argument: SQL_TOKEN_REPLACE ; string_function_4Argument: SQL_TOKEN_INSERT ; string_function: SQL_TOKEN_CHAR | SQL_TOKEN_CONCAT | SQL_TOKEN_DIFFERENCE | SQL_TOKEN_LOCATE_2 | SQL_TOKEN_SOUNDEX ; date_function_0Argument: SQL_TOKEN_CURDATE | SQL_TOKEN_CURTIME | SQL_TOKEN_NOW ; date_function_1Argument: SQL_TOKEN_DAYOFWEEK | SQL_TOKEN_DAYOFMONTH | SQL_TOKEN_DAYOFYEAR | SQL_TOKEN_MONTH | SQL_TOKEN_DAYNAME | SQL_TOKEN_MONTHNAME | SQL_TOKEN_QUARTER | SQL_TOKEN_HOUR | SQL_TOKEN_MINUTE | SQL_TOKEN_SECOND | SQL_TOKEN_YEAR | SQL_TOKEN_DAY | SQL_TOKEN_TIMEVALUE | SQL_TOKEN_DATEVALUE ; date_function: SQL_TOKEN_TIMESTAMPADD | SQL_TOKEN_TIMESTAMPDIFF ; numeric_function_0Argument: SQL_TOKEN_PI ; numeric_function_1Argument: SQL_TOKEN_ABS | SQL_TOKEN_ACOS | SQL_TOKEN_ASIN | SQL_TOKEN_ATAN | SQL_TOKEN_CEILING | SQL_TOKEN_COS | SQL_TOKEN_COT | SQL_TOKEN_DEGREES | SQL_TOKEN_FLOOR | SQL_TOKEN_SIGN | SQL_TOKEN_SIN | SQL_TOKEN_SQRT | SQL_TOKEN_TAN | SQL_TOKEN_EXP | SQL_TOKEN_LOG10 | SQL_TOKEN_LN | SQL_TOKEN_RADIANS | SQL_TOKEN_ROUNDMAGIC ; numeric_function_2Argument: SQL_TOKEN_ATAN2 | SQL_TOKEN_MOD | SQL_TOKEN_POWER ; numeric_function: SQL_TOKEN_RAND | SQL_TOKEN_TRUNCATE ; window_function: window_function_type SQL_TOKEN_OVER window_name_or_specification { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; window_function_type : rank_function_type '(' ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_ROW_NUMBER '(' ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } | general_set_fct | ntile_function | lead_or_lag_function | first_or_last_value_function | nth_value_function ; ntile_function : SQL_TOKEN_NTILE '(' number_of_tiles ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; dynamic_parameter_specification: parameter ; simple_value_specification: literal ; number_of_tiles : simple_value_specification | dynamic_parameter_specification ; opt_lead_or_lag_function: /* empty */ {$$ = SQL_NEW_RULE;} | ',' offset { $$ = SQL_NEW_RULE; $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($2); } | ',' offset ',' default_expression { $$ = SQL_NEW_RULE; $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($4); } ; opt_null_treatment: /* empty */ {$$ = SQL_NEW_RULE;} | null_treatment ; lead_or_lag_function: lead_or_lag '(' lead_or_lag_extent opt_lead_or_lag_function ')' opt_null_treatment { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($6); } ; lead_or_lag: SQL_TOKEN_LEAD | SQL_TOKEN_LAG ; lead_or_lag_extent: value_exp ; offset: SQL_TOKEN_INTNUM ; default_expression: value_exp ; null_treatment: SQL_TOKEN_RESPECT SQL_TOKEN_NULLS | SQL_TOKEN_IGNORE SQL_TOKEN_NULLS ; first_or_last_value_function: first_or_last_value '(' value_exp ')' opt_null_treatment { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($5); } ; first_or_last_value : SQL_TOKEN_FIRST_VALUE | SQL_TOKEN_LAST_VALUE ; opt_from_first_or_last: /* empty */ {$$ = SQL_NEW_RULE;} | from_first_or_last ; nth_value_function: SQL_TOKEN_NTH_VALUE '(' value_exp ',' nth_row ')' opt_from_first_or_last opt_null_treatment { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($7); $$->append($8); } ; nth_row: simple_value_specification | dynamic_parameter_specification ; from_first_or_last: SQL_TOKEN_FROM SQL_TOKEN_FIRST { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_FROM SQL_TOKEN_LAST { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; window_name: SQL_TOKEN_NAME ; window_name_or_specification: window_name | in_line_window_specification ; in_line_window_specification: window_specification ; opt_window_clause: /* empty */ {$$ = SQL_NEW_RULE;} | window_clause ; window_clause: SQL_TOKEN_WINDOW window_definition_list { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; window_definition_list: window_definition_list ',' window_definition {$1->append($3); $$ = $1;} | window_definition {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} ; window_definition: new_window_name SQL_TOKEN_AS window_specification { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; new_window_name: window_name ; window_specification: '(' window_specification_details ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; opt_existing_window_name: /* empty */ {$$ = SQL_NEW_RULE;} | existing_window_name ; opt_window_partition_clause: /* empty */ {$$ = SQL_NEW_RULE;} | window_partition_clause ; opt_window_frame_clause: /* empty */ {$$ = SQL_NEW_RULE;} | window_frame_clause ; window_specification_details: opt_existing_window_name opt_window_partition_clause opt_order_by_clause opt_window_frame_clause ; existing_window_name: window_name ; window_partition_clause: SQL_TOKEN_PARTITION SQL_TOKEN_BY window_partition_column_reference_list { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; window_partition_column_reference_list: window_partition_column_reference_list ',' window_partition_column_reference {$1->append($3); $$ = $1;} | window_partition_column_reference {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} ; window_partition_column_reference: column_ref opt_collate_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; opt_window_frame_exclusion: /* empty */ {$$ = SQL_NEW_RULE;} | window_frame_exclusion ; window_frame_clause: window_frame_units window_frame_extent opt_window_frame_exclusion { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; window_frame_units: SQL_TOKEN_ROWS | SQL_TOKEN_RANGE ; window_frame_extent: window_frame_start | window_frame_between ; window_frame_start: SQL_TOKEN_UNBOUNDED SQL_TOKEN_PRECEDING { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | window_frame_preceding | SQL_TOKEN_CURRENT SQL_TOKEN_ROW { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; window_frame_preceding: unsigned_value_spec SQL_TOKEN_PRECEDING { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; window_frame_between: SQL_TOKEN_BETWEEN window_frame_bound_1 SQL_TOKEN_AND window_frame_bound_2 { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; window_frame_bound_1: window_frame_bound ; window_frame_bound_2: window_frame_bound ; window_frame_bound: window_frame_start | SQL_TOKEN_UNBOUNDED SQL_TOKEN_FOLLOWING { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | window_frame_following ; window_frame_following: unsigned_value_spec SQL_TOKEN_FOLLOWING { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; window_frame_exclusion: SQL_TOKEN_EXCLUDE SQL_TOKEN_CURRENT SQL_TOKEN_ROW { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_EXCLUDE SQL_TOKEN_GROUP { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_EXCLUDE SQL_TOKEN_TIES { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_EXCLUDE SQL_TOKEN_NO SQL_TOKEN_OTHERS { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; op_parameter: {$$ = SQL_NEW_RULE;} | '?' SQL_EQUAL { $$ = SQL_NEW_RULE; $$->append(newNode("?", SQLNodeType::Punctuation)); $$->append($2); } ; odbc_call_spec: op_parameter SQL_TOKEN_CALL table_node op_odbc_call_parameter { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; op_odbc_call_parameter: {$$ = SQL_NEW_RULE;} | '(' odbc_parameter_commalist ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; odbc_parameter_commalist: odbc_parameter {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | odbc_parameter_commalist ',' odbc_parameter { $1->append($3); $$ = $1; } ; odbc_parameter: /* empty */ {$$ = SQL_NEW_RULE;} | literal | parameter ; odbc_fct_spec: odbc_fct_type SQL_TOKEN_STRING { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_FN set_fct_spec { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; odbc_fct_type: SQL_TOKEN_D | SQL_TOKEN_T | SQL_TOKEN_TS ; general_set_fct: set_fct_type '(' opt_all_distinct function_arg ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_COUNT '(' '*' ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append(newNode("*", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_COUNT '(' opt_all_distinct function_arg ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); } | ordered_set_function | array_aggregate_function ; set_fct_type: SQL_TOKEN_AVG | SQL_TOKEN_MAX | SQL_TOKEN_MIN | SQL_TOKEN_SUM | SQL_TOKEN_EVERY | SQL_TOKEN_ANY | SQL_TOKEN_SOME | SQL_TOKEN_STDDEV_POP | SQL_TOKEN_STDDEV_SAMP | SQL_TOKEN_VAR_SAMP | SQL_TOKEN_VAR_POP | SQL_TOKEN_COLLECT | SQL_TOKEN_FUSION | SQL_TOKEN_INTERSECTION ; ordered_set_function: hypothetical_set_function | inverse_distribution_function ; hypothetical_set_function: rank_function_type '(' hypothetical_set_function_value_expression_list ')' within_group_specification { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($5); } | rank_function_type '(' hypothetical_set_function_value_expression_list SQL_TOKEN_BY value_exp_commalist ')' within_group_specification { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($7); } ; within_group_specification: { $$ = SQL_NEW_RULE; } | SQL_TOKEN_WITHIN SQL_TOKEN_GROUP '(' opt_order_by_clause ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; hypothetical_set_function_value_expression_list: value_exp_commalist ; inverse_distribution_function: inverse_distribution_function_type '('inverse_distribution_function_argument ')' within_group_specification { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; inverse_distribution_function_argument: num_value_exp ; inverse_distribution_function_type: SQL_TOKEN_PERCENTILE_CONT | SQL_TOKEN_PERCENTILE_DISC ; array_aggregate_function: SQL_TOKEN_ARRAY_AGG '(' value_exp opt_order_by_clause ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; rank_function_type: SQL_TOKEN_RANK | SQL_TOKEN_DENSE_RANK | SQL_TOKEN_PERCENT_RANK | SQL_TOKEN_CUME_DIST ; outer_join_type: SQL_TOKEN_LEFT %prec SQL_TOKEN_LEFT { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_RIGHT %prec SQL_TOKEN_RIGHT { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_FULL %prec SQL_TOKEN_FULL { $$ = SQL_NEW_RULE; $$->append($1); } ; join_condition: SQL_TOKEN_ON search_condition { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; join_spec: join_condition | named_columns_join ; join_type: /* empty */ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_INNER { $$ = SQL_NEW_RULE; $$->append($1); } | outer_join_type | outer_join_type SQL_TOKEN_OUTER { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; cross_union: table_ref SQL_TOKEN_CROSS SQL_TOKEN_JOIN table_ref { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; qualified_join: /* when SQL_TOKEN_NATURAL, then no join_spec */ table_ref SQL_TOKEN_NATURAL join_type SQL_TOKEN_JOIN table_ref { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } | table_ref join_type SQL_TOKEN_JOIN table_ref join_spec { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } | cross_union ; joined_table: qualified_join ; named_columns_join: SQL_TOKEN_USING '(' column_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; simple_table: select_statement | values_or_query_spec ; non_join_query_primary: simple_table | '(' non_join_query_exp ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; non_join_query_term: non_join_query_primary | query_term SQL_TOKEN_INTERSECT all query_primary { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; query_primary: non_join_query_primary ; non_join_query_exp: non_join_query_term | query_exp SQL_TOKEN_UNION all query_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | query_exp SQL_TOKEN_EXCEPT all query_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; all: /* empty*/ {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ALL ; query_exp: non_join_query_exp /*[^')']*/ ; scalar_subquery: subquery ; cast_operand: value_exp ; cast_target: table_node | data_type ; cast_spec: SQL_TOKEN_CAST '(' cast_operand SQL_TOKEN_AS cast_target ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; value_exp_primary: unsigned_value_spec | column_ref | set_fct_spec | scalar_subquery | case_expression | window_function | '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } | cast_spec ; num_primary: value_exp_primary | num_value_fct ; factor: num_primary | '-' num_primary %prec SQL_TOKEN_UMINUS { $$ = SQL_NEW_RULE; $$->append(newNode("-", SQLNodeType::Punctuation)); $$->append($2); } | '+' num_primary %prec SQL_TOKEN_UMINUS { $$ = SQL_NEW_RULE; $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($2); } ; term: factor | term '*' factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("*", SQLNodeType::Punctuation)); $$->append($3); } | term '/' factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("/", SQLNodeType::Punctuation)); $$->append($3); } ; num_value_exp: term | num_value_exp '+' term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } | num_value_exp '-' term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("-", SQLNodeType::Punctuation)); $$->append($3); } ; datetime_primary: /* value_exp_primary { $$ = SQL_NEW_RULE; $$->append($1); } |*/ datetime_value_fct { $$ = SQL_NEW_RULE; $$->append($1); } ; datetime_value_fct: SQL_TOKEN_CURRENT_DATE { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_CURRENT_TIME { $$ = SQL_NEW_RULE; $$->append($1); } | SQL_TOKEN_CURRENT_TIMESTAMP { $$ = SQL_NEW_RULE; $$->append($1); } ; time_zone: SQL_TOKEN_AT time_zone_specifier { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; time_zone_specifier: SQL_TOKEN_LOCAL { $$ = SQL_NEW_RULE; $$->append($1); } /* | SQL_TOKEN_TIME SQL_TOKEN_ZONE interval_value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); }*/ ; datetime_factor: datetime_primary { $$ = SQL_NEW_RULE; $$->append($1); } | datetime_primary time_zone { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; datetime_term: datetime_factor { $$ = SQL_NEW_RULE; $$->append($1); } ; /* interval_term: literal | interval_term '*' factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("*", SQLNodeType::Punctuation)); $$->append($3); } | interval_term '/' factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("/", SQLNodeType::Punctuation)); $$->append($3); } ; */ datetime_value_exp: datetime_term { $$ = SQL_NEW_RULE; $$->append($1); } /* | interval_value_exp '+' datetime_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } | datetime_value_exp '+' interval_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } | datetime_value_exp '-' interval_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("-", SQLNodeType::Punctuation)); $$->append($3); } */ ; /* interval_value_exp: interval_term { $$ = SQL_NEW_RULE; $$->append($1); } | interval_value_exp '+' interval_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } | interval_value_exp '-' interval_term { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("-", SQLNodeType::Punctuation)); $$->append($3); } | '(' datetime_value_exp '-' datetime_term ')' interval_qualifier { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode("-", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); $$->append($6); } ; */ non_second_datetime_field: SQL_TOKEN_YEAR | SQL_TOKEN_MONTH | SQL_TOKEN_DAY | SQL_TOKEN_HOUR | SQL_TOKEN_MINUTE ; start_field: non_second_datetime_field opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; end_field: non_second_datetime_field | SQL_TOKEN_SECOND opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; single_datetime_field: non_second_datetime_field opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_SECOND opt_paren_precision_scale { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; interval_qualifier: start_field SQL_TOKEN_TO end_field { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | single_datetime_field ; function_arg_commalist2: function_arg ',' function_arg {$$ = SQL_NEW_COMMALISTRULE; $$->append($1); $$->append($3);} ; function_arg_commalist3: function_arg ',' function_arg ',' function_arg { $$ = SQL_NEW_COMMALISTRULE; $$->append($1); $$->append($3); $$->append($5); } ; function_arg_commalist4: function_arg ',' function_arg ',' function_arg ',' function_arg { $$ = SQL_NEW_COMMALISTRULE; $$->append($1); $$->append($3); $$->append($5); $$->append($7); } ; value_exp_commalist: value_exp {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | value_exp_commalist ',' value_exp {$1->append($3); $$ = $1;} /* this rule is only valid if we check predicates */ | value_exp_commalist ';' value_exp { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $1->append($3); $$ = $1; } else YYERROR; } ; function_arg: result | value_exp comparison value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | value_exp SQL_TOKEN_USING value_exp comparison value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | value_exp SQL_TOKEN_BY value_exp_commalist { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; function_args_commalist: function_arg {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | function_args_commalist ',' function_arg {$1->append($3); $$ = $1;} /* this rule is only valid if we check predicates */ | function_args_commalist ';' function_arg { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) { $1->append($3); $$ = $1; } else YYERROR; } ; value_exp: num_value_exp /*[^')']*/ | string_value_exp | datetime_value_exp { $$ = SQL_NEW_RULE; $$->append($1); } ; string_value_exp: char_value_exp /* | bit_value_exp { $$ = SQL_NEW_RULE; $$->append($1); } */ ; char_value_exp: char_factor | concatenation ; concatenation: char_value_exp '+' char_factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } | value_exp SQL_CONCAT value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; char_primary: SQL_TOKEN_STRING | string_value_fct ; collate_clause: SQL_TOKEN_COLLATE table_node { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; char_factor: char_primary | char_primary collate_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; string_value_fct: char_value_fct | bit_value_fct ; bit_value_fct: bit_substring_fct { $$ = SQL_NEW_RULE; $$->append($1); } ; bit_substring_fct: SQL_TOKEN_SUBSTRING '(' bit_value_exp SQL_TOKEN_FROM string_value_exp for_length ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; bit_value_exp: bit_factor { $$ = SQL_NEW_RULE; $$->append($1); } ; /* bit_concatenation { $$ = SQL_NEW_RULE; $$->append($1); } | bit_concatenation: bit_value_exp '+' bit_factor { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("+", SQLNodeType::Punctuation)); $$->append($3); } ; */ bit_factor: bit_primary { $$ = SQL_NEW_RULE; $$->append($1); } ; bit_primary: {$$ = SQL_NEW_RULE;} /* value_exp_primary { $$ = SQL_NEW_RULE; $$->append($1); } | string_value_fct { $$ = SQL_NEW_RULE; $$->append($1); }*/ ; char_value_fct: char_substring_fct | fold | form_conversion { $$ = SQL_NEW_RULE; $$->append($1); } | char_translation { $$ = SQL_NEW_RULE; $$->append($1); } | trim_fct { $$ = SQL_NEW_RULE; $$->append($1); } ; for_length: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_FOR value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; char_substring_fct: SQL_TOKEN_SUBSTRING '(' value_exp SQL_TOKEN_FROM value_exp for_length ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_SUBSTRING '(' value_exp_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; upper_lower: SQL_TOKEN_UPPER | SQL_TOKEN_LOWER ; fold: upper_lower '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; form_conversion: SQL_TOKEN_CONVERT '(' string_value_exp SQL_TOKEN_USING table_node ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_CONVERT '(' cast_operand ',' cast_target ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; char_translation: SQL_TOKEN_TRANSLATE '(' string_value_exp SQL_TOKEN_USING table_node ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append($4); $$->append($5); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; trim_fct: SQL_TOKEN_TRIM '(' trim_operands ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; trim_operands: trim_spec value_exp SQL_TOKEN_FROM value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | trim_spec SQL_TOKEN_FROM value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | value_exp SQL_TOKEN_FROM value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_FROM value_exp { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | value_exp ; trim_spec: SQL_TOKEN_BOTH | SQL_TOKEN_LEADING | SQL_TOKEN_TRAILING ; derived_column: value_exp as_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; /* Tabellenname */ table_node: table_name | schema_name | catalog_name ; catalog_name: SQL_TOKEN_NAME '.' schema_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); } | SQL_TOKEN_NAME ':' schema_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(":", SQLNodeType::Punctuation)); $$->append($3); } ; schema_name: SQL_TOKEN_NAME '.' table_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); } ; table_name: SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append($1);} ; /* Columns */ column_ref: column {$$ = SQL_NEW_RULE; $$->append($1);} /* | table_node '.' column_val %prec '.' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3);} */ | SQL_TOKEN_NAME '.' column_val %prec '.' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); } | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($5);} | SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($7); } | SQL_TOKEN_NAME ':' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val %prec '.' {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(":", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($7); } /* | SQL_TOKEN_NAME ';' SQL_TOKEN_NAME '.' SQL_TOKEN_NAME '.' column_val {$$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode(";", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($5); $$->append(newNode(".", SQLNodeType::Punctuation)); $$->append($7); } */ ; /* data types */ column_val: column {$$ = SQL_NEW_RULE; $$->append($1);} | '*' { $$ = SQL_NEW_RULE; $$->append(newNode("*", SQLNodeType::Punctuation)); } ; data_type: predefined_type ; opt_char_set_spec: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_CHARACTER SQL_TOKEN_SET SQL_TOKEN_NAME { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; opt_collate_clause: {$$ = SQL_NEW_RULE;} | collate_clause ; predefined_type: character_string_type opt_char_set_spec opt_collate_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | national_character_string_type opt_collate_clause { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | binary_string_type | numeric_type | boolean_type | datetime_type | interval_type ; character_string_type: SQL_TOKEN_CHARACTER opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_CHAR opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_CHARACTER SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_CHAR SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_VARCHAR paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | character_large_object_type ; opt_paren_precision: {$$ = SQL_NEW_RULE;} | paren_char_length ; paren_char_length: '(' SQL_TOKEN_INTNUM ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; opt_paren_char_large_length: {$$ = SQL_NEW_RULE;} | paren_character_large_object_length ; paren_character_large_object_length: '(' large_object_length ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; large_object_length: SQL_TOKEN_INTNUM opt_multiplier { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; opt_multiplier: {$$ = SQL_NEW_RULE;} | 'K' { $$ = SQL_NEW_RULE; $$->append(newNode("K", SQLNodeType::Punctuation)); } | 'M' { $$ = SQL_NEW_RULE; $$->append(newNode("M", SQLNodeType::Punctuation)); } | 'G' { $$ = SQL_NEW_RULE; $$->append(newNode("G", SQLNodeType::Punctuation)); } | 'T' { $$ = SQL_NEW_RULE; $$->append(newNode("T", SQLNodeType::Punctuation)); } | 'P' { $$ = SQL_NEW_RULE; $$->append(newNode("P", SQLNodeType::Punctuation)); } ; character_large_object_type: SQL_TOKEN_CHARACTER SQL_TOKEN_LARGE SQL_TOKEN_OBJECT opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_CHAR SQL_TOKEN_LARGE SQL_TOKEN_OBJECT opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_CLOB opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; national_character_string_type: SQL_TOKEN_NATIONAL SQL_TOKEN_CHARACTER opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_NATIONAL SQL_TOKEN_CHAR opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_NCHAR opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_NATIONAL SQL_TOKEN_CHARACTER SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_NATIONAL SQL_TOKEN_CHAR SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_NCHAR SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | national_character_large_object_type ; national_character_large_object_type: SQL_TOKEN_NATIONAL SQL_TOKEN_CHARACTER SQL_TOKEN_LARGE SQL_TOKEN_OBJECT opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } | SQL_TOKEN_NCHAR SQL_TOKEN_LARGE SQL_TOKEN_OBJECT opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_NCLOB opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; binary_string_type: SQL_TOKEN_BINARY opt_paren_precision { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_BINARY SQL_TOKEN_VARYING paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_VARBINARY paren_char_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | binary_large_object_string_type ; binary_large_object_string_type: SQL_TOKEN_BINARY SQL_TOKEN_LARGE SQL_TOKEN_OBJECT opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_BLOB opt_paren_char_large_length { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; numeric_type: exact_numeric_type | approximate_numeric_type ; opt_paren_precision_scale: {$$ = SQL_NEW_RULE;} | '(' SQL_TOKEN_INTNUM ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(")", SQLNodeType::Punctuation)); } | '(' SQL_TOKEN_INTNUM ',' SQL_TOKEN_INTNUM ')' { $$ = SQL_NEW_RULE; $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode(",", SQLNodeType::Punctuation)); $$->append($4); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; exact_numeric_type: SQL_TOKEN_NUMERIC opt_paren_precision_scale { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_DECIMAL opt_paren_precision_scale { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_DEC opt_paren_precision_scale { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } | SQL_TOKEN_SMALLINT | SQL_TOKEN_INTEGER | SQL_TOKEN_INT | SQL_TOKEN_BIGINT ; approximate_numeric_type: SQL_TOKEN_FLOAT '(' SQL_TOKEN_INTNUM ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_FLOAT | SQL_TOKEN_REAL | SQL_TOKEN_DOUBLE | SQL_TOKEN_DOUBLE SQL_TOKEN_PRECISION { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; boolean_type: SQL_TOKEN_BOOLEAN ; datetime_type: SQL_TOKEN_DATE | SQL_TOKEN_TIME opt_paren_precision opt_with_or_without_time_zone { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_TIMESTAMP opt_paren_precision opt_with_or_without_time_zone { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; opt_with_or_without_time_zone: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_WITH SQL_TOKEN_TIME SQL_TOKEN_ZONE { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } | SQL_TOKEN_WITHOUT SQL_TOKEN_TIME SQL_TOKEN_ZONE { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; interval_type: SQL_TOKEN_INTERVAL interval_qualifier { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; /* the various things you can name */ column: SQL_TOKEN_NAME | SQL_TOKEN_POSITION { sal_uInt32 nNod = $$->getRuleID(); delete $$; $$ = newNode(OSQLParser::TokenIDToStr(nNod), SQLNodeType::Name); } | SQL_TOKEN_CHAR_LENGTH { sal_uInt32 nNod = $$->getRuleID(); delete $$; $$ = newNode(OSQLParser::TokenIDToStr(nNod), SQLNodeType::Name); } | SQL_TOKEN_EXTRACT { sal_uInt32 nNod = $$->getRuleID(); delete $$; $$ = newNode(OSQLParser::TokenIDToStr(nNod), SQLNodeType::Name); } ; case_expression: case_abbreviation | case_specification ; case_abbreviation: SQL_TOKEN_NULLIF '(' value_exp_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_COALESCE '(' value_exp ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } | SQL_TOKEN_COALESCE '(' value_exp_commalist ')' { $$ = SQL_NEW_RULE; $$->append($1); $$->append(newNode("(", SQLNodeType::Punctuation)); $$->append($3); $$->append(newNode(")", SQLNodeType::Punctuation)); } ; case_specification: simple_case | searched_case ; simple_case: SQL_TOKEN_CASE case_operand simple_when_clause_list else_clause SQL_TOKEN_END { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); } ; searched_case: SQL_TOKEN_CASE searched_when_clause_list else_clause SQL_TOKEN_END { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; simple_when_clause_list: simple_when_clause { $$ = SQL_NEW_LISTRULE; $$->append($1); } | searched_when_clause_list simple_when_clause { $1->append($2); $$ = $1; } ; simple_when_clause: SQL_TOKEN_WHEN when_operand_list SQL_TOKEN_THEN result { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; when_operand_list: when_operand {$$ = SQL_NEW_COMMALISTRULE; $$->append($1);} | when_operand_list ',' when_operand {$1->append($3); $$ = $1;} ; when_operand: row_value_constructor_elem | comparison_predicate_part_2 %dprec 1 | between_predicate_part_2 | in_predicate_part_2 | character_like_predicate_part_2 | null_predicate_part_2 %dprec 2 ; searched_when_clause_list: searched_when_clause { $$ = SQL_NEW_LISTRULE; $$->append($1); } | searched_when_clause_list searched_when_clause { $1->append($2); $$ = $1; } ; searched_when_clause: SQL_TOKEN_WHEN search_condition SQL_TOKEN_THEN result { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; else_clause: {$$ = SQL_NEW_RULE;} | SQL_TOKEN_ELSE result { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; result: result_expression ; result_expression: value_exp ; case_operand: row_value_constructor_elem ; cursor: SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append($1);} ; /*** module: SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append($1);} ; ***/ parameter: ':' SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append(newNode(":", SQLNodeType::Punctuation)); $$->append($2);} | '?' {$$ = SQL_NEW_RULE; // test $$->append(newNode("?", SQLNodeType::Punctuation));} | '[' SQL_TOKEN_NAME ']' {$$ = SQL_NEW_RULE; $$->append(newNode("[", SQLNodeType::Punctuation)); $$->append($2); $$->append(newNode("]", SQLNodeType::Punctuation));} ; /*** procedure: SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append($1);} ; ***/ range_variable: {$$ = SQL_NEW_RULE;} | opt_as SQL_TOKEN_NAME {$$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; user: SQL_TOKEN_NAME ; /* PREDICATECHECK RULES */ sql: search_condition /* checking predicats */ { if (xxx_pGLOBAL_SQLPARSER->inPredicateCheck()) // sql: rule 1 { $$ = $1; if ( SQL_ISRULE($$,search_condition) ) { $$->insert(0,newNode("(", SQLNodeType::Punctuation)); $$->append(newNode(")", SQLNodeType::Punctuation)); } } else YYERROR; } | '(' sql ')' /* checking predicats */ ; trigger_definition: SQL_TOKEN_CREATE SQL_TOKEN_TRIGGER trigger_name trigger_action_time trigger_event SQL_TOKEN_ON table_name op_referencing triggered_action { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); $$->append($5); $$->append($6); $$->append($7); $$->append($8); $$->append($9); } ; op_referencing: { $$ = SQL_NEW_RULE; } | SQL_TOKEN_REFERENCING transition_table_or_variable_list { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; trigger_action_time: SQL_TOKEN_BEFORE | SQL_TOKEN_AFTER | SQL_TOKEN_INSTEAD SQL_TOKEN_OF { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; trigger_event: SQL_TOKEN_INSERT | SQL_TOKEN_DELETE | SQL_TOKEN_UPDATE op_trigger_columnlist { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; op_trigger_columnlist: { $$ = SQL_NEW_RULE; } | SQL_TOKEN_OF trigger_column_list { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; trigger_column_list: column_commalist ; triggered_action: op_triggered_action_for triggered_when_clause triggered_SQL_statement { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; op_triggered_action_for: { $$ = SQL_NEW_RULE; } | SQL_TOKEN_FOR SQL_TOKEN_EACH trigger_for { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); } ; trigger_for: SQL_TOKEN_ROW | SQL_TOKEN_STATEMENT ; triggered_when_clause: { $$ = SQL_NEW_RULE; } | SQL_TOKEN_WHEN parenthesized_boolean_value_expression { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); } ; triggered_SQL_statement: SQL_procedure_statement | SQL_TOKEN_BEGIN SQL_TOKEN_ATOMIC SQL_procedure_statement_list ';' SQL_TOKEN_END { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append(newNode(";", SQLNodeType::Punctuation)); $$->append($5); } ; SQL_procedure_statement_list: SQL_procedure_statement { $$ = SQL_NEW_LISTRULE; $$->append($1); } | SQL_procedure_statement_list ';' SQL_procedure_statement { $1->append($3); $$ = $1; } ; SQL_procedure_statement: sql ; transition_table_or_variable_list: transition_table_or_variable { $$ = SQL_NEW_LISTRULE; $$->append($1); } | transition_table_or_variable_list transition_table_or_variable { $1->append($2); $$ = $1; } ; transition_table_or_variable: SQL_TOKEN_OLD opt_row opt_as old_transition_variable_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_NEW opt_row opt_as new_transition_variable_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_OLD SQL_TOKEN_TABLE opt_as old_transition_table_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } | SQL_TOKEN_NEW SQL_TOKEN_TABLE opt_as new_transition_table_name { $$ = SQL_NEW_RULE; $$->append($1); $$->append($2); $$->append($3); $$->append($4); } ; old_transition_table_name: transition_table_name ; new_transition_table_name: transition_table_name ; transition_table_name: SQL_TOKEN_NAME ; old_transition_variable_name: SQL_TOKEN_NAME ; new_transition_variable_name: SQL_TOKEN_NAME ; trigger_name: SQL_TOKEN_NAME ; %% #if defined _MSC_VER #pragma warning(pop) #endif using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::i18n; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::util; using namespace ::osl; using namespace ::dbtools; connectivity::OSQLParser* xxx_pGLOBAL_SQLPARSER; connectivity::OSQLInternalNode* newNode(const sal_Char* pNewValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID) { return new connectivity::OSQLInternalNode(pNewValue, eNodeType, nNodeID); } connectivity::OSQLInternalNode* newNode(const OString& _newValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID) { return new connectivity::OSQLInternalNode(_newValue, eNodeType, nNodeID); } connectivity::OSQLInternalNode* newNode(const OUString& _newValue, const connectivity::SQLNodeType eNodeType, const sal_uInt32 nNodeID) { return new connectivity::OSQLInternalNode(_newValue, eNodeType, nNodeID); } OParseContext::OParseContext() { } OParseContext::~OParseContext() { } OUString OParseContext::getErrorMessage(ErrorCode _eCode) const { OUString aMsg; switch (_eCode) { case ErrorCode::General: aMsg = "Syntax error in SQL expression"; break; case ErrorCode::ValueNoLike: aMsg = "The value #1 can not be used with LIKE."; break; case ErrorCode::FieldNoLike: aMsg = "LIKE can not be used with this field."; break; case ErrorCode::InvalidCompare: aMsg = "The entered criterion can not be compared with this field."; break; case ErrorCode::InvalidIntCompare: aMsg = "The field can not be compared with a number."; break; case ErrorCode::InvalidDateCompare: aMsg = "The field can not be compared with a date."; break; case ErrorCode::InvalidRealCompare: aMsg = "The field can not be compared with a floating point number."; break; case ErrorCode::InvalidTableNosuch: aMsg = "The database does not contain a table named \"#\"."; break; case ErrorCode::InvalidTableOrQuery: aMsg = "The database does contain neither a table nor a query named \"#\"."; break; case ErrorCode::InvalidColumn: aMsg = "The column \"#1\" is unknown in the table \"#2\"."; break; case ErrorCode::InvalidTableExist: aMsg = "The database already contains a table or view with name \"#\"."; break; case ErrorCode::InvalidQueryExist: aMsg = "The database already contains a query with name \"#\"."; break; default: OSL_FAIL( "OParseContext::getErrorMessage: unknown error code!" ); break; } return aMsg; } OString OParseContext::getIntlKeywordAscii(InternationalKeyCode _eKey) const { OString aKeyword; switch (_eKey) { case InternationalKeyCode::Like: aKeyword = "LIKE"; break; case InternationalKeyCode::Not: aKeyword = "NOT"; break; case InternationalKeyCode::Null: aKeyword = "NULL"; break; case InternationalKeyCode::True: aKeyword = "True"; break; case InternationalKeyCode::False: aKeyword = "False"; break; case InternationalKeyCode::Is: aKeyword = "IS"; break; case InternationalKeyCode::Between: aKeyword = "BETWEEN"; break; case InternationalKeyCode::Or: aKeyword = "OR"; break; case InternationalKeyCode::And: aKeyword = "AND"; break; case InternationalKeyCode::Avg: aKeyword = "AVG"; break; case InternationalKeyCode::Count: aKeyword = "COUNT"; break; case InternationalKeyCode::Max: aKeyword = "MAX"; break; case InternationalKeyCode::Min: aKeyword = "MIN"; break; case InternationalKeyCode::Sum: aKeyword = "SUM"; break; case InternationalKeyCode::Every: aKeyword = "EVERY"; break; case InternationalKeyCode::Any: aKeyword = "ANY"; break; case InternationalKeyCode::Some: aKeyword = "SOME"; break; case InternationalKeyCode::StdDevPop: aKeyword = "STDDEV_POP"; break; case InternationalKeyCode::StdDevSamp: aKeyword = "STDDEV_SAMP"; break; case InternationalKeyCode::VarSamp: aKeyword = "VAR_SAMP"; break; case InternationalKeyCode::VarPop: aKeyword = "VAR_POP"; break; case InternationalKeyCode::Collect: aKeyword = "COLLECT"; break; case InternationalKeyCode::Fusion: aKeyword = "FUSION"; break; case InternationalKeyCode::Intersection:aKeyword = "INTERSECTION"; break; case InternationalKeyCode::None: break; default: OSL_FAIL( "OParseContext::getIntlKeywordAscii: unknown key!" ); break; } return aKeyword; } IParseContext::InternationalKeyCode OParseContext::getIntlKeyCode(const OString& rToken) const { static IParseContext::InternationalKeyCode Intl_TokenID[] = { InternationalKeyCode::Like, InternationalKeyCode::Not, InternationalKeyCode::Null, InternationalKeyCode::True, InternationalKeyCode::False, InternationalKeyCode::Is, InternationalKeyCode::Between, InternationalKeyCode::Or, InternationalKeyCode::And, InternationalKeyCode::Avg, InternationalKeyCode::Count, InternationalKeyCode::Max, InternationalKeyCode::Min, InternationalKeyCode::Sum, InternationalKeyCode::Every,InternationalKeyCode::Any,InternationalKeyCode::Some, InternationalKeyCode::StdDevPop,InternationalKeyCode::StdDevSamp,InternationalKeyCode::VarSamp, InternationalKeyCode::VarPop,InternationalKeyCode::Collect,InternationalKeyCode::Fusion,InternationalKeyCode::Intersection }; sal_uInt32 nCount = SAL_N_ELEMENTS( Intl_TokenID ); for (sal_uInt32 i = 0; i < nCount; i++) { OString aKey = getIntlKeywordAscii(Intl_TokenID[i]); if (rToken.equalsIgnoreAsciiCase(aKey)) return Intl_TokenID[i]; } return InternationalKeyCode::None; } static Locale& impl_getLocaleInstance( ) { static Locale s_aLocale( "en", "US", "" ); return s_aLocale; } Locale OParseContext::getPreferredLocale( ) const { return getDefaultLocale(); } const Locale& OParseContext::getDefaultLocale() { return impl_getLocaleInstance(); } // The (unfortunately global) yylval for the handing over of // values from the Scanner to the Parser. The global variable // is only used for a short term, the Parser reads the variable // immediately after the call of the Scanner into a same named own // member variable. OUString ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, bool bInternational) { OUStringBuffer aMatchStr(0); if (pTokenNode->isToken()) { sal_Unicode cEscape = 0; if (pEscapeNode->count()) cEscape = pEscapeNode->getChild(1)->getTokenValue().toChar(); // Change place holder aMatchStr = pTokenNode->getTokenValue(); const sal_Int32 nLen = aMatchStr.getLength(); OUStringBuffer sSearch,sReplace; if ( bInternational ) { sSearch.append("%_"); sReplace.append("*?"); } else { sSearch.append("*?"); sReplace.append("%_"); } bool wasEscape = false; for (sal_Int32 i = 0; i < nLen; i++) { const sal_Unicode c = aMatchStr[i]; // SQL standard requires the escape to be followed // by a meta-character ('%', '_' or itself), else error // We are more lenient here and let it escape anything. // Especially since some databases (e.g. Microsoft SQL Server) // have more meta-characters than the standard, such as e.g. '[' and ']' if (wasEscape) { wasEscape=false; continue; } if (c == cEscape) { wasEscape=true; continue; } int match = -1; if (c == sSearch[0]) match=0; else if (c == sSearch[1]) match=1; if (match != -1) { aMatchStr[i] = sReplace[match]; } } } return aMatchStr.makeStringAndClear(); } sal_uInt32 OSQLParser::s_nRuleIDs[OSQLParseNode::rule_count + 1]; OSQLParser::RuleIDMap OSQLParser::s_aReverseRuleIDLookup; OParseContext OSQLParser::s_aDefaultContext; sal_Int32 OSQLParser::s_nRefCount = 0; // ::osl::Mutex OSQLParser::s_aMutex; OSQLScanner* OSQLParser::s_pScanner = nullptr; OSQLParseNodesGarbageCollector* OSQLParser::s_pGarbageCollector = nullptr; css::uno::Reference< css::i18n::XLocaleData4> OSQLParser::s_xLocaleData = nullptr; void setParser(OSQLParser* _pParser) { xxx_pGLOBAL_SQLPARSER = _pParser; } void OSQLParser::setParseTree(OSQLParseNode* pNewParseTree) { ::osl::MutexGuard aGuard(getMutex()); m_pParseTree.reset(pNewParseTree); } /** Delete all comments in a query. See also getComment()/concatComment() implementation for OQueryController::translateStatement(). */ static OUString delComment( const OUString& rQuery ) { // First a quick search if there is any "--" or "//" or "/*", if not then the whole // copying loop is pointless. if (rQuery.indexOf("--") < 0 && rQuery.indexOf("//") < 0 && rQuery.indexOf("/*") < 0) return rQuery; const sal_Unicode* pCopy = rQuery.getStr(); sal_Int32 nQueryLen = rQuery.getLength(); bool bIsText1 = false; // "text" bool bIsText2 = false; // 'text' bool bComment2 = false; // /* comment */ bool bComment = false; // -- or // comment OUStringBuffer aBuf(nQueryLen); for (sal_Int32 i=0; i < nQueryLen; ++i) { if (bComment2) { if ((i+1) < nQueryLen) { if (pCopy[i]=='*' && pCopy[i+1]=='/') { bComment2 = false; ++i; } } else { // comment can't close anymore, actually an error, but.. } continue; } if (pCopy[i] == '\n') bComment = false; else if (!bComment) { if (pCopy[i] == '\"' && !bIsText2) bIsText1 = !bIsText1; else if (pCopy[i] == '\'' && !bIsText1) bIsText2 = !bIsText2; if (!bIsText1 && !bIsText2 && (i+1) < nQueryLen) { if ((pCopy[i]=='-' && pCopy[i+1]=='-') || (pCopy[i]=='/' && pCopy[i+1]=='/')) bComment = true; else if ((pCopy[i]=='/' && pCopy[i+1]=='*')) bComment2 = true; } } if (!bComment && !bComment2) aBuf.append( &pCopy[i], 1); } return aBuf.makeStringAndClear(); } std::unique_ptr OSQLParser::parseTree(OUString& rErrorMessage, const OUString& rStatement, bool bInternational) { // Guard the parsing ::osl::MutexGuard aGuard(getMutex()); // must be reset setParser(this); // delete comments before parsing OUString sTemp = delComment(rStatement); // defines how to scan s_pScanner->SetRule(OSQLScanner::GetSQLRule()); // initial s_pScanner->prepareScan(sTemp, m_pContext, bInternational); SQLyylval.pParseNode = nullptr; // SQLyypvt = NULL; m_pParseTree = nullptr; m_sErrorMessage = ""; // start parsing if (SQLyyparse() != 0) { // only set the error message, if it's not already set if (m_sErrorMessage.isEmpty()) m_sErrorMessage = s_pScanner->getErrorMessage(); if (m_sErrorMessage.isEmpty()) m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::General); rErrorMessage = m_sErrorMessage; // clear the garbage collector (*s_pGarbageCollector)->clearAndDelete(); m_pParseTree.release(); // because the garbage collector deleted it return nullptr; } else { (*s_pGarbageCollector)->clear(); // return result: // to work around a bug in MKS YACC return the member m_pParseTree // instead of Sdbyyval.pParseNode SAL_WARN_IF(!m_pParseTree, "connectivity.parse", "OSQLParser: Parser did not create ParseTree"); return std::move(m_pParseTree); } } OString OSQLParser::TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext) { OString aStr; if (pContext) { IParseContext::InternationalKeyCode eKeyCode = IParseContext::InternationalKeyCode::None; switch( nTokenID ) { case SQL_TOKEN_LIKE: eKeyCode = IParseContext::InternationalKeyCode::Like; break; case SQL_TOKEN_NOT: eKeyCode = IParseContext::InternationalKeyCode::Not; break; case SQL_TOKEN_NULL: eKeyCode = IParseContext::InternationalKeyCode::Null; break; case SQL_TOKEN_TRUE: eKeyCode = IParseContext::InternationalKeyCode::True; break; case SQL_TOKEN_FALSE: eKeyCode = IParseContext::InternationalKeyCode::False; break; case SQL_TOKEN_IS: eKeyCode = IParseContext::InternationalKeyCode::Is; break; case SQL_TOKEN_BETWEEN: eKeyCode = IParseContext::InternationalKeyCode::Between; break; case SQL_TOKEN_OR: eKeyCode = IParseContext::InternationalKeyCode::Or; break; case SQL_TOKEN_AND: eKeyCode = IParseContext::InternationalKeyCode::And; break; case SQL_TOKEN_AVG: eKeyCode = IParseContext::InternationalKeyCode::Avg; break; case SQL_TOKEN_COUNT: eKeyCode = IParseContext::InternationalKeyCode::Count; break; case SQL_TOKEN_MAX: eKeyCode = IParseContext::InternationalKeyCode::Max; break; case SQL_TOKEN_MIN: eKeyCode = IParseContext::InternationalKeyCode::Min; break; case SQL_TOKEN_SUM: eKeyCode = IParseContext::InternationalKeyCode::Sum; break; } if ( eKeyCode != IParseContext::InternationalKeyCode::None ) aStr = pContext->getIntlKeywordAscii(eKeyCode); } if (aStr.isEmpty()) { aStr = yytname[YYTRANSLATE(nTokenID)]; if(aStr.startsWith("SQL_TOKEN_")) aStr = aStr.copy(10); switch( nTokenID ) { case SQL_TOKEN_OJ: case SQL_TOKEN_TS: case SQL_TOKEN_T: case SQL_TOKEN_D: aStr = aStr.toAsciiLowerCase(); } } return aStr; } #if OSL_DEBUG_LEVEL > 0 OUString OSQLParser::RuleIDToStr(sal_uInt32 nRuleID) { OSL_ENSURE(nRuleID < SAL_N_ELEMENTS(yytname), "OSQLParser::RuleIDToStr: Invalid nRuleId!"); return OUString::createFromAscii(yytname[nRuleID]); } #endif sal_uInt32 OSQLParser::StrToRuleID(const OString & rValue) { // Search for the given name in yytname and return the index // (or UNKNOWN_RULE, if not found) static sal_uInt32 nLen = SAL_N_ELEMENTS(yytname); for (sal_uInt32 i = YYTRANSLATE(SQL_TOKEN_INVALIDSYMBOL); i < (nLen-1); i++) { if (rValue == yytname[i]) return i; } // Not found return OSQLParseNode::UNKNOWN_RULE; } OSQLParseNode::Rule OSQLParser::RuleIDToRule( sal_uInt32 _nRule ) { OSQLParser::RuleIDMap::const_iterator i (s_aReverseRuleIDLookup.find(_nRule)); if (i == s_aReverseRuleIDLookup.end()) { SAL_INFO("connectivity.parse", "connectivity::OSQLParser::RuleIDToRule cannot reverse-lookup rule. " "Reverse mapping incomplete? " "_nRule='" << _nRule << "' " "yytname[_nRule]='" << yytname[_nRule] << "'"); return OSQLParseNode::UNKNOWN_RULE; } else return i->second; } sal_uInt32 OSQLParser::RuleID(OSQLParseNode::Rule eRule) { return s_nRuleIDs[(sal_uInt16)eRule]; } sal_Int16 OSQLParser::buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pCompare,OSQLParseNode* pLiteral,OSQLParseNode* pLiteral2) { OSQLParseNode* pColumnRef = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::column_ref)); pColumnRef->append(new OSQLInternalNode(m_sFieldName,SQLNodeType::Name)); OSQLParseNode* pComp = nullptr; if ( SQL_ISTOKEN( pCompare, BETWEEN) && pLiteral2 ) pComp = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::between_predicate_part_2)); else pComp = new OSQLInternalNode("", SQLNodeType::Rule,OSQLParser::RuleID(OSQLParseNode::comparison_predicate)); pComp->append(pColumnRef); pComp->append(pCompare); pComp->append(pLiteral); if ( pLiteral2 ) { pComp->append(new OSQLInternalNode("", SQLNodeType::Keyword,SQL_TOKEN_AND)); pComp->append(pLiteral2); } pAppend->append(pComp); return 1; } sal_Int16 OSQLParser::buildStringNodes(OSQLParseNode*& pLiteral) { if(!pLiteral) return 1; if(SQL_ISRULE(pLiteral,set_fct_spec) || SQL_ISRULE(pLiteral,general_set_fct) || SQL_ISRULE(pLiteral,column_ref) || SQL_ISRULE(pLiteral,subquery)) return 1; // here I have a function that I can't transform into a string if(pLiteral->getNodeType() == SQLNodeType::IntNum || pLiteral->getNodeType() == SQLNodeType::ApproxNum || pLiteral->getNodeType() == SQLNodeType::AccessDate) { OSQLParseNode* pParent = pLiteral->getParent(); OSQLParseNode* pNewNode = new OSQLInternalNode(pLiteral->getTokenValue(), SQLNodeType::String); pParent->replace(pLiteral, pNewNode); delete pLiteral; pLiteral = nullptr; return 1; } for(size_t i=0;icount();++i) { OSQLParseNode* pChild = pLiteral->getChild(i); buildStringNodes(pChild); } if(SQL_ISRULE(pLiteral,term) || SQL_ISRULE(pLiteral,value_exp_primary)) { m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ErrorCode::InvalidCompare); return 0; } return 1; } sal_Int16 OSQLParser::buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral) { OSQLParseNode* pComp = new OSQLInternalNode("=", SQLNodeType::Equal); return buildPredicateRule(pAppend,pLiteral,pComp); } void OSQLParser::reduceLiteral(OSQLParseNode*& pLiteral, bool bAppendBlank) { OSL_ENSURE(pLiteral->isRule(), "This is no Rule"); OSL_ENSURE(pLiteral->count() == 2, "OSQLParser::ReduceLiteral() Invalid count"); OSQLParseNode* pTemp = pLiteral; OUStringBuffer aValue(pLiteral->getChild(0)->getTokenValue()); if (bAppendBlank) { aValue.append(" "); } aValue.append(pLiteral->getChild(1)->getTokenValue()); pLiteral = new OSQLInternalNode(aValue.makeStringAndClear(),SQLNodeType::String); delete pTemp; } void OSQLParser::error(const sal_Char *fmt) { if(m_sErrorMessage.isEmpty()) { OUString sStr(fmt,strlen(fmt),RTL_TEXTENCODING_UTF8); OUString sSQL_TOKEN("SQL_TOKEN_"); sal_Int32 nPos1 = sStr.indexOf(sSQL_TOKEN); if(nPos1 != -1) { OUString sFirst = sStr.copy(0,nPos1); sal_Int32 nPos2 = sStr.indexOf(sSQL_TOKEN,nPos1+1); if(nPos2 != -1) { OUString sSecond = sStr.copy(nPos1+sSQL_TOKEN.getLength(),nPos2-nPos1-sSQL_TOKEN.getLength()); sFirst += sSecond; sFirst += sStr.copy(nPos2+sSQL_TOKEN.getLength()); } else sFirst += sStr.copy(nPos1+sSQL_TOKEN.getLength()); m_sErrorMessage = sFirst; } else m_sErrorMessage = sStr; OUString aError = s_pScanner->getErrorMessage(); if(!aError.isEmpty()) { m_sErrorMessage += ", "; m_sErrorMessage += aError; } } } int OSQLParser::SQLlex() { return OSQLScanner::SQLlex(); }