#!/bin/sh # # This is a shell archive. To extract its contents, # execute this file with /bin/sh to create the file(s): # # Makefile sql_parser.lex test_input test_parser.c # News sql_parser.yacc # # This shell archive created: Fri Feb 4 09:30:52 EST 1994 # echo "Extracting file Makefile" sed -e 's/^X//' <<\SHAR_EOF > Makefile X################################################################ X# X# This program was developed by and for AWA Defence Industries. X# You are hereby granted the rights to copy, modify, and use X# as required any element there of. X# X# The program has no guarantee and is not supported in any way. X# X# In return for the freedom of use, we would ask that if you X# find any errors, ommissions, or improvements, that you share X# them with the author (lwaugh@awadi.com.au) and the rest of X# the network. X# X################################################################ X# X# $Id: Makefile,v 1.4 94/02/04 10:06:14 lwaugh Exp $ X# X X# Parameters. X XSCRIPT = XPROGRAM = sql_parser XSOURCES.c = test_parser.c XSOURCES.h = XSOURCES.yacc = sql_parser.yacc XSOURCES.lex = sql_parser.lex X X# Derived parameters. X XSOURCES = \ X $(SOURCES.h) \ X $(SOURCES.lex) \ X $(SOURCES.yacc) \ X $(SOURCES.c) X XTARGETS.c = \ X y.tab.c X XTARGETS = \ X $(TARGETS.c) X X XOBJECTS = \ X $(SOURCES.c:%.c=%.o) \ X $(TARGETS.c:%.c=%.o) X XLINTFILES = \ X $(SOURCES.c:%.c=%.ln) \ X $(TARGETS.c:%.c=%.ln) X X# Compiler flags. X XCC = gcc XCFLAGS += -O XCPPFLAGS += XLDFLAGS += XLDLIBS += -ll -lmp X X# Standard targets. X Xall: $(PROGRAM) Xobjects: $(SOURCES.c) $(TARGETS.c) $(OBJECTS) Xsources: $(SOURCES) Xtargets: $(SOURCES) $(TARGETS) X X$(PROGRAM): $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) X $(LINK.c) -o $@ $(OBJECTS) $(LDFLAGS) $(LDLIBS) X Xinstall: X install -m 555 $(PROGRAM) $(SCRIPT) $(AWADI)/db_tools X Xclean: X $(RM) $(PROGRAM) $(OBJECTS) $(TARGETS.c) *.BAK *.delta core *~ *.ln *.output lex.yy.c X Xy.tab.c: $(SOURCES.yacc) lex.yy.c X yacc -v $(SOURCES.yacc) X Xlex.yy.c: $(SOURCES.lex) X lex $(SOURCES.lex) X X$(PROGRAM).h: $(PROGRAM).c X @touch $@ X Xlint: X /usr/5bin/lint -n -lansic $(CPPFLAGS) $(SOURCES.c) $(TARGETS.c) SHAR_EOF if [ `wc -c < Makefile` -ne 1754 ] then echo "Lengths do not match -- Bad Copy of Makefile" fi echo "Extracting file News" sed -e 's/^X//' <<\SHAR_EOF > News XFrom: lwaugh@mulga.awadi.com.AU (Lionel Waugh) XDate: 2 Feb 1994 21:58:25 -0500 XSubject: Re: 4GL/SQL grammars XMessage-ID: <2ipp8hINNhg5@emory.mathcs.emory.edu> XReply-To: lwaugh@mulga.awadi.com.AU (Lionel Waugh) XX-Informix-List-ID: X X> X> I was working only intermittently on 4GL/SQL grammar (for X> lex/yacc), and could not get the time to really finish it. X> X> I just wondered if someone else may have implemented it already. X> Or that it may be available from Informix (fat chance). X> X XI have implemented an SQL SELECT parser using lex and yacc. It is Xcurrently in use and seems to work fine. X XI did run into problems with using yacc and distinquishing between Xlogical and expressional brackets (in the WHERE clause) - so I Xhave an additional requirement that logical brackets be enclosed Xin a set of brackets. e.g. X"SELECT .... WHERE (a = b) or (c = d)" will fail, but X"SELECT .... WHERE ((a = b) or (c = d))" will pass. X XIt may be a good starting point if you cannot find exactly what you want. X XIf you would like a copy, then drop me an email. X X _ X(_)__________________________________ X| | /| X| | Lionel Waugh (_|_____________________________ X| | Systems Analyst | / X| | AWA Defence Industries | / X| | PO Box 161 | Phone: +61 8 256 0373 / X| | Elizabeth SA 5112 | Fax: +61 8 255 9117 < X| | Australia | Email: lwaugh@awadi.com.au \ X|_|________________________________| \ X| | (______________________________\ X| | SHAR_EOF if [ `wc -c < News` -ne 1682 ] then echo "Lengths do not match -- Bad Copy of News" fi echo "Extracting file sql_parser.lex" sed -e 's/^X//' <<\SHAR_EOF > sql_parser.lex X /**************************************************************/ X /* X /* This program was developed by and for AWA Defence Industries. X /* You are hereby granted the rights to copy, modify, and use X /* as required any element there of. X /* X /* The program has no guarantee and is not supported in any way. X /* X /* In return for the freedom of use, we would ask that if you X /* find any errors, ommissions, or improvements, that you share X /* them with the author (lwaugh@awadi.com.au) and the rest of X /* the network. X /* X /**************************************************************/ X /* X /* $Id: sql_parser.lex,v 1.6 94/02/04 10:06:16 lwaugh Exp $ X /**/ X%e 900 X%p 3500 X%n 500 X%k 100 X%a 3000 X%o 3200 X%% X#.*$ ; X"database" | X"DATABASE" { strcpy(yylval.str, yytext); return(DATABASE);} X"select" | X"SELECT" { strcpy(yylval.str, yytext); return(SELECT);} X"union" | X"UNION" { strcpy(yylval.str, yytext); return(UNION);} X"from" | X"FROM" { strcpy(yylval.str, yytext); return(FROM);} X"all" | X"ALL" { strcpy(yylval.str, yytext); return(ALL);} X"distinct" | X"DISTINCT" { strcpy(yylval.str, yytext); return(DISTINCT);} X"unique" | X"UNIQUE" { strcpy(yylval.str, yytext); return(UNIQUE);} X"date" | X"DATE" { strcpy(yylval.str, yytext); return(DATE);} X"day" | X"DAY" { strcpy(yylval.str, yytext); return(DAY);} X"extend" | X"EXTEND" { strcpy(yylval.str, yytext); return(EXTEND);} X"length" | X"LENGTH" { strcpy(yylval.str, yytext); return(LENGTH);} X"mdy" | X"MDY" { strcpy(yylval.str, yytext); return(MDY);} X"month" | X"MONTH" { strcpy(yylval.str, yytext); return(MONTH);} X"weekday" | X"WEEKDAY" { strcpy(yylval.str, yytext); return(WEEKDAY);} X"year" | X"YEAR" { strcpy(yylval.str, yytext); return(YEAR);} X"avg" | X"AVG" { strcpy(yylval.str, yytext); return(AVG);} X"count" | X"COUNT" { strcpy(yylval.str, yytext); return(COUNT);} X"max" | X"MAX" { strcpy(yylval.str, yytext); return(MAX);} X"min" | X"MIN" { strcpy(yylval.str, yytext); return(MIN);} X"sum" | X"SUM" { strcpy(yylval.str, yytext); return(SUM);} X"outer" | X"OUTER" { strcpy(yylval.str, yytext); return(OUTER);} X"where" | X"WHERE" { strcpy(yylval.str, yytext); return(WHERE);} X"group by" | X"GROUP BY" { strcpy(yylval.str, yytext); return(GROUP_BY);} X"having" | X"HAVING" { strcpy(yylval.str, yytext); return(HAVING);} X"between" | X"BETWEEN" { strcpy(yylval.str, yytext); return(BETWEEN);} X"not" | X"NOT" { strcpy(yylval.str, yytext); return(NOT);} X"or" | X"OR" { strcpy(yylval.str, yytext); return(OR);} X"and" | X"AND" { strcpy(yylval.str, yytext); return(AND);} X"in" | X"IN" { strcpy(yylval.str, yytext); return(IN);} X"is" | X"IS" { strcpy(yylval.str, yytext); return(IS);} X"null" | X"NULL" { strcpy(yylval.str, yytext); return(NLL);} X"like" | X"LIKE" { strcpy(yylval.str, yytext); return(LIKE);} X"matches" | X"MATCHES" { strcpy(yylval.str, yytext); return(MATCHES);} X"order by" | X"ORDER BY" { strcpy(yylval.str, yytext); return(ORDER_BY);} X"asc" | X"ASC" { strcpy(yylval.str, yytext); return(ASC);} X"desc" | X"DESC" { strcpy(yylval.str, yytext); return(DESC);} X"current" | X"CURRENT" { strcpy(yylval.str, yytext); return(CURRENT);} X"datetime" | X"DATETIME" { strcpy(yylval.str, yytext); return(DATETIME);} X"interval" | X"INTERVAL" { strcpy(yylval.str, yytext); return(INTERVAL);} X"today" | X"TODAY" { strcpy(yylval.str, yytext); return(TODAY);} X"units" | X"UNITS" { strcpy(yylval.str, yytext); return(UNITS);} X"user" | X"USER" { strcpy(yylval.str, yytext); return(USER);} X"to" | X"TO" { strcpy(yylval.str, yytext); return(TO);} X"hour" | X"HOUR" { strcpy(yylval.str, yytext); return(HOUR);} X"minute" | X"MINUTE" { strcpy(yylval.str, yytext); return(MINUTE);} X"second" | X"SECOND" { strcpy(yylval.str, yytext); return(SECOND);} X"fraction" | X"FRACTION" { strcpy(yylval.str, yytext); return(FRACTION);} X"exists" | X"EXISTS" { strcpy(yylval.str, yytext); return(EXISTS);} X"any" | X"ANY" { strcpy(yylval.str, yytext); return(ANY);} X"some" | X"SOME" { strcpy(yylval.str, yytext); return(SOME);} X\"[^\"]+\" { strcpy(yylval.str, yytext); return(CHAR_VALUE);} X[0-9]+ | X[0-9]*\.[0-9]+ { strcpy(yylval.str, yytext); return(NUMBER_VALUE);} X[a-zA-Z]+[a-zA-Z\_0-9]* { strcpy(yylval.str, yytext); return(NAME);} X[<>]= | X"<>" | X[=<>] { strcpy(yylval.str, yytext); return(COMPARITOR);} X[\n ]+ ; X"(" { strcpy(yylval.str, yytext); return(open_bracket_type);} X")" { strcpy(yylval.str, yytext); return(close_bracket_type);} X. { return(yytext[0]);} X%% SHAR_EOF if [ `wc -c < sql_parser.lex` -ne 4520 ] then echo "Lengths do not match -- Bad Copy of sql_parser.lex" fi echo "Extracting file sql_parser.yacc" sed -e 's/^X//' <<\SHAR_EOF > sql_parser.yacc X%{ X/**************************************************************/ X/* X/* This program was developed by and for AWA Defence Industries. X/* You are hereby granted the rights to copy, modify, and use X/* as required any element there of. X/* X/* The program has no guarantee and is not supported in any way. X/* X/* In return for the freedom of use, we would ask that if you X/* find any errors, ommissions, or improvements, that you share X/* them with the author (lwaugh@awadi.com.au) and the rest of X/* the network. X/* X/**************************************************************/ X/* X/* $Id: sql_parser.yacc,v 1.7 94/02/04 10:06:19 lwaugh Exp $ X/**/ X#include X#include X#include X Xchar where_having[7]; Xint open_bracket_type; Xint close_bracket_type; X X%} X%start sql X%union { X char str[1024]; X } X%token CHAR_VALUE NUMBER_VALUE NAME COMPARITOR X%token DATABASE SELECT FROM ALL DISTINCT UNIQUE DATE DAY EXTEND LENGTH MDY MONTH X%token WEEKDAY YEAR AVG COUNT MAX MIN SUM OUTER WHERE GROUP_BY HAVING BETWEEN X%token NOT OR AND IS NLL LIKE MATCHES ORDER_BY ASC DESC IN UNION EXISTS ANY SOME X%token CURRENT DATETIME INTERVAL TODAY UNITS USER TO HOUR MINUTE SECOND FRACTION X%token LOG_OP_BRAC EXP_OP_BRAC CLOSE_BRACKET X%right '=' X%left '+' '-' X%left '*' '/' X%left POWER X%left UMINUS X%% X/* rules */ Xsql : statement X | sql ';' statement X ; Xstatement : /* empty */ X { strcpy($$, "");} X | mselect_stmt X | database_stmt X ; Xdatabase_stmt : DATABASE dbase_name X { printf("DATABASE:%s\n", $2); } X ; Xdbase_name : NAME X | CHAR_VALUE X ; Xmselect_stmt : select_stmt X | mselect_stmt UNION X { X printf("UNION:\n"); X strcpy($$, ""); X } X select_stmt X | mselect_stmt UNION ALL X { X printf("UNION_ALL:\n"); X strcpy($$, ""); X } X select_stmt X ; Xselect_stmt : SELECT X { X open_bracket_type = EXP_OP_BRAC; X close_bracket_type = CLOSE_BRACKET; X printf("SELECT:\n"); X strcpy($$, ""); X } X sel_restrict X { X if (strcmp($3, "")) printf("RESTRICT:%s\n", $3); X strcpy($$, ""); X } X select_list FROM table_list restrict order X ; Xsel_restrict : /* empty */ X { strcpy($$, "");} X | ALL X | DISTINCT X | UNIQUE X ; Xselect_list : select_item X | select_list ',' select_item X ; Xselect_item : field X | '*' X { X printf("FIELD:*\n"); X } X | NAME '.' '*' X { X sprintf($$, "%s.*", $1); X printf("FIELD:%s\n", $$); X } X ; Xfield : expr X { printf("FIELD:%s\n", $1); } X | expr NAME X { X printf("FIELD:%s\n", $1); X printf("FIELD_ALIAS:%s\n", $2); X sprintf($$, "%s %s", $1, $2); X } X ; Xcolname : NAME X | NAME '.' NAME X { X sprintf($$, "%s.%s", $1, $3); X } X ; Xtable_list : table_name X | table_list ',' table_name X ; Xtable_name : NAME X { printf("TABLE:%s\n", $1); } X | NAME NAME X { X printf("TABLE:%s\n", $1); X printf("TABLE_ALIAS:%s\n", $2); X sprintf($$, "%s %s", $1, $2); X } X | OUTER NAME X { X printf("TABLE_OUTER:%s\n", $2); X sprintf($$, "outer %s", $2); X } X | OUTER NAME NAME X { X printf("TABLE_OUTER:%s\n", $2); X printf("TABLE_ALIAS:%s\n", $3); X sprintf($$, "outer %s %s", $2, $3); X } X ; Xrestrict : /* empty */ X { strcpy($$, "");} X | WHERE X { X open_bracket_type = LOG_OP_BRAC; X sprintf(where_having, "WHERE"); X strcpy($$, ""); X } X conditions restrict X | GROUP_BY columns_list restrict X | HAVING X { X open_bracket_type = LOG_OP_BRAC; X sprintf(where_having, "HAVING"); X strcpy($$, ""); X } X conditions X ; Xconditions : LOG_OP_BRAC X { X open_bracket_type = EXP_OP_BRAC; X printf("%s:(\n", where_having); X strcpy($$, ""); X } X conditions CLOSE_BRACKET X { X printf("%s:)\n", where_having); X open_bracket_type = LOG_OP_BRAC; X } X | conditions relop X { X printf("%s:%s\n", where_having, $2); X strcpy($$, ""); X } X conditions X | NOT X { X printf("%s:%s\n", where_having, $1); X strcpy($$, ""); X } X conditions X | condition X { printf("%s:%s\n", where_having, $1); } X ; Xrelop : AND X | OR X ; Xcondition : expr COMPARITOR subqcomp EXP_OP_BRAC X { X printf("SUBQUERY:START\n"); X strcpy($$, ""); X } X select_stmt X { X printf("SUBQUERY:END\n"); X strcpy($$, ""); X } X CLOSE_BRACKET X { X sprintf($$, "%s %s %s (SUBQUERY)", $1, $2, $3); X } X | expr COMPARITOR EXP_OP_BRAC X { X printf("SUBQUERY:START\n"); X strcpy($$, ""); X } X select_stmt X { X printf("SUBQUERY:END\n"); X strcpy($$, ""); X } X CLOSE_BRACKET X { X sprintf($$, "%s %s (SUBQUERY)", $1, $2); X } X | expr COMPARITOR expr X { X sprintf($$, "%s %s %s", $1, $2, $3); X } X | expr modifier LIKE CHAR_VALUE X { X if (strcmp($2, "")) X sprintf($$, "%s not like %s", $1, $4); X else X sprintf($$, "%s like %s", $1, $4); X } X | expr modifier MATCHES CHAR_VALUE X { X if (strcmp($2, "")) X sprintf($$, "%s not matches %s", $1, $4); X else X sprintf($$, "%s matches %s", $1, $4); X } X | expr modifier BETWEEN expr AND expr X { X if (strcmp($2, "")) X sprintf($$, "%s not between %s and %s", $1, $4, $6); X else X sprintf($$, "%s between %s and %s", $1, $4, $6); X } X | expr modifier IN EXP_OP_BRAC value_list CLOSE_BRACKET X { X if (strcmp($2, "")) X sprintf($$, "%s not in (%s)", $1, $5); X else X sprintf($$, "%s in (%s)", $1, $5); X } X | expr modifier IN EXP_OP_BRAC X { X printf("SUBQUERY:START\n"); X strcpy($$, ""); X } X select_stmt X { X printf("SUBQUERY:END\n"); X strcpy($$, ""); X } X CLOSE_BRACKET X { X if (strcmp($2, "")) X sprintf($$, "%s not in (SUBQUERY)", $1); X else X sprintf($$, "%s in (SUBQUERY)", $1); X } X | expr IS modifier NLL X { X if (strcmp($3, "")) X sprintf($$, "%s is not null", $1); X else X sprintf($$, "%s is null", $1); X } X | modifier EXISTS EXP_OP_BRAC X { X printf("SUBQUERY:START\n"); X strcpy($$, ""); X } X select_stmt X { X printf("SUBQUERY:END\n"); X strcpy($$, ""); X } X CLOSE_BRACKET X { X if (strcmp($2, "")) X sprintf($$, "not exists (SUBQUERY)", $1); X else X sprintf($$, "exists (SUBQUERY)", $1); X } X ; Xvalue_list : expr X | value_list ',' expr X { X sprintf($$, "%s,%s", $1, $3); X } X ; Xmodifier : /* empty */ X { strcpy($$, "");} X | NOT X ; Xsubqcomp : ALL X | ANY X | SOME X ; Xcolumns_list : column_list X { printf("GROUP_BY:%s\n", $1);} X | columns_list ',' column_list X { printf("GROUP_BY:%s\n", $3);} X ; Xcolumn_list : NAME X | NAME '.' NAME X { X sprintf($$, "%s.%s", $1, $3); X } X | NUMBER_VALUE X ; Xorder : /* empty */ X { strcpy($$, "");} X | ORDER_BY orders_list X { X sprintf($$, "order by %s", $2); X } X ; Xorders_list : order_list X { printf("ORDER_BY:%s\n", $1);} X | orders_list ',' order_list X { printf("ORDER_BY:%s\n", $3);} X ; Xorder_list : NAME X | NAME '.' NAME X { X sprintf($$, "%s.%s", $1, $3); X } X | NUMBER_VALUE X | order_list ASC X { X sprintf($$, "%s asc", $1); X } X | order_list DESC X { X sprintf($$, "%s desc", $1); X } X ; Xexpr : EXP_OP_BRAC expr CLOSE_BRACKET X { X sprintf($$, "(%s)", $2); X } X | expr '+' expr X { X sprintf($$, "%s+%s", $1, $3); X } X | expr '-' expr X { X sprintf($$, "%s-%s", $1, $3); X } X | expr '*' '*' expr %prec POWER X { X sprintf($$, "%s**%s", $1, $4); X } X | expr '*' expr X { X sprintf($$, "%s*%s", $1, $3); X } X | expr '/' expr X { X sprintf($$, "%s/%s", $1, $3); X } X | colname X | CHAR_VALUE X | '-' NUMBER_VALUE %prec UMINUS X { X sprintf($$, "-%s", $2); X } X | NUMBER_VALUE X | function EXP_OP_BRAC expr CLOSE_BRACKET X { X sprintf($$, "%s(%s)", $1, $3); X } X | aggregate EXP_OP_BRAC agg_restrict expr CLOSE_BRACKET X { X if (strcmp($3, "")) X { X sprintf($$, "%s(%s %s)", $1, $3, $4); X } X else X { X sprintf($$, "%s(%s)", $1, $4); X } X } X | COUNT EXP_OP_BRAC agg_restrict expr CLOSE_BRACKET X { X if (strcmp($3, "")) X { X sprintf($$, "%s(%s %s)", $1, $3, $4); X } X else X { X sprintf($$, "%s(%s)", $1, $4); X } X } X | COUNT EXP_OP_BRAC '*' CLOSE_BRACKET X { X sprintf($$, "count(*)"); X } X | CURRENT dtime_range X { X sprintf($$, "current %s", $2); X } X | CURRENT X | DATE X | DATETIME EXP_OP_BRAC dtime_value CLOSE_BRACKET dtime_range X { X sprintf($$, "datetime (%s) %s", $3, $5); X } X | EXTEND EXP_OP_BRAC expr ',' dtime_range CLOSE_BRACKET X { X sprintf($$, "extend (%s,%s)", $3, $5); X } X | EXTEND EXP_OP_BRAC expr CLOSE_BRACKET X { X sprintf($$, "extend (%s)", $3); X } X | INTERVAL EXP_OP_BRAC dtime_value CLOSE_BRACKET dtime_range X { X sprintf($$, "interval (%s) %s", $3, $5); X } X | MDY EXP_OP_BRAC expr ',' expr ',' expr CLOSE_BRACKET X { X sprintf($$, "mdy(%s,%s,%s)", $3, $5, $7); X } X | TODAY X | NUMBER_VALUE UNITS dtime_unit X { X sprintf($$, "%s units %s", $1, $3); X } X | USER X | colname '[' NUMBER_VALUE ',' NUMBER_VALUE ']' X { X sprintf($$, "%s[%s,%s]", $1,$3,$5); X } X ; Xfunction : DATE X | DAY X | LENGTH X | MONTH X | WEEKDAY X | YEAR X ; Xaggregate : AVG X | MAX X | MIN X | SUM X ; Xagg_restrict : /* empty */ X { strcpy($$, "");} X | ALL X | DISTINCT X | UNIQUE X ; Xdtime_range : dtime_unit EXP_OP_BRAC NUMBER_VALUE CLOSE_BRACKET TO dtime_unit X { X sprintf($$, "%s(%s) to %s", $1, $3, $5); X } X | dtime_unit TO dtime_unit X { X sprintf($$, "%s to %s", $1, $3); X } X ; Xdtime_unit : YEAR X | MONTH X | DAY X | HOUR X | MINUTE X | SECOND X | FRACTION EXP_OP_BRAC NUMBER_VALUE CLOSE_BRACKET X { X sprintf($$, "fraction(%s)", $3); X } X | FRACTION X ; Xdtime_value : date_value time_value X { X sprintf($$, "%s %s", $1, $2); X } X | date_value X | time_value X ; Xdate_value : NUMBER_VALUE '-' NUMBER_VALUE '-' NUMBER_VALUE X { X sprintf($$, "%s-%s-%s", $1, $3, $5); X } X | NUMBER_VALUE '-' NUMBER_VALUE X { X sprintf($$, "%s-%s", $1, $3); X } X | NUMBER_VALUE X ; Xtime_value : NUMBER_VALUE ':' NUMBER_VALUE ':' NUMBER_VALUE X { X sprintf($$, "%s:%s:%s", $1, $3, $5); X } X | NUMBER_VALUE ':' NUMBER_VALUE X { X sprintf($$, "%s:%s", $1, $3); X } X | NUMBER_VALUE X ; X%% X/* programmer routines */ X# include "lex.yy.c" SHAR_EOF if [ `wc -c < sql_parser.yacc` -ne 11633 ] then echo "Lengths do not match -- Bad Copy of sql_parser.yacc" fi echo "Extracting file test_input" sed -e 's/^X//' <<\SHAR_EOF > test_input Xdatabase a; Xdatabase "a"; Xselect unique a from b; Xselect all a from b; Xselect distinct a from b; Xselect a from b; Xselect (a + c) from b; Xselect a e from b; Xselect (a - b)*c from d; Xselect (a * b)**c e from d; Xselect a, b from c; Xselect a, b e from c; Xselect a from outer c; Xselect a from outer c d; Xselect a from c d; Xselect a from c,d; Xselect a from c,outer d; Xselect a from c,d e; Xselect a from b where c = d; Xselect a from b where c=d or e=f; Xselect a from b where (c=d or e=f) and g=h; Xselect a from b where (c=d or e=f) and (g=h or i=j); Xselect a from b where not a=b; Xselect a from b where not a=b or c=d; Xselect a from b where not (a=b or c=d); Xselect a from b where ((a+b)*c > 5 and g=h); Xselect a from b where ((a+b)*c > 5 or g=h) and i=j; Xselect a from b where ((a+b)*c > 5 or g=h) and (i=j); Xselect a from b where ((a+b)*c > 5 or g=h) and (i=j or k=l); Xselect a from b where ((a+b)*c > 5 or g=h) and ((a+b)**c < 3); Xselect a from b where not a=b; Xselect a from b where not (a=b or c=d); Xselect a from b where (not a=b) or not (c=d or h=g); Xselect a from b group by a; Xselect a from b where a = b group by c; Xselect a from b group by a,b,c; Xselect a from b having c = d; Xselect a from b where ((a+b)*c > 3) having c = d; Xselect a from b where a=b group by 1 having c = d; Xselect a from b having c=d or e=f; Xselect a from b having (c=d or e=f) and g=h; Xselect a from b having (c=d or e=f) and (g=h or i=j); Xselect a from b having not a=b; Xselect a from b having not a=b or c=d; Xselect a from b having not (a=b or c=d); Xselect a from b having ((a+b)*c > 5 and g=h); Xselect a from b having ((a+b)*c > 5 or g=h) and i=j; Xselect a from b having ((a+b)*c > 5 or g=h) and (i=j); Xselect a from b having ((a+b)*c > 5 or g=h) and (i=j or k=l); Xselect a from b where ((a+b)*c > 5 or g=h) and ((a+b)**c < 3) having ((a+b)*c > 5 or g=h) and ((a+b)**c < 3); Xselect a from b having not a=b; Xselect a from b having not (a=b or c=d); Xselect a from b having (not a=b) or not (c=d or h=g); Xselect a from b order by 1; Xselect a from b where a = b order by c; Xselect a from b order by a,b,c; Xselect a from b order by a desc,b asc,c; Xselect a from b union select c from d; Xselect a from b union all select c from d; Xselect a from b where c=d; Xselect a from b where c<>d; Xselect a from b where cd; Xselect a from b where c>=d; Xselect a from b where a between c and d; Xselect a from b where a not between c and d; Xselect a from b where (a in (b,c,d)); Xselect a from b where (a not in (b,c,d)); Xselect a from b where (a in (select c from d)); Xselect a from b where (a not in (select c from d)); Xselect a from b where a like "b"; Xselect a from b where a not like "b"; Xselect a from b where a matches "b"; Xselect a from b where a not matches "b"; Xselect a from b where a is null; Xselect a from b where a is not null; Xselect a from b where (a > (select b from c)); Xselect a from b where (a < all (select b from c)); Xselect a from b where (a <= any (select b from c)); Xselect a from b where (a >= some (select b from c)); Xselect a from b where (exists (select b from c)); Xselect a from b where (not exists (select b from c)); Xselect current, current day to year, date, date(a), day(a), extend(a), extend(a,day to year), length(a), mdy(a,b,c), month(a), today, 5 units year, user, weekday(a), year(a) from b; Xselect avg(a), count(a), max(a), min(a), sum(a) from b; Xselect avg(distinct a), count(unique a), max(all a), min(distinct a), sum(unique a) from b; Xselect * from b; Xselect a.* from b; Xselect count(*) from b; Xselect avg((a+b)*c) from b; Xselect a + 5 units day from b; Xselect a from b where a - b > 30 units day; Xselect datetime (89-8-16 14:26:0.345) year to fraction(3) from b; Xselect -3 * 5 + 2 from b; SHAR_EOF if [ `wc -c < test_input` -ne 3747 ] then echo "Lengths do not match -- Bad Copy of test_input" fi echo "Extracting file test_parser.c" sed -e 's/^X//' <<\SHAR_EOF > test_parser.c X/**************************************************************/ X/* X/* This program was developed by and for AWA Defence Industries. X/* You are hereby granted the rights to copy, modify, and use X/* as required any element there of. X/* X/* The program has no guarantee and is not supported in any way. X/* X/* In return for the freedom of use, we would ask that if you X/* find any errors, ommissions, or improvements, that you share X/* them with the author (lwaugh@awadi.com.au) and the rest of X/* the network. X/* X/**************************************************************/ X/* X/* $Id: test_parser.c,v 1.3 94/02/04 10:06:21 lwaugh Exp $ X/**/ X#include X Xextern int yydebug; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X/* yydebug = 1; X/**/ X X if ((argc > 1) && (!strcmp(argv[1],"-h"))) X { X printf("\n"); X printf("Usage: %s out_file\n", argv[0]); X printf("\n"); X printf(" This programs parses SQL syntax returning the elements of SELECT\n"); X printf(" and DATABASE statements. Output is in the form '{Token}:{Value}\\n'.\n"); X printf("\n"); X printf(" Token Value\n"); X printf(" DATABASE Name of database\n"); X printf(" UNION No value\n"); X printf(" UNION_ALL No value\n"); X printf(" SELECT No value\n"); X printf(" RESTRICT { all | distinct | unique }\n"); X printf(" FIELD Field expression\n"); X printf(" FIELD_ALIAS Field alias name\n"); X printf(" TABLE Table name\n"); X printf(" TABLE_ALIAS Table alias name\n"); X printf(" TABLE_OUTER Outer table name\n"); X printf(" WHERE { ( | ) | NOT | AND | OR | expression }\n"); X printf(" HAVING { ( | ) | NOT | AND | OR | expression }\n"); X printf(" SUBQUERY { START | END }\n"); X printf(" GROUP_BY Group column name\n"); X printf(" ORDER_BY Order column name\n"); X printf("\n"); X printf(" ERROR Error message that occurred\n"); X printf("\n"); X X return; X } X X return(yyparse()); X} X Xyyerror(s) Xchar *s; X{ X fprintf(stdout, "ERROR:%s\n", s); X} SHAR_EOF if [ `wc -c < test_parser.c` -ne 2074 ] then echo "Lengths do not match -- Bad Copy of test_parser.c" fi echo "Done." exit 0