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

📄 swq.c

📁 mitab,读取MapInfo的地图文件
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    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 + -