1/*
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1996-2009 Oracle.  All rights reserved.
5 *
6 */
7
8#include "db_sql.h"
9
10extern void bdb_create_database(Token *, Parse *pParse);
11
12static void
13preparserSyntaxError(t, pParse)
14	Token *t;
15	Parse *pParse;
16{
17	sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", t);
18	pParse->parseError = 1;
19}
20
21/*
22 * The pre-parser is invoked for each token found by the lexical
23 * analyzer.  It passes most tokens on to the main SQLite parser
24 * unchanged; however it maintains its own state machine so that it
25 * can notice certain sequences of tokens.  In particular, it catches
26 * CREATE DATABASE, which is a sequence that the SQLite parser does
27 * not recognize.
28 */
29void preparser(pEngine, tokenType, token, pParse)
30	void *pEngine;
31	int tokenType;
32	Token token;
33	Parse *pParse;
34{
35	static enum preparserState {
36		IDLE = 0, GOT_CREATE = 1, GOT_DATABASE = 2, GOT_NAME = 3
37	} state = IDLE;
38
39	switch (state) {
40
41	    case IDLE:
42
43		if (tokenType == TK_CREATE)
44			state = GOT_CREATE;
45		else    /* pass token to sqlite parser -- the common case */
46			sqlite3Parser(pEngine, tokenType,
47				      pParse->sLastToken, pParse);
48		break;
49
50	    case GOT_CREATE:
51
52		if (tokenType == TK_DATABASE)
53			state = GOT_DATABASE;
54		else {  /* return to idle, pass the CREATE token, then
55			 * the current token to the sqlite parser */
56			state = IDLE;
57			sqlite3Parser(pEngine, TK_CREATE,
58				      pParse->sLastToken, pParse);
59			sqlite3Parser(pEngine, tokenType,
60				      pParse->sLastToken, pParse);
61		}
62		break;
63
64	    case GOT_DATABASE:
65
66		if (tokenType == TK_ID) {
67			state = GOT_NAME;
68			bdb_create_database(&token, pParse);
69		} else
70			preparserSyntaxError(&token, pParse);
71
72		break;
73
74	    case GOT_NAME:
75
76		if (tokenType == TK_SEMI)
77			state = IDLE;
78		else
79			preparserSyntaxError(&token, pParse);
80		break;
81	}
82}
83