123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /*****************************************************************************
- *
- * MODULE: SQL statement parser library
- *
- * AUTHOR(S): lex.l and yac.y were originaly taken from unixODBC and
- * probably written by Peter Harvey <pharvey@codebydesigns.com>,
- * original modifications & added code by
- * Radim Blazek <radim.blazek gmail.com>
- * Glynn Clements <glynn gclements.plus.com>,
- * Markus Neteler <neteler itc.it>,
- * Martin Landa <landa.martin gmail.com>,
- * Moritz Lennert <mlennert club.worldonline.be>,
- * Hamish Bowman <hamish_nospam yahoo.com>,
- * Daniel Calvelo Aros <dca.gis gmail.com>,
- * Paul Kelly <paul-grass stjohnspoint.co.uk>,
- * Alex Shevlakov <sixote yahoo.com>
- *
- * PURPOSE: Parse input string containing SQL statement to
- * SQLPSTMT structure.
- * SQL parser may be used by simple database drivers.
- *
- * COPYRIGHT: (C) 2000-2007 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #define SQLP_MAIN
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
- #include <grass/sqlp.h>
- /* save string to value */
- int sqpSaveStr(SQLPVALUE *val, char *c )
- {
- int len = 0;
- len = strlen ( c ) + 1;
- val->s = (char *) realloc (val->s, len);
- strcpy ( val->s, c );
- return (1);
- }
- void
- sqpInitValue ( SQLPVALUE *val)
- {
- val->type = SQLP_NULL;
- val->s = NULL;
- val->i = 0;
- val->d = 0.0;
- }
- void
- sqpCopyValue ( SQLPVALUE *from, SQLPVALUE *to)
- {
- to->type = from->type;
-
- if ( to->s )
- free ( to->s );
-
- if ( from->s )
- to->s = strdup ( from->s );
-
- to->i = from->i;
- to->d = from->d;
- }
-
- int sqpInitParser(SQLPSTMT *st)
- {
- sqlpStmt = st;
- sqlpStmt->cur = sqlpStmt->stmt;
- sqlpStmt->errmsg[0] = '\0';
- sqlpStmt->table[0] = '\0';
- sqlpStmt->nCol = 0;
- sqlpStmt->nVal = 0;
- sqlpStmt->upperNodeptr = NULL;
- sqlpStmt->orderCol = NULL;
- return (1);
- }
- void sqpCommand( int command )
- {
- sqlpStmt->command = command;
- return;
- }
- void sqpTable( char *tbl )
- {
- strncpy (sqlpStmt->table, tbl, SQLP_MAX_TABLE );
- return;
- }
- void sqpColumn( char *col )
- {
- int i;
- i = sqlpStmt->nCol;
- sqpAllocCol(sqlpStmt, i + 1 );
- sqpSaveStr ( &(sqlpStmt->Col[i]), col );
- sqlpStmt->nCol++;
- return;
- }
- void sqpColumnDef( char *col, int type, int width, int decimals )
- {
- int i;
-
- i = sqlpStmt->nCol;
- sqpAllocCol(sqlpStmt, i + 1 );
- sqpSaveStr ( &(sqlpStmt->Col[i]), col );
- sqlpStmt->ColType[i] = type;
- sqlpStmt->ColWidth[i] = width;
- sqlpStmt->ColDecim[i] = decimals;
- sqlpStmt->nCol++;
- return;
- }
- void sqpValue( char *strval, int intval, double dblval, int type )
- {
- int i;
-
- i = sqlpStmt->nVal;
- /* allocate space for cols because if in INSERT cols were not
- * specified array for ColNum would not be allocated */
- sqpAllocCol(sqlpStmt, i + 1 );
- sqpAllocVal(sqlpStmt, i + 1 );
- sqlpStmt->Val[i].s = NULL;
- sqlpStmt->Val[i].i = 0; /* not necessay I think */
- sqlpStmt->Val[i].d = 0.0; /* not necessay I think */
-
- sqlpStmt->Val[i].type = type;
- switch ( type )
- {
- case (SQLP_S):
- sqpSaveStr ( &(sqlpStmt->Val[i]), strval );
- break;
- case (SQLP_I):
- sqlpStmt->Val[i].i = intval;
- break;
- case (SQLP_D):
- sqlpStmt->Val[i].d = dblval;
- break;
- /* SQLP_NULL, nothing to do */
- }
- sqlpStmt->nVal++;
- return;
- }
- void sqpAssignment( char *col, char *strval, int intval, double dblval, SQLPNODE *expval, int type )
- {
- int i;
-
- i = sqlpStmt->nCol;
- sqpAllocCol(sqlpStmt, i + 1 );
- sqpSaveStr ( &(sqlpStmt->Col[i]), col );
- sqpAllocVal(sqlpStmt, i + 1 );
- sqlpStmt->Val[i].s = NULL;
- sqlpStmt->Val[i].i = 0; /* not necessay I think */
- sqlpStmt->Val[i].d = 0.0; /* not necessay I think */
- sqlpStmt->Val[i].type = type;
- switch ( type )
- {
- case (SQLP_S):
- sqpSaveStr ( &(sqlpStmt->Val[i]), strval );
- break;
- case (SQLP_I):
- sqlpStmt->Val[i].i = intval;
- break;
- case (SQLP_D):
- sqlpStmt->Val[i].d = dblval;
- break;
- case (SQLP_EXPR):
- sqlpStmt->Val[i].expr = expval;
- /* Don't do anything right now; come back to this when executing */
- break;
- /* SQLP_NULL, nothing to do */
- }
- sqlpStmt->nCol++;
- sqlpStmt->nVal++;
- return;
- }
- void sqpOrderColumn( char *col, int dir )
- {
- sqlpStmt->orderCol = (char *) realloc (sqlpStmt->orderCol, strlen(col)+1);
- strcpy ( sqlpStmt->orderCol, col );
- sqlpStmt->orderDir = dir;
- return;
- }
- /* Create and init new node */
- SQLPNODE *sqpNewNode ( void )
- {
- SQLPNODE *np;
- np = (SQLPNODE *) calloc ( 1, sizeof (SQLPNODE) );
- return np;
- }
- SQLPNODE *
- sqpNewExpressionNode (int oper, SQLPNODE *left, SQLPNODE *right)
- {
- SQLPNODE *np;
- np = sqpNewNode ();
- np->node_type = SQLP_NODE_EXPRESSION;
- np->oper = oper;
- np->left = left;
- np->right = right;
- return np;
- }
- SQLPNODE *
- sqpNewColumnNode ( char *name )
- {
- SQLPNODE *np;
- np = sqpNewNode ();
- np->node_type = SQLP_NODE_COLUMN;
- np->column_name = strdup ( name );
- return np;
- }
- SQLPNODE *
- sqpNewValueNode (char *strval, int intval, double dblval, int type)
- {
- SQLPNODE *np;
- np = sqpNewNode ();
- np->node_type = SQLP_NODE_VALUE;
- np->value.type = type;
- if ( strval )
- np->value.s = strdup ( strval );
- np->value.i = intval;
- np->value.d = dblval;
- return np;
- }
- void
- sqpFreeNode ( SQLPNODE *np )
- {
- if ( !np ) return;
- if ( np->left )
- sqpFreeNode ( np->left );
- if ( np->right )
- sqpFreeNode ( np->right );
- if ( np->column_name )
- free ( np->column_name );
- if ( np->value.s )
- free ( np->value.s );
- free ( np );
- }
- int
- sqpOperatorCode( char *oper)
- {
- char *tmp, *ptr;
- /* Convert to lower case */
- tmp = strdup ( oper );
- ptr = tmp;
- while ( *ptr ) {
- *ptr = tolower ( *ptr );
- ptr++;
- }
- if ( strcmp ( oper, "=") == 0 )
- return SQLP_EQ;
- else if ( strcmp ( oper, "<") == 0 )
- return SQLP_LT;
- else if ( strcmp ( oper, "<=") == 0 )
- return SQLP_LE;
- else if ( strcmp ( oper, ">") == 0 )
- return SQLP_GT;
- else if ( strcmp ( oper, ">=") == 0 )
- return SQLP_GE;
- else if ( strcmp ( oper, "<>") == 0 )
- return SQLP_NE;
- else if ( strcmp ( oper, "~") == 0 )
- return SQLP_MTCH;
- else if ( strcmp ( oper, "+") == 0 )
- return SQLP_ADD;
- else if ( strcmp ( oper, "-") == 0 )
- return SQLP_SUBTR;
- else if ( strcmp ( oper, "*") == 0 )
- return SQLP_MLTP;
- else if ( strcmp ( oper, "/") == 0 )
- return SQLP_DIV;
- else if ( strcmp ( oper, "and") == 0 )
- return SQLP_AND;
- else if ( strcmp ( oper, "or") == 0 )
- return SQLP_OR;
- else if ( strcmp ( oper, "not") == 0 )
- return SQLP_NOT;
- free ( tmp );
-
- return 0;
- }
- char *
- sqpOperatorName( int oper )
- {
- switch ( oper ) {
- case SQLP_EQ:
- return "=";
- break;
- case SQLP_LT:
- return "<";
- break;
- case SQLP_LE:
- return "<=";
- break;
- case SQLP_GT:
- return ">";
- break;
- case SQLP_GE:
- return ">=";
- break;
- case SQLP_NE:
- return "<>";
- break;
- case SQLP_MTCH:
- return "~";
- break;
- case SQLP_ADD:
- return "+";
- break;
- case SQLP_SUBTR:
- return "-";
- break;
- case SQLP_MLTP:
- return "*";
- break;
- case SQLP_DIV:
- return "/";
- break;
- case SQLP_AND:
- return "AND";
- break;
- case SQLP_OR:
- return "OR";
- break;
- case SQLP_NOT:
- return "NOT";
- break;
- }
- return "?";
- }
|