UnQL

Check-in [fb25f79d0f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Begin adding code to perform queries. Compiles and links, but probably does not work. This is code from a few days ago that I am just now coming back to work on again.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fb25f79d0f843c124afc1a81ecb688685e2d0951
User & Date: drh 2011-06-21 17:10:22
Context
2011-06-21
17:31
Rename TABLE to DATASET. check-in: b854a47a54 user: drh tags: trunk
17:10
Begin adding code to perform queries. Compiles and links, but probably does not work. This is code from a few days ago that I am just now coming back to work on again. check-in: fb25f79d0f user: drh tags: trunk
2011-06-14
18:47
Get INSERT working. Improved error messages. check-in: c9b9b54e59 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to main.mk.

36
37
38
39
40
41
42

43
44
45
46
47
48
49
50

# Object files for the SQLite library.
#
LIBOBJ+= complete.o conn.o context.o
LIBOBJ+= json.o
LIBOBJ+= memory.o
LIBOBJ+= parse.o

LIBOBJ+= sqlite3.o stmt.o string.o
LIBOBJ+= tokenize.o trace.o

# All of the source code files.
#
SRC = \
  $(TOP)/src/parse.y 








>
|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# Object files for the SQLite library.
#
LIBOBJ+= complete.o conn.o context.o
LIBOBJ+= json.o
LIBOBJ+= memory.o
LIBOBJ+= parse.o
LIBOBJ+= query.o
LIBOBJ+= scan.o sqlite3.o stmt.o string.o
LIBOBJ+= tokenize.o trace.o

# All of the source code files.
#
SRC = \
  $(TOP)/src/parse.y 

Added src/query.c.



























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
** Copyright (c) 2011 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains code used to implement query processing.
*/
#include "xjd1Int.h"

/*
** Called after statement parsing to initalize every Query object
** within the statement.
*/
int xjd1QueryInit(xjd1_stmt *pStmt, Query *pQuery){
  if( pQuery==0 ) return XJD1_OK;
  pQuery->pStmt = pStmt;
  if( pQuery->eQType==TK_SELECT ){
    xjd1ScannerInit(pQuery, pQuery->u.simple.pFrom);
  }else{
    xjd1QueryInit(pStmt, pQuery->u.compound.pLeft);
    xjd1QueryInit(pStmt, pQuery->u.compound.pRight);
  }
  return XJD1_OK;
}

/*
** Rewind a query so that it is pointing at the first row.
*/
int xjd1QueryRewind(Query *pQuery){
  if( pQuery==0 ) return XJD1_OK;
  if( pQuery->eQType==TK_SELECT ){
    xjd1ScannerRewind(pQuery->u.simple.pFrom);
  }else{
    xjd1QueryRewind(pQuery->u.compound.pLeft);
    xjd1QueryRewind(pQuery->u.compound.pRight);
  }
  return XJD1_OK;
}

/*
** Advance a query to the next row.
*/
int xjd1QueryStep(Query *pQuery){
  if( pQuery==0 ) return XJD1_OK;
  if( pQuery->eQType==TK_SELECT ){
    /* TBD */
  }else{
    /* TBD */
  }
  return XJD1_OK;
}

/*
** The destructor for a Query object.
*/
int xjd1QueryClose(Query *pQuery){
  int rc = XJD1_OK;
  if( pQuery==0 ) return rc;
  if( pQuery->eQType==TK_SELECT ){
    xjd1ScannerClose(pQuery->u.simple.pFrom);
  }else{
    xjd1QueryClose(pQuery->u.compound.pLeft);
    xjd1QueryClose(pQuery->u.compound.pRight);
  }
  return rc;
}

Added src/scan.c.











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
** Copyright (c) 2011 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains code used to scan a data source during a query.
*/
#include "xjd1Int.h"

int xjd1ScannerInit(Query *pQuery, DataSrc *pDSrc){
  if( pDSrc==0 ) return XJD1_OK;
  pDSrc->pQuery = pQuery;
  return XJD1_OK;
}
int xjd1ScannerEOF(DataSrc *pDSrc){
  return 1;
}
int xjd1ScannerStep(DataSrc *pDSrc){
  return XJD1_DONE;
}
int xjd1ScannerRewind(DataSrc *pDSrc){
  return XJD1_OK;
}
int xjd1ScannerClose(DataSrc *pDSrc){
  return XJD1_OK;
}

Changes to src/stmt.c.

22
23
24
25
26
27
28


29
30
31
32
33
34
35
36
37
38
39














40
41
42
43
44
45
46
47
48
49
50
51
52

53
54
55















56
57
58
59
60
61
62
...
140
141
142
143
144
145
146




147
148
149
150
151
152
153
154













155
156
157
158
159
160
161
** Create a new prepared statement for database connection pConn.  The
** program code to be parsed is zStmt.  Return the new statement in *ppNew.
** Write the number of zStmt bytes read into *pN.
*/
int xjd1_stmt_new(xjd1 *pConn, const char *zStmt, xjd1_stmt **ppNew, int *pN){
  xjd1_stmt *p;
  int dummy;



  *pN = strlen(zStmt);
  *ppNew = p = malloc( sizeof(*p) );
  if( p==0 ) return XJD1_NOMEM;
  memset(p, 0, sizeof(*p));
  p->pConn = pConn;
  p->pNext = pConn->pStmt;
  pConn->pStmt = p;
  p->zCode = xjd1PoolDup(&p->sPool, zStmt, -1);
  if( pN==0 ) pN = &dummy;
  return xjd1RunParser(pConn, p, p->zCode, pN);














}

/*
** Configure a prepared statement.
*/
int xdj1_stmt_config(xjd1_stmt *pStmt, int op, ...){
  return XJD1_UNKNOWN;
}

/*
** Delete a prepared statement.
*/
int xjd1_stmt_delete(xjd1_stmt *pStmt){

  if( pStmt==0 ) return XJD1_OK;
  pStmt->isDying = 1;
  if( pStmt->nRef>0 ) return XJD1_OK;















  if( pStmt->pPrev ){
    pStmt->pPrev->pNext = pStmt->pNext;
  }else{
    assert( pStmt->pConn->pStmt==pStmt );
    pStmt->pConn->pStmt = pStmt->pNext;
  }
  if( pStmt->pNext ){
................................................................................
        xjd1Error(pStmt->pConn, XJD1_ERROR, "%s", zErr);
        sqlite3_free(zErr);
        rc = XJD1_ERROR;
      }
      sqlite3_free(zSql);
      break;
    }




  }
  return rc;
}

/*
** Rewind a prepared statement back to the beginning.
*/
int xjd1_stmt_rewind(xjd1_stmt *pStmt){













  return XJD1_OK;
}

/*
** Return the output value of a prepared statement resulting from
** its most recent xjd1_stmt_step() call.
*/







>
>










|
>
>
>
>
>
>
>
>
>
>
>
>
>
>













>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
** Create a new prepared statement for database connection pConn.  The
** program code to be parsed is zStmt.  Return the new statement in *ppNew.
** Write the number of zStmt bytes read into *pN.
*/
int xjd1_stmt_new(xjd1 *pConn, const char *zStmt, xjd1_stmt **ppNew, int *pN){
  xjd1_stmt *p;
  int dummy;
  Command *pCmd;
  int rc;

  *pN = strlen(zStmt);
  *ppNew = p = malloc( sizeof(*p) );
  if( p==0 ) return XJD1_NOMEM;
  memset(p, 0, sizeof(*p));
  p->pConn = pConn;
  p->pNext = pConn->pStmt;
  pConn->pStmt = p;
  p->zCode = xjd1PoolDup(&p->sPool, zStmt, -1);
  if( pN==0 ) pN = &dummy;
  rc = xjd1RunParser(pConn, p, p->zCode, pN);
  pCmd = p->pCmd;
  if( pCmd ){
    switch( pCmd->eCmdType ){
      case TK_SELECT: {
        xjd1QueryInit(p, pCmd->u.q.pQuery);
        break;
      }
      case TK_INSERT: {
        xjd1QueryInit(p, pCmd->u.ins.pQuery);
        break;
      }
    }
  }
  return rc;
}

/*
** Configure a prepared statement.
*/
int xdj1_stmt_config(xjd1_stmt *pStmt, int op, ...){
  return XJD1_UNKNOWN;
}

/*
** Delete a prepared statement.
*/
int xjd1_stmt_delete(xjd1_stmt *pStmt){
  Command *pCmd;
  if( pStmt==0 ) return XJD1_OK;
  pStmt->isDying = 1;
  if( pStmt->nRef>0 ) return XJD1_OK;

  pCmd = pStmt->pCmd;
  if( pCmd ){
    switch( pCmd->eCmdType ){
      case TK_SELECT: {
        xjd1QueryClose(pCmd->u.q.pQuery);
        break;
      }
      case TK_INSERT: {
        xjd1QueryClose(pCmd->u.ins.pQuery);
        break;
      }
    }
  }

  if( pStmt->pPrev ){
    pStmt->pPrev->pNext = pStmt->pNext;
  }else{
    assert( pStmt->pConn->pStmt==pStmt );
    pStmt->pConn->pStmt = pStmt->pNext;
  }
  if( pStmt->pNext ){
................................................................................
        xjd1Error(pStmt->pConn, XJD1_ERROR, "%s", zErr);
        sqlite3_free(zErr);
        rc = XJD1_ERROR;
      }
      sqlite3_free(zSql);
      break;
    }
    case TK_SELECT: {
      rc = xjd1QueryStep(pStmt->pCmd->u.q.pQuery);
      break;
    }
  }
  return rc;
}

/*
** Rewind a prepared statement back to the beginning.
*/
int xjd1_stmt_rewind(xjd1_stmt *pStmt){
  Command *pCmd = pStmt->pCmd;
  if( pCmd ){
    switch( pCmd->eCmdType ){
      case TK_SELECT: {
        xjd1QueryRewind(pCmd->u.q.pQuery);
        break;
      }
      case TK_INSERT: {
        xjd1QueryRewind(pCmd->u.ins.pQuery);
        break;
      }
    }
  }
  return XJD1_OK;
}

/*
** Return the output value of a prepared statement resulting from
** its most recent xjd1_stmt_step() call.
*/

Changes to src/xjd1Int.h.

154
155
156
157
158
159
160

161
162
163
164
165
166
167
...
176
177
178
179
180
181
182

183
184
185
186
187
188
189
...
275
276
277
278
279
280
281















282
283
284
285
286
287
288
  int errCode;                    /* Error code */
  String errMsg;                  /* Error message string */
};

/* A query statement */
struct Query {
  int eQType;                   /* Query type */

  union {
    struct {                    /* For compound queries */
      Query *pLeft;               /* Left subquery */
      Query *pRight;              /* Righ subquery */
    } compound;
    struct {                    /* For simple queries */
      ExprList *pCol;             /* List of result columns */
................................................................................
  } u;
};

/* A Data Source is a representation of a term out of the FROM clause. */
struct DataSrc {
  int eDSType;              /* Source type */
  Token asId;               /* The identifier after the AS keyword */

  union {
    struct {                /* For a join.  eDSType==TK_COMMA */
      DataSrc *pLeft;          /* Data source on the left */
      DataSrc *pRight;         /* Data source on the right */
    } join;
    struct {                /* For a named table.  eDSType==TK_ID */
      Token name;              /* The table name */
................................................................................
/******************************** malloc.c ***********************************/
Pool *xjd1PoolNew(void);
void xjd1PoolClear(Pool*);
void xjd1PoolDelete(Pool*);
void *xjd1PoolMalloc(Pool*, int);
void *xjd1PoolMallocZero(Pool*, int);
char *xjd1PoolDup(Pool*, const char *, int);
















/******************************** string.c ***********************************/
int xjd1Strlen30(const char *);
void xjd1StringInit(String*, Pool*, int);
String *xjd1StringNew(Pool*, int);
int xjd1StringAppend(String*, const char*, int);
#define xjd1StringText(S)      ((S)->zBuf)







>







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  int errCode;                    /* Error code */
  String errMsg;                  /* Error message string */
};

/* A query statement */
struct Query {
  int eQType;                   /* Query type */
  xjd1_stmt *pStmt;             /* Statement this query is part of */
  union {
    struct {                    /* For compound queries */
      Query *pLeft;               /* Left subquery */
      Query *pRight;              /* Righ subquery */
    } compound;
    struct {                    /* For simple queries */
      ExprList *pCol;             /* List of result columns */
................................................................................
  } u;
};

/* A Data Source is a representation of a term out of the FROM clause. */
struct DataSrc {
  int eDSType;              /* Source type */
  Token asId;               /* The identifier after the AS keyword */
  Query *pQuery;            /* Query this data source services */
  union {
    struct {                /* For a join.  eDSType==TK_COMMA */
      DataSrc *pLeft;          /* Data source on the left */
      DataSrc *pRight;         /* Data source on the right */
    } join;
    struct {                /* For a named table.  eDSType==TK_ID */
      Token name;              /* The table name */
................................................................................
/******************************** malloc.c ***********************************/
Pool *xjd1PoolNew(void);
void xjd1PoolClear(Pool*);
void xjd1PoolDelete(Pool*);
void *xjd1PoolMalloc(Pool*, int);
void *xjd1PoolMallocZero(Pool*, int);
char *xjd1PoolDup(Pool*, const char *, int);

/******************************** query.c ************************************/
int xjd1QueryInit(xjd1_stmt*,Query*);
int xjd1QueryRewind(Query*);
int xjd1QueryStep(Query*);
int xjd1QueryClose(Query*);

/******************************** scan.c *************************************/
int xjd1ScannerInit(Query*,DataSrc*);
int xjd1ScannerRewind(DataSrc*);
int xjd1ScannerEOF(DataSrc*);
int xjd1ScannerStep(DataSrc*);
int xjd1ScannerClose(DataSrc*);

/******************************** stmt.c *************************************/

/******************************** string.c ***********************************/
int xjd1Strlen30(const char *);
void xjd1StringInit(String*, Pool*, int);
String *xjd1StringNew(Pool*, int);
int xjd1StringAppend(String*, const char*, int);
#define xjd1StringText(S)      ((S)->zBuf)