📄 swq.c
字号:
}
op = NULL;
/*
** Are we part of an unparantized logical expression chain? If so,
** grab the remainder of the expression at "this level" and add to the
** local tree.
*/
op_code = SWQ_UNKNOWN;
if( tokens[*tokens_consumed] != NULL )
op_code = swq_identify_op( tokens, tokens_consumed );
if( SWQ_OP_IS_LOGICAL(op_code) )
{
swq_expr *remainder = NULL;
swq_expr *parent;
int sub_consumed;
error = swq_subexpr_compile( tokens + *tokens_consumed + 1, field_list,
&remainder, &sub_consumed );
if( error != NULL )
{
swq_expr_free( *expr_out );
*expr_out = NULL;
return error;
}
parent = (swq_field_op *) SWQ_MALLOC(sizeof(swq_field_op));
memset( parent, 0, sizeof(swq_field_op) );
parent->field_index = -1;
parent->first_sub_expr = (struct swq_node_s *) *expr_out;
parent->second_sub_expr = (struct swq_node_s *) remainder;
parent->operation = op_code;
*expr_out = parent;
*tokens_consumed += sub_consumed + 1;
}
return NULL;
}
/************************************************************************/
/* swq_expr_compile() */
/************************************************************************/
const char *swq_expr_compile( const char *where_clause,
int field_count,
char **field_names,
swq_field_type *field_types,
swq_expr **expr_out )
{
swq_field_list field_list;
field_list.count = field_count;
field_list.names = field_names;
field_list.types = field_types;
field_list.table_ids = NULL;
field_list.ids = NULL;
field_list.table_count = 0;
field_list.table_defs = NULL;
return swq_expr_compile2( where_clause, &field_list, expr_out );
}
/************************************************************************/
/* swq_expr_compile2() */
/************************************************************************/
const char *swq_expr_compile2( const char *where_clause,
swq_field_list *field_list,
swq_expr **expr_out )
{
#define MAX_TOKEN 1024
char *token_list[MAX_TOKEN], *rest_of_expr;
int token_count = 0;
int tokens_consumed, i;
const char *error;
/*
** Collect token array.
*/
rest_of_expr = (char *) where_clause;
while( token_count < MAX_TOKEN )
{
token_list[token_count] = swq_token(rest_of_expr,&rest_of_expr,NULL);
if( token_list[token_count] == NULL )
break;
token_count++;
}
token_list[token_count] = NULL;
/*
** Parse the expression.
*/
*expr_out = NULL;
error =
swq_subexpr_compile( token_list, field_list, expr_out,
&tokens_consumed );
for( i = 0; i < token_count; i++ )
SWQ_FREE( token_list[i] );
if( error != NULL )
return error;
if( tokens_consumed < token_count )
{
swq_expr_free( *expr_out );
*expr_out = NULL;
sprintf( swq_error, "Syntax error, %d extra tokens",
token_count - tokens_consumed );
return swq_error;
}
return NULL;
}
/************************************************************************/
/* swq_expr_free() */
/************************************************************************/
void swq_expr_free( swq_expr *expr )
{
if( expr == NULL )
return;
if( expr->first_sub_expr != NULL )
swq_expr_free( (swq_expr *) expr->first_sub_expr );
if( expr->second_sub_expr != NULL )
swq_expr_free( (swq_expr *) expr->second_sub_expr );
if( expr->string_value != NULL )
SWQ_FREE( expr->string_value );
SWQ_FREE( expr );
}
/************************************************************************/
/* swq_expr_evaluate() */
/************************************************************************/
int swq_expr_evaluate( swq_expr *expr, swq_op_evaluator fn_evaluator,
void *record_handle )
{
if( expr->operation == SWQ_OR )
{
return swq_expr_evaluate( (swq_expr *) expr->first_sub_expr,
fn_evaluator,
record_handle)
|| swq_expr_evaluate( (swq_expr *) expr->second_sub_expr,
fn_evaluator,
record_handle);
}
else if( expr->operation == SWQ_AND )
{
return swq_expr_evaluate( (swq_expr *) expr->first_sub_expr,
fn_evaluator,
record_handle)
&& swq_expr_evaluate( (swq_expr *) expr->second_sub_expr,
fn_evaluator,
record_handle);
}
else if( expr->operation == SWQ_NOT )
{
return !swq_expr_evaluate( (swq_expr *) expr->second_sub_expr,
fn_evaluator,
record_handle);
}
else
{
return fn_evaluator( expr, record_handle );
}
}
/************************************************************************/
/* swq_expr_dump() */
/************************************************************************/
void swq_expr_dump( swq_expr *expr, FILE * fp, int depth )
{
char spaces[60];
int i;
const char *op_name = "unknown";
for( i = 0; i < depth*2 && i < sizeof(spaces); i++ )
spaces[i] = ' ';
spaces[i] = '\0';
/*
** first term.
*/
if( expr->first_sub_expr != NULL )
swq_expr_dump( (swq_expr *) expr->first_sub_expr, fp, depth + 1 );
else
fprintf( fp, "%s Field %d\n", spaces, expr->field_index );
/*
** Operation.
*/
if( expr->operation == SWQ_OR )
op_name = "OR";
if( expr->operation == SWQ_AND )
op_name = "AND";
if( expr->operation == SWQ_NOT)
op_name = "NOT";
if( expr->operation == SWQ_GT )
op_name = ">";
if( expr->operation == SWQ_LT )
op_name = "<";
if( expr->operation == SWQ_EQ )
op_name = "=";
if( expr->operation == SWQ_NE )
op_name = "!=";
if( expr->operation == SWQ_GE )
op_name = ">=";
if( expr->operation == SWQ_LE )
op_name = "<=";
if( expr->operation == SWQ_LIKE )
op_name = "LIKE";
if( expr->operation == SWQ_ISNULL )
op_name = "IS NULL";
if( expr->operation == SWQ_IN )
op_name = "IN";
fprintf( fp, "%s%s\n", spaces, op_name );
/*
** Second term.
*/
if( expr->second_sub_expr != NULL )
swq_expr_dump( (swq_expr *) expr->second_sub_expr, fp, depth + 1 );
else if( expr->operation == SWQ_IN || expr->operation == SWQ_NOTIN )
{
const char *src;
fprintf( fp, "%s (\"%s\"", spaces, expr->string_value );
src = expr->string_value + strlen(expr->string_value) + 1;
while( *src != '\0' )
{
fprintf( fp, ",\"%s\"", src );
src += strlen(src) + 1;
}
fprintf( fp, ")\n" );
}
else if( expr->string_value != NULL )
fprintf( fp, "%s %s\n", spaces, expr->string_value );
}
/************************************************************************/
/* ==================================================================== */
/* SELECT statement parsing */
/* ==================================================================== */
/************************************************************************/
/*
Supported SQL Syntax:
SELECT <field-list> FROM <table_def>
[LEFT JOIN <table_def>
ON [<table_ref>.]<key_field> = [<table_ref>.].<key_field>]*
[WHERE <where-expr>]
[ORDER BY <sort specification list>]
<field-list> ::= DISTINCT <field_ref> | <field-spec>
| <field-spec> , <field-list>
<field-spec> ::= <field_ref>
| <field_func> ( [DISTINCT] <field-func> )
| Count(*)
<field-func> ::= AVG | MAX | MIN | SUM | COUNT
<field_ref> ::= [<table_ref>.]field_name
<sort specification list> ::=
<sort specification> [ { <comma> <sort specification> }... ]
<sort specification> ::= <sort key> [ <ordering specification> ]
<sort key> ::= <field_ref>
<ordering specification> ::= ASC | DESC
<table_def> ::= ['<datasource name>'.]table_name [table_alias]
<table_ref> ::= table_name | table_alias
*/
static int swq_parse_table_def( swq_select *select_info,
int *is_literal,
char **token, char **input );
/************************************************************************/
/* swq_select_preparse() */
/************************************************************************/
const char *swq_select_preparse( const char *select_statement,
swq_select **select_info_ret )
{
swq_select *select_info;
char *token;
char *input;
int is_literal;
swq_col_def *swq_cols;
#define MAX_COLUMNS 250
*select_info_ret = NULL;
/* -------------------------------------------------------------------- */
/* Get first token. Ensure it is SELECT. */
/* -------------------------------------------------------------------- */
token = swq_token( select_statement, &input, NULL );
if( strcasecmp(token,"select") != 0 )
{
SWQ_FREE( token );
strcpy( swq_error, "Missing keyword SELECT" );
return swq_error;
}
SWQ_FREE( token );
/* -------------------------------------------------------------------- */
/* allocate selection structure. */
/* -------------------------------------------------------------------- */
select_info = (swq_select *) SWQ_MALLOC(sizeof(swq_select));
memset( select_info, 0, sizeof(swq_select) );
select_info->raw_select = swq_strdup( select_statement );
/* -------------------------------------------------------------------- */
/* Allocate a big field list. */
/* -------------------------------------------------------------------- */
swq_cols = (swq_col_def *) SWQ_MALLOC(sizeof(swq_col_def) * MAX_COLUMNS);
memset( swq_cols, 0, sizeof(swq_col_def) * MAX_COLUMNS );
select_info->column_defs = swq_cols;
/* -------------------------------------------------------------------- */
/* Collect the field list, terminated by FROM keyword. */
/* -------------------------------------------------------------------- */
token = swq_token( input, &input, &is_literal );
while( token != NULL
&& (is_literal || strcasecmp(token,"FROM") != 0) )
{
char *next_token;
int next_is_literal;
if( select_info->result_columns == MAX_COLUMNS )
{
SWQ_FREE( token );
swq_select_free( select_info );
sprintf( swq_error,
"More than MAX_COLUMNS (%d) columns in SELECT statement.",
MAX_COLUMNS );
return swq_error;
}
/* Ensure that we have a comma before fields other than the first. */
if( select_info->result_columns > 0 )
{
if( strcasecmp(token,",") != 0 )
{
sprintf( swq_error,
"Missing comma after column %s in SELECT statement.",
swq_cols[select_info->result_columns-1].field_name );
SWQ_FREE( token );
swq_select_free( select_info );
return swq_error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -