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

📄 parse.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Module:          parse.c * * Description:     This module contains routines related to parsing SQL statements. *                  This can be useful for two reasons: * *                  1. So the query does not actually have to be executed to return data about it * *                  2. To be able to return information about precision, nullability, aliases, etc. *                     in the functions SQLDescribeCol and SQLColAttributes.  Currently, Postgres *                     doesn't return any information about these things in a query. * * Classes:         none * * API functions:   none * * Comments:        See "notice.txt" for copyright and license information. * */#include <stdio.h>#include <string.h>#include <ctype.h>#include "statement.h"#include "connection.h"#include "qresult.h"#include "pgtypes.h"#ifndef WIN32#ifndef HAVE_STRICMP#define stricmp(s1,s2) 		strcasecmp(s1,s2)#define strnicmp(s1,s2,n)	strncasecmp(s1,s2,n)#endif#endif#define FLD_INCR	32#define TAB_INCR	8#define COL_INCR	16char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric);void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k);char searchColInfo(COL_INFO *col_info, FIELD_INFO *fi);char *getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric){int i = 0;int out = 0;char qc, in_escape = FALSE;	if (smax <= 1)		return NULL;	smax--;	/* skip leading delimiters */	while (isspace(s[i]) || s[i] == ',') {		// mylog("skipping '%c'\n", s[i]);		i++;	}	if (s[0] == '\0') {		token[0] = '\0';		return NULL;	}	if (quote) *quote = FALSE;	if (dquote) *dquote = FALSE;	if (numeric) *numeric = FALSE;	/* get the next token */	while ( ! isspace(s[i]) && s[i] != ',' && s[i] != '\0' && out != smax) {		/*	Handle quoted stuff */		if ( out == 0 && (s[i] == '\"' || s[i] == '\'')) {			qc = s[i];			if (qc == '\"') {				if (dquote) *dquote = TRUE;			}			if (qc == '\'') {				if (quote) *quote = TRUE;			}			i++;		/* dont return the quote */			while (s[i] != '\0' && out != smax) {  				if (s[i] == qc && ! in_escape) {					break;				}				if (s[i] == '\\' && ! in_escape) {					in_escape = TRUE;				}				else {					in_escape = FALSE;						token[out++] = s[i];				}				i++;			}			if (s[i] == qc)				i++;			break;		}		/*	Check for numeric literals */		if ( out == 0 && isdigit(s[i])) {			if (numeric) *numeric = TRUE;			token[out++] = s[i++];			while ( isalnum(s[i]) || s[i] == '.')				token[out++] = s[i++];			break;		}		if ( ispunct(s[i]) && s[i] != '_') {			mylog("got ispunct: s[%d] = '%c'\n", i, s[i]);			if (out == 0) {				token[out++] = s[i++];				break;			}			else				break;		}		if (out != smax)			token[out++] = s[i];		i++;	}	// mylog("done -- s[%d] = '%c'\n", i, s[i]);	token[out] = '\0';	/*	find the delimiter  */	while ( isspace(s[i]))		i++;	/*	return the most priority delimiter */	if (s[i] == ',')  {		if (delim) *delim = s[i];	}	else if (s[i] == '\0') {		if (delim) *delim = '\0';	}	else  {		if (delim) *delim = ' ';	}	/* skip trailing blanks  */	while ( isspace(s[i])) {		i++;	}	return &s[i];}/*QR_set_num_fields(stmt->result, 14);QR_set_field_info(stmt->result, 0, "TABLE_QUALIFIER", PG_TYPE_TEXT, MAX_INFO_STRING);QR_set_field_info(stmt->result, 1, "TABLE_OWNER", PG_TYPE_TEXT, MAX_INFO_STRING);QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);QR_set_field_info(stmt->result, 3, "COLUMN_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);QR_set_field_info(stmt->result, 4, "DATA_TYPE", PG_TYPE_INT2, 2);QR_set_field_info(stmt->result, 5, "TYPE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING);QR_set_field_info(stmt->result, 6, "PRECISION", PG_TYPE_INT4, 4);QR_set_field_info(stmt->result, 7, "LENGTH", PG_TYPE_INT4, 4);QR_set_field_info(stmt->result, 8, "SCALE", PG_TYPE_INT2, 2);QR_set_field_info(stmt->result, 9, "RADIX", PG_TYPE_INT2, 2);QR_set_field_info(stmt->result, 10, "NULLABLE", PG_TYPE_INT2, 2);QR_set_field_info(stmt->result, 11, "REMARKS", PG_TYPE_TEXT, 254);//	User defined fieldsQR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4);QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4);*/voidgetColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k){	if (fi->name[0] == '\0')		strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3));	fi->type = atoi( QR_get_value_manual(col_info->result, k, 13));	fi->precision = atoi( QR_get_value_manual(col_info->result, k, 6));	fi->length = atoi( QR_get_value_manual(col_info->result, k, 7));	fi->nullable = atoi( QR_get_value_manual(col_info->result, k, 10));	fi->display_size = atoi( QR_get_value_manual(col_info->result, k, 12));}charsearchColInfo(COL_INFO *col_info, FIELD_INFO *fi){int k;char *col;	for (k = 0; k < QR_get_num_tuples(col_info->result); k++) {		col = QR_get_value_manual(col_info->result, k, 3);		if ( ! strcmp(col, fi->name)) {			getColInfo(col_info, fi, k);			mylog("PARSE: searchColInfo: \n");			return TRUE;		}	}	return FALSE;}charparse_statement(StatementClass *stmt){static char *func="parse_statement";char token[256];char delim, quote, dquote, numeric, unquoted;char *ptr;char in_select = FALSE, in_distinct = FALSE, in_on = FALSE, in_from = FALSE, in_where = FALSE, in_table = FALSE;char in_field = FALSE, in_expr = FALSE, in_func = FALSE, in_dot = FALSE, in_as = FALSE;int j, i, k = 0, n, blevel = 0;FIELD_INFO **fi;TABLE_INFO **ti;char parse;ConnectionClass *conn = stmt->hdbc;HSTMT hcol_stmt;StatementClass *col_stmt;RETCODE result;	mylog("%s: entering...\n", func);	ptr = stmt->statement;	fi = stmt->fi;	ti = stmt->ti;	stmt->nfld = 0;	stmt->ntab = 0;	while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, &quote, &dquote, &numeric)) != NULL) {		unquoted = ! ( quote || dquote );		mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr);		if ( unquoted && ! stricmp(token, "select")) {			in_select = TRUE;			mylog("SELECT\n");			continue;		}		if ( unquoted && in_select && ! stricmp(token, "distinct")) {			in_distinct = TRUE;			mylog("DISTINCT\n");			continue;		}		if ( unquoted && ! stricmp(token, "into")) {			in_select = FALSE;			mylog("INTO\n");			continue;		}		if ( unquoted && ! stricmp(token, "from")) {			in_select = FALSE;			in_from = TRUE;			mylog("FROM\n");			continue;		}		if ( unquoted && (! stricmp(token, "where") ||			! stricmp(token, "union") || 			! stricmp(token, "order") || 			! stricmp(token, "group") || 			! stricmp(token, "having"))) {			in_select = FALSE;			in_from = FALSE;			in_where = TRUE;			mylog("WHERE...\n");			break;		}		if (in_select) {			if ( in_distinct) {				mylog("in distinct\n");				if (unquoted && ! stricmp(token, "on")) {					in_on = TRUE;					mylog("got on\n");					continue;				}				if (in_on) {					in_distinct = FALSE;					in_on = FALSE;					continue;		/*	just skip the unique on field */				}				mylog("done distinct\n");				in_distinct = FALSE;			}			if ( in_expr || in_func) {		/* just eat the expression */				mylog("in_expr=%d or func=%d\n", in_expr, in_func);				if (quote || dquote)					continue;				if (in_expr && blevel == 0 && delim == ',') {					mylog("**** in_expr and Got comma\n");					in_expr = FALSE;					in_field = FALSE;				}				else if (token[0] == '(') {					blevel++;					mylog("blevel++ = %d\n", blevel);				}				else if (token[0] == ')') {					blevel--;					mylog("blevel-- = %d\n", blevel);					if (delim==',') {						in_func = FALSE;						in_expr = FALSE;						in_field = FALSE;					}				}				continue;			}			if ( ! in_field) {				if ( ! token[0])					continue;				if ( ! (stmt->nfld % FLD_INCR)) {					mylog("reallocing at nfld=%d\n", stmt->nfld);					fi = (FIELD_INFO **) realloc(fi, (stmt->nfld + FLD_INCR) * sizeof(FIELD_INFO *));					if ( ! fi) {						stmt->parse_status = STMT_PARSE_FATAL;						return FALSE;					}					stmt->fi = fi;				}				fi[stmt->nfld] = (FIELD_INFO *) malloc( sizeof(FIELD_INFO));				if (fi[stmt->nfld] == NULL) {					stmt->parse_status = STMT_PARSE_FATAL;					return FALSE;				}				/*	Initialize the field info */				memset(fi[stmt->nfld], 0, sizeof(FIELD_INFO));				/*	double quotes are for qualifiers */				if (dquote)					fi[stmt->nfld]->dquote = TRUE;				if (quote) {					fi[stmt->nfld++]->quote = TRUE;					continue;				}				else if (numeric) {					mylog("**** got numeric: nfld = %d\n", stmt->nfld);					fi[stmt->nfld]->numeric = TRUE;				}				else if (token[0] == '(') {		/* expression */					mylog("got EXPRESSION\n");					fi[stmt->nfld++]->expr = TRUE;					in_expr = TRUE;					blevel = 1;					continue;				}				else {					strcpy(fi[stmt->nfld]->name, token);					fi[stmt->nfld]->dot[0] = '\0';				}				mylog("got field='%s', dot='%s'\n", fi[stmt->nfld]->name, fi[stmt->nfld]->dot);				if (delim == ',') {					mylog("comma (1)\n");				}				else {					in_field = TRUE;				}				stmt->nfld++;				continue;			}

⌨️ 快捷键说明

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