📄 pass1.c
字号:
case nod_add: case nod_concatenate: case nod_divide: case nod_multiply: case nod_negate: case nod_substr: case nod_subtract: case nod_add2: case nod_divide2: case nod_multiply2: case nod_subtract2: case nod_upcase: case nod_extract: case nod_list: aggregate = FALSE; for (ptr = sub->nod_arg, end = ptr + sub->nod_count; ptr < end; ptr++) { DEV_BLKCHK (*ptr, type_nod); aggregate |= aggregate_found2 (request, *ptr, proj, field); } return aggregate; case nod_cast: case nod_udf: case nod_gen_id: case nod_gen_id2: if (sub->nod_count == 2) return (aggregate_found2 (request, sub->nod_arg[1], proj, field)); else return FALSE; default: return FALSE; }}static void assign_fld_dtype_from_dsc ( FLD field, DSC *nod_desc){/************************************** * * a s s i g n _ f l d _ d t y p e _ f r o m _ d s c * ************************************** * * Functional description * Set a field's descriptor from a DSC * (If FLD is ever redefined this can be removed) * **************************************/DEV_BLKCHK (field, type_fld);field->fld_dtype = nod_desc->dsc_dtype;field->fld_scale = nod_desc->dsc_scale;field->fld_sub_type = nod_desc->dsc_sub_type;field->fld_length = nod_desc->dsc_length;if (nod_desc->dsc_dtype <= dtype_any_text) { field->fld_collation_id = DSC_GET_COLLATE (nod_desc); field->fld_character_set_id = DSC_GET_CHARSET (nod_desc); }else if (nod_desc->dsc_dtype == dtype_blob) field->fld_character_set_id = nod_desc->dsc_scale;}static NOD compose ( NOD expr1, NOD expr2, NOD_TYPE operator){/************************************** * * c o m p o s e * ************************************** * * Functional description * Compose two booleans. * **************************************/NOD node;DEV_BLKCHK (expr1, type_nod);DEV_BLKCHK (expr2, type_nod);if (!expr1) return expr2;if (!expr2) return expr1;node = MAKE_node (operator, 2);node->nod_arg [0] = expr1;node->nod_arg [1] = expr2;return node;}static NOD copy_field ( NOD field, CTX context){/************************************** * * c o p y _ f i e l d * ************************************** * * Functional description * Copy a field list for a SELECT against an artificial context. * **************************************/NOD temp, actual, *ptr, *end, *ptr2;MAP map;STR alias;DEV_BLKCHK (field, type_nod);DEV_BLKCHK (context, type_ctx);switch (field->nod_type) { case nod_map: map = (MAP) field->nod_arg[e_map_map]; DEV_BLKCHK (map, type_map); temp = map->map_node; return post_map (temp, context); case nod_alias: actual = field->nod_arg [e_alias_value]; alias = (STR) field->nod_arg[e_alias_alias]; DEV_BLKCHK (alias, type_str); temp = MAKE_node (nod_alias, e_alias_count); temp->nod_arg [e_alias_value] = copy_field (actual, context); temp->nod_arg [e_alias_alias] = (NOD) alias; return temp; case nod_add: case nod_add2: case nod_concatenate: case nod_divide: case nod_divide2: case nod_multiply: case nod_multiply2: case nod_negate: case nod_substr: case nod_subtract: case nod_subtract2: case nod_upcase: case nod_extract: case nod_list: temp = MAKE_node (field->nod_type, field->nod_count); ptr2 = temp->nod_arg; for (ptr = field->nod_arg, end = ptr + field->nod_count; ptr < end; ptr++) *ptr2++ = copy_field (*ptr, context); return temp; case nod_cast: case nod_gen_id: case nod_gen_id2: case nod_udf: temp = MAKE_node (field->nod_type, field->nod_count); temp->nod_arg[0] = field->nod_arg[0]; if (field->nod_count == 2) temp->nod_arg[1] = copy_field (field->nod_arg[1], context); return temp; default: return post_map (field, context); }}static NOD copy_fields ( NOD fields, CTX context){/************************************** * * c o p y _ f i e l d s * ************************************** * * Functional description * Copy a field list for a SELECT against an artificial context. * **************************************/NOD list;USHORT i;DEV_BLKCHK (fields, type_nod);DEV_BLKCHK (context, type_ctx);list = MAKE_node (nod_list, fields->nod_count);for (i = 0; i < fields->nod_count; i++) list->nod_arg[i] = copy_field (fields->nod_arg[i], context);return list;}static void explode_asterisk ( NOD node, NOD aggregate, LLS *stack){/************************************** * * e x p l o d e _ a s t e r i s k * ************************************** * * Functional description * Expand an '*' in a field list to the corresponding fields. * **************************************/CTX context;DSQL_REL relation;PRC procedure;FLD field;DEV_BLKCHK (node, type_nod);DEV_BLKCHK (aggregate, type_nod);if (node->nod_type == nod_join) { explode_asterisk (node->nod_arg [e_join_left_rel], aggregate, stack); explode_asterisk (node->nod_arg [e_join_rght_rel], aggregate, stack); }else { context = (CTX) node->nod_arg [e_rel_context]; DEV_BLKCHK (context, type_ctx); if (relation = context->ctx_relation) for (field = relation->rel_fields; field; field = field->fld_next) { DEV_BLKCHK (field, type_fld); node = MAKE_field (context, field, NULL_PTR); if (aggregate) { if (invalid_reference (node, aggregate->nod_arg [e_agg_group])) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__field_ref_err, /* invalid field reference */ 0); } LLS_PUSH (MAKE_field (context, field, NULL_PTR), stack); } else if (procedure = context->ctx_procedure) for (field = procedure->prc_outputs; field; field = field->fld_next) { DEV_BLKCHK (field, type_fld); node = MAKE_field (context, field, NULL_PTR); if (aggregate) { if (invalid_reference (node, aggregate->nod_arg [e_agg_group])) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -104, gds_arg_gds, gds__field_ref_err, /* invalid field reference */ 0); } LLS_PUSH (MAKE_field (context, field, NULL_PTR), stack); } }}static NOD explode_outputs ( REQ request, PRC procedure){/************************************** * * e x p l o d e _ o u t p u t s * ************************************** * * Functional description * Generate a parameter list to correspond to procedure outputs. * **************************************/NOD node, *ptr, p_node;FLD field;PAR parameter;SSHORT count;DEV_BLKCHK (request, type_req);DEV_BLKCHK (procedure, type_prc);count = procedure->prc_out_count;node = MAKE_node (nod_list, count);for (field = procedure->prc_outputs, ptr = node->nod_arg; field; field = field->fld_next, ptr++) { DEV_BLKCHK (field, type_fld); DEV_BLKCHK (*ptr, type_nod); *ptr = p_node = MAKE_node (nod_parameter, e_par_count); p_node->nod_count = 0; parameter = MAKE_parameter (request->req_receive, TRUE, TRUE); p_node->nod_arg [e_par_parameter] = (NOD) parameter; MAKE_desc_from_field (¶meter->par_desc, field); parameter->par_name = parameter->par_alias = field->fld_name; parameter->par_rel_name = procedure->prc_name; parameter->par_owner_name = procedure->prc_owner; }return node;}static void field_error ( TEXT *qualifier_name, TEXT *field_name, NOD flawed_node){/************************************** * * f i e l d _ e r r o r * ************************************** * * Functional description * Report a field parsing recognition error. * **************************************/TEXT field_string [64], linecol [64];if (qualifier_name) { sprintf (field_string, "%s.%s", qualifier_name, field_name ? field_name : "*"); field_name = field_string; }if (flawed_node) sprintf (linecol, "At line %d, column %d.", (int) flawed_node->nod_line, (int) flawed_node->nod_column);else sprintf (linecol, "At unknown line and column.");if (field_name) ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -206, gds_arg_gds, gds__dsql_field_err, gds_arg_gds, gds__random, gds_arg_string, field_name, gds_arg_gds, gds__random, gds_arg_string, linecol, 0);else ERRD_post (gds__sqlerr, gds_arg_number, (SLONG) -206, gds_arg_gds, gds__dsql_field_err, gds_arg_gds, gds__random, gds_arg_string, linecol, 0);}static PAR find_dbkey ( REQ request, NOD relation_name){/************************************** * * f i n d _ d b k e y * ************************************** * * Functional description * Find dbkey for named relation in request's saved dbkeys. * **************************************/CTX context;MSG message;PAR parameter, candidate;DSQL_REL relation;STR rel_name;DEV_BLKCHK (request, type_req);DEV_BLKCHK (relation_name, type_nod);message = request->req_receive;candidate = NULL;rel_name = (STR) relation_name->nod_arg [e_rln_name];DEV_BLKCHK (rel_name, type_str);for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next) { DEV_BLKCHK (parameter, type_par); if (context = parameter->par_dbkey_ctx) { DEV_BLKCHK (context, type_ctx); relation = context->ctx_relation; if (!strcmp (rel_name->str_data, relation->rel_name)) { if (candidate) return NULL; else candidate = parameter; } } }return candidate;}static PAR find_record_version ( REQ request, NOD relation_name){/************************************** * * f i n d _ r e c o r d _ v e r s i o n * ************************************** * * Functional description * Find record version for relation in request's saved record version * **************************************/CTX context;MSG message;PAR parameter, candidate;DSQL_REL relation;STR rel_name;DEV_BLKCHK (request, type_req);DEV_BLKCHK (relation_name, type_nod);message = request->req_receive;candidate = NULL;rel_name = (STR) relation_name->nod_arg [e_rln_name];DEV_BLKCHK (rel_name, type_str);for (parameter = message->msg_parameters; parameter; parameter = parameter->par_next) { DEV_BLKCHK (parameter, type_par); if (context = parameter->par_rec_version_ctx) { DEV_BLKCHK (context, type_ctx); relation = context->ctx_relation; if (!strcmp (rel_name->str_data, relation->rel_name)) { if (candidate) return NULL; else candidate = parameter; } } }return candidate;}static BOOLEAN invalid_reference ( NOD node, NOD list){/************************************** * * i n v a l i d _ r e f e r e n c e * ************************************** * * Functional description * Validate that an expanded field / context * pair is in a specified list. Thus is used * in one instance to check that a simple field selected * through a grouping rse is a grouping field - * thus a valid field reference. For the sake of * argument, we'll match qualified to unqualified * reference, but qualified reference must match * completely. * * A list element containing a simple CAST for collation purposes * is allowed. * **************************************/NOD *ptr, *end; BOOLEAN invalid;DEV_BLKCHK (node, type_nod);DEV_BLKCHK (list, type_nod);if (node == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -