📄 pass1.c
字号:
DEV_BLKCHK (request, type_req);DEV_BLKCHK (input, type_nod);tdsql = GET_THREAD_DATA;(void) PASS1_make_context (request, input->nod_arg [e_blb_relation]);field = pass1_field (request, input->nod_arg [e_blb_field], 0, &fcount);if (field->nod_desc.dsc_dtype != dtype_blob) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -206, gds_arg_gds, gds__dsql_blob_err, 0);request->req_type = (input->nod_type == nod_get_segment) ? REQ_GET_SEGMENT : REQ_PUT_SEGMENT;request->req_blob = blob = (BLB) ALLOCDV (type_blb, 0);blob->blb_field = field;blob->blb_open_in_msg = request->req_send;blob->blb_open_out_msg = (MSG) ALLOCD (type_msg);blob->blb_segment_msg = request->req_receive;/* Create a parameter for the blob segment */blob->blb_segment = parameter = MAKE_parameter (blob->blb_segment_msg, TRUE, TRUE);parameter->par_desc.dsc_dtype = dtype_text;parameter->par_desc.dsc_ttype = ttype_binary;parameter->par_desc.dsc_length = ((FLD) field->nod_arg [e_fld_field])->fld_seg_length;DEV_BLKCHK (field->nod_arg [e_fld_field], type_fld);/* The Null indicator is used to pass back the segment length, * set DSC_nullable so that the SQL_type is set to SQL_TEXT+1 instead * of SQL_TEXT. */if (input->nod_type == nod_get_segment) parameter->par_desc.dsc_flags |= DSC_nullable;/* Create a parameter for the blob id */blob->blb_blob_id = parameter = MAKE_parameter ( (input->nod_type == nod_get_segment) ? blob->blb_open_in_msg : blob->blb_open_out_msg, TRUE, TRUE);parameter->par_desc = field->nod_desc;parameter->par_desc.dsc_dtype = dtype_quad;parameter->par_desc.dsc_scale = 0;if (list = input->nod_arg [e_blb_filter]) { if (list->nod_arg [0]) blob->blb_from = PASS1_node (request, list->nod_arg [0], FALSE); if (list->nod_arg [1]) blob->blb_to = PASS1_node (request, list->nod_arg [1], FALSE); }if (!blob->blb_from) blob->blb_from = MAKE_constant ((STR) 0, 1);if (!blob->blb_to) blob->blb_to = MAKE_constant ((STR) 0, 1);for (parameter = blob->blb_open_in_msg->msg_parameters; parameter; parameter = parameter->par_next) if (parameter->par_index > (input->nod_type == nod_get_segment) ? 1 : 0) { parameter->par_desc.dsc_dtype = dtype_short; parameter->par_desc.dsc_scale = 0; parameter->par_desc.dsc_length = sizeof (SSHORT); }}static NOD pass1_collate ( REQ request, NOD sub1, STR collation){/************************************** * * p a s s 1 _ c o l l a t e * ************************************** * * Functional description * Turn a collate clause into a cast clause. * If the source is not already text, report an error. * (SQL 92: Section 13.1, pg 308, item 11) * **************************************/NOD node;FLD field;TSQL tdsql;DEV_BLKCHK (request, type_req);DEV_BLKCHK (sub1, type_nod);DEV_BLKCHK (collation, type_str);tdsql = GET_THREAD_DATA;node = MAKE_node (nod_cast, e_cast_count);field = (FLD) ALLOCDV (type_fld, 1);field->fld_name[0] = 0;node->nod_arg [e_cast_target] = (NOD) field;node->nod_arg [e_cast_source] = sub1;MAKE_desc (&sub1->nod_desc, sub1);if (sub1->nod_desc.dsc_dtype <= dtype_any_text) { assign_fld_dtype_from_dsc (field, &sub1->nod_desc); field->fld_character_length = 0; if (sub1->nod_desc.dsc_dtype == dtype_varying) field->fld_length += sizeof (USHORT); }else { ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, gds_arg_gds, gds__dsql_datatype_err, gds_arg_gds, gds__collation_requires_text, 0); }DDL_resolve_intl_type (request, field, collation);MAKE_desc_from_field (&node->nod_desc, field);return node;}static NOD pass1_constant ( REQ request, NOD constant){/************************************** * * p a s s 1 _ c o n s t a n t * ************************************** * * Functional description * Turn an international string reference into internal * subtype ID. * **************************************/STR string;INTLSYM resolved;INTLSYM resolved_collation = NULL;DEV_BLKCHK (request, type_req);DEV_BLKCHK (constant, type_nod);if (constant->nod_desc.dsc_dtype > dtype_any_text) return constant;string = (STR) constant->nod_arg[0];DEV_BLKCHK (string, type_str);if (!string || !string->str_charset) return constant;resolved = METD_get_charset (request, strlen (string->str_charset), string->str_charset);if (!resolved) /* character set name is not defined */ ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__charset_not_found, gds_arg_string, string->str_charset, 0);if (temp_collation_name) { resolved_collation = METD_get_collation (request, temp_collation_name); if (!resolved_collation) /* ** Specified collation not found */ ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -204, gds_arg_gds, gds__dsql_datatype_err, gds_arg_gds, gds__collation_not_found, gds_arg_string, temp_collation_name->str_data, 0); resolved = resolved_collation; }INTL_ASSIGN_TTYPE (&constant->nod_desc, resolved->intlsym_ttype);return constant;}static NOD pass1_cursor ( REQ request, NOD cursor, NOD relation_name){/************************************** * * p a s s 1 _ c u r s o r * ************************************** * * Functional description * Turn a cursor reference into a record selection expression. * **************************************/SYM symbol;NOD rse, node, temp, relation_node;REQ parent;STR string;PAR parameter, source, rv_source;DEV_BLKCHK (request, type_req);DEV_BLKCHK (cursor, type_nod);DEV_BLKCHK (relation_name, type_nod);/* Lookup parent request */string = (STR) cursor->nod_arg [e_cur_name];DEV_BLKCHK (string, type_str);symbol = HSHD_lookup (request->req_dbb, string->str_data, string->str_length, SYM_cursor, 0);if (!symbol) /* cursor is not defined */ ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__dsql_cursor_err, 0);parent = (REQ) symbol->sym_object;/* Verify that the cursor is appropriate and updatable */rv_source = find_record_version (parent, relation_name);if (parent->req_type != REQ_SELECT_UPD || !(source = find_dbkey (parent, relation_name)) || (!rv_source && !(request->req_dbb->dbb_flags & DBB_v3))) /* cursor is not updatable */ ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -510, gds_arg_gds, gds__dsql_cursor_update_err, 0);request->req_parent = parent;request->req_parent_dbkey = source;request->req_parent_rec_version = rv_source;request->req_sibling = parent->req_offspring;parent->req_offspring = request;/* Build record selection expression */rse = MAKE_node (nod_rse, e_rse_count);rse->nod_arg [e_rse_streams] = temp = MAKE_node (nod_list, 1);temp->nod_arg [0] = relation_node = pass1_relation (request, relation_name);rse->nod_arg [e_rse_boolean] = node = MAKE_node (nod_eql, 2);node->nod_arg [0] = temp = MAKE_node (nod_dbkey, 1);temp->nod_arg [0] = relation_node;node->nod_arg [1] = temp = MAKE_node (nod_parameter, e_par_count);temp->nod_count = 0;parameter = request->req_dbkey = MAKE_parameter (request->req_send, FALSE, FALSE);temp->nod_arg [e_par_parameter] = (NOD) parameter;parameter->par_desc = source->par_desc;/* record version will be set only for V4 - for the parent select cursor */if (rv_source) { node = MAKE_node (nod_eql, 2); node->nod_arg [0] = temp = MAKE_node (nod_rec_version, 1); temp->nod_arg [0] = relation_node; node->nod_arg [1] = temp = MAKE_node (nod_parameter, e_par_count); temp->nod_count = 0; parameter = request->req_rec_version = MAKE_parameter (request->req_send, FALSE, FALSE); temp->nod_arg [e_par_parameter] = (NOD) parameter; parameter->par_desc = rv_source->par_desc; rse->nod_arg [e_rse_boolean] = compose (rse->nod_arg [e_rse_boolean], node, nod_and); }return rse;}static CTX pass1_cursor_context ( REQ request, NOD cursor, NOD relation_name){/************************************** * * p a s s 1 _ c u r s o r _ c o n t e x t * ************************************** * * Functional description * Turn a cursor reference into a record selection expression. * **************************************/NOD node, temp, *ptr, *end, procedure, r_node;CTX context, candidate;STR string, cname, rname;DSQL_REL relation;DEV_BLKCHK (request, type_req);DEV_BLKCHK (cursor, type_nod);DEV_BLKCHK (relation_name, type_nod);string = (STR) cursor->nod_arg [e_cur_name];DEV_BLKCHK (string, type_str);procedure = request->req_ddl_node;context = NULL;for (node = procedure->nod_arg [e_prc_cursors]; node; node = node->nod_arg [e_cur_next]) { DEV_BLKCHK (node, type_nod); cname = (STR) node->nod_arg [e_cur_name]; DEV_BLKCHK (cname, type_str); if (!strcmp (string->str_data, cname->str_data)) { temp = node->nod_arg [e_cur_context]; temp = temp->nod_arg [e_flp_select]; temp = temp->nod_arg [e_rse_streams]; for (ptr = temp->nod_arg, end = ptr + temp->nod_count; ptr < end; ptr++) { DEV_BLKCHK (*ptr, type_nod); r_node = *ptr; if (r_node->nod_type == nod_relation) { candidate = (CTX) r_node->nod_arg [e_rel_context]; DEV_BLKCHK (candidate, type_ctx); relation = candidate->ctx_relation; rname = (STR) relation_name->nod_arg [e_rln_name]; DEV_BLKCHK (rname, type_str); if (!strcmp (rname->str_data, relation->rel_name)) { if (context) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__dsql_cursor_err, 0); else context = candidate; } } } if (context) return context; else break; } }ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -504, gds_arg_gds, gds__dsql_cursor_err, 0);return (NULL); /* Added to remove compiler warnings */ }static NOD pass1_dbkey ( REQ request, NOD input){/************************************** * * p a s s 1 _ d b k e y * ************************************** * * Functional description * Resolve a dbkey to an available context. * **************************************/NOD node, rel_node;STR qualifier;LLS stack;CTX context;DEV_BLKCHK (request, type_req);DEV_BLKCHK (input, type_nod);if (!(qualifier = (STR) input->nod_arg [0])) { DEV_BLKCHK (qualifier, type_str); /* No qualifier, if only one context then use, else error */ if ((stack = request->req_context) && !stack->lls_next) { context = (CTX) stack->lls_object; DEV_BLKCHK (context, type_ctx); node = MAKE_node (nod_dbkey, 1); rel_node = MAKE_node (nod_relation, e_rel_count); rel_node->nod_arg[0] = (NOD) context; node->nod_arg[0] = rel_node; return node; } }else { for (stack = request->req_context; stack; stack = stack->lls_next) { context = (CTX) stack->lls_object; DEV_BLKCHK (context, type_ctx); if ((!(context->ctx_relation) || strcmp (qualifier->str_data, context->ctx_relation->rel_name)) && (!(context->ctx_alias) || strcmp (qualifier->str_data, context->ctx_alias))) continue; node = MAKE_node (nod_dbkey, 1); rel_node = MAKE_node (nod_relation, e_rel_count); rel_node->nod_arg[0] = (NOD) context; node->nod_arg[0] = rel_node; return node; } }/* field unresolved */field_error (qualifier ? qualifier->str_data : (UCHAR *) NULL_PTR, DB_KEY_STRING, input); return NULL;}static NOD pass1_delete ( REQ request, NOD input){/************************************** * * p a s s 1 _ d e l e t e * ************************************** * * Functional description * Process INSERT statement. * **************************************/NOD rse, node, temp, cursor, relation;DEV_BLKCHK (request, type_req);DEV_BLKCHK (input, type_nod);cursor = input->nod_arg [e_del_cursor];relation = input->nod_arg [e_del_relation];if (cursor && (request->req_flags & REQ_procedure)) { node = MAKE_node (nod_erase_current, e_erc_count); node->nod_arg [e_erc_context] = (NOD) pass1_cursor_context (request, cursor, relation); return node; }request->req_type = (cursor) ? REQ_DELETE_CURSOR : REQ_DELETE;node = MAKE_node (nod_erase, e_era_count);/* Generate record selection expression */if (cursor) rse = pass1_cursor (request, cursor, relation);else { rse = MAKE_node (nod_rse, e_rse_count); rse->nod_arg [e_rse_streams] = temp = MAKE_node (nod_list, 1); temp->nod_arg [0] = PASS1_node (request, relation, 0); if (temp = input->nod_arg [e_del_boolean]) rse->nod_arg [e_rse_boolean] = PASS1_node (request, temp, 0); }node->nod_arg [e_era_rse] = rse;temp = rse->nod_arg [e_rse_streams];node->nod_arg [e_era_relation] = temp->nod_arg [0];LLS_POP (&request->req_context);return node;}static NOD pass1_field ( REQ request, NOD input, USHORT list, USHORT *fcount){/************************************** * * p a s s 1 _ f i e l d * ************************************** * * Functional description * Resolve a field name t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -