📄 par.c
字号:
NOD relation, node;SET_TDBB (tdbb);/* Fake RSE */for_node->nod_arg [e_for_re] = PAR_make_node (tdbb, 1 + rse_delta + 2);rse = (RSE) for_node->nod_arg [e_for_re];rse->nod_type = nod_rse;rse->nod_count = 0;rse->rse_count = 1;rse->rse_relation [0] = relation = parse (tdbb, csb, RELATION);#ifdef GATEWAYif (!(((REL) relation->nod_arg [e_rel_relation])->rel_flags & REL_dbkey)) error (*csb, gds__no_dbkey, 0); /* Msg365 dbkey not available for multi-table views */#endif/* Fake boolean */node = rse->rse_boolean = PAR_make_node (tdbb, 2);node->nod_type = nod_eql;node->nod_flags = nod_comparison;node->nod_arg [1] = parse (tdbb, csb, VALUE);node->nod_arg [0] = PAR_make_node (tdbb, 1);node = node->nod_arg [0];node->nod_type = nod_dbkey;node->nod_count = 0;node->nod_arg [0] = relation->nod_arg [e_rel_stream];/* Pick up statement */for_node->nod_arg [e_for_statement] = parse (tdbb, csb, STATEMENT);return for_node;}static NOD par_field ( TDBB tdbb, CSB *csb, SSHORT _operator){/************************************** * * p a r _ f i e l d * ************************************** * * Functional description * Parse a field. * **************************************/REL relation;PRC procedure;TEXT name[32];NOD node;SSHORT stream, id, context, flags;struct csb_repeat *tail;PRC scan_proc;FLD field;REL temp_rel;BOOLEAN is_column = FALSE;SET_TDBB (tdbb);context = (unsigned int) BLR_BYTE;if (context >= (*csb)->csb_count) error (*csb, gds__ctxnotdef, 0);stream = (*csb)->csb_rpt [context].csb_stream;flags = 0;if (_operator == blr_fid) { id = BLR_WORD; flags = nod_id; is_column = TRUE; }else if (_operator == blr_field) { tail = &(*csb)->csb_rpt [stream]; procedure = tail->csb_procedure; /* make sure procedure has been scanned before using it */ if ( procedure && (!(procedure->prc_flags & PRC_scanned) || (procedure->prc_flags & PRC_being_scanned) || (procedure->prc_flags & PRC_being_altered))) { scan_proc = MET_procedure (tdbb, procedure->prc_id, 0); if ( scan_proc != procedure) procedure = NULL; } if (procedure) { par_name (csb, name); if ((id = find_proc_field (procedure, name)) == -1) error (*csb, gds__fldnotdef, gds_arg_string, ERR_cstring (name), gds_arg_string, procedure->prc_name->str_data, 0); } else { if ( !(relation = tail->csb_relation)) error (*csb, gds__ctxnotdef, 0); /* make sure relation has been scanned before using it */ if (!(relation->rel_flags & REL_scanned) || (relation->rel_flags & REL_being_scanned)) MET_scan_relation (tdbb, relation); par_name (csb, name); if ((id = MET_lookup_field (tdbb, relation, name, 0)) < 0) if ((*csb)->csb_g_flags & csb_validation) { id = 0; flags |= nod_id; is_column = TRUE; } else { if (tdbb->tdbb_attachment->att_flags & ATT_gbak_attachment) warning (*csb, gds__fldnotdef, gds_arg_string, ERR_cstring (name), gds_arg_string, relation->rel_name, 0); else if (relation->rel_name) error (*csb, gds__fldnotdef, gds_arg_string, ERR_cstring (name), gds_arg_string, relation->rel_name, 0); else error (*csb, gds__ctxnotdef, 0); } } } /* check for dependencies -- if a field name was given, use it because when restoring the database the field id's may not be valid yet */if ((*csb)->csb_g_flags & csb_get_dependencies) if (_operator == blr_fid) par_dependency (tdbb, csb, stream, id, NULL_PTR); else par_dependency (tdbb, csb, stream, id, name);node = PAR_gen_field (tdbb, stream, id);node->nod_flags |= flags;if (is_column == TRUE) { if (temp_rel = (*csb)->csb_rpt [stream].csb_relation) { if (field = (FLD) temp_rel->rel_fields->vec_object[id]) { if (field->fld_default_value && field->fld_not_null) node->nod_arg [e_fld_default_value] = field->fld_default_value; } } }return node;}static NOD par_function ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ f u n c t i o n * ************************************** * * Functional description * Parse a function reference. * **************************************/NOD node;FUN function, homonyms;TEXT name [32];USHORT count;SET_TDBB (tdbb);count = par_name (csb, name);function = FUN_lookup_function (name);if (!function) { if (tdbb->tdbb_flags & TDBB_prc_being_dropped) { node = PAR_make_node (tdbb, e_fun_length); node->nod_count = 1; node->nod_arg [e_fun_function] = (NOD) NULL; node->nod_arg [e_fun_args] = par_args (tdbb, csb, VALUE); return node; } else { (*csb)->csb_running -= count; error (*csb, gds__funnotdef, gds_arg_string, ERR_cstring (name), 0); } }for (homonyms = function; homonyms; homonyms = homonyms->fun_homonym) if (homonyms->fun_entrypoint) break;if (!homonyms) if (tdbb->tdbb_attachment->att_flags & ATT_gbak_attachment) warning (*csb, gds__funnotdef, gds_arg_string, ERR_cstring (name), gds_arg_interpreted, "module name or entrypoint could not be found", 0); else { (*csb)->csb_running -= count; error (*csb, gds__funnotdef, gds_arg_string, ERR_cstring (name), gds_arg_interpreted, "module name or entrypoint could not be found", 0); }node = PAR_make_node (tdbb, e_fun_length);node->nod_count = 1;node->nod_arg [e_fun_function] = (NOD) function;node->nod_arg [e_fun_args] = par_args (tdbb, csb, VALUE);/* CVC: I will track ufds only if a proc is not being dropped. */if ((*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) function; dep_node->nod_arg [e_dep_object_type] = (NOD) obj_udf; LLS_PUSH (dep_node, &(*csb)->csb_dependencies);}return node;}static NOD par_literal ( TDBB tdbb, register CSB *csb){/************************************** * * p a r _ l i t e r a l * ************************************** * * Functional description * Parse a literal value. * **************************************/register LIT literal;NOD node;DSC desc;UCHAR *p, *q;SSHORT count, l, scale;UCHAR dtype;SET_TDBB (tdbb);PAR_desc (csb, &desc);count = lit_delta + (desc.dsc_length + sizeof (int) - 1) / sizeof (int);node = PAR_make_node (tdbb, count);literal = (LIT) node;node->nod_count = 0;literal->lit_desc = desc;literal->lit_desc.dsc_address = p = literal->lit_data;literal->lit_desc.dsc_flags = 0;q = (*csb)->csb_running;l = desc.dsc_length;switch (desc.dsc_dtype) { case dtype_short: l = 2; *(SSHORT*) p = (SSHORT) gds__vax_integer (q, l); break; case dtype_long: case dtype_sql_date: case dtype_sql_time: l = 4; *(SLONG*) p = (SLONG) gds__vax_integer (q, l); break; case dtype_timestamp: l = 8; *(SLONG*) p = (SLONG) gds__vax_integer (q, 4); p += 4; q += 4; *(SLONG*) p = (SLONG) gds__vax_integer (q, 4); break; case dtype_int64: l = sizeof (SINT64); *(SINT64*) p = (SINT64) isc_portable_integer(q, l); break; case dtype_double: /* the double literal could potentially be used for any numeric literal - the value is passed as if it were a text string. Convert the numeric string to its binary value (int64, long or double as appropriate). */ l = BLR_WORD; q = (*csb)->csb_running; dtype = CVT_get_numeric (q, l, &scale, (double*) p, (FPTR_VOID) ERR_post); literal->lit_desc.dsc_dtype = dtype; if (dtype == dtype_double) literal->lit_desc.dsc_length = sizeof(double); else if (dtype == dtype_long) { literal->lit_desc.dsc_length = sizeof(SLONG); literal->lit_desc.dsc_scale = (SCHAR) scale; } else { literal->lit_desc.dsc_length = sizeof(SINT64); literal->lit_desc.dsc_scale = (SCHAR) scale; } break; default: assert (FALSE); case dtype_text: if (count = l) do *p++ = *q++; while (--count); break; }(*csb)->csb_running += l;return node;}static NOD par_map ( TDBB tdbb, CSB *csb, USHORT stream){/************************************** * * p a r _ m a p * ************************************** * * Functional description * Parse a MAP clause for a union or global aggregate expression. * **************************************/NOD assignment, node;SSHORT count;LLS map;SET_TDBB (tdbb);if (BLR_BYTE != blr_map) syntax_error (*csb, "blr_map");count = BLR_WORD;map = NULL;while (--count >= 0) { assignment = PAR_make_node (tdbb, e_asgn_length); assignment->nod_type = nod_assignment; assignment->nod_count = e_asgn_length; assignment->nod_arg [e_asgn_to] = PAR_gen_field (tdbb, stream, BLR_WORD); assignment->nod_arg [e_asgn_from] = parse (tdbb, csb, VALUE); LLS_PUSH (assignment, &map); }node = PAR_make_list (tdbb, map);node->nod_type = nod_map;return node;}static NOD par_message ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ m e s s a g e * ************************************** * * Functional description * Parse a message declaration, including operator byte. * **************************************/NOD node;FMT format;DSC *desc, *end;USHORT n, alignment;ULONG offset;struct csb_repeat *tail;SET_TDBB (tdbb);/* Get message number, register it in the compile scratch block, and allocate a node to represent the message */n = (unsigned int) BLR_BYTE;tail = CMP_csb_element (csb, n);tail->csb_message = node = PAR_make_node (tdbb, e_msg_length);node->nod_count = 0;node->nod_arg [e_msg_number] = (NOD) (SLONG) n;if (n > (*csb)->csb_msg_number) (*csb)->csb_msg_number = n;/* Get the number of parameters in the message and prepare to fill out the format block */n = BLR_WORD;format = (FMT) ALLOCDV (type_fmt, n);node->nod_arg [e_msg_format] = (NOD) format;format->fmt_count = n;offset = 0;for (desc = format->fmt_desc, end = desc + n; desc < end; desc++) { alignment = PAR_desc (csb, desc); if (alignment) offset = FB_ALIGN(offset, alignment); desc->dsc_address = (UCHAR*) (SLONG) offset; offset += desc->dsc_length; }if (offset > MAX_FORMAT_SIZE) error (*csb, gds__imp_exc, gds_arg_gds, gds__blktoobig, 0);format->fmt_length = (USHORT) offset;return node;}static NOD par_modify ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ m o d i f y * ************************************** * * Functional description * Parse a modify statement. * **************************************/NOD node;SSHORT context, new_stream, org_stream;struct csb_repeat *tail;SET_TDBB (tdbb);/* Parse the original and new contexts */context = (unsigned int) BLR_BYTE;if (context >= (*csb)->csb_count) error (*csb, gds__ctxnotdef, 0);org_stream = (*csb)->csb_rpt [context].csb_stream;new_stream = (*csb)->csb_n_stream++;context = (unsigned int) BLR_BYTE;/* Make sure the compiler scratch block is big enough to hold everything */tail = CMP_csb_element (csb, context);tail->csb_stream = (UCHAR) new_stream;tail = CMP_csb_element (csb, new_stream);tail->csb_relation = (*csb)->csb_rpt [org_stream].csb_relation;/* Make the node and parse the sub-expression */node = PAR_make_node (tdbb, e_mod_length);node->nod_count = 1;node->nod_arg [e_mod_org_stream] = (NOD) (SLONG) org_stream;node->nod_arg [e_mod_new_stream] = (NOD) (SLONG) new_stream;node->nod_arg [e_mod_statement] = parse (tdbb, csb, STATEMENT);return node;}static USHORT par_name ( CSB *csb, TEXT *string){/************************************** * * p a r _ n a m e * ************************************** * * Functional description * Parse a counted string, returning count. * **************************************/USHORT count, l;if (count = l = BLR_BYTE) do *string++ = BLR_BYTE; while (--l);*string = 0;return count;}static NOD par_plan ( TDBB tdbb, CSB *csb){/************************************** * * p a r _ p l a n * ************************************** * * Functional description * Parse an access plan expression. * At this stage we are just generating the * parse tree and checking contexts * and indices. * **************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -