⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 par.c

📁 firebird源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *	PROGRAM:	JRD Access Method *	MODULE:		par.c *	DESCRIPTION:	BLR Parser * * The contents of this file are subject to the Interbase Public * License Version 1.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.Inprise.com/IPL.html * * Software distributed under the License is distributed on an * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express * or implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code was created by Inprise Corporation * and its predecessors. Portions created by Inprise Corporation are * Copyright (C) Inprise Corporation. * * All Rights Reserved. * Contributor(s): ______________________________________. * 27-May-2001 Claudio Valderrama: par_plan() no longer uppercases *			an index's name before doing a lookup of such index. * 2001.07.28: Added parse code for blr_skip to support LIMIT. *//*$Id: par.c,v 1.1 2001/10/13 10:22:56 dimitr Exp $*/#include "../jrd/ib_stdio.h"#include <string.h>#include "../jrd/common.h"#include <stdarg.h>#include "../jrd/jrd.h"#include "../jrd/gds.h"#include "../jrd/val.h"#include "../jrd/align.h"#include "../jrd/exe.h"#include "../jrd/lls.h"#include "../jrd/scl.h"#include "../jrd/all.h"#include "../jrd/req.h"#include "../jrd/blb.h"#include "../jrd/intl.h"#include "../jrd/met.h"#include "../jrd/all_proto.h"#include "../jrd/cmp_proto.h"#include "../jrd/cvt_proto.h"#include "../jrd/err_proto.h"#include "../jrd/fun_proto.h"#include "../jrd/gds_proto.h"#include "../jrd/met_proto.h"#include "../jrd/par_proto.h"#include "../jrd/thd_proto.h"/* blr type classes */#define OTHER		0#define STATEMENT	1#define BOOL		2#define VALUE		3#define TYPE_RSE	4#define RELATION	5#define ACCESS_TYPE	6#include "../jrd/blrtable.h"static CONST TEXT	elements [][10] = { "", "statement", "boolean", "value", "RSE", "TABLE"};static CONST struct {    CONST SCHAR	*code_string;    SLONG	code_number;} FAR_VARIABLE codes [] = {#include "../jrd/codetext.h"    NULL, 0};static void	error (CSB, ...);static SSHORT	find_proc_field (PRC, TEXT *);static NOD	par_args (TDBB, CSB *, USHORT);static NOD	par_cast (TDBB, CSB *);static XCP	par_condition (TDBB, CSB *);static XCP	par_conditions (TDBB, CSB *);static SSHORT	par_context (CSB *, SSHORT *);static void	par_dependency (TDBB, CSB *, SSHORT, SSHORT, TEXT *);static NOD	par_exec_proc (TDBB, CSB *, SSHORT);static NOD	par_fetch (TDBB, CSB *, NOD);static NOD	par_field (TDBB, CSB *, SSHORT);static NOD	par_function (TDBB, CSB *);static NOD	par_literal (TDBB, register CSB *);static NOD	par_map (TDBB, CSB *, USHORT);static NOD	par_message (TDBB, CSB *);static NOD	par_modify (TDBB, CSB *);static USHORT	par_name (CSB *, TEXT *);static NOD	par_plan (TDBB, CSB *);static NOD	par_procedure (TDBB, CSB *, SSHORT);static void	par_procedure_parms (TDBB, CSB *, PRC, NOD *, NOD *, USHORT);static NOD	par_relation (TDBB, CSB *, SSHORT, BOOLEAN);static NOD	par_rse (TDBB, CSB *, SSHORT);static NOD	par_sort (TDBB, CSB *, BOOLEAN);static NOD	par_stream (TDBB, CSB *);static NOD	par_union (TDBB, CSB *);static USHORT	par_word (CSB *);static NOD	parse (TDBB, register CSB *, USHORT);static void	syntax_error (CSB, CONST TEXT *);static void	warning (CSB, ...);#define BLR_PEEK	*((*csb)->csb_running)#define BLR_BYTE	*((*csb)->csb_running)++#define BLR_PUSH	((*csb)->csb_running)--#define BLR_WORD	par_word (csb)NOD PAR_blr (    TDBB	tdbb,    REL		relation,    UCHAR	*blr,    CSB		view_csb,    CSB		*csb_ptr,    REQ		*request_ptr,    BOOLEAN	trigger,    USHORT	flags){/************************************** * *	P A R _ b l r * ************************************** * * Functional description *	Parse blr, returning a compiler scratch block with the results. *	Caller must do pool handling. * **************************************/CSB		csb;NOD		node;SSHORT		version, stream, count;struct csb_repeat	*t1, *t2, *end;SET_TDBB (tdbb);if (!(csb_ptr && (csb = *csb_ptr)))    {    count = 5;    if (view_csb) 	count += view_csb->csb_count;    csb = (CSB) ALLOCDV (type_csb, count);    csb->csb_count = count;    csb->csb_g_flags |= flags;    }/* If there is a request ptr, this is a trigger.  Set up contexts 0 and 1 for   the target relation */if (trigger)    {    stream = csb->csb_n_stream++;    t1 = CMP_csb_element (&csb, 0);    t1->csb_flags |= csb_used | csb_active | csb_trigger;    t1->csb_relation = relation;    t1->csb_stream = (UCHAR) stream;    stream = csb->csb_n_stream++;    t1 = CMP_csb_element (&csb, 1);    t1->csb_flags |= csb_used | csb_active | csb_trigger;    t1->csb_relation = relation;    t1->csb_stream = (UCHAR) stream;    }else    {    ++csb->csb_n_stream;    csb->csb_rpt [0].csb_relation = relation;    }csb->csb_running = csb->csb_blr = blr;if (view_csb)    {    t1 = view_csb->csb_rpt;    end = t1 + view_csb->csb_n_stream;    for (stream = 0; t1 < end; t1++, stream++)	{	t2 = CMP_csb_element (&csb, stream);	t2->csb_relation = t1->csb_relation;	t2->csb_stream = t1->csb_stream;	}    csb->csb_n_stream = view_csb->csb_n_stream;    }version = *csb->csb_running++;if (version != blr_version4 && version != blr_version5)   error (csb, gds__metadata_corrupt,	gds_arg_gds, gds__wroblrver, 	gds_arg_number, (SLONG) blr_version4, 	gds_arg_number, (SLONG) version,	0);if (version == blr_version4)    csb->csb_g_flags |= csb_blr_version4;node = parse (tdbb, &csb, OTHER);csb->csb_node = node;if (*csb->csb_running++ != (UCHAR) blr_eoc)   syntax_error (csb, "end_of_command");if (request_ptr)    *request_ptr = CMP_make_request (tdbb, &csb);if (csb_ptr)    *csb_ptr = csb;else    ALL_RELEASE (csb);return node;}int PAR_desc (    CSB		*csb,    DSC		*desc){/************************************** * *	P A R _ d e s c  * ************************************** * * Functional description *	Parse a BLR descriptor.  Return the alignment requirements *	of the datatype. * **************************************/USHORT	dtype;desc->dsc_scale = 0;desc->dsc_sub_type = 0;desc->dsc_address = (UCHAR*) NULL_PTR;desc->dsc_flags = 0;switch (dtype = BLR_BYTE)    {    case blr_text:	desc->dsc_dtype = dtype_text;	desc->dsc_flags |= DSC_no_subtype;	desc->dsc_length = BLR_WORD;	INTL_ASSIGN_TTYPE (desc, ttype_dynamic);	break;    case blr_cstring:	desc->dsc_dtype = dtype_cstring;	desc->dsc_flags |= DSC_no_subtype;	desc->dsc_length = BLR_WORD;	INTL_ASSIGN_TTYPE (desc, ttype_dynamic);	break;    case blr_varying:	desc->dsc_dtype = dtype_varying;	desc->dsc_flags |= DSC_no_subtype;	desc->dsc_length = BLR_WORD + sizeof (USHORT);	INTL_ASSIGN_TTYPE (desc, ttype_dynamic);	break;    case blr_text2:	desc->dsc_dtype = dtype_text;	INTL_ASSIGN_TTYPE (desc, BLR_WORD);	desc->dsc_length = BLR_WORD;	break;    case blr_cstring2:	desc->dsc_dtype = dtype_cstring;	INTL_ASSIGN_TTYPE (desc, BLR_WORD);	desc->dsc_length = BLR_WORD;	break;    case blr_varying2:	desc->dsc_dtype = dtype_varying;	INTL_ASSIGN_TTYPE (desc, BLR_WORD);	desc->dsc_length = BLR_WORD + sizeof (USHORT); 	break;    case blr_short:	desc->dsc_dtype = dtype_short;	desc->dsc_length = sizeof (SSHORT);	desc->dsc_scale = (int) BLR_BYTE;	break;    case blr_long:	desc->dsc_dtype = dtype_long;	desc->dsc_length = sizeof (SLONG);	desc->dsc_scale = (int) BLR_BYTE;	break;    case blr_int64:	desc->dsc_dtype = dtype_int64;	desc->dsc_length = sizeof (SINT64);	desc->dsc_scale = (int) BLR_BYTE;	break;    case blr_quad:	desc->dsc_dtype = dtype_quad;	desc->dsc_length = sizeof (GDS__QUAD);	desc->dsc_scale = (int) BLR_BYTE;	break;    case blr_float:	desc->dsc_dtype = dtype_real;	desc->dsc_length = sizeof (float);	break;    case blr_timestamp:	desc->dsc_dtype = dtype_timestamp;	desc->dsc_length = sizeof (GDS__QUAD);	break;    case blr_sql_date:	desc->dsc_dtype = dtype_sql_date;	desc->dsc_length = type_lengths [dtype_sql_date];	break;    case blr_sql_time:	desc->dsc_dtype = dtype_sql_time;	desc->dsc_length = type_lengths [dtype_sql_time];	break;    case blr_double:#ifndef VMS    case blr_d_float:#endif	desc->dsc_dtype = dtype_double;	desc->dsc_length = sizeof (double);	break;#ifdef VMS    case blr_d_float:	desc->dsc_dtype = dtype_d_float;	desc->dsc_length = sizeof (double);	break;#endif    default:	if (dtype == blr_blob)	    {	    desc->dsc_dtype = dtype_blob;	    desc->dsc_length = sizeof (GDS__QUAD);	    break;	    }	error (*csb, gds__datnotsup, 0);    }return type_alignments [desc->dsc_dtype];}NOD PAR_gen_field (    TDBB	tdbb,    USHORT	stream,    USHORT	id){/************************************** * *	P A R _ g e n _ f i e l d * ************************************** * * Functional description *	Generate a field block. * **************************************/NOD	node;SET_TDBB (tdbb);node = (NOD) ALLOCDV (type_nod, e_fld_length);node->nod_type = nod_field;node->nod_arg [e_fld_id] = (NOD) (SLONG) id;node->nod_arg [e_fld_stream] = (NOD) (SLONG) stream;return node;}NOD PAR_make_field (    TDBB	tdbb,    CSB		csb,    USHORT	context,    TEXT	*base_field){/************************************** * *	P A R _ m a k e _ f i e l d * ************************************** * * Functional description *	Make up a field node in the permanent pool.  This is used *	by MET_scan_relation to handle view fields. * **************************************/SSHORT	id;USHORT	stream;TEXT	name [32];FLD     field;REL     temp_rel;NOD     temp_node;SET_TDBB (tdbb);stream = csb->csb_rpt [context].csb_stream;/* CVC: This is just another case of a custom function that isn't preparedfor quoted identifiers and that causes views with fields names like "z x"to fail miserably. Since this function was truncating field names like "z x",MET_lookup_field() call below failed and hence the function returned NULLso only caller MET_scan_relation() did field->fld_source = 0;This means a field without entry in rdb$fields. This is the origin of themysterious message "cannot access column z x in view VF" when selecting fromsuch view that has field "z x". This closes Firebird Bug #227758. */strcpy (name, base_field);MET_exact_name (name);id = MET_lookup_field (tdbb, csb->csb_rpt [stream].csb_relation, name, 0);if (id < 0)    return NULL;temp_rel = csb->csb_rpt [stream].csb_relation;/* If rel_fields is NULL this means that the relation is * in a temporary state (partially loaded).  In this case * there is nothing we can do but post an error and exit. * Note: This will most likely happen if we have a large list * of deffered work which can not complete because of some * error, and while we are trying to commit, we find  * that we have a dependency on something later in the list. * IF there were no error, then the dependency woyld have * been resolved, because we would have fully loaded the * relation, but if it can not be loaded, then we have this * problem. The only thing that can be done to remedy this * problem is to rollback.  This will clear the dfw list and * allow the user to remedy the original error.  Note: it would * be incorrect for us (the server) to perform the rollback * implicitly, because this is a task for the user to do, and * should never be decided by the server. This fixes bug 10052 */if (!temp_rel->rel_fields)    {    ERR_post(isc_depend_on_uncommitted_rel, 0);    }temp_node = PAR_gen_field (tdbb, stream, id);if (field = (FLD) temp_rel->rel_fields->vec_object[id])    {    if (field->fld_default_value && field->fld_not_null)	temp_node->nod_arg [e_fld_default_value] = field->fld_default_value;    }return temp_node;}NOD PAR_make_list (    TDBB	tdbb,    LLS		stack){/************************************** * *	P A R _ m a k e _ l i s t * ************************************** * * Functional description *	Make a list node out of a stack. * **************************************/NOD	node, *ptr;LLS	temp;USHORT	count;SET_TDBB (tdbb);/* Count the number of nodes */for (temp = stack, count = 0; temp; count++)    temp = temp->lls_next;node = PAR_make_node (tdbb, count);node->nod_type = nod_list;ptr = node->nod_arg + count;while (stack)    *--ptr = (NOD) LLS_POP (&stack);return node;}NOD PAR_make_node (    TDBB	tdbb,    int	size){/************************************** * *	P A R _ m a k e _ n o d e * ************************************** * * Functional description *	Make a node element and pass it back. * **************************************/NOD	node;SET_TDBB (tdbb);node = (NOD) ALLOCDV (type_nod, size);node->nod_count = size;return node;}CSB PAR_parse (    TDBB	tdbb,    UCHAR	*blr,    USHORT	internal_flag){/************************************** * *	P A R _ p a r s e * ************************************** * * Functional description *	Parse blr, returning a compiler scratch block with the results. * **************************************/NOD	node;CSB	csb;SSHORT	version;SET_TDBB (tdbb);csb = (CSB) ALLOCDV (type_csb, 5);csb->csb_count = 5;csb->csb_running = csb->csb_blr = blr;version = *csb->csb_running++;if (internal_flag)    csb->csb_g_flags |= csb_internal;if (version != blr_version4 && version!= blr_version5)   error (csb, gds__wroblrver, 	gds_arg_number, (SLONG) blr_version4, 	gds_arg_number, (SLONG) version, 	0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -