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

📄 swq.c

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

            SWQ_FREE( token );
            token = swq_token( input, &input, &is_literal );
        }

        /* read an extra token to check for brackets. */
        
        select_info->result_columns++;

        next_token = swq_token( input, &input, &next_is_literal );

        /*
        ** Handle function operators.
        */
        if( !is_literal && !next_is_literal && next_token != NULL 
            && strcasecmp(next_token,"(") == 0 )
        {
            SWQ_FREE( next_token );

            swq_cols[select_info->result_columns-1].col_func_name = token;

            token = swq_token( input, &input, &is_literal );

            if( token != NULL && !is_literal 
                && strcasecmp(token,"DISTINCT") == 0 )
            {
                swq_cols[select_info->result_columns-1].distinct_flag = 1;

                SWQ_FREE( token );
                token = swq_token( input, &input, &is_literal );
            }

            swq_cols[select_info->result_columns-1].field_name = token;

            token = swq_token( input, &input, &is_literal );

            if( token == NULL || strcasecmp(token,")") != 0 )
            {
                if( token != NULL )
                    SWQ_FREE( token );
                swq_select_free( select_info );
                return "Missing closing bracket in field function.";
            }

            SWQ_FREE( token );
            token = swq_token( input, &input, &is_literal );
        }

        /*
        ** Handle simple field.
        */
        else
        {
            if( token != NULL && !is_literal 
                && strcasecmp(token,"DISTINCT") == 0 )
            {
                swq_cols[select_info->result_columns-1].distinct_flag = 1;

                SWQ_FREE( token );
                token = next_token;
                is_literal = next_is_literal;

                next_token = swq_token( input, &input, &next_is_literal );
            }
            
            swq_cols[select_info->result_columns-1].field_name = token;
            token = next_token;
            is_literal = next_is_literal;
        }
    }

    /* make a columns_def list that is just the right size. */
    select_info->column_defs = (swq_col_def *) 
        SWQ_MALLOC(sizeof(swq_col_def) * select_info->result_columns);
    memcpy( select_info->column_defs, swq_cols,
            sizeof(swq_col_def) * select_info->result_columns );
    SWQ_FREE( swq_cols );

/* -------------------------------------------------------------------- */
/*      Collect the table name from the FROM clause.                    */
/* -------------------------------------------------------------------- */
    if( token == NULL || strcasecmp(token,"FROM") != 0 )
    {
        strcpy( swq_error, "Missing FROM clause in SELECT statement." );
        swq_select_free( select_info );
        return swq_error;
    }

    SWQ_FREE( token );
    token = swq_token( input, &input, &is_literal );

    if( token == NULL )
    {
        strcpy( swq_error, "Missing table name in FROM clause." );
        swq_select_free( select_info );
        return swq_error;
    }

    if( swq_parse_table_def( select_info, &is_literal, &token, &input) != 0 )
    {
        swq_select_free( select_info );
        return swq_error;
    }

/* -------------------------------------------------------------------- */
/*      Do we have a LEFT JOIN (or just JOIN) clause?                   */
/* -------------------------------------------------------------------- */
    while( token != NULL 
        && (strcasecmp(token,"LEFT") == 0 
            || strcasecmp(token,"JOIN") == 0) )
    {
        swq_join_def *join_info;

        if( strcasecmp(token,"LEFT") == 0 )
        {
            SWQ_FREE( token );
            token = swq_token( input, &input, &is_literal );

            if( token == NULL || strcasecmp(token,"JOIN") != 0 )
            {
                strcpy( swq_error, "Missing JOIN keyword after LEFT." );
                swq_select_free( select_info );
                return swq_error;
            }
        }

        SWQ_FREE( token );
        token = swq_token( input, &input, &is_literal );
        
        /* Create join definition structure */
        select_info->join_defs = (swq_join_def *) 
            swq_realloc( select_info->join_defs, 
                         sizeof(swq_join_def) * (select_info->join_count),
                         sizeof(swq_join_def) * (select_info->join_count+1) );

        join_info = select_info->join_defs + select_info->join_count++;

        /* Parse out target table */
        join_info->secondary_table = 
            swq_parse_table_def( select_info, &is_literal, &token, &input);
        
        if( join_info->secondary_table < 0 )
        {
            swq_select_free( select_info );
            return swq_error;
        }

        /* Check for ON keyword */
        if( token == NULL )
            token = swq_token( input, &input, &is_literal );

        if( token == NULL || strcasecmp(token,"ON") != 0 )
        {
            swq_select_free( select_info );
            strcpy( swq_error,"Corrupt JOIN clause, expecting ON keyword." );
            return swq_error;
        }

        SWQ_FREE( token );

        join_info->primary_field_name = 
            swq_token( input, &input, &is_literal );
        
        token = swq_token( input, &input, &is_literal );
        if( token == NULL || strcasecmp(token,"=") != 0 )
        {
            swq_select_free( select_info );
            strcpy( swq_error,"Corrupt JOIN clause, expecting '=' condition.");
            return swq_error;
        }

        SWQ_FREE( token );

        join_info->op = SWQ_EQ;

        join_info->secondary_field_name = 
            swq_token( input, &input, &is_literal );

        if( join_info->secondary_field_name == NULL )
        {
            swq_select_free( select_info );
            strcpy( swq_error,"Corrupt JOIN clause, missing secondary field.");
            return swq_error;
        }

        token = swq_token( input, &input, &is_literal );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a WHERE clause?                                      */
/* -------------------------------------------------------------------- */
    if( token != NULL && strcasecmp(token,"WHERE") == 0 )
    {
        const char *where_base = input;

        while( *where_base == ' ' )
            where_base++;
        
        SWQ_FREE( token );
        
        token = swq_token( input, &input, &is_literal );
        while( token != NULL )
        {
            if( strcasecmp(token,"ORDER") == 0 && !is_literal )
            {
                break;
            }

            if( token != NULL )
            {
                SWQ_FREE( token );
            
                token = swq_token( input, &input, &is_literal );
            }
        }

        select_info->whole_where_clause = swq_strdup(where_base);

        if( input != NULL )
        {
            if( token != NULL )
                select_info->whole_where_clause[input - where_base - strlen(token)] = '\0';
            else
                select_info->whole_where_clause[input - where_base] = '\0';
        }
    }

/* -------------------------------------------------------------------- */
/*      Parse ORDER BY clause.                                          */
/* -------------------------------------------------------------------- */
    if( token != NULL && strcasecmp(token,"ORDER") == 0 )
    {
        SWQ_FREE( token );
        
        token = swq_token( input, &input, &is_literal );

        if( token == NULL || strcasecmp(token,"BY") != 0 )
        {
            if( token != NULL )
                SWQ_FREE( token );

            strcpy( swq_error, "ORDER BY clause missing BY keyword." );
            swq_select_free( select_info );
            return swq_error;
        }

        SWQ_FREE( token );
        token = swq_token( input, &input, &is_literal );
        while( token != NULL 
               && (select_info->order_specs == 0 
                   || strcasecmp(token,",") == 0) )
        {
            swq_order_def  *old_defs = select_info->order_defs;
            swq_order_def  *def;

            if( select_info->order_specs != 0 )
            {
                SWQ_FREE( token );
                token = swq_token( input, &input, &is_literal );
            }

            select_info->order_defs = (swq_order_def *) 
                SWQ_MALLOC(sizeof(swq_order_def)*(select_info->order_specs+1));

            if( old_defs != NULL )
            {
                memcpy( select_info->order_defs, old_defs, 
                        sizeof(swq_order_def)*select_info->order_specs );
                SWQ_FREE( old_defs );
            }

            def = select_info->order_defs + select_info->order_specs;
            def->field_name = token;
            def->field_index = 0;
            def->ascending_flag = 1;

            token = swq_token( input, &input, &is_literal );
            if( token != NULL && strcasecmp(token,"DESC") == 0 )
            {
                SWQ_FREE( token );
                token = swq_token( input, &input, &is_literal );

                def->ascending_flag = 0;
            } 
            else if( token != NULL && strcasecmp(token,"ASC") == 0 )
            {
                SWQ_FREE( token );
                token = swq_token( input, &input, &is_literal );
            }

            select_info->order_specs++;
        }
    }

/* -------------------------------------------------------------------- */
/*      If we have anything left it indicates an error!                 */
/* -------------------------------------------------------------------- */
    if( token != NULL )
    {

        sprintf( swq_error, 
                 "Failed to parse SELECT statement, extra input at %s token.", 
                 token );

        SWQ_FREE( token );
        swq_select_free( select_info );
        return swq_error;
    }

    *select_info_ret = select_info;

    return NULL;
}

/************************************************************************/
/*                        swq_parse_table_def()                         */
/*                                                                      */
/*      Supported table definition forms:                               */
/*                                                                      */
/*      <table_def> :== table_name                                      */
/*                   |  'data_source'.table_name                        */
/*                   |  table_name table_alias                          */
/*                   |  'data_source'.table_name table_alias            */
/************************************************************************/

static int swq_parse_table_def( swq_select *select_info, 
                                int *is_literal,
                                char **token, char **input )

{
    int  i;
    char *datasource = NULL;
    char *table = NULL;
    char *alias = NULL;

    if( *token == NULL )
        *token = swq_token( *input, input, is_literal );

    if( *token == NULL )
    {
        strcpy( swq_error, "Corrupt table definition, insufficient tokens." );
        return -1;
    }
    
/* -------------------------------------------------------------------- */
/*      Do we have a datasource literal?                                */
/* -------------------------------------------------------------------- */
    if( *token != NULL && *is_literal )
    {
        datasource = *token;
        *token = swq_token( *input, input, is_literal );

        if( *token == NULL )
        {
            *token = datasource;
            datasource = NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Get the table name.  Remove the '.' used to qualify it          */
/*      relative to the datasource name if found.                       */
/* -------------------------------------------------------------------- */
    if( datasource != NULL && (*token)[0] != '.' )
    {
        table = datasource;
        datasource = NULL;
    }
    else if( (*token)[0] == '.' )
    {
        table = swq_strdup( (*token) + 1 );
        SWQ_FREE( *token );
        *token = swq_token( *input, input, is_literal );
    }
    else
    {
        table = *token;
        *token = swq_token( *input, input, is_literal );
    }

/* -------------------------------------------------------------------- */
/*      Was an alias provided?                                          */
/* -------------------------------------------------------------------- */
    if( *token != NULL && ! *is_literal
        && strcasecmp(*token,"ON") != 0

⌨️ 快捷键说明

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