📄 par.c
字号:
count = (unsigned int) BLR_BYTE;clause = PAR_make_node (tdbb, count * 2);clause->nod_type = nod_sort;clause->nod_count = count;ptr = clause->nod_arg;ptr2 = ptr + count;while (--count >= 0) { if (flag) *ptr2++ = (NOD) (SLONG) ((BLR_BYTE == blr_descending) ? TRUE : FALSE); *ptr++ = parse (tdbb, csb, VALUE); }return clause;}static NOD par_stream ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ s t r e a m * ************************************** * * Functional description * Parse a stream expression. * **************************************/register RSE rse;UCHAR op;SET_TDBB (tdbb);rse = (RSE) PAR_make_node (tdbb, 1 + rse_delta + 2);rse->nod_count = 0;rse->rse_count = 1;rse->rse_relation [0] = parse (tdbb, csb, RELATION);while (TRUE) switch (op = BLR_BYTE) { case blr_boolean: rse->rse_boolean = parse (tdbb, csb, BOOL); break; default: if (op == (UCHAR) blr_end) return (NOD) rse; syntax_error (*csb, "stream_clause"); }}static NOD par_union ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ u n i o n * ************************************** * * Functional description * Parse a union reference. * **************************************/NOD node;SSHORT count;USHORT stream;LLS clauses;SET_TDBB (tdbb);/* Make the node, parse the context number, get a stream assigned, and get the number of sub-rse's. */node = PAR_make_node (tdbb, e_uni_length);node->nod_count = 2;stream = par_context (csb, NULL_PTR);node->nod_arg [e_uni_stream] = (NOD) (SLONG) stream;count = (unsigned int) BLR_BYTE;/* Pick up the sub-rse's and maps */clauses = NULL;while (--count >= 0) { LLS_PUSH (parse (tdbb, csb, TYPE_RSE), &clauses); LLS_PUSH (par_map (tdbb, csb, stream), &clauses); }node->nod_arg [e_uni_clauses] = PAR_make_list (tdbb, clauses);return node;}static USHORT par_word ( CSB *csb){/************************************** * * p a r _ w o r d * ************************************** * * Functional description * Pick up a BLR word. * **************************************/UCHAR low, high;low = BLR_BYTE;high = BLR_BYTE;return high * 256 + low;}static NOD parse ( TDBB tdbb, register CSB *csb, USHORT expected){/************************************** * * p a r s e * ************************************** * * Functional description * Parse a BLR expression. * **************************************/register NOD node, *arg;SSHORT sub_type, _operator;USHORT n;SET_TDBB (tdbb);_operator = BLR_BYTE;if (!(_operator >= 0 && _operator < sizeof(type_table)/sizeof(type_table[0]))) syntax_error (*csb, "Invalid BLR code");sub_type = sub_type_table [_operator];if (expected && expected != type_table [_operator]) syntax_error (*csb, elements [expected]);/* If there is a length given in the length table, pre-allocate the node and set its count. This saves an enormous amount of repetitive code. */if (n = length_table [_operator]) { node = PAR_make_node (tdbb, n); node->nod_count = count_table [_operator]; arg = node->nod_arg; } else { node = NULL; arg = NULL; };/* Dispatch on operator type. */switch (_operator) { case blr_any: case blr_unique: case blr_ansi_any: case blr_ansi_all: case blr_exists: node->nod_arg [e_any_rse] = parse (tdbb, csb, sub_type); break; /* Boring operators -- no special handling req'd */ case blr_value_if: case blr_substring: case blr_matching2: case blr_ansi_like: *arg++ = parse (tdbb, csb, sub_type); *arg++ = parse (tdbb, csb, sub_type); *arg++ = parse (tdbb, csb, sub_type); break; case blr_and: case blr_or: case blr_prot_mask: case blr_containing: case blr_matching: case blr_like: case blr_starting: case blr_add: case blr_subtract: case blr_multiply: case blr_divide: case blr_add2: case blr_subtract2: case blr_multiply2: case blr_divide2: case blr_concatenate: case blr_assignment: *arg++ = parse (tdbb, csb, sub_type); /* Fall into ... */ case blr_handler: case blr_loop:#ifndef GATEWAY case blr_lock_state:#endif case blr_upcase: case blr_negate: case blr_not: case blr_missing: case blr_agg_count2: case blr_agg_max: case blr_agg_min: case blr_agg_total: case blr_agg_average: case blr_agg_count_distinct: case blr_agg_total_distinct: case blr_agg_average_distinct: case blr_agg_total2: case blr_agg_average2: case blr_agg_total_distinct2: case blr_agg_average_distinct2: case blr_post: case blr_exec_sql: *arg++ = parse (tdbb, csb, sub_type); break; case blr_null: case blr_agg_count: case blr_user_name: case blr_current_role: case blr_current_date: case blr_current_time: case blr_current_timestamp: case blr_start_savepoint: case blr_end_savepoint: break; case blr_store: case blr_store2: node->nod_arg [e_sto_relation] = parse (tdbb, csb, RELATION); node->nod_arg [e_sto_statement] = parse (tdbb, csb, sub_type); if (_operator == blr_store2) node->nod_arg [e_sto_statement2] = parse (tdbb, csb, sub_type); break; /* Comparison operators */ case blr_between: *arg++ = parse (tdbb, csb, sub_type); case blr_eql: case blr_neq: case blr_geq: case blr_gtr: case blr_leq: case blr_lss: *arg++ = parse (tdbb, csb, sub_type); *arg++ = parse (tdbb, csb, sub_type); node->nod_flags = nod_comparison; break; case blr_erase: n = BLR_BYTE; if (n >= (*csb)->csb_count) error (*csb, gds__ctxnotdef, 0); node->nod_arg [e_erase_stream] = (NOD) (SLONG) (*csb)->csb_rpt [n].csb_stream; break; case blr_modify: node = par_modify (tdbb, csb); break; case blr_exec_proc: case blr_exec_pid: node = par_exec_proc (tdbb, csb, _operator); break; case blr_pid: case blr_procedure: node = par_procedure (tdbb, csb, _operator); break; case blr_function: node = par_function (tdbb, csb); break; case blr_index:#ifndef GATEWAY node->nod_arg [0] = parse (tdbb, csb, sub_type); node->nod_arg [1] = par_args (tdbb, csb, sub_type);#else error (*csb, gds__wish_list, gds_arg_interpreted, "blr_index not supported", 0);#endif break; case blr_for: if (BLR_PEEK == (UCHAR) blr_stall) node->nod_arg [e_for_stall] = parse (tdbb, csb, STATEMENT); if (BLR_PEEK == (UCHAR) blr_rse || BLR_PEEK == (UCHAR) blr_singular || BLR_PEEK == (UCHAR) blr_stream) node->nod_arg [e_for_re] = parse (tdbb, csb, TYPE_RSE); else node->nod_arg [e_for_re] = par_rse (tdbb, csb, _operator); node->nod_arg [e_for_statement] = parse (tdbb, csb, sub_type); break; case blr_rse: case blr_rs_stream: node = par_rse (tdbb, csb, _operator); break; case blr_singular: node = parse (tdbb, csb, TYPE_RSE); ((RSE) node)->nod_flags |= rse_singular; break; case blr_relation: case blr_rid: case blr_relation2: case blr_rid2: node = par_relation (tdbb, csb, _operator, TRUE); break; case blr_union: node = par_union (tdbb, csb); break; case blr_aggregate: node->nod_arg [e_agg_stream] = (NOD) (SLONG) par_context (csb, NULL_PTR); node->nod_arg [e_agg_rse] = parse (tdbb, csb, TYPE_RSE); node->nod_arg [e_agg_group] = parse (tdbb, csb, OTHER); node->nod_arg [e_agg_map] = par_map (tdbb, csb, (USHORT) node->nod_arg [e_agg_stream]); break; case blr_group_by: node = par_sort (tdbb, csb, FALSE); return (node->nod_count) ? node : NULL; case blr_field: case blr_fid : node = par_field (tdbb, csb, _operator); break;#ifndef GATEWAY case blr_gen_id: case blr_set_generator: case blr_gen_id2: case blr_set_generator2: { SLONG tmp; TEXT name [32]; par_name (csb, name); tmp = MET_lookup_generator (tdbb, name); if (tmp < 0) error (*csb, gds__gennotdef, gds_arg_string, ERR_cstring (name), 0); node->nod_arg [e_gen_relation] = (NOD) tmp; node->nod_arg [e_gen_value] = parse (tdbb, csb, VALUE); /* CVC: There're thousand ways to go wrong, but I don't see any value in posting dependencies with set generator since it's DDL, so I will track only gen_id() in both dialects. */ if ((_operator == blr_gen_id || _operator == blr_gen_id2) && ((*csb)->csb_g_flags & csb_get_dependencies)) { NOD dep_node = PAR_make_node (tdbb, e_dep_length); dep_node->nod_type = nod_dependency; dep_node->nod_arg [e_dep_object] = (NOD) tmp; dep_node->nod_arg [e_dep_object_type] = (NOD) obj_generator; LLS_PUSH (dep_node, &(*csb)->csb_dependencies); } } break;#else case blr_gen_id: error (*csb, gds__wish_list, gds_arg_interpreted, "blr_gen_id not supported", 0); break; case blr_set_generator: error (*csb, gds__wish_list, gds_arg_interpreted, "blr_set_generator not supported", 0); break;#endif case blr_record_version: case blr_dbkey: n = BLR_BYTE; if (n >= (*csb)->csb_count) error (*csb, gds__ctxnotdef, 0); node->nod_arg [0] = (NOD) (SLONG) (*csb)->csb_rpt [n].csb_stream; break; case blr_fetch: par_fetch (tdbb, csb, node); break; case blr_send: case blr_receive: n = BLR_BYTE; node->nod_arg [e_send_message] = (*csb)->csb_rpt [n].csb_message; node->nod_arg [e_send_statement] = parse (tdbb, csb, sub_type); break; case blr_message: node = par_message (tdbb, csb); break; case blr_literal: node = par_literal (tdbb, csb); break; case blr_cast: node = par_cast (tdbb, csb); break; case blr_extract: node->nod_arg [e_extract_part] = BLR_BYTE; node->nod_arg [e_extract_value] = parse (tdbb, csb, sub_type); node->nod_count = e_extract_count; break; case blr_dcl_variable: { VEC vector; n = BLR_WORD; node->nod_arg [e_dcl_id] = (NOD) (SLONG) n; PAR_desc (csb, (DSC*) (node->nod_arg + e_dcl_desc)); vector = ALL_vector (tdbb->tdbb_default, &(*csb)->csb_variables, n); vector->vec_object [n] = (BLK) node; } break; case blr_variable: { VEC vector; n = BLR_WORD; node->nod_arg [e_var_id] = (NOD) (SLONG) n; if (!(vector = (*csb)->csb_variables) || n >= vector->vec_count || !(node->nod_arg [e_var_variable] = (NOD) vector->vec_object [n])) syntax_error (*csb, "variable identifier"); } break; case blr_parameter: case blr_parameter2: case blr_parameter3: { NOD message, temp; FMT format; n = (USHORT) BLR_BYTE; if (n >= (*csb)->csb_count || !(message = (*csb)->csb_rpt [n].csb_message)) error (*csb, gds__badmsgnum, 0); node->nod_arg [e_arg_message] = message; n = BLR_WORD; node->nod_arg [e_arg_number] = (NOD) (SLONG) n; format = (FMT) message->nod_arg [e_msg_format]; if (n >= format->fmt_count) error (*csb, gds__badparnum, 0); if (_operator != blr_parameter) { node->nod_arg [e_arg_flag] = temp = PAR_make_node (tdbb, e_arg_length); node->nod_count = 1; temp->nod_count = 0; temp->nod_type = nod_argument; temp->nod_arg [e_arg_message] = message; n = BLR_WORD; temp->nod_arg [e_arg_number] = (NOD) (SLONG) n; if (n >= format->fmt_count) error (*csb, gds__badparnum, 0); } if (_operator == blr_parameter3) { node->nod_arg [e_arg_indicator] = temp = PAR_make_node (tdbb, e_arg_length); node->nod_count = 2; temp->nod_count = 0; temp->nod_type = nod_argument; temp->nod_arg [e_arg_message] = message; n = BLR_WORD; temp->nod_arg [e_arg_number] = (NOD) (SLONG) n; if (n >= format->fmt_count) error (*csb, gds__badparnum, 0); } } break; case blr_stall: break; case blr_select: case blr_begin: { LLS stack = NULL; while (BLR_PEEK != (UCHAR) blr_end) { if (_operator == blr_select && BLR_PEEK != blr_receive) syntax_error (*csb, "blr_receive"); LLS_PUSH (parse (tdbb, csb, sub_type), &stack); } (void) BLR_BYTE; node = PAR_make_list (tdbb, stack); } break; case blr_block: { LLS stack = NULL; node->nod_arg [e_blk_action] = parse (tdbb, csb, sub_type); while (BLR_PEEK != (UCHAR) blr_end) LLS_PUSH (parse (tdbb, csb, sub_type), &stack); (void) BLR_BYTE; node->nod_arg [e_blk_handlers] = PAR_make_list (tdbb, stack); } break; case blr_error_handler: node->nod_arg [e_err_conditions] = (NOD) par_conditio
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -