📄 swq.c
字号:
/****************************************************************************** * * Component: OGDI Driver Support Library * Purpose: Generic SQL WHERE Expression Implementation. * Author: Frank Warmerdam <warmerdam@pobox.com> * ****************************************************************************** * Copyright (C) 2001 Information Interoperability Institute (3i) * * Permission to use, copy, modify and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies, that * both the copyright notice and this permission notice appear in * supporting documentation, and that the name of 3i not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. 3i makes no * representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. ****************************************************************************** * * $Log: swq.c,v $ * Revision 1.22 2003/05/21 04:49:17 warmerda * avoid warnings * * Revision 1.21 2003/03/26 16:08:20 warmerda * fixed table_def parsing when table name is quoted (literal) * * Revision 1.20 2003/03/21 03:39:10 warmerda * allow more than one LEFT JOIN per SELECT * * Revision 1.19 2003/03/19 20:26:33 warmerda * fixed memory leak for join info * * Revision 1.18 2003/03/19 05:12:08 warmerda * support table.* wildcard expansion * * Revision 1.17 2003/03/05 05:08:29 warmerda * added preliminary support for joins * * Revision 1.16 2003/01/10 15:35:24 warmerda * fixed and tested support for single quoted strings * * Revision 1.15 2002/08/08 13:41:36 warmerda * added support for single quoted string constants * * Revision 1.14 2002/04/30 18:19:01 warmerda * eat newlines as whitespace * * Revision 1.13 2002/04/29 19:32:34 warmerda * added swq_select_parse, fix problem with where parsing and sorting code * * Revision 1.12 2002/04/25 20:57:35 warmerda * expand tabs * * Revision 1.11 2002/04/25 20:45:57 warmerda * fixed some bugs with WHERE processing * * Revision 1.10 2002/04/25 19:33:23 warmerda * avoid warning * * Revision 1.9 2002/04/25 19:32:06 warmerda * added swq_select_reform_command * * Revision 1.8 2002/04/25 16:06:57 warmerda * added more general distinct support * * Revision 1.7 2002/04/25 02:23:43 warmerda * fixed support for ORDER BY <field> ASC * * Revision 1.6 2002/04/23 20:05:23 warmerda * added SELECT statement parsing * * Revision 1.5 2002/04/19 20:46:06 warmerda * added [NOT] IN, [NOT] LIKE and IS [NOT] NULL support * * Revision 1.4 2002/03/01 04:13:40 warmerda * Made swq_error static. * * Revision 1.3 2001/11/07 12:45:42 danmo * Use #ifdef _WIN32 instead of WIN32 for strcasecmp check * * Revision 1.2 2001/06/26 00:59:39 warmerda * fixed strcasecmp on WIN32 * * Revision 1.1 2001/06/19 15:46:30 warmerda * New * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "swq.h"#ifndef SWQ_MALLOC#define SWQ_MALLOC(x) malloc(x)#define SWQ_FREE(x) free(x)#endif#ifndef TRUE# define TRUE 1#endif#ifndef FALSE# define FALSE 0#endif#ifdef _WIN32# define strcasecmp stricmp#endifstatic char swq_error[1024];#define SWQ_OP_IS_LOGICAL(op) ((op) == SWQ_OR || (op) == SWQ_AND || (op) == SWQ_NOT)#define SWQ_OP_IS_POSTUNARY(op) ((op) == SWQ_ISNULL || (op) == SWQ_ISNOTNULL)/************************************************************************//* swq_free() *//************************************************************************/void swq_free( void *pMemory ){ SWQ_FREE( pMemory );}/************************************************************************//* swq_malloc() *//************************************************************************/void *swq_malloc( int nSize ){ return SWQ_MALLOC(nSize);}/************************************************************************//* swq_realloc() *//************************************************************************/void *swq_realloc( void *old_mem, int old_size, int new_size ){ void *new_mem; new_mem = swq_malloc( new_size ); if( old_mem != NULL ) { memcpy( new_mem, old_mem, old_size ); SWQ_FREE( old_mem ); } memset( ((char *) new_mem) + old_size, 0, new_size - old_size ); return new_mem;}/************************************************************************//* swq_isalphanum() *//* *//* Is the passed character in the set of things that could *//* occur in an alphanumeric token, or a number? *//************************************************************************/static int swq_isalphanum( char c ){ if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '.' || c == '+' || c == '-' || c == '_' || c == '*' ) return TRUE; else return FALSE;}/************************************************************************//* swq_token() *//************************************************************************/static char *swq_token( const char *expression, char **next, int *is_literal ){ char *token; int i_token; if( is_literal != NULL ) *is_literal = 0; while( *expression == ' ' || *expression == '\t' || *expression == 10 || *expression == 13 ) expression++; if( *expression == '\0' ) { *next = (char *) expression; return NULL; }/* -------------------------------------------------------------------- *//* Handle string constants. *//* -------------------------------------------------------------------- */ if( *expression == '"' || *expression == '\'' ) { expression++; token = (char *) SWQ_MALLOC(strlen(expression)+1); i_token = 0; while( *expression != '\0' ) { if( *expression == '\\' && expression[1] == '"' ) expression++; else if( *expression == '\\' && expression[1] == '\'' ) expression++; else if( *expression == '"' ) { expression++; break; } else if( *expression == '\'' ) { expression++; break; } token[i_token++] = *(expression++); } token[i_token] = '\0'; if( is_literal != NULL ) *is_literal = 1; }/* -------------------------------------------------------------------- *//* Handle alpha-numerics. *//* -------------------------------------------------------------------- */ else if( swq_isalphanum( *expression ) ) { token = (char *) SWQ_MALLOC(strlen(expression)+1); i_token = 0; while( swq_isalphanum( *expression ) ) { token[i_token++] = *(expression++); } token[i_token] = '\0'; }/* -------------------------------------------------------------------- *//* Handle special tokens. *//* -------------------------------------------------------------------- */ else { token = (char *) SWQ_MALLOC(3); token[0] = *expression; token[1] = '\0'; expression++; /* special logic to group stuff like '>=' into one token. */ if( (*token == '<' || *token == '>' || *token == '=' || *token == '!') && (*expression == '<' || *expression == '>' || *expression == '=')) { token[1] = *expression; token[2] = '\0'; expression++; } } *next = (char *) expression; return token;}/************************************************************************//* swq_strdup() *//************************************************************************/static char *swq_strdup( const char *input ){ char *result; result = (char *) SWQ_MALLOC(strlen(input)+1); strcpy( result, input ); return result;}/************************************************************************//* ==================================================================== *//* WHERE clause parsing *//* ==================================================================== *//************************************************************************//************************************************************************//* swq_test_like() *//* *//* Does input match pattern? *//************************************************************************/int swq_test_like( const char *input, const char *pattern ){ if( input == NULL || pattern == NULL ) return 0; while( *input != '\0' ) { if( *pattern == '\0' ) return 0; else if( *pattern == '_' ) { input++; pattern++; } else if( *pattern == '%' ) { int eat; if( pattern[1] == '\0' ) return 1; /* try eating varying amounts of the input till we get a positive*/ for( eat = 0; input[eat] != '\0'; eat++ ) { if( swq_test_like(input+eat,pattern+1) ) return 1; } return 0; } else { if( tolower(*pattern) != tolower(*input) ) return 0; else { input++; pattern++; } } } if( *pattern != '\0' && strcmp(pattern,"%") != 0 ) return 0; else return 1;}/************************************************************************//* swq_identify_op() *//************************************************************************/static swq_op swq_identify_op( char **tokens, int *tokens_consumed ){ const char *token = tokens[*tokens_consumed]; if( strcasecmp(token,"OR") == 0 ) return SWQ_OR; if( strcasecmp(token,"AND") == 0 ) return SWQ_AND; if( strcasecmp(token,"NOT") == 0 ) { if( tokens[*tokens_consumed+1] != NULL && strcasecmp(tokens[*tokens_consumed+1],"LIKE") == 0 ) { *tokens_consumed += 1; return SWQ_NOTLIKE; } else if( tokens[*tokens_consumed+1] != NULL && strcasecmp(tokens[*tokens_consumed+1],"IN") == 0 ) { *tokens_consumed += 1; return SWQ_NOTIN; } else return SWQ_NOT; } if( strcasecmp(token,"<=") == 0 ) return SWQ_LE; if( strcasecmp(token,">=") == 0 ) return SWQ_GE; if( strcasecmp(token,"=") == 0 ) return SWQ_EQ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -