libgda r3193 - in trunk: . doc/C doc/C/tmpl libgda libgda/handlers libgda/providers-support libgda/sql-parser libgda/sqlite libgda/sqlite/sqlite-src po providers/mysql providers/postgres tests tests/data-models tools
- From: vivien svn gnome org
- To: svn-commits-list gnome org
- Subject: libgda r3193 - in trunk: . doc/C doc/C/tmpl libgda libgda/handlers libgda/providers-support libgda/sql-parser libgda/sqlite libgda/sqlite/sqlite-src po providers/mysql providers/postgres tests tests/data-models tools
- Date: Thu, 28 Aug 2008 19:43:51 -0000
Author: vivien
Date: Thu Aug 28 19:38:33 2008
New Revision: 3193
URL: http://svn.gnome.org/viewvc/libgda?rev=3193&view=rev
Log:
2008-08-28 Vivien Malerba <malerba gnome-db org>
* libgda/handlers/gda-handler-numerical.c:
* libgda/gda-data-model.c:
* libgda/gda-data-model-import.c:
* libgda/gda-server-operation.c:
* libgda/gda-set.c:
* libgda/gda-util.c:
* libgda/gda-init.c: set the global variables gda_numeric_locale and gda_lang_locale
when calling gda_init() and use those variables whenever setlocale() was called to fetch
those locale values
* providers/mysql/gda-mysql-recordset.c:
* providers/postgres/gda-postgres-recordset.c: correctly restore
the user LC_NUMERIC locale after having altered it (thanks to Tim Lapawa)
* libgda/gda-util.c: understand the "time" and "timestamp" datatypes
as synonyms for "GdaTime" and and "GdaTimestamp"
* libgda/gda-value.c: reset a value before copying the other value's contents
* libgda/providers-support/gda-pmodel.[ch]: improvements to modifiable
data models (working now are gda_data_model_set_value_at(), gda_data_model_remove_row() and
gda_data_model_append_values())
* tests/data-models: updates to the check_pmodel test
* libgda/gda-holder.c: speed improvement in gda_holder_set_value_str(), and avoid mem leak in
some circumnstances
* libgda/sql-parser/gda-sql-parser.c: fix to remove a warning
* libgda/gda-connection.[ch]: removed gda_connection_add_events_list() as it was not used and
did not behave in an usual way regarding its input arguments, moved gda_connection_add_event(),
gda_connection_add_event_string() and gda_connection_clear_events_list() to the providers' API
* libgda/gda-connection.c: automatically clear the events list before executing any new
statement (see bug #545977)
* libgda/gda-connection.c: fix for bug #545979
* libgda/gda-data-model-query.c: applied patch for bug #546230 (thanks to Carl-Anton Ingmarsson)
* libgda/gda-data-model-array.c: fixed the set_values() method (ignore NULL values)
* providers/mysql/gda-mysql-provider.c: modified string to translate to make it easier to
understand (for bug #549498)
* libgda/gda-meta-struct.[ch]: added an "extra" attribute to the GdaMetaTableColumn structure
to hold extra column's info such as AUTO_INCREMENT
* libgda/gda-meta-struct-io.c: fill in the new GdaMetaTableColumn's "extra" attribute
* tools/command-exec.c: added an "Extra" column when listing the columns of a table
* libgda/gda-enums.h: #define possible values for extra attributes: EXTRA_AUTO_INCREMENT for now
* tests/gda-ddl-creator.c:
* tools/command-exec.c:
* providers/postgres/gda-postgres-meta.c:
* libgda/gda-meta-struct-io.c:
* libgda/sqlite/gda-sqlite-meta.c: use EXTRA_AUTO_INCREMENT
* libgda/gda-set.c: bug fixed in gda_set_get_spec()
* libgda/sqlite/gda-sqlite-provider.c:
* providers/postgres/gda-postgres-provider.c: set the "name" property of the individual GdaHolder
objects in the last_inserted_row set returned when an INSERT statement is executed
* providers/mysql/gda-mysql-provider.c: set last_inserted_row to NULL when a statement is executed
(the feature is not yet implemented)
* libgda/sqlite/sqlite-src: up to version 3.6.1
* po/: ran "make update-po"
* other files: documentation updates
Modified:
trunk/ChangeLog
trunk/doc/C/libgda-4.0-docs.sgml
trunk/doc/C/libgda-4.0-sections.txt
trunk/doc/C/tmpl/gda-connection.sgml
trunk/doc/C/tmpl/gda-meta-struct.sgml
trunk/doc/C/tmpl/gda-pmodel.sgml
trunk/doc/C/tmpl/gda-sql-statement.sgml
trunk/doc/C/tmpl/provider-support.sgml
trunk/libgda/gda-connection-private.h
trunk/libgda/gda-connection.c
trunk/libgda/gda-connection.h
trunk/libgda/gda-data-model-array.c
trunk/libgda/gda-data-model-import.c
trunk/libgda/gda-data-model-query.c
trunk/libgda/gda-data-model.c
trunk/libgda/gda-enums.h
trunk/libgda/gda-holder.c
trunk/libgda/gda-init.c
trunk/libgda/gda-meta-struct-io.c
trunk/libgda/gda-meta-struct.c
trunk/libgda/gda-meta-struct.h
trunk/libgda/gda-server-operation.c
trunk/libgda/gda-set.c
trunk/libgda/gda-util.c
trunk/libgda/gda-util.h
trunk/libgda/gda-value.c
trunk/libgda/handlers/gda-handler-numerical.c
trunk/libgda/information_schema.xml
trunk/libgda/providers-support/gda-pmodel.c
trunk/libgda/providers-support/gda-pmodel.h
trunk/libgda/sql-parser/gda-sql-parser.c
trunk/libgda/sql-parser/gda-statement-struct.c
trunk/libgda/sqlite/gda-sqlite-meta.c
trunk/libgda/sqlite/gda-sqlite-provider.c
trunk/libgda/sqlite/sqlite-src/PragmasPatch
trunk/libgda/sqlite/sqlite-src/sqlite3.c
trunk/libgda/sqlite/sqlite-src/sqlite3.h
trunk/po/ar.po
trunk/po/az.po
trunk/po/ca.po
trunk/po/cs.po
trunk/po/da.po
trunk/po/de.po
trunk/po/dz.po
trunk/po/el.po
trunk/po/en_CA.po
trunk/po/en_GB.po
trunk/po/es.po
trunk/po/eu.po
trunk/po/fa.po
trunk/po/fi.po
trunk/po/fr.po
trunk/po/ga.po
trunk/po/gl.po
trunk/po/hr.po
trunk/po/hu.po
trunk/po/it.po
trunk/po/ja.po
trunk/po/ko.po
trunk/po/lt.po
trunk/po/mk.po
trunk/po/ml.po
trunk/po/ms.po
trunk/po/nb.po
trunk/po/ne.po
trunk/po/nl.po
trunk/po/oc.po
trunk/po/pa.po
trunk/po/pl.po
trunk/po/pt.po
trunk/po/pt_BR.po
trunk/po/ru.po
trunk/po/rw.po
trunk/po/sk.po
trunk/po/sl.po
trunk/po/sq.po
trunk/po/sr.po
trunk/po/sr Latn po
trunk/po/sv.po
trunk/po/tr.po
trunk/po/uk.po
trunk/po/vi.po
trunk/po/zh_CN.po
trunk/po/zh_HK.po
trunk/po/zh_TW.po
trunk/providers/mysql/gda-mysql-provider.c
trunk/providers/mysql/gda-mysql-recordset.c
trunk/providers/postgres/gda-postgres-meta.c
trunk/providers/postgres/gda-postgres-provider.c
trunk/providers/postgres/gda-postgres-recordset.c
trunk/tests/data-models/check_data_proxy.c
trunk/tests/data-models/check_pmodel.c
trunk/tests/data-models/pmodel_data_customers.xml
trunk/tests/data-models/pmodel_dbstruct.xml
trunk/tests/gda-ddl-creator.c
trunk/tools/command-exec.c
Modified: trunk/doc/C/libgda-4.0-docs.sgml
==============================================================================
--- trunk/doc/C/libgda-4.0-docs.sgml (original)
+++ trunk/doc/C/libgda-4.0-docs.sgml Thu Aug 28 19:38:33 2008
@@ -98,6 +98,7 @@
<!ENTITY libgda-GdaMetaStore SYSTEM "xml/gda-meta-store.xml">
<!ENTITY libgda-GdaMetaStruct SYSTEM "xml/gda-meta-struct.xml">
<!ENTITY libgda-PModel SYSTEM "xml/gda-pmodel.xml">
+<!ENTITY libgda-PModelUser SYSTEM "xml/gda-pmodel-user.xml">
<!ENTITY libgda-PStmt SYSTEM "xml/gda-pstmt.xml">
<!ENTITY libgda-Enums SYSTEM "xml/gda-enums.xml">
<!ENTITY libgda-convenient SYSTEM "xml/gda-convenient.xml">
@@ -504,6 +505,7 @@
&libgda-GdaSqlParser;
&libgda-GdaStatement;
&libgda-GdaBatch;
+ &libgda-PModelUser;
&libgda-GdaHolder;
&libgda-GdaSet;
&libgda-GdaSqlStatement;
Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt (original)
+++ trunk/doc/C/libgda-4.0-sections.txt Thu Aug 28 19:38:33 2008
@@ -142,11 +142,7 @@
gda_connection_get_cnc_string
gda_connection_get_authentification
<SUBSECTION>
-gda_connection_add_event
-gda_connection_add_event_string
-gda_connection_add_events_list
gda_connection_get_events
-gda_connection_clear_events_list
<SUBSECTION>
gda_connection_create_operation
gda_connection_perform_operation
@@ -1384,8 +1380,6 @@
gda_pmodel_take_row
gda_pmodel_get_stored_row
gda_pmodel_get_connection
-gda_pmodel_set_modification_statement
-gda_pmodel_compute_modification_statements
<SUBSECTION Standard>
GDA_IS_PMODEL
GDA_PMODEL
@@ -1395,6 +1389,18 @@
</SECTION>
<SECTION>
+<FILE>gda-pmodel-user</FILE>
+<TITLE>Modifying the result of a SELECT statement</TITLE>
+<INCLUDE>providers-support/gda-pmodel.h</INCLUDE>
+gda_pmodel_set_row_selection_condition_sql
+gda_pmodel_set_row_selection_condition
+gda_pmodel_compute_row_selection_condition
+gda_pmodel_set_modification_statement
+gda_pmodel_set_modification_statement_sql
+gda_pmodel_compute_modification_statements
+</SECTION>
+
+<SECTION>
<FILE>gda-pstmt</FILE>
<TITLE>GdaPStmt</TITLE>
<INCLUDE>providers-support/gda-pstmt.h</INCLUDE>
@@ -1429,6 +1435,10 @@
gda_virtual_connection_internal_set_provider_data
gda_virtual_connection_internal_get_provider_data
<SUBSECTION>
+gda_connection_add_event
+gda_connection_add_event_string
+gda_connection_clear_events_list
+<SUBSECTION>
gda_connection_add_prepared_statement
gda_connection_del_prepared_statement
gda_connection_get_prepared_statement
Modified: trunk/doc/C/tmpl/gda-connection.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-connection.sgml (original)
+++ trunk/doc/C/tmpl/gda-connection.sgml Thu Aug 28 19:38:33 2008
@@ -421,35 +421,6 @@
@Returns:
-<!-- ##### FUNCTION gda_connection_add_event ##### -->
-<para>
-
-</para>
-
- cnc:
- event:
-
-
-<!-- ##### FUNCTION gda_connection_add_event_string ##### -->
-<para>
-
-</para>
-
- cnc:
- str:
- Varargs:
- Returns:
-
-
-<!-- ##### FUNCTION gda_connection_add_events_list ##### -->
-<para>
-
-</para>
-
- cnc:
- events_list:
-
-
<!-- ##### FUNCTION gda_connection_get_events ##### -->
<para>
@@ -459,14 +430,6 @@
@Returns:
-<!-- ##### FUNCTION gda_connection_clear_events_list ##### -->
-<para>
-
-</para>
-
- cnc:
-
-
<!-- ##### FUNCTION gda_connection_create_operation ##### -->
<para>
Modified: trunk/doc/C/tmpl/gda-meta-struct.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-meta-struct.sgml (original)
+++ trunk/doc/C/tmpl/gda-meta-struct.sgml Thu Aug 28 19:38:33 2008
@@ -208,6 +208,7 @@
@pkey:
@nullok:
@default_value:
+ extra:
<!-- ##### MACRO GDA_META_TABLE_COLUMN ##### -->
<para>
Modified: trunk/doc/C/tmpl/gda-pmodel.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-pmodel.sgml (original)
+++ trunk/doc/C/tmpl/gda-pmodel.sgml Thu Aug 28 19:38:33 2008
@@ -84,25 +84,3 @@
@Returns:
-<!-- ##### FUNCTION gda_pmodel_set_modification_statement ##### -->
-<para>
-
-</para>
-
- model:
- mod_stmt:
- error:
- Returns:
-
-
-<!-- ##### FUNCTION gda_pmodel_compute_modification_statements ##### -->
-<para>
-
-</para>
-
- model:
- require_pk:
- error:
- Returns:
-
-
Modified: trunk/doc/C/tmpl/gda-sql-statement.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-sql-statement.sgml (original)
+++ trunk/doc/C/tmpl/gda-sql-statement.sgml Thu Aug 28 19:38:33 2008
@@ -652,7 +652,6 @@
@name:
@descr:
- type:
@is_param:
@nullok:
@g_type:
Modified: trunk/doc/C/tmpl/provider-support.sgml
==============================================================================
--- trunk/doc/C/tmpl/provider-support.sgml (original)
+++ trunk/doc/C/tmpl/provider-support.sgml Thu Aug 28 19:38:33 2008
@@ -135,6 +135,34 @@
@Returns:
+<!-- ##### FUNCTION gda_connection_add_event ##### -->
+<para>
+
+</para>
+
+ cnc:
+ event:
+
+
+<!-- ##### FUNCTION gda_connection_add_event_string ##### -->
+<para>
+
+</para>
+
+ cnc:
+ str:
+ Varargs:
+ Returns:
+
+
+<!-- ##### FUNCTION gda_connection_clear_events_list ##### -->
+<para>
+
+</para>
+
+ cnc:
+
+
<!-- ##### FUNCTION gda_connection_add_prepared_statement ##### -->
<para>
Modified: trunk/libgda/gda-connection-private.h
==============================================================================
--- trunk/libgda/gda-connection-private.h (original)
+++ trunk/libgda/gda-connection-private.h Thu Aug 28 19:38:33 2008
@@ -35,6 +35,13 @@
gpointer gda_connection_internal_get_provider_data (GdaConnection *cnc);
/*
+ * Connection's events
+ */
+void gda_connection_add_event (GdaConnection *cnc, GdaConnectionEvent *event);
+GdaConnectionEvent *gda_connection_add_event_string (GdaConnection *cnc, const gchar *str, ...);
+void gda_connection_clear_events_list (GdaConnection *cnc);
+
+/*
* Transaction related
*/
void gda_connection_internal_transaction_started (GdaConnection *cnc, const gchar *parent_trans, const gchar *trans_name,
Modified: trunk/libgda/gda-connection.c
==============================================================================
--- trunk/libgda/gda-connection.c (original)
+++ trunk/libgda/gda-connection.c Thu Aug 28 19:38:33 2008
@@ -56,6 +56,8 @@
gboolean is_open;
GdaMetaStore *meta_store;
+
+ gboolean auto_clear_events_list; /* TRUE if events_list is cleared before any statement execution */
GList *events_list; /* last event is stored as the first node */
GdaTransactionStatus *trans_status;
@@ -241,6 +243,7 @@
cnc->priv->cnc_string = NULL;
cnc->priv->auth_string = NULL;
cnc->priv->is_open = FALSE;
+ cnc->priv->auto_clear_events_list = TRUE;
cnc->priv->events_list = NULL;
cnc->priv->trans_status = NULL; /* no transaction yet */
}
@@ -257,6 +260,14 @@
cnc->priv->unique_possible_thread = NULL;
gda_connection_close_no_warning (cnc);
+ /* get rid of prepared statements to avoid problems */
+ if (cnc->priv->prepared_stmts) {
+ g_hash_table_foreach (cnc->priv->prepared_stmts,
+ (GHFunc) prepared_stms_foreach_func, cnc);
+ g_hash_table_destroy (cnc->priv->prepared_stmts);
+ cnc->priv->prepared_stmts = NULL;
+ }
+
if (cnc->priv->provider_obj) {
g_object_unref (G_OBJECT (cnc->priv->provider_obj));
cnc->priv->provider_obj = NULL;
@@ -264,7 +275,7 @@
if (cnc->priv->events_list) {
g_list_foreach (cnc->priv->events_list, (GFunc) g_object_unref, NULL);
- g_slist_free (cnc->priv->events_list);
+ g_list_free (cnc->priv->events_list);
cnc->priv->events_list = NULL;
}
@@ -1217,41 +1228,16 @@
return error;
}
-/** TODO: This actually frees the input GList. That's very very unusual. murrayc. */
-
-/**
- * gda_connection_add_events_list
- * @cnc: a #GdaConnection object.
- * @events_list: a list of #GdaConnectionEvent.
- *
- * This is just another convenience function which lets you add
- * a list of #GdaConnectionEvent's to the given connection.*
- * As with
- * #gda_connection_add_event and #gda_connection_add_event_string,
- * this function makes the connection object emit the "error"
- * signal for each error event.
- *
- * @events_list is copied to an internal list and freed.
- */
-void
-gda_connection_add_events_list (GdaConnection *cnc, GList *events_list)
+static void
+_clear_events_list (GdaConnection *cnc)
{
- GList *l;
-
- g_return_if_fail (GDA_IS_CONNECTION (cnc));
- g_return_if_fail (cnc->priv);
- g_return_if_fail (events_list != NULL);
-
gda_connection_lock ((GdaLockable*) cnc);
- for (l = events_list; l ; l = l->next) {
- cnc->priv->events_list = g_list_prepend (cnc->priv->events_list, l->data);
- if (gda_connection_event_get_event_type (GDA_CONNECTION_EVENT (l->data)) ==
- GDA_CONNECTION_EVENT_ERROR)
- g_signal_emit (G_OBJECT (cnc), gda_connection_signals[ERROR], 0, l->data);
+ if (cnc->priv->events_list != NULL) {
+ g_list_foreach (cnc->priv->events_list, (GFunc) g_object_unref, NULL);
+ g_list_free (cnc->priv->events_list);
+ cnc->priv->events_list = NULL;
}
gda_connection_unlock ((GdaLockable*) cnc);
-
- g_list_free (events_list);
}
/**
@@ -1266,14 +1252,7 @@
{
g_return_if_fail (GDA_IS_CONNECTION (cnc));
g_return_if_fail (cnc->priv);
-
- gda_connection_lock ((GdaLockable*) cnc);
- if (cnc->priv->events_list != NULL) {
- g_list_foreach (cnc->priv->events_list, (GFunc) g_object_unref, NULL);
- g_list_free (cnc->priv->events_list);
- cnc->priv->events_list = NULL;
- }
- gda_connection_unlock ((GdaLockable*) cnc);
+ _clear_events_list (cnc);
}
/**
@@ -1316,12 +1295,17 @@
gboolean
gda_connection_perform_operation (GdaConnection *cnc, GdaServerOperation *op, GError **error)
{
+ gboolean auto_clear_events, retval;
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
g_return_val_if_fail (cnc->priv, FALSE);
g_return_val_if_fail (cnc->priv->provider_obj, FALSE);
g_return_val_if_fail (GDA_IS_SERVER_OPERATION (op), FALSE);
- return gda_server_provider_perform_operation (cnc->priv->provider_obj, cnc, op, error);
+ auto_clear_events = cnc->priv->auto_clear_events_list;
+ cnc->priv->auto_clear_events_list = FALSE;
+ retval = gda_server_provider_perform_operation (cnc->priv->provider_obj, cnc, op, error);
+ cnc->priv->auto_clear_events_list = auto_clear_events;
+ return retval;
}
/**
@@ -1368,11 +1352,14 @@
GdaStatementModelUsage model_usage, GError **error)
{
GSList *retlist = NULL, *stmt_list;
+ gboolean auto_clear_events;
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
g_return_val_if_fail (cnc->priv, NULL);
g_return_val_if_fail (GDA_IS_BATCH (batch), NULL);
gda_connection_lock ((GdaLockable*) cnc);
+ auto_clear_events = cnc->priv->auto_clear_events_list;
+ cnc->priv->auto_clear_events_list = FALSE;
for (stmt_list = (GSList*) gda_batch_get_statements (batch); stmt_list; stmt_list = stmt_list->next) {
GObject *obj;
obj = gda_connection_statement_execute (cnc, GDA_STATEMENT (stmt_list->data), params,
@@ -1381,6 +1368,7 @@
break;
retlist = g_slist_prepend (retlist, obj);
}
+ cnc->priv->auto_clear_events_list = auto_clear_events;
gda_connection_unlock ((GdaLockable*) cnc);
return g_slist_reverse (retlist);
@@ -1493,6 +1481,8 @@
if (last_inserted_row)
*last_inserted_row = NULL;
+ if (cnc->priv->auto_clear_events_list)
+ _clear_events_list (cnc);
obj = PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, cnc, stmt, params,
model_usage, types, last_inserted_row,
NULL, NULL, NULL, error);
@@ -1516,8 +1506,8 @@
* <itemizedlist>
* <listitem><para>a #GdaDataModel if @stmt is a SELECT statement (a GDA_SQL_STATEMENT_SELECT, see #GdaSqlStatementType)
* containing the results of the SELECT. The resulting data model is by default read only, but
- * modifications can be made possible using gda_pmodel_set_modification_query() and/or
- * gda_pmodel_compute_modification_queries().</para></listitem>
+ * modifications can be enabled, see the section about
+ * <link linkend="libgda-40-Modifying-the-result-of-a-SELECT-statement">modifying the result of a SELECT statement</link>.</para></listitem> for more information.
* <listitem><para>a #GdaSet for any other SQL statement which correctly executed. In this case
* (if the provider supports it), then the #GdaSet may contain value holders named:
* <itemizedlist>
@@ -1532,8 +1522,8 @@
* which is auto incremented and a 'name' column then the execution of a "INSERT INTO mytable (name) VALUES ('joe')"
* query will return a #GdaSet with two holders:
* <itemizedlist>
- * <listitem><para>one named '+0' which may for example contain 1</para></listitem>
- * <listitem><para>one named '+1' which will contain 'joe'</para></listitem>
+ * <listitem><para>one with the '+0' ID which may for example contain 1 (note that its "name" property should be "id")</para></listitem>
+ * <listitem><para>one with the '+1' ID which will contain 'joe' (note that its "name" property should be "name")</para></listitem>
* </itemizedlist>
* See the <link linkend="limitations">provider's limitations</link> section for more details about this feature
* depending on which database is accessed.
@@ -1717,6 +1707,9 @@
va_start (ap, error);
types = make_col_types_array (10, ap);
va_end (ap);
+
+ if (cnc->priv->auto_clear_events_list)
+ _clear_events_list (cnc);
model = (GdaDataModel *) PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj,
cnc, stmt, params, model_usage,
types, NULL, NULL,
@@ -1769,6 +1762,8 @@
g_return_val_if_fail (GDA_IS_STATEMENT (stmt), NULL);
g_return_val_if_fail (PROV_CLASS (cnc->priv->provider_obj)->statement_execute, NULL);
+ if (cnc->priv->auto_clear_events_list)
+ _clear_events_list (cnc);
model = (GdaDataModel *) PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj,
cnc, stmt, params,
model_usage, col_types, NULL,
Modified: trunk/libgda/gda-connection.h
==============================================================================
--- trunk/libgda/gda-connection.h (original)
+++ trunk/libgda/gda-connection.h Thu Aug 28 19:38:33 2008
@@ -156,10 +156,6 @@
const gchar *gda_connection_get_cnc_string (GdaConnection *cnc);
const gchar *gda_connection_get_authentication (GdaConnection *cnc);
-void gda_connection_add_event (GdaConnection *cnc, GdaConnectionEvent *event);
-GdaConnectionEvent *gda_connection_add_event_string (GdaConnection *cnc, const gchar *str, ...);
-void gda_connection_add_events_list (GdaConnection *cnc, GList *events_list);
-void gda_connection_clear_events_list (GdaConnection *cnc);
const GList *gda_connection_get_events (GdaConnection *cnc);
GdaSqlParser *gda_connection_create_parser (GdaConnection *cnc);
Modified: trunk/libgda/gda-data-model-array.c
==============================================================================
--- trunk/libgda/gda-data-model-array.c (original)
+++ trunk/libgda/gda-data-model-array.c Thu Aug 28 19:38:33 2008
@@ -385,7 +385,7 @@
g_return_val_if_fail (GDA_IS_DATA_MODEL_ARRAY (model), NULL);
if (row >= model->priv->rows->len) {
- g_set_error (error, 0, 0,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, 0,
_("Row %d out of range (0-%d)"), row,
model->priv->rows->len- 1);
return NULL;
@@ -597,13 +597,13 @@
g_return_val_if_fail (row >= 0, FALSE);
if (amodel->priv->read_only) {
- g_set_error (error, 0, GDA_DATA_MODEL_ACCESS_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
_("Attempting to modify a read-only data model"));
return FALSE;
}
if (row > amodel->priv->rows->len) {
- g_set_error (error, 0, GDA_DATA_MODEL_VALUES_LIST_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_VALUES_LIST_ERROR,
_("Row number out of range"));
return FALSE;
}
@@ -637,13 +637,13 @@
return TRUE;
if (amodel->priv->read_only) {
- g_set_error (error, 0, GDA_DATA_MODEL_ACCESS_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
_("Attempting to modify a read-only data model"));
return FALSE;
}
if (g_list_length (values) > gda_data_model_get_n_columns (model)) {
- g_set_error (error, 0, GDA_DATA_MODEL_VALUES_LIST_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_VALUES_LIST_ERROR,
_("Too many values in list"));
return FALSE;
}
@@ -659,8 +659,6 @@
gda_value_reset_with_type (dest, G_VALUE_TYPE ((GValue *) list->data));
gda_value_set_from_value (dest, (GValue *) list->data);
}
- else
- gda_value_set_null (dest);
}
gda_data_model_row_updated (model, row);
return TRUE;
@@ -678,13 +676,13 @@
GdaDataModelArray *amodel = (GdaDataModelArray *) model;
if (amodel->priv->read_only) {
- g_set_error (error, 0, GDA_DATA_MODEL_ACCESS_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
_("Attempting to modify a read-only data model"));
return FALSE;
}
if (g_list_length ((GList *) values) > amodel->priv->number_of_columns) {
- g_set_error (error, 0, GDA_DATA_MODEL_VALUES_LIST_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_VALUES_LIST_ERROR,
_("Too many values in list"));
return FALSE;
}
@@ -713,7 +711,7 @@
GdaDataModelArray *amodel = (GdaDataModelArray *) model;
if (amodel->priv->read_only) {
- g_set_error (error, 0, GDA_DATA_MODEL_ACCESS_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
_("Attempting to modify a read-only data model"));
return FALSE;
}
@@ -738,7 +736,7 @@
return TRUE;
}
- g_set_error (error, 0, GDA_DATA_MODEL_ROW_NOT_FOUND_ERROR,
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ROW_NOT_FOUND_ERROR,
_("Row not found in data model"));
return FALSE;
}
Modified: trunk/libgda/gda-data-model-import.c
==============================================================================
--- trunk/libgda/gda-data-model-import.c (original)
+++ trunk/libgda/gda-data-model-import.c Thu Aug 28 19:38:33 2008
@@ -36,6 +36,8 @@
#include <locale.h>
#endif
+extern gchar *gda_lang_locale;
+
#include <glib/gi18n-lib.h>
#include <libgda/gda-decl.h>
#include <libgda/gda-enums.h>
@@ -1295,18 +1297,12 @@
const xmlChar *name;
gint ret;
- const gchar *lang = NULL;
+ const gchar *lang = gda_lang_locale;
GSList *columns = model->priv->columns;
GdaColumn *last_column = NULL;
GSList *values = NULL;
-#ifdef HAVE_LC_MESSAGES
- lang = setlocale (LC_MESSAGES, NULL);
-#else
- lang = setlocale (LC_CTYPE, NULL);
-#endif
-
if (model->priv->cursor_values) {
g_slist_foreach (model->priv->cursor_values, (GFunc) gda_value_free, NULL);
g_slist_free (model->priv->cursor_values);
Modified: trunk/libgda/gda-data-model-query.c
==============================================================================
--- trunk/libgda/gda-data-model-query.c (original)
+++ trunk/libgda/gda-data-model-query.c Thu Aug 28 19:38:33 2008
@@ -675,17 +675,16 @@
model->priv->data = gda_connection_statement_execute_select (model->priv->cnc,
model->priv->statements[SEL_QUERY],
- model->priv->params [SEL_QUERY], error);
+ model->priv->params [SEL_QUERY],
+ &model->priv->refresh_error);
if (!model->priv->data) {
- model->priv->data = NULL;
- g_assert (model->priv->refresh_error);
- if (error)
+ if (model->priv->refresh_error && error)
*error = g_error_copy (model->priv->refresh_error);
return FALSE;
}
-
+
gda_data_model_reset ((GdaDataModel *) model);
- return model->priv->data ? TRUE : FALSE;
+ return TRUE;
}
/**
@@ -765,8 +764,10 @@
selmodel = GDA_DATA_MODEL_QUERY (model);
g_return_val_if_fail (selmodel->priv, 0);
- if (!selmodel->priv->data && !selmodel->priv->refresh_error)
- gda_data_model_query_refresh (selmodel, NULL);
+ if (!selmodel->priv->data && !selmodel->priv->refresh_error) {
+ if (!gda_data_model_query_refresh (selmodel, NULL))
+ return 0;
+ }
create_columns (selmodel);
@@ -851,8 +852,10 @@
selmodel = GDA_DATA_MODEL_QUERY (model);
g_return_val_if_fail (selmodel->priv, NULL);
- if (!selmodel->priv->data && !selmodel->priv->refresh_error)
- gda_data_model_query_refresh (selmodel, NULL);
+ if (!selmodel->priv->data && !selmodel->priv->refresh_error) {
+ if (!gda_data_model_query_refresh (selmodel, NULL))
+ return NULL;
+ }
create_columns (selmodel);
if (selmodel->priv->columns)
Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c (original)
+++ trunk/libgda/gda-data-model.c Thu Aug 28 19:38:33 2008
@@ -40,6 +40,8 @@
#endif
#include "csv.h"
+extern gchar *gda_lang_locale;
+
static GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
static void gda_data_model_class_init (gpointer g_class);
@@ -641,6 +643,8 @@
* @value: a #GValue, or %NULL
* @error: a place to store errors, or %NULL
*
+ * Modifies a value in @model, at (@col, @row).
+ *
* Returns: TRUE if the value in the data model has been updated and no error occurred
*/
gboolean
@@ -660,11 +664,14 @@
* gda_data_model_set_values
* @model: a #GdaDataModel object.
* @row: row number.
- * @values: a list of #GValue, one for each n (<nb_cols) columns of @model
+ * @values: a list of #GValue, one for at most the number of columns of @model
* @error: a place to store errors, or %NULL
*
- * If any value in @values is actually %NULL, then
- * it is considered as a default value.
+ * In a similar way to gda_data_model_set_value_at(), this method modifies a data model's contents
+ * by setting several values at once.
+ *
+ * If any value in @values is actually %NULL, then the value in the corresponding column is left
+ * unchanged.
*
* Returns: TRUE if the value in the data model has been updated and no error occurred
*/
@@ -1528,12 +1535,7 @@
gboolean retval = TRUE;
gint pos = 0;
- const gchar *lang = NULL;
-#ifdef HAVE_LC_MESSAGES
- lang = setlocale (LC_MESSAGES, NULL);
-#else
- lang = setlocale (LC_CTYPE, NULL);
-#endif
+ const gchar *lang = gda_lang_locale;
values = g_ptr_array_new ();
g_ptr_array_set_size (values, gda_data_model_get_n_columns (model));
Modified: trunk/libgda/gda-enums.h
==============================================================================
--- trunk/libgda/gda-enums.h (original)
+++ trunk/libgda/gda-enums.h Thu Aug 28 19:38:33 2008
@@ -58,6 +58,9 @@
GDA_ENTITY_FIELD_ANY = GDA_ENTITY_FIELD_VISIBLE | GDA_ENTITY_FIELD_INVISIBLE
} GdaQueryFieldState;
+/* possible different keywords used when qualifying a table's column's extra attributes */
+#define GDA_EXTRA_AUTO_INCREMENT "AUTO_INCREMENT"
+
#endif
Modified: trunk/libgda/gda-holder.c
==============================================================================
--- trunk/libgda/gda-holder.c (original)
+++ trunk/libgda/gda-holder.c Thu Aug 28 19:38:33 2008
@@ -729,11 +729,8 @@
if (dh)
gdaval = gda_data_handler_get_value_from_str (dh, value, holder->priv->g_type);
- if (gdaval) {
- gda_holder_set_value (holder, gdaval);
- gda_value_free (gdaval);
- return TRUE;
- }
+ if (gdaval)
+ return real_gda_holder_set_value (holder, gdaval, FALSE);
else
return FALSE;
}
@@ -836,7 +833,7 @@
g_print ("Holder %p is alias of holder %p => propagating changes to holder %p\n",
holder, holder->priv->full_bind, holder->priv->full_bind);
#endif
- gda_holder_set_value (holder->priv->full_bind, value);
+ retval = real_gda_holder_set_value (holder->priv->full_bind, value, do_copy);
}
else {
if (holder->priv->value) {
Modified: trunk/libgda/gda-init.c
==============================================================================
--- trunk/libgda/gda-init.c (original)
+++ trunk/libgda/gda-init.c Thu Aug 28 19:38:33 2008
@@ -21,6 +21,9 @@
#include <gmodule.h>
#include <libgda/libgda.h>
#include <glib/gi18n-lib.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
#include <libgda/binreloc/gda-binreloc.h>
#include <sql-parser/gda-sql-parser.h>
@@ -30,6 +33,8 @@
xmlDtdPtr gda_paramlist_dtd = NULL;
xmlDtdPtr gda_server_op_dtd = NULL;
+gchar *gda_numeric_locale = NULL;
+gchar *gda_lang_locale = NULL;
/**
* gda_init
@@ -98,6 +103,22 @@
type = GDA_TYPE_TIMESTAMP;
g_assert (type);
+ /* acquire locale */
+ gda_numeric_locale = setlocale (LC_NUMERIC, NULL);
+ if (gda_numeric_locale)
+ gda_numeric_locale = g_strdup (gda_numeric_locale);
+ else
+ gda_numeric_locale = g_strdup ("");
+#ifdef HAVE_LC_MESSAGES
+ gda_lang_locale = setlocale (LC_MESSAGES, NULL);
+#else
+ gda_lang_locale = setlocale (LC_CTYPE, NULL);
+#endif
+ if (gda_lang_locale)
+ gda_lang_locale = g_strdup (gda_lang_locale);
+ else
+ gda_lang_locale = g_strdup ("");
+
/* binreloc */
gda_gbr_init ();
Modified: trunk/libgda/gda-meta-struct-io.c
==============================================================================
--- trunk/libgda/gda-meta-struct-io.c (original)
+++ trunk/libgda/gda-meta-struct-io.c Thu Aug 28 19:38:33 2008
@@ -228,9 +228,10 @@
gint colsindex = 0;
for (cnode = node->children; cnode; cnode = cnode->next) {
if (!strcmp ((gchar *) cnode->name, "column")) {
- xmlChar *cname, *ctype, *xstr;
+ xmlChar *cname, *ctype, *xstr, *extra;
gboolean pkey = FALSE;
- gboolean nullok = FALSE;
+ gboolean nullok = FALSE;
+ GArray *extra_array = NULL;
if (strcmp ((gchar *) cnode->name, "column"))
continue;
@@ -253,7 +254,15 @@
xmlFree (xstr);
}
ctype = xmlGetProp (cnode, BAD_CAST "type");
-
+ extra = xmlGetProp (cnode, BAD_CAST "autoinc");
+ if (extra) {
+ gchar *tmp = g_strdup (GDA_EXTRA_AUTO_INCREMENT); /* see gda-enums.h */
+ if (!extra_array)
+ extra_array = g_array_new (FALSE, FALSE, sizeof (gchar*));
+ g_array_append_val (extra_array, tmp);
+ xmlFree (extra);
+ }
+
/* a field */
GdaMetaTableColumn *tcol;
@@ -268,6 +277,7 @@
tcol->nullok = nullok;
if (pkey)
g_array_append_val (pk_cols_array, colsindex);
+ tcol->extra = extra_array;
colsindex++;
/* FIXME: handle default value */
Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c (original)
+++ trunk/libgda/gda-meta-struct.c Thu Aug 28 19:38:33 2008
@@ -590,7 +590,7 @@
}
case GDA_META_DB_TABLE: {
/* columns */
- gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, c.column_default, t.table_owner, c.array_spec FROM _columns as c NATURAL JOIN _tables as t WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string ORDER BY ordinal_position";
+ gchar *sql = "SELECT c.column_name, c.data_type, c.gtype, c.is_nullable, t.table_short_name, t.table_full_name, c.column_default, t.table_owner, c.array_spec, c.extra FROM _columns as c NATURAL JOIN _tables as t WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string ORDER BY ordinal_position";
GdaMetaTable *mt;
GdaDataModel *model;
gint i, nrows;
@@ -639,6 +639,22 @@
val = gda_data_model_get_value_at (model, 6, i);
if (val && !gda_value_is_null (val))
tcol->default_value = g_strdup (g_value_get_string (val));
+ val = gda_data_model_get_value_at (model, 9, i);
+ if (val && !gda_value_is_null (val)) {
+ gchar **array, *tmp;
+ gint ai;
+ GArray *extra_array = NULL;
+ cstr = g_value_get_string (val);
+ array = g_strsplit (cstr, ",", 0);
+ for (ai = 0; array [ai]; ai++) {
+ if (!extra_array)
+ extra_array = g_array_new (FALSE, FALSE, sizeof (gchar*));
+ tmp = g_strstrip (array [ai]);
+ g_array_append_val (extra_array, tmp);
+ }
+ g_free (array); /* don't use g_strfreev() here because we have stolen the string pointers */
+ tcol->extra = extra_array;
+ }
/* Note: tcol->pkey is not determined here */
mt->columns = g_slist_prepend (mt->columns, tcol);
@@ -1562,6 +1578,12 @@
g_free (tcol->column_name);
g_free (tcol->column_type);
g_free (tcol->default_value);
+ if (tcol->extra) {
+ gint i;
+ for (i = 0; i < tcol->extra->len; i++)
+ g_free (g_array_index (tcol->extra, gchar *, i));
+ g_array_free (tcol->extra, TRUE);
+ }
g_free (tcol);
}
Modified: trunk/libgda/gda-meta-struct.h
==============================================================================
--- trunk/libgda/gda-meta-struct.h (original)
+++ trunk/libgda/gda-meta-struct.h Thu Aug 28 19:38:33 2008
@@ -146,6 +146,7 @@
gboolean pkey;
gboolean nullok;
gchar *default_value;
+ GArray *extra; /* array of strings such as "AUTO_INCREMENT", may be NULL */
} GdaMetaTableColumn;
#define GDA_META_TABLE_COLUMN(x) ((GdaMetaTableColumn*)(x))
Modified: trunk/libgda/gda-server-operation.c
==============================================================================
--- trunk/libgda/gda-server-operation.c (original)
+++ trunk/libgda/gda-server-operation.c Thu Aug 28 19:38:33 2008
@@ -38,6 +38,8 @@
#endif
#include <glib/gi18n-lib.h>
+extern gchar *gda_lang_locale;
+
#define CLASS(operation) (GDA_SERVER_OPERATION_CLASS (G_OBJECT_GET_CLASS (operation)))
static void gda_server_operation_class_init (GdaServerOperationClass *klass);
@@ -690,18 +692,12 @@
load_xml_spec (GdaServerOperation *op, xmlNodePtr specnode, const gchar *root)
{
xmlNodePtr node;
- const gchar *lang;
+ const gchar *lang = gda_lang_locale;
GSList *retlist = NULL;
Node *parent = NULL;
if (root)
parent = node_find (op, root);
-
-#ifdef HAVE_LC_MESSAGES
- lang = setlocale (LC_MESSAGES, NULL);
-#else
- lang = setlocale (LC_CTYPE, NULL);
-#endif
g_assert (specnode);
Modified: trunk/libgda/gda-set.c
==============================================================================
--- trunk/libgda/gda-set.c (original)
+++ trunk/libgda/gda-set.c Thu Aug 28 19:38:33 2008
@@ -37,6 +37,7 @@
#include "gda-util.h"
extern xmlDtdPtr gda_paramlist_dtd;
+extern gchar *gda_lang_locale;
/*
* Main static functions
@@ -641,18 +642,12 @@
GdaSet *set = NULL;
GSList *holders = NULL, *sources = NULL;
GSList *list;
- const gchar *lang;
+ const gchar *lang = gda_lang_locale;
xmlNodePtr cur;
gboolean allok = TRUE;
gchar *str;
-#ifdef HAVE_LC_MESSAGES
- lang = setlocale (LC_MESSAGES, NULL);
-#else
- lang = setlocale (LC_CTYPE, NULL);
-#endif
-
if (strcmp ((gchar*)xml_spec->name, "parameters") != 0){
g_set_error (error, GDA_SET_ERROR, GDA_SET_XML_SPEC_ERROR,
_("Missing node <parameters>: '%s'"), xml_spec->name);
@@ -830,7 +825,7 @@
g_object_get (G_OBJECT (holder), "name", &str, NULL);
if (str)
- xmlSetProp(node, (xmlChar*)"name", (xmlChar*)cstr);
+ xmlSetProp(node, (xmlChar*)"name", (xmlChar*)str);
g_free (str);
g_object_get (G_OBJECT (holder), "description", &str, NULL);
Modified: trunk/libgda/gda-util.c
==============================================================================
--- trunk/libgda/gda-util.c (original)
+++ trunk/libgda/gda-util.c Thu Aug 28 19:38:33 2008
@@ -43,6 +43,8 @@
#include <libgda/binreloc/gda-binreloc.h>
+extern gchar *gda_lang_locale;
+
/**
* gda_g_type_to_string
* @type: Type to convert from.
@@ -78,6 +80,10 @@
type = G_TYPE_STRING;
else if (!g_ascii_strcasecmp (str, "date"))
type = G_TYPE_DATE;
+ else if (!g_ascii_strcasecmp (str, "time"))
+ type = GDA_TYPE_TIME;
+ else if (!g_ascii_strcasecmp (str, "timestamp"))
+ type = GDA_TYPE_TIMESTAMP;
else if (!strcmp (str, "boolean"))
type = G_TYPE_BOOLEAN;
else if (!strcmp (str, "null"))
@@ -459,15 +465,10 @@
vnode = node->children;
if (vnode) {
xmlChar *this_lang, *isnull;
- const gchar *lang;
+ const gchar *lang = gda_lang_locale;
GType gdatype;
gdatype = gda_holder_get_g_type (holder);
-#ifdef HAVE_LC_MESSAGES
- lang = setlocale (LC_MESSAGES, NULL);
-#else
- lang = setlocale (LC_CTYPE, NULL);
-#endif
while (vnode) {
if (xmlNodeIsText (vnode)) {
vnode = vnode->next;
@@ -649,8 +650,8 @@
/*
* Builds the WHERE condition of the computed DML statement
*/
-static GdaSqlExpr*
-dml_statements_build_condition (GdaSqlStatementSelect *stsel, GdaMetaTable *mtable, gboolean require_pk, GError **error)
+GdaSqlExpr*
+gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTable *mtable, gboolean require_pk, GError **error)
{
gint i;
GdaSqlExpr *expr;
@@ -720,6 +721,11 @@
}
}
}
+ else {
+ TO_IMPLEMENT;
+ gda_sql_expr_free (expr);
+ expr = NULL;
+ }
return expr;
onerror:
@@ -786,9 +792,9 @@
GDA_SQL_ANY_PART (ust)->type = GDA_SQL_ANY_STMT_UPDATE;
ust->table = gda_sql_table_new (GDA_SQL_ANY_PART (ust));
ust->table->table_name = g_strdup ((gchar *) target->table_name);
- ust->cond = dml_statements_build_condition (stsel,
- GDA_META_TABLE (target->validity_meta_object),
- require_pk, error);
+ ust->cond = gda_compute_unique_table_row_condition (stsel,
+ GDA_META_TABLE (target->validity_meta_object),
+ require_pk, error);
if (!ust->cond) {
retval = FALSE;
goto cleanup;
@@ -801,9 +807,9 @@
GDA_SQL_ANY_PART (dst)->type = GDA_SQL_ANY_STMT_DELETE;
dst->table = gda_sql_table_new (GDA_SQL_ANY_PART (dst));
dst->table->table_name = g_strdup ((gchar *) target->table_name);
- dst->cond = dml_statements_build_condition (stsel,
- GDA_META_TABLE (target->validity_meta_object),
- require_pk, error);
+ dst->cond = gda_compute_unique_table_row_condition (stsel,
+ GDA_META_TABLE (target->validity_meta_object),
+ require_pk, error);
if (!dst->cond) {
retval = FALSE;
goto cleanup;
Modified: trunk/libgda/gda-util.h
==============================================================================
--- trunk/libgda/gda-util.h (original)
+++ trunk/libgda/gda-util.h Thu Aug 28 19:38:33 2008
@@ -29,6 +29,7 @@
#include "gda-holder.h"
#include "gda-row.h"
#include "gda-connection.h"
+#include <sql-parser/gda-sql-statement.h>
G_BEGIN_DECLS
@@ -65,6 +66,8 @@
/*
* Statement computation from meta store
*/
+GdaSqlExpr *gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTable *mtable,
+ gboolean require_pk, GError **error);
gboolean gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gboolean require_pk,
GdaStatement **insert_stmt, GdaStatement **update_stmt, GdaStatement **delete_stmt,
GError **error);
Modified: trunk/libgda/gda-value.c
==============================================================================
--- trunk/libgda/gda-value.c (original)
+++ trunk/libgda/gda-value.c Thu Aug 28 19:38:33 2008
@@ -1746,8 +1746,13 @@
g_return_val_if_fail (from, FALSE);
if (G_IS_VALUE (from)) {
- g_value_copy (from, value);
- return g_value_type_compatible (G_VALUE_TYPE (from), G_VALUE_TYPE (value));
+ if (g_value_type_compatible (G_VALUE_TYPE (from), G_VALUE_TYPE (value))) {
+ g_value_reset (value);
+ g_value_copy (from, value);
+ return TRUE;
+ }
+ else
+ return FALSE;
}
else {
l_g_value_unset (value);
Modified: trunk/libgda/handlers/gda-handler-numerical.c
==============================================================================
--- trunk/libgda/handlers/gda-handler-numerical.c (original)
+++ trunk/libgda/handlers/gda-handler-numerical.c Thu Aug 28 19:38:33 2008
@@ -22,6 +22,8 @@
#include <locale.h>
#include <glib/gi18n-lib.h>
+extern gchar *gda_numeric_locale;
+
static void gda_handler_numerical_class_init (GdaHandlerNumericalClass * class);
static void gda_handler_numerical_init (GdaHandlerNumerical * wid);
static void gda_handler_numerical_dispose (GObject * object);
@@ -189,7 +191,7 @@
setlocale (LC_NUMERIC, "C");
str = gda_value_stringify ((GValue *) value);
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
if (str)
retval = str;
else
@@ -217,7 +219,7 @@
setlocale (LC_NUMERIC, "C");
value = gda_handler_numerical_get_value_from_str (iface, sql, type);
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
return value;
}
Modified: trunk/libgda/information_schema.xml
==============================================================================
--- trunk/libgda/information_schema.xml (original)
+++ trunk/libgda/information_schema.xml Thu Aug 28 19:38:33 2008
@@ -333,7 +333,7 @@
<column name="collation_catalog" nullok="TRUE"/>
<column name="collation_schema" nullok="TRUE"/>
<column name="collation_name" nullok="TRUE"/>
- <column name="extra" nullok="TRUE" descr="CSV string with: AUTO_INCREMENT"/>
+ <column name="extra" nullok="TRUE" descr="CSV string with: AUTO_INCREMENT"/> <!-- set the gda-enums.h file -->
<column name="is_updatable" type="boolean" nullok="TRUE"/>
<column name="column_comments" nullok="TRUE"/>
<fkey ref_table="_tables">
Modified: trunk/libgda/providers-support/gda-pmodel.c
==============================================================================
--- trunk/libgda/providers-support/gda-pmodel.c (original)
+++ trunk/libgda/providers-support/gda-pmodel.c Thu Aug 28 19:38:33 2008
@@ -32,7 +32,7 @@
#include <libgda/gda-holder.h>
#include <libgda/gda-connection.h>
#include <libgda/gda-util.h>
-#include <sql-parser/gda-sql-statement.h>
+#include <sql-parser/gda-sql-parser.h>
#define CLASS(x) (GDA_PMODEL_CLASS (G_OBJECT_GET_CLASS (x)))
@@ -45,9 +45,28 @@
NB_QUERIES = 3
} ModType;
+typedef struct {
+ GdaStatement *select;
+ GdaSet *params;
+ GdaRow *row; /* non NULL once @select has been executed */
+} DelayedSelectStmt;
+
+static void delayed_select_stmt_free (DelayedSelectStmt *dstmt);
+
+/*
+ * To go from an "external" row number to an "internal" row number and then to a GdaRow,
+ * the following steps are required:
+ * - use @del_rows to determine if the row has been removed (if it's in the array), and otherwise
+ * get an "internal" row number
+ * - use the @upd_rows index to see if the row has been modified, and if it has, then use
+ * the associated DelayedSelectStmt to retreive the GdaRow
+ * - use the virtual methods to actually retreive the requested GdaRow
+ */
+static gint external_to_internal_row (GdaPModel *model, gint ext_row, GError **error);
+
/*
* Getting a GdaRow from a model row:
- * model row ==(model->index)==> model->rows index ==(model->rows)==> GdaRow
+ * [model row] ==(model->index)==> [index in model->rows] ==(model->rows)==> [GdaRow pointer]
*/
struct _GdaPModelPrivate {
GdaConnection *cnc;
@@ -56,16 +75,27 @@
GHashTable *index; /* key = model row number + 1, value = index in @rows array + 1*/
/* Internal iterator's information, if GDA_DATA_MODEL_CURSOR_* based access */
- gint iter_row; /* G_MININT if at start, G_MAXINT if at end */
+ gint iter_row; /* G_MININT if at start, G_MAXINT if at end, "external" row number */
GdaDataModelIter *iter;
GdaDataModelAccessFlags usage_flags;
+ /* attributes specific to data model modifications */
+ GdaSqlExpr *unique_row_condition;
+ gint *insert_to_select_mapping; /* see compute_insert_select_params_mapping() */
+
GdaSet *exec_set; /* owned by this object (copied) */
GdaSet *modif_set; /* owned by this object */
GdaStatement *modif_stmts[NB_QUERIES];
-
- GdaStatement **upd_stmts; /* one stmt per data model column */
+ GHashTable *upd_stmts; /* key = a gboolean vector with TRUEs when the column is used, value = an UPDATE GdaStatement */
+ GHashTable *ins_stmts; /* key = a gboolean vector with TRUEs when the column is used, value = an INSERT GdaStatement */
+ GdaStatement *one_row_select_stmt; /* used to retreive one row after an UPDATE
+ * or INSERT operation */
+
+ /* Global overriding data when the data model has been modified */
+ GArray *del_rows; /* array[index] = number of the index'th deleted row,
+ * sorted by row number (row numbers are internal row numbers )*/
+ GHashTable *upd_rows; /* key = internal row number + 1, value = a DelayedSelectStmt pointer */
};
/* properties */
@@ -105,6 +135,18 @@
GValue *value,
GParamSpec *pspec);
+/* utility functions */
+typedef struct {
+ gint size; /* number of elements in the @data array */
+ guchar *data; /* data[0] tp data[ size-1] are valid */
+} BVector;
+static GdaStatement *check_acceptable_statement (GdaPModel *model, GError **error);
+static GdaStatement *compute_single_update_stmt (GdaPModel *model, BVector *bv, GError **error);
+static GdaStatement *compute_single_insert_stmt (GdaPModel *model, BVector *bv, GError **error);
+static GdaStatement *compute_single_select_stmt (GdaPModel *model, GError **error);
+static gint *compute_insert_select_params_mapping (GdaSet *sel_params, GdaSet *ins_values, GdaSqlExpr *row_cond);
+
+
/* GdaDataModel interface */
static void gda_pmodel_data_model_init (GdaDataModelClass *iface);
static gint gda_pmodel_get_n_rows (GdaDataModel *model);
@@ -265,9 +307,16 @@
model->priv->iter_row = G_MININT;
model->priv->iter = NULL;
+ model->priv->unique_row_condition = NULL;
+ model->priv->insert_to_select_mapping = NULL;
model->priv->modif_set = NULL;
model->priv->exec_set = NULL;
model->priv->upd_stmts = NULL;
+ model->priv->ins_stmts = NULL;
+ model->priv->one_row_select_stmt = NULL;
+
+ model->priv->upd_rows = NULL;
+ model->priv->del_rows = NULL;
}
static void
@@ -281,10 +330,36 @@
if (model->priv) {
gint i;
+ if (model->priv->unique_row_condition) {
+ gda_sql_expr_free (model->priv->unique_row_condition);
+ model->priv->unique_row_condition = NULL;
+ }
+
+ if (model->priv->insert_to_select_mapping) {
+ g_free (model->priv->insert_to_select_mapping);
+ model->priv->insert_to_select_mapping = NULL;
+ }
+
+ if (model->priv->upd_rows) {
+ g_hash_table_destroy (model->priv->upd_rows);
+ model->priv->upd_rows = NULL;
+ }
+
+ if (model->priv->del_rows) {
+ g_array_free (model->priv->del_rows, TRUE);
+ model->priv->del_rows = NULL;
+ }
+
if (model->priv->cnc) {
g_object_unref (model->priv->cnc);
model->priv->cnc = NULL;
}
+
+ if (model->priv->one_row_select_stmt) {
+ g_object_unref (model->priv->one_row_select_stmt);
+ model->priv->one_row_select_stmt = NULL;
+ }
+
if (model->prep_stmt) {
g_object_unref (model->prep_stmt);
model->prep_stmt = NULL;
@@ -325,12 +400,12 @@
}
}
if (model->priv->upd_stmts) {
- gint j, ncols;
- ncols = gda_pmodel_get_n_columns ((GdaDataModel *) model);
- for (j = 0; j < ncols; j++)
- if (model->priv->upd_stmts [j])
- g_object_unref (model->priv->upd_stmts [j]);
- g_free (model->priv->upd_stmts);
+ g_hash_table_destroy (model->priv->upd_stmts);
+ model->priv->upd_stmts = NULL;
+ }
+ if (model->priv->ins_stmts) {
+ g_hash_table_destroy (model->priv->ins_stmts);
+ model->priv->ins_stmts = NULL;
}
}
@@ -419,12 +494,14 @@
break;
}
case PROP_ALL_STORED:
- if ((model->advertized_nrows < 0) && CLASS (model)->fetch_nb_rows)
- CLASS (model)->fetch_nb_rows (model);
+ if (g_value_get_boolean (value)) {
+ if ((model->advertized_nrows < 0) && CLASS (model)->fetch_nb_rows)
+ CLASS (model)->fetch_nb_rows (model);
- if (model->nb_stored_rows != model->advertized_nrows) {
- if (CLASS (model)->store_all)
- CLASS (model)->store_all (model, NULL);
+ if (model->nb_stored_rows != model->advertized_nrows) {
+ if (CLASS (model)->store_all)
+ CLASS (model)->store_all (model, NULL);
+ }
}
break;
case PROP_PARAMS: {
@@ -512,8 +589,8 @@
* @row: a #GdaRow row
* @rownum: "external" advertized row number
*
- * Stores @row into @model, externally advertized at row number @rownum. The reference to
- * @row is stolen.
+ * Stores @row into @model, externally advertized at row number @rownum (if no row has been removed).
+ * The reference to @row is stolen.
*/
void
gda_pmodel_take_row (GdaPModel *model, GdaRow *row, gint rownum)
@@ -534,7 +611,7 @@
* @model: a #GdaPModel data model
* @rownum: "external" advertized row number
*
- * Get the #GdaRow object stored within @model at row @rownum
+ * Get the #GdaRow object stored within @model at row @rownum (without taking care of removed rows)
*
* Returns: the requested #GdaRow, or %NULL if not found
*/
@@ -642,13 +719,113 @@
}
/**
- * gda_pmodel_set_modification_query
+ * gda_pmodel_set_modification_statement_sql
+ * @model: a #GdaPModel data model
+ * @sql: an SQL text
+ * @error: a place to store errors, or %NULL
+ *
+ * Offers the same feature as gda_pmodel_set_modification_statement() but using an SQL statement
+ *
+ * Returns: TRUE if no error occurred.
+ */
+gboolean
+gda_pmodel_set_modification_statement_sql (GdaPModel *model, const gchar *sql, GError **error)
+{
+ GdaSqlParser *parser;
+ GdaStatement *stmt;
+ const gchar *remain = NULL;
+ gboolean retval;
+
+ g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
+ g_return_val_if_fail (model->priv, FALSE);
+
+ /* check the original SELECT statement which was executed is not a compound statement */
+ if (! check_acceptable_statement (model, error))
+ return FALSE;
+
+ parser = gda_connection_create_parser (model->priv->cnc);
+ if (!parser)
+ parser = gda_sql_parser_new ();
+
+ stmt = gda_sql_parser_parse_string (parser, sql, &remain, error);
+ g_object_unref (parser);
+ if (!stmt)
+ return FALSE;
+ if (remain) {
+ g_object_unref (stmt);
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_SQL_ERROR,
+ _("Incorrect SQL expression"));
+ return FALSE;
+ }
+
+ retval = gda_pmodel_set_modification_statement (model, stmt, error);
+ g_object_unref (stmt);
+
+ return retval;
+}
+
+/*
+ * Checks that the SELECT statement which created @model exists and is correct.
+ *
+ * Returns: the SELECT #GdaStatement, or %NULL if an error occurred.
+ */
+static GdaStatement *
+check_acceptable_statement (GdaPModel *model, GError **error)
+{
+ GdaStatement *sel_stmt;
+ if (! model->prep_stmt) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Internal error: the \"prepared-stmt\" property has not been set"));
+ return NULL;
+ }
+
+ sel_stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
+ if (! sel_stmt) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Internal error: can't get the prepared statement's actual statement"));
+ return NULL;
+ }
+
+ if (gda_statement_get_statement_type (sel_stmt) != GDA_SQL_STATEMENT_SELECT) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Unsupported type of SELECT statement"));
+ return NULL;
+ }
+
+ return sel_stmt;
+}
+
+/**
+ * gda_pmodel_set_modification_statement
* @model: a #GdaPModel data model
* @mod_stmt: a #GdaStatement (INSERT, UPDATE or DELETE)
* @error: a place to store errors, or %NULL
*
- * Forces @model to allow data modification using @mod_stmt as the statement executed when the corresponding
- * modification is requested
+ * Informs @model that it should allow modifications to the data in some columns and some rows
+ * using @mod_stmt to propagate those modifications into the database.
+ *
+ * If @mod_stmt is:
+ * <itemizedlist>
+ * <listitem><para>an UPDATE statement, then all the rows in @model will be modifyable</para></listitem>
+ * <listitem><para>a DELETE statement, then it will be possible to delete rows in @model</para></listitem>
+ * <listitem><para>in INSERT statement, then it will be possible to add some rows to @model</para></listitem>
+ * <listitem><para>any other statement, then this method will return an error</para></listitem>
+ * </itemizedlist>
+ *
+ * This method can be called several times to specify different types of modification.
+ *
+ * If @mod_stmt is an UPDATE or DELETE statement then it should have a WHERE part which identifies
+ * a unique row in @model (please note that this property can't be checked but may result
+ * in @model behaving in an unpredictable way).
+ *
+ * NOTE1: However, if the gda_pmodel_set_row_selection_condition()
+ * or gda_pmodel_set_row_selection_condition_sql() have been successfully be called before, the WHERE
+ * part of @mod_stmt <emphasis>WILL</emphasis> be modified to use the row selection condition specified through one of
+ * these methods (please not that it is then possible to avoid specifying a WHERE part in @mod_stmt then).
+ *
+ * NOTE2: if gda_pmodel_set_row_selection_condition()
+ * or gda_pmodel_set_row_selection_condition_sql() have not yet been successfully be called before, then
+ * the WHERE part of @mod_stmt will be used as if one of these functions had been called.
*
* Returns: TRUE if no error occurred.
*/
@@ -661,22 +838,124 @@
g_return_val_if_fail (model->priv, FALSE);
g_return_val_if_fail (GDA_IS_STATEMENT (mod_stmt), FALSE);
+ /* check the original SELECT statement which was executed is not a compound statement */
+ if (! check_acceptable_statement (model, error))
+ return FALSE;
+
+ /* checks on the actual modification statement */
switch (gda_statement_get_statement_type (mod_stmt)) {
- case GDA_SQL_STATEMENT_INSERT:
+ case GDA_SQL_STATEMENT_INSERT: {
+ GdaSqlStatement *sqlst;
+ GdaSqlStatementInsert *ins;
+
mtype = INS_QUERY;
+
+ /* check that we have only one list of values (<=> only one row will be inserted) */
+ g_object_get (G_OBJECT (mod_stmt), "structure", &sqlst, NULL);
+ g_assert (sqlst);
+ ins = (GdaSqlStatementInsert*) sqlst->contents;
+ if (!ins->values_list || ! ins->values_list->data) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("INSERT statement must contain values to insert"));
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+ if (ins->values_list->next) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("INSERT statement must insert only one row"));
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+
+ gda_sql_statement_free (sqlst);
break;
- case GDA_SQL_STATEMENT_DELETE:
+ }
+ case GDA_SQL_STATEMENT_DELETE: {
+ GdaSqlStatement *sqlst;
+ GdaSqlStatementDelete *del;
+
mtype = DEL_QUERY;
+
+ /* if there is no WHERE part, then use model->priv->unique_row_condition if set */
+ g_object_get (G_OBJECT (mod_stmt), "structure", &sqlst, NULL);
+ g_assert (sqlst);
+ del = (GdaSqlStatementDelete*) sqlst->contents;
+ if (!del->cond) {
+ if (model->priv->unique_row_condition) {
+ /* copy model->priv->unique_row_condition */
+ del->cond = gda_sql_expr_copy (model->priv->unique_row_condition);
+ GDA_SQL_ANY_PART (del->cond)->parent = GDA_SQL_ANY_PART (del);
+ g_object_set (G_OBJECT (mod_stmt), "structure", sqlst, NULL);
+ }
+ else {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("DELETE statement must have a WHERE part"));
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+ }
+ else {
+ if (model->priv->unique_row_condition) {
+ /* replace WHERE with model->priv->unique_row_condition */
+ gda_sql_expr_free (del->cond);
+ del->cond = gda_sql_expr_copy (model->priv->unique_row_condition);
+ GDA_SQL_ANY_PART (del->cond)->parent = GDA_SQL_ANY_PART (del);
+ g_object_set (G_OBJECT (mod_stmt), "structure", sqlst, NULL);
+ }
+ else if (! gda_pmodel_set_row_selection_condition (model, del->cond, error)) {
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+ }
+ gda_sql_statement_free (sqlst);
break;
- case GDA_SQL_STATEMENT_UPDATE:
+ }
+ case GDA_SQL_STATEMENT_UPDATE: {
+ GdaSqlStatement *sqlst;
+ GdaSqlStatementUpdate *upd;
+
mtype = UPD_QUERY;
+
+ /* if there is no WHERE part, then use model->priv->unique_row_condition if set */
+ g_object_get (G_OBJECT (mod_stmt), "structure", &sqlst, NULL);
+ g_assert (sqlst);
+ upd = (GdaSqlStatementUpdate*) sqlst->contents;
+ if (!upd->cond) {
+ if (model->priv->unique_row_condition) {
+ /* copy model->priv->unique_row_condition */
+ upd->cond = gda_sql_expr_copy (model->priv->unique_row_condition);
+ GDA_SQL_ANY_PART (upd->cond)->parent = GDA_SQL_ANY_PART (upd);
+ g_object_set (G_OBJECT (mod_stmt), "structure", sqlst, NULL);
+ }
+ else {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("UPDATE statement must have a WHERE part"));
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+ }
+ else {
+ if (model->priv->unique_row_condition) {
+ /* replace WHERE with model->priv->unique_row_condition */
+ gda_sql_expr_free (upd->cond);
+ upd->cond = gda_sql_expr_copy (model->priv->unique_row_condition);
+ GDA_SQL_ANY_PART (upd->cond)->parent = GDA_SQL_ANY_PART (upd);
+ g_object_set (G_OBJECT (mod_stmt), "structure", sqlst, NULL);
+ }
+ else if (! gda_pmodel_set_row_selection_condition (model, upd->cond, error)) {
+ gda_sql_statement_free (sqlst);
+ return FALSE;
+ }
+ }
+ gda_sql_statement_free (sqlst);
break;
+ }
default:
break;
}
if (mtype != NB_QUERIES) {
- if (! gda_sql_statement_check_structure (mod_stmt, error))
+ if (! gda_statement_check_structure (mod_stmt, error))
return FALSE;
if (model->priv->modif_stmts[mtype]) {
@@ -754,7 +1033,7 @@
}
/**
- * gda_pmodel_compute_modification_queries
+ * gda_pmodel_compute_modification_statements
* @model: a #GdaPModel data model
* @require_pk: FALSE if all fields can be used in the WHERE condition when no primary key exists
* @error: a place to store errors, or %NULL
@@ -770,15 +1049,15 @@
{
GdaStatement *stmt;
ModType mtype;
+ gboolean retval = TRUE;
+ GdaStatement *modif_stmts[NB_QUERIES];
g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
g_return_val_if_fail (model->priv, FALSE);
- stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
- if (!stmt) {
- g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("No SELECT statement to use"));
+ stmt = check_acceptable_statement (model, error);
+ if (!stmt)
return FALSE;
- }
+
if (!model->priv->cnc) {
g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_CONNECTION_ERROR,
_("No connection to use"));
@@ -789,21 +1068,246 @@
g_object_unref (model->priv->modif_stmts[mtype]);
model->priv->modif_stmts[mtype] = NULL;
}
- return gda_compute_dml_statements (model->priv->cnc, stmt, require_pk,
- &(model->priv->modif_stmts[INS_QUERY]),
- &(model->priv->modif_stmts[UPD_QUERY]),
- &(model->priv->modif_stmts[DEL_QUERY]), error);
- if (!compute_modif_set (model, error)) {
- for (mtype = FIRST_QUERY; mtype < NB_QUERIES; mtype++)
- if (model->priv->modif_stmts[mtype]) {
- g_object_unref (model->priv->modif_stmts[mtype]);
- model->priv->modif_stmts[mtype] = NULL;
+
+ retval = gda_compute_dml_statements (model->priv->cnc, stmt, require_pk,
+ &(modif_stmts[INS_QUERY]),
+ &(modif_stmts[UPD_QUERY]),
+ &(modif_stmts[DEL_QUERY]), error);
+ if (retval) {
+ for (mtype = FIRST_QUERY; mtype < NB_QUERIES; mtype++) {
+#ifdef GDA_DEBUG_NO
+ gchar *sql;
+ sql = gda_statement_to_sql (modif_stmts[mtype], NULL, NULL);
+ g_print ("type %d => %s\n", mtype, sql);
+ g_free (sql);
+#endif
+ if (modif_stmts[mtype] &&
+ ! gda_pmodel_set_modification_statement (model, modif_stmts[mtype], error)) {
+ retval = FALSE;
+ break;
}
+ }
+ }
+ if (!retval) {
+ for (mtype = FIRST_QUERY; mtype < NB_QUERIES; mtype++) {
+ if (modif_stmts[mtype])
+ g_object_unref (modif_stmts[mtype]);
+ }
+ }
+ return retval;
+}
+
+static gboolean
+row_selection_condition_foreach_func (GdaSqlAnyPart *part, gpointer data, GError **error)
+{
+ if (part->type != GDA_SQL_ANY_SQL_OPERATION)
+ return TRUE;
+
+ GdaSqlOperation *op = (GdaSqlOperation*) part;
+ if (op->operator != GDA_SQL_OPERATOR_TYPE_EQ) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Invalid unique row condition (ony equal operators are allowed)"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gda_pmodel_set_row_selection_condition
+ * @model: a #GdaPModel data model
+ * @expr: a #GdaSqlExpr expression
+ * @error: a place to store errors, or %NULL
+ *
+ * Offers the same features as gda_pmodel_set_row_selection_condition_sql() but using a #GdaSqlExpr
+ * structure instead of an SQL syntax.
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_pmodel_set_row_selection_condition (GdaPModel *model, GdaSqlExpr *expr, GError **error)
+{
+ gboolean valid;
+
+ g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
+ g_return_val_if_fail (model->priv, FALSE);
+ g_return_val_if_fail (expr, FALSE);
+
+ if (!check_acceptable_statement (model, error))
+ return FALSE;
+
+ if (model->priv->unique_row_condition) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Unique row condition has already been specified"));
return FALSE;
}
+
+ valid = gda_sql_any_part_foreach (GDA_SQL_ANY_PART (expr),
+ (GdaSqlForeachFunc) row_selection_condition_foreach_func,
+ NULL, error);
+ if (!valid)
+ return FALSE;
+
+ model->priv->unique_row_condition = gda_sql_expr_copy (expr);
return TRUE;
}
+/**
+ * gda_pmodel_set_row_selection_condition_sql
+ * @model: a #GdaPModel data model
+ * @sql_where: an SQL condition (withouth the WHERE keyword)
+ * @error: a place to store errors, or %NULL
+ *
+ * Specifies the SQL condition corresponding to the WHERE part of a SELECT statement which would
+ * return only 1 row (the expression of the primary key).
+ *
+ * For example for a table created as <![CDATA["CREATE TABLE mytable (part1 int NOT NULL, part2 string NOT NULL,
+ * name string, PRIMARY KEY (part1, part2))"]]>, and if @pmodel corresponds to the execution of the
+ * <![CDATA["SELECT name, part1, part2 FROM mytable"]]>, then the sensible value for @sql_where would be
+ * <![CDATA["part1 = ##-1::int AND part2 = ##-2::string"]]> because the values of the 'part1' field are located
+ * in @pmodel's column number 1 and the values of the 'part2' field are located
+ * in @pmodel's column number 2 and the primary key is composed of (part1, part2).
+ *
+ * For more information about the syntax of the parameters (named <![CDATA["##-1::int"]]> for example), see the
+ * <link linkend="GdaSqlParser.description">GdaSqlParser</link> documentation, and
+ * gda_pmodel_set_modification_statement().
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_pmodel_set_row_selection_condition_sql (GdaPModel *model, const gchar *sql_where, GError **error)
+{
+ GdaSqlParser *parser;
+ GdaStatement *stmt;
+ gchar *sql;
+ const gchar *remain = NULL;
+ gboolean retval;
+ GdaSqlStatement *sqlst;
+ GdaSqlStatementSelect *selstmt;
+
+ g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
+ g_return_val_if_fail (model->priv, FALSE);
+
+ if (!check_acceptable_statement (model, error))
+ return FALSE;
+
+ if (model->priv->unique_row_condition) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Unique row condition has already been specified"));
+ return FALSE;
+ }
+
+ parser = gda_connection_create_parser (model->priv->cnc);
+ if (!parser)
+ parser = gda_sql_parser_new ();
+
+ sql= g_strdup_printf ("SELECT * FROM table WHERE %s", sql_where);
+ stmt = gda_sql_parser_parse_string (parser, sql, &remain, error);
+ g_object_unref (parser);
+ if (!stmt) {
+ g_free (sql);
+ return FALSE;
+ }
+ if (remain) {
+ g_object_unref (stmt);
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_SQL_ERROR,
+ _("Incorrect filter expression"));
+ g_free (sql);
+ return FALSE;
+ }
+ g_free (sql);
+
+
+ g_object_get (stmt, "structure", &sqlst, NULL);
+ selstmt = (GdaSqlStatementSelect *) sqlst->contents;
+
+ retval = gda_pmodel_set_row_selection_condition (model, selstmt->where_cond, error);
+ gda_sql_statement_free (sqlst);
+
+ g_object_unref (stmt);
+ return retval;
+}
+
+/**
+ * gda_pmodel_compute_row_selection_condition
+ * @model: a #GdaPModel object
+ * @error: a place to store errors, or %NULL
+ *
+ * Offers the same features as gda_pmodel_set_row_selection_condition() but the expression
+ * is computed from the meta data associated to the connection being used when @model was created.
+ *
+ * NOTE1: make sure the meta data associated to the connection is up to date before using this
+ * method, see gda_connection_update_meta_store().
+ *
+ * NOTE2: if the SELECT statement from which @model has been created uses more than one table, or
+ * if the table used does not have any primary key, then this method will fail
+ *
+ * Returns: TRUE if no error occurred.
+ */
+gboolean
+gda_pmodel_compute_row_selection_condition (GdaPModel *model, GError **error)
+{
+ GdaSqlExpr *expr;
+ gboolean retval = FALSE;
+ GdaStatement *stmt;
+ GdaSqlStatement *sqlst = NULL;
+ GdaSqlStatementSelect *select;
+ GdaSqlSelectTarget *target;
+ GdaMetaStruct *mstruct = NULL;
+ GdaMetaDbObject *dbo;
+ GValue *nvalue = NULL;
+
+ g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
+ g_return_val_if_fail (model->priv, FALSE);
+
+ stmt = check_acceptable_statement (model, error);
+ if (!stmt)
+ return FALSE;
+
+ if (!model->priv->cnc) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_CONNECTION_ERROR,
+ _("No connection to use"));
+ return FALSE;
+ }
+
+ g_object_get (G_OBJECT (stmt), "structure", &sqlst, NULL);
+ g_assert (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT);
+ select = (GdaSqlStatementSelect*) sqlst->contents;
+ if (!select->from || ! select->from->targets || ! select->from->targets->data) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_SQL_ERROR,
+ _("No table to select from in SELECT statement"));
+ goto out;
+ }
+ if (select->from->targets->next) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_SQL_ERROR,
+ _("SELECT statement uses more than one table to select from"));
+ goto out;
+ }
+ target = (GdaSqlSelectTarget *) select->from->targets->data;
+ if (!target->table_name) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_SQL_ERROR,
+ _("No table to select from in SELECT statement"));
+ goto out;
+ }
+ g_value_set_string ((nvalue = gda_value_new (G_TYPE_STRING)), target->table_name);
+ mstruct = gda_meta_struct_new (gda_connection_get_meta_store (model->priv->cnc), GDA_META_STRUCT_FEATURE_NONE);
+ dbo = gda_meta_struct_complement (mstruct, GDA_META_DB_TABLE, NULL, NULL, nvalue, error);
+ if (!dbo)
+ goto out;
+
+ expr = gda_compute_unique_table_row_condition (select, GDA_META_TABLE (dbo), TRUE, error);
+ retval = gda_pmodel_set_row_selection_condition (model, expr, error);
+
+ out:
+ if (sqlst)
+ gda_sql_statement_free (sqlst);
+ if (mstruct)
+ g_object_unref (mstruct);
+ if (nvalue)
+ gda_value_free (nvalue);
+
+ return retval;
+}
/*
* GdaDataModel interface implementation
@@ -812,16 +1316,20 @@
gda_pmodel_get_n_rows (GdaDataModel *model)
{
GdaPModel *imodel;
+ gint retval;
g_return_val_if_fail (GDA_IS_PMODEL (model), 0);
imodel = GDA_PMODEL (model);
g_return_val_if_fail (imodel->priv, 0);
+ retval = imodel->advertized_nrows;
if ((imodel->advertized_nrows < 0) &&
(imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM) &&
CLASS (model)->fetch_nb_rows)
- return CLASS (model)->fetch_nb_rows (imodel);
+ retval = CLASS (model)->fetch_nb_rows (imodel);
- return imodel->advertized_nrows;
+ if ((retval > 0) && (imodel->priv->del_rows))
+ retval -= imodel->priv->del_rows->len;
+ return retval;
}
static gint
@@ -878,11 +1386,60 @@
return flags;
}
+/*
+ * Converts an external row number to an internal row number
+ * Returns: a row number, or -1 if row number does not exist
+ */
+static gint
+external_to_internal_row (GdaPModel *model, gint ext_row, GError **error)
+{
+ gint nrows;
+ gint int_row = ext_row;
+
+ /* row number alteration: deleted rows */
+ if (model->priv->del_rows) {
+ gint i;
+ for (i = 0; i < model->priv->del_rows->len; i++) {
+ gint indexed = g_array_index (model->priv->del_rows, gint, i);
+ if (indexed <= ext_row + i)
+ int_row += 1;
+ else
+ break;
+ }
+ }
+
+ /* check row number validity */
+ nrows = model->advertized_nrows < 0 ? gda_pmodel_get_n_rows ((GdaDataModel*) model) :
+ model->advertized_nrows;
+ if ((ext_row < 0) || ((nrows >= 0) && (int_row >= nrows))) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ROW_OUT_OF_RANGE_ERROR,
+ _("Row %d out of range (0-%d)"), ext_row,
+ gda_pmodel_get_n_rows ((GdaDataModel*) model) - 1);
+ return -1;
+ }
+
+ return int_row;
+}
+
+#ifdef GDA_DEBUG_NO
+static void foreach_func_dump (gpointer key, gpointer value, gpointer dummy)
+{
+ g_print (" row %d => %p\n", *(const gint*) key, value);
+}
+static void dump_d (GdaPModel *model)
+{
+ if (model->priv->upd_rows) {
+ g_print ("Delayed SELECT for %p:\n", model);
+ g_hash_table_foreach (model->priv->upd_rows, foreach_func_dump, NULL);
+ }
+}
+#endif
+
static const GValue *
gda_pmodel_get_value_at (GdaDataModel *model, gint col, gint row)
{
GdaRow *prow;
- gint irow, nrows;
+ gint int_row, irow;
GdaPModel *imodel;
g_return_val_if_fail (GDA_IS_PMODEL (model), NULL);
@@ -893,19 +1450,70 @@
if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM))
return NULL;
- /* check row number validity */
- nrows = imodel->advertized_nrows < 0 ? gda_pmodel_get_n_rows (model) : imodel->advertized_nrows;
- if ((row < 0) || ((nrows >= 0) && (row >= nrows)))
+ int_row = external_to_internal_row (imodel, row, NULL);
+ if (int_row < 0)
return NULL;
- irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (row + 1)));
- if (irow <= 0) {
- prow = NULL;
- if (CLASS (model)->fetch_random)
- CLASS (model)->fetch_random (imodel, &prow, row, NULL);
+ DelayedSelectStmt *dstmt = NULL;
+#ifdef GDA_DEBUG_NO
+ dump_d (imodel);
+#endif
+ if (imodel->priv->upd_rows)
+ dstmt = g_hash_table_lookup (imodel->priv->upd_rows, &int_row);
+ if (dstmt) {
+ if (! dstmt->row) {
+ GdaDataModel *tmpmodel;
+ if (!dstmt->select || !dstmt->params)
+ return NULL;
+ tmpmodel = gda_connection_statement_execute_select (imodel->priv->cnc,
+ dstmt->select,
+ dstmt->params, NULL);
+ if (!tmpmodel)
+ return NULL;
+
+ if (gda_data_model_get_n_rows (tmpmodel) != 1) {
+ g_object_unref (tmpmodel);
+ return NULL;
+ }
+
+ gint i, ncols;
+ ncols = gda_data_model_get_n_columns (tmpmodel);
+ prow = gda_row_new (ncols);
+ for (i = 0; i < ncols; i++) {
+ GValue *value;
+ const GValue *cvalue;
+ value = gda_row_get_value (prow, i);
+ cvalue = gda_data_model_get_value_at (tmpmodel, i, 0);
+
+ if (cvalue && !gda_value_is_null (cvalue)) {
+ gda_value_reset_with_type (value, G_VALUE_TYPE (cvalue));
+ if (! gda_value_set_from_value (value, cvalue)) {
+ g_object_unref (tmpmodel);
+ g_object_unref (prow);
+ return NULL;
+ }
+ }
+ else
+ gda_value_set_null (value);
+ }
+ dstmt->row = prow;
+ //gda_data_model_dump (tmpmodel, stdout);
+ g_object_unref (tmpmodel);
+ }
+ else
+ prow = dstmt->row;
+ }
+ else {
+ irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index,
+ GINT_TO_POINTER (int_row + 1)));
+ if (irow <= 0) {
+ prow = NULL;
+ if (CLASS (model)->fetch_random)
+ CLASS (model)->fetch_random (imodel, &prow, int_row, NULL);
+ }
+ else
+ prow = g_array_index (imodel->priv->rows, GdaRow *, irow - 1);
}
- else
- prow = g_array_index (imodel->priv->rows, GdaRow *, irow - 1);
if (prow)
return gda_row_get_value (prow, col);
@@ -960,7 +1568,7 @@
GdaPModel *imodel;
GdaRow *prow = NULL;
gint target_iter_row;
- gint irow;
+ gint irow, int_row;
g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
imodel = (GdaPModel *) model;
@@ -979,11 +1587,12 @@
target_iter_row = 0;
else
target_iter_row = imodel->priv->iter_row + 1;
+ int_row = external_to_internal_row (imodel, target_iter_row, NULL);
- irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (target_iter_row + 1)));
+ irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (int_row + 1)));
if (irow > 0)
prow = g_array_index (imodel->priv->rows, GdaRow *, irow - 1);
- if (!CLASS (model)->fetch_next (imodel, &prow, target_iter_row, NULL))
+ if (!CLASS (model)->fetch_next (imodel, &prow, int_row, NULL))
TO_IMPLEMENT;
if (prow) {
@@ -1005,7 +1614,7 @@
GdaPModel *imodel;
GdaRow *prow = NULL;
gint target_iter_row;
- gint irow;
+ gint irow, int_row;
g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
imodel = (GdaPModel *) model;
@@ -1028,10 +1637,11 @@
else
target_iter_row = imodel->priv->iter_row - 1;
- irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (target_iter_row + 1)));
+ int_row = external_to_internal_row (imodel, target_iter_row, NULL);
+ irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (int_row + 1)));
if (irow > 0)
prow = g_array_index (imodel->priv->rows, GdaRow *, irow - 1);
- if (!CLASS (model)->fetch_prev (imodel, &prow, target_iter_row, NULL))
+ if (!CLASS (model)->fetch_prev (imodel, &prow, int_row, NULL))
TO_IMPLEMENT;
if (prow) {
@@ -1051,24 +1661,26 @@
{
GdaPModel *imodel;
GdaRow *prow = NULL;
- gint irow;
+ gint irow, int_row;
g_return_val_if_fail (GDA_IS_PMODEL (model), FALSE);
imodel = (GdaPModel *) model;
g_return_val_if_fail (imodel->priv, FALSE);
+ int_row = external_to_internal_row (imodel, row, NULL);
if (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)
- return gda_data_model_move_iter_at_row_default (model, iter, row);
+ return gda_data_model_move_iter_at_row_default (model, iter, int_row);
g_return_val_if_fail (iter, FALSE);
g_return_val_if_fail (imodel->priv->iter == iter, FALSE);
- irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index, GINT_TO_POINTER (row + 1)));
+ irow = GPOINTER_TO_INT (g_hash_table_lookup (imodel->priv->index,
+ GINT_TO_POINTER (int_row + 1)));
if (irow > 0)
prow = g_array_index (imodel->priv->rows, GdaRow *, irow - 1);
if (CLASS (model)->fetch_at) {
- if (!CLASS (model)->fetch_at (imodel, &prow, row, NULL))
+ if (!CLASS (model)->fetch_at (imodel, &prow, int_row, NULL))
TO_IMPLEMENT;
if (prow) {
imodel->priv->iter_row = row;
@@ -1122,12 +1734,12 @@
/*
* creates a derivative of the model->priv->modif_stmts [UPD_QUERY] statement
- * where only the column @col is updated.
+ * where only the columns where @bv->data[colnum] is not 0 are updated.
*
* Returns: a new #GdaStatement, or %NULL
*/
static GdaStatement *
-compute_single_update_stmt (GdaPModel *model, gint col, GError **error)
+compute_single_update_stmt (GdaPModel *model, BVector *bv, GError **error)
{
GdaSqlStatement *sqlst;
GdaSqlStatementUpdate *upd;
@@ -1137,6 +1749,8 @@
g_assert (model->priv->modif_stmts [UPD_QUERY]);
g_object_get (G_OBJECT (model->priv->modif_stmts [UPD_QUERY]), "structure", &sqlst, NULL);
g_assert (sqlst);
+ g_free (sqlst->sql);
+ sqlst->sql = NULL;
g_assert (sqlst->stmt_type == GDA_SQL_STATEMENT_UPDATE);
upd = (GdaSqlStatementUpdate*) sqlst->contents;
@@ -1153,8 +1767,8 @@
flist = flist->next;
continue;
}
- if (num == col) {
- /* this field is the field to be updated */
+ if ((num < bv->size) && bv->data[num]) {
+ /* this field is a field to be updated */
field_found = TRUE;
elist = elist->next;
flist = flist->next;
@@ -1178,34 +1792,299 @@
updstmt = (GdaStatement *) g_object_new (GDA_TYPE_STATEMENT, "structure", sqlst, NULL);
else
g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("Column %d can't be modified"), col);
+ _("Some columns can't be modified"));
gda_sql_statement_free (sqlst);
#ifdef GDA_DEBUG_NO
+ GString *bvstr;
+ gint i;
+ gboolean first = TRUE;
+ bvstr = g_string_new ("(");
+ for (i = 0; i < bv->size; i++) {
+ if (bv->data[i]) {
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (bvstr, ", ");
+ g_string_append_printf (bvstr, "%d", i);
+ }
+ }
+ g_string_append_c (bvstr, ')');
+
if (updstmt) {
gchar *sql;
sql = gda_statement_serialize (updstmt);
- g_print ("UPDATE for col %d => %s\n", col, sql);
+ g_print ("UPDATE for columns %s => %s\n", bvstr->str, sql);
g_free (sql);
}
else
- g_print ("UPDATE for col %d: ERROR\n", col);
+ g_print ("UPDATE for columns %s: ERROR\n", bvstr->str);
+ g_string_free (bvstr, TRUE);
#endif
return updstmt;
}
-static gboolean
-gda_pmodel_set_value_at (GdaDataModel *model, gint col, gint row, const GValue *value, GError **error)
+/*
+ * creates a derivative of the model->priv->modif_stmts [INS_QUERY] statement
+ * where only the columns where @bv->data[colnum] is not 0 are not mentionned.
+ *
+ * Returns: a new #GdaStatement, or %NULL
+ */
+static GdaStatement *
+compute_single_insert_stmt (GdaPModel *model, BVector *bv, GError **error)
{
- GdaPModel *imodel;
- gint i, ncols;
+ GdaSqlStatement *sqlst;
+ GdaSqlStatementInsert *ins;
+ GdaStatement *insstmt = NULL;
+
+ /* get a copy of complete INSERT stmt */
+ g_assert (model->priv->modif_stmts [INS_QUERY]);
+ g_object_get (G_OBJECT (model->priv->modif_stmts [INS_QUERY]), "structure", &sqlst, NULL);
+ g_assert (sqlst);
+ g_free (sqlst->sql);
+ sqlst->sql = NULL;
+ g_assert (sqlst->stmt_type == GDA_SQL_STATEMENT_INSERT);
+ ins = (GdaSqlStatementInsert*) sqlst->contents;
+
+ /* remove fields to insert for which we don't have any value (the default value will be used) */
+ GSList *elist, *flist;
+ gboolean field_found = FALSE;
+ for (elist = (GSList*) ins->values_list->data, flist = ins->fields_list; elist && flist; ) {
+ GdaSqlExpr *expr = (GdaSqlExpr *) elist->data;
+ gint num;
+ gboolean old_val;
+ if (! expr->param_spec || !param_name_to_int (expr->param_spec->name, &num, &old_val) || old_val) {
+ /* ignore this field to be inserted */
+ elist = elist->next;
+ flist = flist->next;
+ continue;
+ }
+ if ((num < bv->size) && bv->data[num]) {
+ /* this field is a field to be inserted */
+ field_found = TRUE;
+ elist = elist->next;
+ flist = flist->next;
+ continue;
+ }
+ /* remove that field */
+ GSList *nelist, *nflist;
+ nelist = elist->next;
+ nflist = flist->next;
+ gda_sql_expr_free (expr);
+ gda_sql_field_free ((GdaSqlField*) flist->data);
+
+ ins->values_list->data = g_slist_delete_link ((GSList*) ins->values_list->data, elist);
+ ins->fields_list = g_slist_delete_link (ins->fields_list, flist);
+ elist = nelist;
+ flist = nflist;
+ }
+
+ /* create a new GdaStatement */
+ if (field_found)
+ insstmt = (GdaStatement *) g_object_new (GDA_TYPE_STATEMENT, "structure", sqlst, NULL);
+ else
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Some columns can't be modified"));
+ gda_sql_statement_free (sqlst);
+
+#ifdef GDA_DEBUG_NO
+ GString *bvstr;
+ gint i;
+ gboolean first = TRUE;
+ bvstr = g_string_new ("(");
+ for (i = 0; i < bv->size; i++) {
+ if (bv->data[i]) {
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (bvstr, ", ");
+ g_string_append_printf (bvstr, "%d", i);
+ }
+ }
+ g_string_append_c (bvstr, ')');
+
+ if (insstmt) {
+ gchar *sql;
+ sql = gda_statement_serialize (insstmt);
+ g_print ("INSERT for columns %s => %s\n", bvstr->str, sql);
+ g_free (sql);
+ }
+ else
+ g_print ("INSERT for columns %s: ERROR\n", bvstr->str);
+ g_string_free (bvstr, TRUE);
+#endif
+
+ return insstmt;
+}
+
+/*
+ * creates a derivative of the SELECT statement from which @model has been created,
+ * but to select only one single row (this statement is executed when a GdaRow is requested
+ * after an UPDATE or INSERT statement has been run)
+ *
+ * The new created statement is merely the copy of the SELECT statement where the WHERE part
+ * has been altered as "<original condition> AND <update condition>"
+ *
+ * Returns: a new #GdaStatement, or %NULL
+ */
+static GdaStatement *
+compute_single_select_stmt (GdaPModel *model, GError **error)
+{
+ GdaStatement *sel_stmt;
+ GdaStatement *ret_stmt = NULL;
+ GdaSqlStatement *sel_sqlst;
+ GdaSqlExpr *row_cond = NULL;
+
+ if (! model->prep_stmt) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Internal error: the \"prepared-stmt\" property has not been set"));
+ return NULL;
+ }
+
+ sel_stmt = gda_pstmt_get_gda_statement (model->prep_stmt);
+ if (! sel_stmt) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Internal error: can't get the prepared statement's actual statement"));
+ return NULL;
+ }
+
+ if (model->priv->unique_row_condition)
+ row_cond = gda_sql_expr_copy (model->priv->unique_row_condition);
+ else if (model->priv->modif_stmts [DEL_QUERY]) {
+ GdaStatement *del_stmt;
+ GdaSqlStatement *del_sqlst;
+ GdaSqlStatementDelete *del;
+ del_stmt = model->priv->modif_stmts [DEL_QUERY];
+
+ g_object_get (G_OBJECT (del_stmt), "structure", &del_sqlst, NULL);
+ del = (GdaSqlStatementDelete*) del_sqlst->contents;
+ row_cond = del->cond;
+ del->cond = NULL;
+ gda_sql_statement_free (del_sqlst);
+ if (!gda_pmodel_set_row_selection_condition (model, row_cond, NULL)) {
+ gda_sql_expr_free (row_cond);
+ row_cond = NULL;
+ }
+ }
+ else if (model->priv->modif_stmts [UPD_QUERY]) {
+ GdaStatement *upd_stmt;
+ GdaSqlStatement *upd_sqlst;
+ GdaSqlStatementUpdate *upd;
+ upd_stmt = model->priv->modif_stmts [UPD_QUERY];
+
+ g_object_get (G_OBJECT (upd_stmt), "structure", &upd_sqlst, NULL);
+ upd = (GdaSqlStatementUpdate*) upd_sqlst->contents;
+ row_cond = upd->cond;
+ upd->cond = NULL;
+ gda_sql_statement_free (upd_sqlst);
+ if (!gda_pmodel_set_row_selection_condition (model, row_cond, NULL)) {
+ gda_sql_expr_free (row_cond);
+ row_cond = NULL;
+ }
+ }
+ if (!row_cond) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Unable to identify a way to fetch a single row"));
+ return NULL;
+ }
+
+ g_object_get (G_OBJECT (sel_stmt), "structure", &sel_sqlst, NULL);
+ if (sel_sqlst->stmt_type != GDA_SQL_STATEMENT_SELECT) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Can only operate on non compound SELECT statements"));
+ gda_sql_statement_free (sel_sqlst);
+ gda_sql_expr_free (row_cond);
+ return NULL;
+ }
+
+ GdaSqlStatementSelect *sel;
+
+ sel = (GdaSqlStatementSelect*) sel_sqlst->contents;
+ g_free (sel_sqlst->sql);
+ sel_sqlst->sql = NULL;
+ if (sel->where_cond) {
+ GdaSqlExpr *and_expr;
+ GdaSqlOperation *and_cond;
+
+ and_expr = gda_sql_expr_new (GDA_SQL_ANY_PART (sel));
+ and_cond = gda_sql_operation_new (GDA_SQL_ANY_PART (and_expr));
+ and_expr->cond = and_cond;
+ and_cond->operator = GDA_SQL_OPERATOR_TYPE_AND;
+ and_cond->operands = g_slist_append (NULL, sel->where_cond);
+ GDA_SQL_ANY_PART (sel->where_cond)->parent = GDA_SQL_ANY_PART (and_cond);
+ sel->where_cond = and_expr;
+
+ and_cond->operands = g_slist_append (and_cond->operands, row_cond);
+ GDA_SQL_ANY_PART (row_cond)->parent = GDA_SQL_ANY_PART (and_cond);
+ }
+ else {
+ sel->where_cond = row_cond;
+ GDA_SQL_ANY_PART (row_cond)->parent = GDA_SQL_ANY_PART (sel);
+ }
+
+ ret_stmt = (GdaStatement *) g_object_new (GDA_TYPE_STATEMENT, "structure", sel_sqlst, NULL);
+
+ gda_sql_statement_free (sel_sqlst);
+
+#ifdef GDA_DEBUG_NO
+ gchar *sql;
+ sql = gda_statement_serialize (ret_stmt);
+ g_print ("SINGLE ROW SELECT => %s\n", sql);
+ g_free (sql);
+ sql = gda_statement_to_sql (ret_stmt, NULL, NULL);
+ g_print ("SINGLE ROW SELECT => %s\n", sql);
+ g_free (sql);
+#endif
+
+ return ret_stmt;
+}
+
+/*
+ * Hash and Equal functions for usage in a GHashTable
+ * The comparison is made of BVector vectors
+ */
+static guint
+bvector_hash (BVector *key)
+{
+ gint i;
+ guint ret = 0;
+ for (i = 0; i < key->size; i++) {
+ ret += key->data [i];
+ ret <<= 1;
+ }
+ return ret;
+}
+
+static gboolean
+bvector_equal (BVector *key1, BVector *key2)
+{
+ if (key1->size != key2->size)
+ return FALSE;
+ return memcmp (key1->data, key2->data, sizeof (guchar) * key1->size) == 0 ? TRUE : FALSE;
+}
+
+static void
+bvector_free (BVector *key)
+{
+ g_free (key->data);
+ g_free (key);
+}
+
+/*
+ * REM: @bv is stolen here
+ */
+static gboolean
+vector_set_value_at (GdaPModel *imodel, BVector *bv, gint row, GError **error)
+{
+ gint int_row, i, ncols;
GdaHolder *holder;
gchar *str;
+ GdaStatement *stmt;
+ gboolean free_bv = TRUE;
- imodel = (GdaPModel *) model;
-
- g_return_val_if_fail (imodel->priv, FALSE);
+ /* arguments check */
+ g_assert (bv);
if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)) {
g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
@@ -1218,48 +2097,36 @@
return FALSE;
}
- if (row >= gda_pmodel_get_n_rows (model)) {
- g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("Row %d out of range (0-%d)"), row, gda_pmodel_get_n_rows (model)-1);
+ int_row = external_to_internal_row (imodel, row, error);
+ if (int_row < 0)
return FALSE;
- }
-
- ncols = gda_pmodel_get_n_columns (model);
- if (col >= ncols) {
- g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("Column %d out of range (0-%d)"), col, ncols-1);
- return FALSE;
- }
+ /* compute UPDATE statement */
if (! imodel->priv->upd_stmts)
- imodel->priv->upd_stmts = g_new0 (GdaStatement *, ncols);
- if (! imodel->priv->upd_stmts [col]) {
- imodel->priv->upd_stmts [col] = compute_single_update_stmt (imodel, col, error);
- if (!imodel->priv->upd_stmts [col])
+ imodel->priv->upd_stmts = g_hash_table_new_full ((GHashFunc) bvector_hash, (GEqualFunc) bvector_equal,
+ (GDestroyNotify) bvector_free, g_object_unref);
+ stmt = g_hash_table_lookup (imodel->priv->upd_stmts, bv);
+ if (! stmt) {
+ stmt = compute_single_update_stmt (imodel, bv, error);
+ if (stmt) {
+ free_bv = FALSE;
+ g_hash_table_insert (imodel->priv->upd_stmts, bv, stmt);
+ }
+ else {
+ bvector_free (bv);
return FALSE;
- }
-
- str = g_strdup_printf ("+%d", col);
- holder = gda_set_get_holder (imodel->priv->modif_set, str);
- g_free (str);
- if (! holder) {
- g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
- _("Column %d can't be modified"), col);
- return FALSE;
- }
- if (! gda_holder_set_value (holder, value)) {
- g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
- _("Wrong value type"));
- return FALSE;
+ }
}
+ /* give values to params for old values */
+ ncols = gda_pmodel_get_n_columns ((GdaDataModel*) imodel);
for (i = 0; i < ncols; i++) {
str = g_strdup_printf ("-%d", i);
holder = gda_set_get_holder (imodel->priv->modif_set, str);
g_free (str);
if (holder) {
if (! gda_holder_set_value (holder,
- gda_data_model_get_value_at (model, i, row))) {
+ gda_data_model_get_value_at ((GdaDataModel*) imodel, i, int_row))) {
g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
_("Wrong value type"));
return FALSE;
@@ -1267,10 +2134,14 @@
}
}
+ if (free_bv)
+ bvector_free (bv);
+
+ /* actually execute UPDATE statement */
#ifdef GDA_DEBUG_NO
gchar *sql;
GError *lerror = NULL;
- sql = gda_statement_to_sql_extended (imodel->priv->upd_stmts [col],
+ sql = gda_statement_to_sql_extended (stmt,
imodel->priv->cnc,
imodel->priv->modif_set,
GDA_STATEMENT_SQL_PRETTY, NULL,
@@ -1281,48 +2152,575 @@
g_free (sql);
#endif
- if (gda_connection_statement_execute_non_select (imodel->priv->cnc,
- imodel->priv->upd_stmts [col],
+ if (gda_connection_statement_execute_non_select (imodel->priv->cnc, stmt,
imodel->priv->modif_set, NULL, error) == -1)
return FALSE;
- TO_IMPLEMENT;
+ /* mark that this row has been modified */
+ DelayedSelectStmt *dstmt;
+ dstmt = g_new0 (DelayedSelectStmt, 1);
+ if (! imodel->priv->one_row_select_stmt)
+ imodel->priv->one_row_select_stmt = compute_single_select_stmt (imodel, error);
+ if (imodel->priv->one_row_select_stmt) {
+ dstmt->select = g_object_ref (imodel->priv->one_row_select_stmt);
+ gda_statement_get_parameters (dstmt->select, &(dstmt->params), NULL);
+ if (dstmt->params) {
+ GSList *list;
+ for (list = dstmt->params->holders; list; list = list->next) {
+ GdaHolder *holder = GDA_HOLDER (list->data);
+ GdaHolder *eholder;
+ eholder = gda_set_get_holder (imodel->priv->modif_set,
+ gda_holder_get_id (holder));
+ if (!eholder ||
+ ! gda_holder_set_value (holder, gda_holder_get_value (eholder))) {
+ g_object_unref (dstmt->params);
+ dstmt->params = NULL;
+ break;
+ }
+ }
+ }
+ }
+ dstmt->row = NULL;
+ if (! imodel->priv->upd_rows)
+ imodel->priv->upd_rows = g_hash_table_new_full (g_int_hash, g_int_equal,
+ g_free,
+ (GDestroyNotify) delayed_select_stmt_free);
+ gint *tmp = g_new (gint, 1);
+ *tmp = int_row;
+ g_hash_table_insert (imodel->priv->upd_rows, tmp, dstmt);
+#ifdef GDA_DEBUG_NO
+ dump_d (imodel);
+#endif
+
+ gda_data_model_row_updated ((GdaDataModel *) imodel, row);
return TRUE;
+
+}
+
+static gboolean
+gda_pmodel_set_value_at (GdaDataModel *model, gint col, gint row, const GValue *value, GError **error)
+{
+ GdaPModel *imodel;
+ gint ncols;
+ GdaHolder *holder;
+ gchar *str;
+
+ imodel = (GdaPModel *) model;
+ g_return_val_if_fail (imodel->priv, FALSE);
+
+ if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
+ _("Data model does not support random access"));
+ return FALSE;
+ }
+ if (! imodel->priv->modif_stmts [UPD_QUERY]) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("No UPDATE statement provided"));
+ return FALSE;
+ }
+
+ /* arguments check */
+ ncols = gda_pmodel_get_n_columns (model);
+ if (col >= ncols) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Column %d out of range (0-%d)"), col, ncols-1);
+ return FALSE;
+ }
+
+ /* give values to params for new value */
+ str = g_strdup_printf ("+%d", col);
+ holder = gda_set_get_holder (imodel->priv->modif_set, str);
+ g_free (str);
+ if (! holder) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Column %d can't be modified"), col);
+ return FALSE;
+ }
+ if (! gda_holder_set_value (holder, value)) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
+ _("Wrong value type"));
+ return FALSE;
+ }
+
+ /* BVector */
+ BVector *bv;
+ bv = g_new (BVector, 1);
+ bv->size = col + 1;
+ bv->data = g_new0 (guchar, bv->size);
+ bv->data[col] = 1;
+
+ return vector_set_value_at (imodel, bv, row, error);
+}
+
+static void
+delayed_select_stmt_free (DelayedSelectStmt *dstmt)
+{
+ if (dstmt->select)
+ g_object_unref (dstmt->select);
+ if (dstmt->params)
+ g_object_unref (dstmt->params);
+ if (dstmt->row)
+ g_object_unref (dstmt->row);
+ g_free (dstmt);
}
static gboolean
gda_pmodel_set_values (GdaDataModel *model, gint row, GList *values, GError **error)
{
GdaPModel *imodel;
+ gint i, ncols, nvalues;
+ GdaHolder *holder;
+ gchar *str;
+ GList *list;
+
imodel = (GdaPModel *) model;
+ /* arguments check */
g_return_val_if_fail (imodel->priv, FALSE);
- TO_IMPLEMENT;
- return FALSE;
+ if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
+ _("Data model does not support random access"));
+ return FALSE;
+ }
+ if (! imodel->priv->modif_stmts [UPD_QUERY]) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("No UPDATE statement provided"));
+ return FALSE;
+ }
+
+ ncols = gda_pmodel_get_n_columns (model);
+ nvalues = g_list_length (values);
+ if (nvalues >= ncols) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Too many values (%d as maximum)"), ncols-1);
+ return FALSE;
+ }
+
+ /* BVector */
+ BVector *bv;
+ gboolean has_mods = FALSE;
+
+ bv = g_new (BVector, 1);
+ bv->size = nvalues;
+ bv->data = g_new0 (guchar, bv->size);
+ for (i = 0, list = values; list; i++, list = list->next) {
+ if (list->data) {
+ bv->data[i] = 1;
+ has_mods = TRUE;
+ }
+ }
+ if (!has_mods) {
+ /* no actual modification to do */
+ bvector_free (bv);
+ return TRUE;
+ }
+
+ /* give values to params for new values */
+ for (i = 0, list = values; list; i++, list = list->next) {
+ if (!bv->data[i])
+ continue;
+
+ str = g_strdup_printf ("+%d", i);
+ holder = gda_set_get_holder (imodel->priv->modif_set, str);
+ g_free (str);
+ if (! holder) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Column %d can't be modified"), i);
+ bvector_free (bv);
+ return FALSE;
+ }
+ if (! gda_holder_set_value (holder, (GValue *) list->data)) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
+ _("Wrong value type"));
+ bvector_free (bv);
+ return FALSE;
+ }
+ }
+
+ return vector_set_value_at (imodel, bv, row, error);
}
static gint
gda_pmodel_append_values (GdaDataModel *model, const GList *values, GError **error)
{
GdaPModel *imodel;
+ gint row, int_row, i;
+ GdaHolder *holder;
+ gchar *str;
+ const GList *list;
+
imodel = (GdaPModel *) model;
g_return_val_if_fail (imodel->priv, -1);
- TO_IMPLEMENT;
- return -1;
+ if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
+ _("Data model does not support random access"));
+ return -1;
+ }
+ if (! imodel->priv->modif_stmts [INS_QUERY]) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("No INSERT statement provided"));
+ return -1;
+ }
+ if (gda_pmodel_get_n_rows (model) < 0) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_ACCESS_ERROR,
+ _("Cannot add a row because the number of rows in unknown"));
+ return -1;
+ }
+
+ /* compute added row's number */
+ row = imodel->advertized_nrows;
+ imodel->advertized_nrows++;
+ int_row = external_to_internal_row (imodel, row, error);
+ imodel->advertized_nrows--;
+
+ /* BVector */
+ BVector *bv;
+ gboolean has_mods = FALSE, free_bv = TRUE;
+
+ bv = g_new (BVector, 1);
+ bv->size = g_list_length ((GList*) values);
+ bv->data = g_new0 (guchar, bv->size);
+ for (i = 0, list = values; list; i++, list = list->next) {
+ if (list->data) {
+ bv->data[i] = 1;
+ has_mods = TRUE;
+ }
+ }
+ if (!has_mods) {
+ /* no actual modification to do */
+ bvector_free (bv);
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
+ _("Missing values to insert in INSERT statement"));
+
+ return -1;
+ }
+
+ /* compute INSERT statement */
+ GdaStatement *stmt;
+ if (! imodel->priv->ins_stmts)
+ imodel->priv->ins_stmts = g_hash_table_new_full ((GHashFunc) bvector_hash, (GEqualFunc) bvector_equal,
+ (GDestroyNotify) bvector_free, g_object_unref);
+ stmt = g_hash_table_lookup (imodel->priv->ins_stmts, bv);
+ if (! stmt) {
+ stmt = compute_single_insert_stmt (imodel, bv, error);
+ if (stmt) {
+ free_bv = FALSE;
+ g_hash_table_insert (imodel->priv->ins_stmts, bv, stmt);
+ }
+ else {
+ bvector_free (bv);
+ return -1;
+ }
+ }
+
+ /* give values to params for new values */
+ for (i = 0, list = values; list; i++, list = list->next) {
+ if (!bv->data[i])
+ continue;
+
+ str = g_strdup_printf ("+%d", i);
+ holder = gda_set_get_holder (imodel->priv->modif_set, str);
+ g_free (str);
+ if (! holder) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("Column %d can't be modified"), i);
+ bvector_free (bv);
+ return -1;
+ }
+ if (! gda_holder_set_value (holder, (GValue *) list->data)) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
+ _("Wrong value type"));
+ bvector_free (bv);
+ return -1;
+ }
+ }
+
+ if (free_bv)
+ bvector_free (bv);
+
+ /* actually execute INSERT statement */
+#ifdef GDA_DEBUG_NO
+ gchar *sql;
+ GError *lerror = NULL;
+ sql = gda_statement_to_sql_extended (stmt,
+ imodel->priv->cnc,
+ imodel->priv->modif_set,
+ GDA_STATEMENT_SQL_PRETTY, NULL,
+ &lerror);
+ g_print ("%s(): SQL=> %s\n", __FUNCTION__, sql);
+ if (!sql) {
+ gchar *tmp;
+ g_print ("\tERR: %s\n", lerror && lerror->message ? lerror->message : "No detail");
+ tmp = gda_statement_serialize (stmt);
+ g_print ("\tSER: %s\n", tmp);
+ g_free (tmp);
+ }
+ g_free (sql);
+#endif
+
+ GdaSet *last_insert;
+ if (gda_connection_statement_execute_non_select (imodel->priv->cnc, stmt,
+ imodel->priv->modif_set, &last_insert, error) == -1)
+ return -1;
+
+ /* mark that this row has been modified */
+ DelayedSelectStmt *dstmt;
+ dstmt = g_new0 (DelayedSelectStmt, 1);
+ if (! imodel->priv->one_row_select_stmt)
+ imodel->priv->one_row_select_stmt = compute_single_select_stmt (imodel, error);
+ if (last_insert && imodel->priv->one_row_select_stmt) {
+ dstmt->select = g_object_ref (imodel->priv->one_row_select_stmt);
+ gda_statement_get_parameters (dstmt->select, &(dstmt->params), NULL);
+ if (dstmt->params) {
+ GSList *list;
+ if (! imodel->priv->insert_to_select_mapping)
+ imodel->priv->insert_to_select_mapping =
+ compute_insert_select_params_mapping (dstmt->params, last_insert,
+ imodel->priv->unique_row_condition);
+ if (imodel->priv->insert_to_select_mapping) {
+ for (list = dstmt->params->holders; list; list = list->next) {
+ GdaHolder *holder = GDA_HOLDER (list->data);
+ GdaHolder *eholder;
+ gint pos;
+
+ g_assert (param_name_to_int (gda_holder_get_id (holder), &pos, NULL));
+
+ eholder = g_slist_nth_data (last_insert->holders,
+ imodel->priv->insert_to_select_mapping[pos]);
+ if (!eholder ||
+ ! gda_holder_set_value (holder, gda_holder_get_value (eholder))) {
+ g_object_unref (dstmt->params);
+ dstmt->params = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (last_insert)
+ g_object_unref (last_insert);
+
+ dstmt->row = NULL;
+ if (! imodel->priv->upd_rows)
+ imodel->priv->upd_rows = g_hash_table_new_full (g_int_hash, g_int_equal,
+ g_free,
+ (GDestroyNotify) delayed_select_stmt_free);
+ gint *tmp = g_new (gint, 1);
+ *tmp = int_row;
+ g_hash_table_insert (imodel->priv->upd_rows, tmp, dstmt);
+#ifdef GDA_DEBUG_NO
+ dump_d (imodel);
+#endif
+
+ imodel->advertized_nrows++;
+ gda_data_model_row_inserted ((GdaDataModel *) imodel, row);
+
+ return row;
}
+
static gboolean
gda_pmodel_remove_row (GdaDataModel *model, gint row, GError **error)
{
GdaPModel *imodel;
+ gint int_row, i, ncols, index;
+ GdaHolder *holder;
+ gchar *str;
+
imodel = (GdaPModel *) model;
g_return_val_if_fail (imodel->priv, FALSE);
- TO_IMPLEMENT;
- return FALSE;
+ if (! (imodel->priv->usage_flags & GDA_DATA_MODEL_ACCESS_RANDOM)) {
+ g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
+ _("Data model does not support random access"));
+ return FALSE;
+ }
+ if (! imodel->priv->modif_stmts [DEL_QUERY]) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
+ _("No DELETE statement provided"));
+ return FALSE;
+ }
+
+ int_row = external_to_internal_row (imodel, row, error);
+ if (int_row < 0)
+ return FALSE;
+
+ ncols = gda_pmodel_get_n_columns (model);
+ for (i = 0; i < ncols; i++) {
+ str = g_strdup_printf ("-%d", i);
+ holder = gda_set_get_holder (imodel->priv->modif_set, str);
+ g_free (str);
+ if (holder) {
+ if (! gda_holder_set_value (holder,
+ gda_data_model_get_value_at (model, i, int_row))) {
+ g_set_error (error, GDA_PMODEL_ERROR, GDA_PMODEL_VALUE_ERROR,
+ _("Wrong value type"));
+ return FALSE;
+ }
+ }
+ }
+
+#ifdef GDA_DEBUG_NO
+ gchar *sql;
+ GError *lerror = NULL;
+ sql = gda_statement_to_sql_extended (imodel->priv->modif_stmts [DEL_QUERY],
+ imodel->priv->cnc,
+ imodel->priv->modif_set,
+ GDA_STATEMENT_SQL_PRETTY, NULL,
+ &lerror);
+ g_print ("%s(): SQL=> %s\n", __FUNCTION__, sql);
+ if (!sql)
+ g_print ("\tERR: %s\n", lerror && lerror->message ? lerror->message : "No detail");
+ g_free (sql);
+#endif
+ if (gda_connection_statement_execute_non_select (imodel->priv->cnc,
+ imodel->priv->modif_stmts [DEL_QUERY],
+ imodel->priv->modif_set, NULL, error) == -1)
+ return FALSE;
+
+ /* mark that this row has been removed */
+ if (!imodel->priv->del_rows)
+ imodel->priv->del_rows = g_array_new (FALSE, FALSE, sizeof (gint));
+ for (index = 0, i = 0; i < imodel->priv->del_rows->len; i++, index++) {
+ if (g_array_index (imodel->priv->del_rows, gint, i) >= int_row)
+ break;
+ }
+
+ g_array_insert_val (imodel->priv->del_rows, index, int_row);
+ gda_data_model_row_removed (model, row);
+
+ return TRUE;
+}
+
+/*
+ * The following function creates a correspondance between the parameters required to
+ * execute the model->one_row_select_stmt statement (GdaHolders named "-<num>", in ), and the GdaHolder
+ * returned after having executed the model->modif_stmts[INS_QUERY] INSERT statement.
+ *
+ * The way of preceeding is:
+ * - for each parameter required by model->one_row_select_stmt statement (the @sel_params argument),
+ * use the model->priv->unique_row_condition to get the name of the corresponding column (the GdaHolder's ID
+ * is "-<num1>" )
+ * - from the column name get the GdaHolder in the GdaSet retruned after the INSERT statement (the
+ * @ins_values argument) using the "name" property of each GdaHolder in the GdaSet (the GdaHolder's ID
+ * is "+<num2>" )
+ * - add an entry in the returned array: array[num1] = num2
+ */
+typedef struct {
+ const gchar *hid;
+ const gchar *colid;
+} CorrespData;
+static gboolean compute_insert_select_params_mapping_foreach_func (GdaSqlAnyPart *part, CorrespData *data, GError **error);
+static gint *
+compute_insert_select_params_mapping (GdaSet *sel_params, GdaSet *ins_values, GdaSqlExpr *row_cond)
+{
+ GArray *array;
+ gint *retval;
+ GSList *sel_list;
+
+ array = g_array_new (FALSE, TRUE, sizeof (gint));
+ for (sel_list = sel_params->holders; sel_list; sel_list = sel_list->next) {
+ CorrespData cdata;
+ const gchar *pid = gda_holder_get_id (GDA_HOLDER (sel_list->data));
+ cdata.hid = pid;
+ cdata.colid = NULL;
+
+ gint spnum, ipnum;
+ gboolean spold, ipold;
+ if (! param_name_to_int (pid, &spnum, &spold) || !spold)
+ continue;
+
+ if (gda_sql_any_part_foreach (GDA_SQL_ANY_PART (row_cond),
+ (GdaSqlForeachFunc) compute_insert_select_params_mapping_foreach_func,
+ &cdata, NULL)) {
+ g_warning ("Could not find column for parameter '%s'", cdata.hid);
+ goto onerror;
+ }
+ g_assert (cdata.colid);
+ g_print ("SEL param '%s' <=> column named '%s'\n", cdata.hid, cdata.colid);
+
+ GSList *ins_list;
+ cdata.hid = NULL;
+ for (ins_list = ins_values->holders; ins_list; ins_list = ins_list->next) {
+ gchar *name;
+ g_object_get (G_OBJECT (ins_list->data), "name", &name, NULL);
+ if (!name) {
+ g_warning ("Provider does not report column names");
+ goto onerror;
+ }
+ if (!strcmp (name, cdata.colid)) {
+ cdata.hid = gda_holder_get_id (GDA_HOLDER (ins_list->data));
+ g_free (name);
+ break;
+ }
+ g_free (name);
+ }
+
+ if (!cdata.hid) {
+ g_warning ("Could not find column named '%s'", cdata.colid);
+ goto onerror;
+ }
+
+ g_print ("column named '%s' <=> INS param '%s'\n", cdata.colid, cdata.hid);
+
+ if (! param_name_to_int (cdata.hid, &ipnum, &ipold) || ipold) {
+ g_warning ("Provider reported a malformed parameter named '%s'", cdata.hid);
+ goto onerror;
+ }
+
+ g_array_insert_val (array, spnum, ipnum);
+ g_print (" array[%d] = %d\n", spnum, ipnum);
+ }
+
+ retval = (gint *) array->data;
+ g_array_free (array, FALSE);
+ return retval;
+
+ onerror:
+ g_array_free (array, TRUE);
+ return NULL;
+}
+
+static gboolean
+compute_insert_select_params_mapping_foreach_func (GdaSqlAnyPart *part, CorrespData *data, GError **error)
+{
+ if (part->type != GDA_SQL_ANY_SQL_OPERATION)
+ return TRUE;
+
+ GdaSqlOperation *op = (GdaSqlOperation*) part;
+ if (op->operator != GDA_SQL_OPERATOR_TYPE_EQ)
+ return TRUE;
+
+ if (!op->operands || !op->operands->data || !op->operands->next || !op->operands->next->data ||
+ op->operands->next->next)
+ return TRUE;
+
+ GdaSqlExpr *e1, *e2;
+ e1 = (GdaSqlExpr *) op->operands->data;
+ e2 = (GdaSqlExpr *) op->operands->next->data;
+ if (e2->value && e1->param_spec) {
+ /* swap e1 and e2 */
+ GdaSqlExpr *ex = e1;
+ e1 = e2;
+ e2 = ex;
+ }
+ if (e1->value && e2->param_spec) {
+ /* e1->value should be a column name */
+ /* e2->param_spec should be a parameter */
+ if (e2->param_spec->name && !strcmp (e2->param_spec->name, data->hid)) {
+ if (G_VALUE_TYPE (e1->value) != G_TYPE_STRING)
+ return TRUE;
+ data->colid = g_value_get_string (e1->value);
+ if (* data->colid)
+ return FALSE;
+ data->colid = NULL;
+ return TRUE;
+ }
+ }
+ return TRUE;
}
Modified: trunk/libgda/providers-support/gda-pmodel.h
==============================================================================
--- trunk/libgda/providers-support/gda-pmodel.h (original)
+++ trunk/libgda/providers-support/gda-pmodel.h Thu Aug 28 19:38:33 2008
@@ -26,6 +26,7 @@
#include <glib-object.h>
#include <libgda/gda-row.h>
#include <libgda/providers-support/gda-pstmt.h>
+#include <sql-parser/gda-sql-statement.h>
G_BEGIN_DECLS
@@ -47,7 +48,9 @@
GDA_PMODEL_MODIFICATION_STATEMENT_ERROR,
GDA_PMODEL_MISSING_MODIFICATION_STATEMENT_ERROR,
GDA_PMODEL_CONNECTION_ERROR,
- GDA_PMODEL_VALUE_ERROR
+ GDA_PMODEL_VALUE_ERROR,
+ GDA_PMODEL_ACCESS_ERROR,
+ GDA_PMODEL_SQL_ERROR
};
struct _GdaPModel {
@@ -57,7 +60,7 @@
/* read only information */
GdaPStmt *prep_stmt; /* use the "prepared-stmt" property to set this */
gint nb_stored_rows; /* number of GdaRow objects currently stored */
- gint advertized_nrows; /* set when the number of rows becomes known */
+ gint advertized_nrows; /* set when the number of rows becomes known, -1 untill then */
};
/*
@@ -87,11 +90,19 @@
};
GType gda_pmodel_get_type (void) G_GNUC_CONST;
+
+/* API reserved to provider's implementations */
void gda_pmodel_take_row (GdaPModel *model, GdaRow *row, gint rownum);
GdaRow *gda_pmodel_get_stored_row (GdaPModel *model, gint rownum);
-
GdaConnection *gda_pmodel_get_connection (GdaPModel *model);
-gboolean gda_pmodel_set_modification_statements (GdaPModel *model, GdaStatement *mod_stmt, GError **error);
+
+/* public API */
+gboolean gda_pmodel_set_row_selection_condition (GdaPModel *model, GdaSqlExpr *expr, GError **error);
+gboolean gda_pmodel_set_row_selection_condition_sql (GdaPModel *model, const gchar *sql_where, GError **error);
+gboolean gda_pmodel_compute_row_selection_condition (GdaPModel *model, GError **error);
+
+gboolean gda_pmodel_set_modification_statement (GdaPModel *model, GdaStatement *mod_stmt, GError **error);
+gboolean gda_pmodel_set_modification_statement_sql (GdaPModel *model, const gchar *sql, GError **error);
gboolean gda_pmodel_compute_modification_statements (GdaPModel *model, gboolean require_pk, GError **error);
G_END_DECLS
Modified: trunk/libgda/sql-parser/gda-sql-parser.c
==============================================================================
--- trunk/libgda/sql-parser/gda-sql-parser.c (original)
+++ trunk/libgda/sql-parser/gda-sql-parser.c Thu Aug 28 19:38:33 2008
@@ -1564,8 +1564,10 @@
v1 = v2;
}
if (ttype != exp_type) {
- g_value_reset (v1);
- g_free (v1);
+ if (v1) {
+ g_value_reset (v1);
+ g_free (v1);
+ }
/* not what was expected => pop all the contexts */
for (; npushed > nmatched ; npushed--)
Modified: trunk/libgda/sql-parser/gda-statement-struct.c
==============================================================================
--- trunk/libgda/sql-parser/gda-statement-struct.c (original)
+++ trunk/libgda/sql-parser/gda-statement-struct.c Thu Aug 28 19:38:33 2008
@@ -444,7 +444,7 @@
* using @expr context, set expr->param_spec->validity_meta_dict.
*/
TO_IMPLEMENT;
- return FALSE;
+ return TRUE;
}
void
Modified: trunk/libgda/sqlite/gda-sqlite-meta.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-meta.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-meta.c Thu Aug 28 19:38:33 2008
@@ -838,7 +838,7 @@
g_value_set_boolean ((v3 = gda_value_new (G_TYPE_BOOLEAN)), pNotNull ? FALSE : TRUE);
g_value_set_string ((v4 = gda_value_new (G_TYPE_STRING)), pzCollSeq);
if (pAutoinc)
- g_value_set_string ((v5 = gda_value_new (G_TYPE_STRING)), "AUTO_INCREMENT");
+ g_value_set_string ((v5 = gda_value_new (G_TYPE_STRING)), GDA_EXTRA_AUTO_INCREMENT);
g_value_set_int (v1, g_value_get_int (v1) + 1);
if (pzDataType) {
Modified: trunk/libgda/sqlite/gda-sqlite-provider.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-provider.c (original)
+++ trunk/libgda/sqlite/gda-sqlite-provider.c Thu Aug 28 19:38:33 2008
@@ -1774,7 +1774,8 @@
col = gda_data_model_describe_column (model, i);
h = gda_holder_new (gda_column_get_g_type (col));
id = g_strdup_printf ("+%d", i);
- g_object_set (G_OBJECT (h), "id", id, "not-null", FALSE, NULL);
+ g_object_set (G_OBJECT (h), "id", id, "not-null", FALSE,
+ "name", gda_column_get_name (col), NULL);
g_free (id);
gda_holder_set_value (h, gda_data_model_get_value_at (model, i, 0));
holders = g_slist_prepend (holders, h);
@@ -2089,12 +2090,12 @@
if (status != SQLITE_DONE) {
if (sqlite3_errcode (handle) != SQLITE_OK) {
const char *errmsg = sqlite3_errmsg (handle);
- sqlite3_reset (ps->sqlite_stmt);
event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
gda_connection_event_set_description (event, errmsg);
- gda_connection_add_event (cnc, event);
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_STATEMENT_EXEC_ERROR, errmsg);
+ sqlite3_reset (ps->sqlite_stmt);
+ gda_connection_add_event (cnc, event);
gda_connection_internal_statement_executed (cnc, stmt, params, event);
if (new_ps)
g_object_unref (ps);
Modified: trunk/libgda/sqlite/sqlite-src/PragmasPatch
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/PragmasPatch (original)
+++ trunk/libgda/sqlite/sqlite-src/PragmasPatch Thu Aug 28 19:38:33 2008
@@ -1,6 +1,6 @@
---- sqlite3.c.orig 2008-07-24 11:07:44.000000000 +0200
-+++ sqlite3.c 2008-07-24 11:46:03.000000000 +0200
-@@ -64139,6 +64139,48 @@
+--- sqlite3.c.orig 2008-08-28 21:24:44.000000000 +0200
++++ sqlite3.c 2008-08-28 21:24:51.000000000 +0200
+@@ -65313,6 +65313,48 @@
#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
/*
Modified: trunk/libgda/sqlite/sqlite-src/sqlite3.c
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/sqlite3.c (original)
+++ trunk/libgda/sqlite/sqlite-src/sqlite3.c Thu Aug 28 19:38:33 2008
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.0. By combining all the individual C code files into this
+** version 3.6.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a one translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -11,13 +11,13 @@
** programs, you need this file and the "sqlite3.h" header file that defines
** the programming interface to the SQLite library. (If you do not have
** the "sqlite3.h" header file at hand, you will find a copy in the first
-** 6139 lines past this header comment.) Additional code files may be
+** 6279 lines past this header comment.) Additional code files may be
** needed if you want a wrapper to interface SQLite with your choice of
** programming language. The code for the "sqlite3" command-line shell
** is also in a separate file. This file contains only code for the core
** SQLite library.
**
-** This amalgamation was generated on 2008-07-16 14:52:32 UTC.
+** This amalgamation was generated on 2008-08-05 21:36:42 UTC.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -41,7 +41,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.742 2008/07/12 14:52:20 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.752 2008/08/04 20:13:27 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -253,7 +253,9 @@
#endif
/* Needed for various definitions... */
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
/*
** Include standard header files as necessary
@@ -472,7 +474,7 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
-** @(#) $Id: sqlite.h.in,v 1.372 2008/07/16 13:29:51 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.387 2008/08/05 17:53:23 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -504,7 +506,7 @@
#endif
/*
-** CAPI3REF: Compile-Time Library Version Numbers {F10010}
+** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
**
** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
** the sqlite3.h file specify the version of SQLite with which
@@ -525,19 +527,19 @@
**
** INVARIANTS:
**
-** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
+** {H10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
** evaluate to a string literal that is the SQLite version
** with which the header file is associated.
**
-** {F10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
+** {H10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
** are the major version, minor version, and release number.
*/
-#define SQLITE_VERSION "3.6.0"
-#define SQLITE_VERSION_NUMBER 3006000
+#define SQLITE_VERSION "3.6.1"
+#define SQLITE_VERSION_NUMBER 3006001
/*
-** CAPI3REF: Run-Time Library Version Numbers {F10020}
+** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
** KEYWORDS: sqlite3_version
**
** These features provide the same information as the [SQLITE_VERSION]
@@ -554,13 +556,13 @@
**
** INVARIANTS:
**
-** {F10021} The [sqlite3_libversion_number()] interface shall return
+** {H10021} The [sqlite3_libversion_number()] interface shall return
** an integer equal to [SQLITE_VERSION_NUMBER].
**
-** {F10022} The [sqlite3_version] string constant shall contain
+** {H10022} The [sqlite3_version] string constant shall contain
** the text of the [SQLITE_VERSION] string.
**
-** {F10023} The [sqlite3_libversion()] function shall return
+** {H10023} The [sqlite3_libversion()] function shall return
** a pointer to the [sqlite3_version] string constant.
*/
SQLITE_API const char sqlite3_version[];
@@ -568,7 +570,7 @@
SQLITE_API int sqlite3_libversion_number(void);
/*
-** CAPI3REF: Test To See If The Library Is Threadsafe {F10100}
+** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
**
** SQLite can be compiled with or without mutexes. When
** the [SQLITE_THREADSAFE] C preprocessor macro is true, mutexes
@@ -596,12 +598,12 @@
**
** INVARIANTS:
**
-** {F10101} The [sqlite3_threadsafe()] function shall return nonzero if
+** {H10101} The [sqlite3_threadsafe()] function shall return nonzero if
** SQLite was compiled with the its mutexes enabled by default
** or zero if SQLite was compiled such that mutexes are
** permanently disabled.
**
-** {F10102} The value returned by the [sqlite3_threadsafe()] function
+** {H10102} The value returned by the [sqlite3_threadsafe()] function
** shall not change when mutex setting are modified at
** runtime using the [sqlite3_config()] interface and
** especially the [SQLITE_CONFIG_SINGLETHREAD],
@@ -611,7 +613,7 @@
SQLITE_API int sqlite3_threadsafe(void);
/*
-** CAPI3REF: Database Connection Handle {F12000}
+** CAPI3REF: Database Connection Handle {H12000} <S40200>
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
@@ -626,7 +628,7 @@
typedef struct sqlite3 sqlite3;
/*
-** CAPI3REF: 64-Bit Integer Types {F10200}
+** CAPI3REF: 64-Bit Integer Types {H10200} <S10110>
** KEYWORDS: sqlite_int64 sqlite_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
@@ -638,10 +640,10 @@
**
** INVARIANTS:
**
-** {F10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
+** {H10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
** a 64-bit signed integer.
**
-** {F10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
+** {H10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
** a 64-bit unsigned integer.
*/
#ifdef SQLITE_INT64_TYPE
@@ -666,7 +668,7 @@
#endif
/*
-** CAPI3REF: Closing A Database Connection {F12010}
+** CAPI3REF: Closing A Database Connection {H12010} <S30100><S40200>
**
** This routine is the destructor for the [sqlite3] object.
**
@@ -689,30 +691,30 @@
**
** INVARIANTS:
**
-** {F12011} A successful call to [sqlite3_close(C)] shall destroy the
+** {H12011} A successful call to [sqlite3_close(C)] shall destroy the
** [database connection] object C.
**
-** {F12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
+** {H12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
**
-** {F12013} A successful call to [sqlite3_close(C)] shall release all
+** {H12013} A successful call to [sqlite3_close(C)] shall release all
** memory and system resources associated with [database connection]
** C.
**
-** {F12014} A call to [sqlite3_close(C)] on a [database connection] C that
+** {H12014} A call to [sqlite3_close(C)] on a [database connection] C that
** has one or more open [prepared statements] shall fail with
** an [SQLITE_BUSY] error code.
**
-** {F12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
+** {H12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
** return SQLITE_OK.
**
-** {F12019} When [sqlite3_close(C)] is invoked on a [database connection] C
+** {H12019} When [sqlite3_close(C)] is invoked on a [database connection] C
** that has a pending transaction, the transaction shall be
** rolled back.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12016} The C parameter to [sqlite3_close(C)] must be either a NULL
-** pointer or an [sqlite3] object pointer previously obtained
+** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
*/
@@ -726,7 +728,7 @@
typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
-** CAPI3REF: One-Step Query Execution Interface {F12100}
+** CAPI3REF: One-Step Query Execution Interface {H12100} <S10000>
**
** The sqlite3_exec() interface is a convenient way of running one or more
** SQL statements without having to write a lot of C code. The UTF-8 encoded
@@ -754,69 +756,69 @@
**
** INVARIANTS:
**
-** {F12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
+** {H12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
** shall sequentially evaluate all of the UTF-8 encoded,
** semicolon-separated SQL statements in the zero-terminated
** string S within the context of the [database connection] D.
**
-** {F12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
+** {H12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
** the actions of the interface shall be the same as if the
** S parameter were an empty string.
**
-** {F12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
+** {H12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
** SQL statements run successfully and to completion.
**
-** {F12105} The return value of [sqlite3_exec()] shall be an appropriate
+** {H12105} The return value of [sqlite3_exec()] shall be an appropriate
** non-zero [error code] if any SQL statement fails.
**
-** {F12107} If one or more of the SQL statements handed to [sqlite3_exec()]
+** {H12107} If one or more of the SQL statements handed to [sqlite3_exec()]
** return results and the 3rd parameter is not NULL, then
** the callback function specified by the 3rd parameter shall be
** invoked once for each row of result.
**
-** {F12110} If the callback returns a non-zero value then [sqlite3_exec()]
+** {H12110} If the callback returns a non-zero value then [sqlite3_exec()]
** shall abort the SQL statement it is currently evaluating,
** skip all subsequent SQL statements, and return [SQLITE_ABORT].
**
-** {F12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
+** {H12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
** as the 1st parameter of the callback.
**
-** {F12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
+** {H12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
** callback to be the number of columns in the current row of
** result.
**
-** {F12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
+** {H12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
** callback to be an array of pointers to strings holding the
** values for each column in the current result set row as
** obtained from [sqlite3_column_text()].
**
-** {F12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
+** {H12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
** callback to be an array of pointers to strings holding the
** names of result columns as obtained from [sqlite3_column_name()].
**
-** {F12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
+** {H12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
** [sqlite3_exec()] shall silently discard query results.
**
-** {F12131} If an error occurs while parsing or evaluating any of the SQL
+** {H12131} If an error occurs while parsing or evaluating any of the SQL
** statements in the S parameter of [sqlite3_exec(D,S,C,A,E)] and if
** the E parameter is not NULL, then [sqlite3_exec()] shall store
** in *E an appropriate error message written into memory obtained
** from [sqlite3_malloc()].
**
-** {F12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
+** {H12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
** *E to NULL if E is not NULL and there are no errors.
**
-** {F12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
+** {H12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
** and message accessible via [sqlite3_errcode()],
** [sqlite3_errmsg()], and [sqlite3_errmsg16()].
**
-** {F12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
+** {H12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
** empty string or contains nothing other than whitespace, comments,
** and/or semicolons, then results of [sqlite3_errcode()],
** [sqlite3_errmsg()], and [sqlite3_errmsg16()]
** shall reset to indicate no errors.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12141} The first parameter to [sqlite3_exec()] must be an valid and open
** [database connection].
@@ -840,7 +842,7 @@
);
/*
-** CAPI3REF: Result Codes {F10210}
+** CAPI3REF: Result Codes {H10210} <S10700>
** KEYWORDS: SQLITE_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**
@@ -884,7 +886,7 @@
/* end-of-error-codes */
/*
-** CAPI3REF: Extended Result Codes {F10220}
+** CAPI3REF: Extended Result Codes {H10220} <S10700>
** KEYWORDS: {extended error code} {extended error codes}
** KEYWORDS: {extended result code} {extended result codes}
**
@@ -908,14 +910,14 @@
**
** INVARIANTS:
**
-** {F10223} The symbolic name for an extended result code shall contains
+** {H10223} The symbolic name for an extended result code shall contains
** a related primary result code as a prefix.
**
-** {F10224} Primary result code names shall contain a single "_" character.
+** {H10224} Primary result code names shall contain a single "_" character.
**
-** {F10225} Extended result code names shall contain two or more "_" characters.
+** {H10225} Extended result code names shall contain two or more "_" characters.
**
-** {F10226} The numeric value of an extended result code shall contain the
+** {H10226} The numeric value of an extended result code shall contain the
** numeric value of its corresponding primary result code in
** its least significant 8 bits.
*/
@@ -935,7 +937,7 @@
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
/*
-** CAPI3REF: Flags For File Open Operations {F10230}
+** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
@@ -957,7 +959,7 @@
#define SQLITE_OPEN_NOMUTEX 0x00008000
/*
-** CAPI3REF: Device Characteristics {F10240}
+** CAPI3REF: Device Characteristics {H10240} <H11120>
**
** The xDeviceCapabilities method of the [sqlite3_io_methods]
** object returns an integer which is a vector of the these
@@ -989,7 +991,7 @@
#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
/*
-** CAPI3REF: File Locking Levels {F10250}
+** CAPI3REF: File Locking Levels {H10250} <H11120> <H11310>
**
** SQLite uses one of these integer values as the second
** argument to calls it makes to the xLock() and xUnlock() methods
@@ -1002,7 +1004,7 @@
#define SQLITE_LOCK_EXCLUSIVE 4
/*
-** CAPI3REF: Synchronization Type Flags {F10260}
+** CAPI3REF: Synchronization Type Flags {H10260} <H11120>
**
** When SQLite invokes the xSync() method of an
** [sqlite3_io_methods] object it uses a combination of
@@ -1019,7 +1021,7 @@
#define SQLITE_SYNC_DATAONLY 0x00010
/*
-** CAPI3REF: OS Interface Open File Handle {F11110}
+** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
**
** An [sqlite3_file] object represents an open file in the OS
** interface layer. Individual OS interface implementations will
@@ -1034,7 +1036,7 @@
};
/*
-** CAPI3REF: OS Interface File Virtual Methods Object {F11120}
+** CAPI3REF: OS Interface File Virtual Methods Object {H11120} <S20110>
**
** Every file opened by the [sqlite3_vfs] xOpen method populates an
** [sqlite3_file] object (or, more commonly, a subclass of the
@@ -1127,7 +1129,7 @@
};
/*
-** CAPI3REF: Standard File Control Opcodes {F11310}
+** CAPI3REF: Standard File Control Opcodes {H11310} <S30800>
**
** These integer constants are opcodes for the xFileControl method
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
@@ -1144,7 +1146,7 @@
#define SQLITE_FCNTL_LOCKSTATE 1
/*
-** CAPI3REF: Mutex Handle {F17110}
+** CAPI3REF: Mutex Handle {H17110} <S20130>
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object. The SQLite core never looks
@@ -1156,7 +1158,7 @@
typedef struct sqlite3_mutex sqlite3_mutex;
/*
-** CAPI3REF: OS Interface Object {F11140}
+** CAPI3REF: OS Interface Object {H11140} <S20100>
**
** An instance of the sqlite3_vfs object defines the interface between
** the SQLite core and the underlying operating system. The "vfs"
@@ -1189,11 +1191,11 @@
** The zName field holds the name of the VFS module. The name must
** be unique across all VFS modules.
**
-** {F11141} SQLite will guarantee that the zFilename parameter to xOpen
+** {H11141} SQLite will guarantee that the zFilename parameter to xOpen
** is either a NULL pointer or string obtained
** from xFullPathname(). SQLite further guarantees that
** the string will be valid and unchanged until xClose() is
-** called. {END} Becasue of the previous sentense,
+** called. {END} Because of the previous sentense,
** the [sqlite3_file] can safely store a pointer to the
** filename if it needs to remember the filename for some reason.
** If the zFilename parameter is xOpen is a NULL pointer then xOpen
@@ -1201,14 +1203,14 @@
** xFilename parameter is NULL it will also be the case that the
** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
**
-** {F11142} The flags argument to xOpen() includes all bits set in
+** {H11142} The flags argument to xOpen() includes all bits set in
** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
** or [sqlite3_open16()] is used, then flags includes at least
** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. {END}
** If xOpen() opens a file read-only then it sets *pOutFlags to
** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
**
-** {F11143} SQLite will also add one of the following flags to the xOpen()
+** {H11143} SQLite will also add one of the following flags to the xOpen()
** call, depending on the object being opened:
**
** <ul>
@@ -1237,27 +1239,27 @@
** <li> [SQLITE_OPEN_EXCLUSIVE]
** </ul>
**
-** {F11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. {F11146} The [SQLITE_OPEN_DELETEONCLOSE]
+** {H11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
+** deleted when it is closed. {H11146} The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases, journals and for subjournals.
**
-** {F11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
+** {H11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
** for exclusive access. This flag is set for all files except
** for the main database file.
**
-** {F11148} At least szOsFile bytes of memory are allocated by SQLite
+** {H11148} At least szOsFile bytes of memory are allocated by SQLite
** to hold the [sqlite3_file] structure passed as the third
** argument to xOpen. {END} The xOpen method does not have to
** allocate the structure; it should just fill it in.
**
-** {F11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
+** {H11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
** to test whether a file is at least readable. {END} The file can be a
** directory.
**
-** {F11150} SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. {F11151} The exact size of the output buffer
+** {H11150} SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname. {H11151} The exact size of the output buffer
** is also passed as a parameter to both methods. {END} If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
@@ -1299,16 +1301,16 @@
};
/*
-** CAPI3REF: Flags for the xAccess VFS method {F11190}
+** CAPI3REF: Flags for the xAccess VFS method {H11190} <H11140>
**
-** {F11191} These integer constants can be used as the third parameter to
+** {H11191} These integer constants can be used as the third parameter to
** the xAccess method of an [sqlite3_vfs] object. {END} They determine
** what kind of permissions the xAccess method is looking for.
-** {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
+** {H11192} With SQLITE_ACCESS_EXISTS, the xAccess method
** simply checks whether the file exists.
-** {F11193} With SQLITE_ACCESS_READWRITE, the xAccess method
+** {H11193} With SQLITE_ACCESS_READWRITE, the xAccess method
** checks whether the file is both readable and writable.
-** {F11194} With SQLITE_ACCESS_READ, the xAccess method
+** {H11194} With SQLITE_ACCESS_READ, the xAccess method
** checks whether the file is readable.
*/
#define SQLITE_ACCESS_EXISTS 0
@@ -1316,7 +1318,7 @@
#define SQLITE_ACCESS_READ 2
/*
-** CAPI3REF: Initialize The SQLite Library {F10130}
+** CAPI3REF: Initialize The SQLite Library {H10130} <S20000><S30100>
**
** The sqlite3_initialize() routine initializes the
** SQLite library. The sqlite3_shutdown() routine
@@ -1381,7 +1383,8 @@
SQLITE_API int sqlite3_os_end(void);
/*
-** CAPI3REF: Configuring The SQLite Library {F10145}
+** CAPI3REF: Configuring The SQLite Library {H10145} <S20000><S30200>
+** EXPERIMENTAL
**
** The sqlite3_config() interface is used to make global configuration
** changes to SQLite in order to tune SQLite to the specific needs of
@@ -1406,15 +1409,33 @@
** When a configuration option is set, sqlite3_config() returns SQLITE_OK.
** If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
-**
-** The sqlite3_config() interface is considered experimental in that
-** new configuration options may be added in future releases and existing
-** configuration options may be discontinued or modified.
*/
SQLITE_API int sqlite3_config(int, ...);
/*
-** CAPI3REF: Memory Allocation Routines {F10155}
+** CAPI3REF: Configure database connections {H10180} <S20000>
+** EXPERIMENTAL
+**
+** The sqlite3_db_config() interface is used to make configuration
+** changes to a [database connection]. The interface is similar to
+** [sqlite3_config()] except that the changes apply to a single
+** [database connection] (specified in the first argument). The
+** sqlite3_db_config() interface can only be used immediately after
+** the database connection is created using [sqlite3_open()],
+** [sqlite3_open16()], or [sqlite3_open_v2()].
+**
+** The second argument to sqlite3_db_config(D,V,...) is the
+** configuration verb - an integer code that indicates what
+** aspect of the [database connection] is being configured.
+** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
+** New verbs are likely to be added in future releases of SQLite.
+** Additional arguments depend on the verb.
+*/
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+
+/*
+** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
+** EXPERIMENTAL
**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
@@ -1468,7 +1489,8 @@
};
/*
-** CAPI3REF: Configuration Options {F10160}
+** CAPI3REF: Configuration Options {H10160} <S20000>
+** EXPERIMENTAL
**
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
@@ -1524,14 +1546,15 @@
** tracks memory usage, for example.</dd>
**
** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd>This option takes single boolean argument which enables or disables
-** the collection of memory allocation statistics. When disabled, the
-** following SQLite interfaces become non-operational:
+** <dd>This option takes single argument of type int, interpreted as a
+** boolean, which enables or disables the collection of memory allocation
+** statistics. When disabled, the following SQLite interfaces become
+** non-operational:
** <ul>
** <li> [sqlite3_memory_used()]
** <li> [sqlite3_memory_highwater()]
** <li> [sqlite3_soft_heap_limit()]
-** <li> sqlite3_memory_status()
+** <li> [sqlite3_status()]
** </ul>
** </dd>
**
@@ -1539,8 +1562,10 @@
** <dd>This option specifies a static memory buffer that SQLite can use for
** scratch memory. There are three arguments: A pointer to the memory, the
** size of each scratch buffer (sz), and the number of buffers (N). The sz
-** argument must be a multiple of 16. The first
-** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** argument must be a multiple of 16. The sz parameter should be a few bytes
+** larger than the actual scratch space required due internal overhead.
+** The first
+** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use no more than one scratch buffer at once per thread, so
** N should be set to the expected maximum number of threads. The sz
** parameter should be 6 times the size of the largest database page size.
@@ -1554,11 +1579,13 @@
** the database page cache. There are three arguments: A pointer to the
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument must be a power of two between 512 and 32768. The first
-** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. If additional
** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.
+** The implementation might use one or more of the N buffers to hold
+** memory accounting information. </dd>
**
** <dt>SQLITE_CONFIG_HEAP</dt>
** <dd>This option specifies a static memory buffer that SQLite will use
@@ -1587,6 +1614,14 @@
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.</dd>
+**
+** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
+** <dd>This option takes two arguments that determine the default
+** memory allcation lookaside optimization. The first argument is the
+** size of each lookaside buffer slot and the second is the number of
+** slots allocated to each database connection.</dd>
+**
+** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@@ -1599,10 +1634,42 @@
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
+#define SQLITE_CONFIG_CHUNKALLOC 12 /* int threshold */
+#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
+
+/*
+** CAPI3REF: Configuration Options {H10170} <S20000>
+** EXPERIMENTAL
+**
+** These constants are the available integer configuration options that
+** can be passed as the second argument to the [sqlite3_db_config()] interface.
+**
+** New configuration options may be added in future releases of SQLite.
+** Existing configuration options might be discontinued. Applications
+** should check the return code from [sqlite3_db_config()] to make sure that
+** the call worked. The [sqlite3_db_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+** <dd>This option takes three additional arguments that determine the
+** [lookaside memory allocator] configuration for the [database connection].
+** The first argument (the third parameter to [sqlite3_db_config()] is a
+** pointer to a memory buffer to use for lookaside memory. The first
+** argument may be NULL in which case SQLite will allocate the lookaside
+** buffer itself using [sqlite3_malloc()]. The second argument is the
+** size of each lookaside buffer slot and the third argument is the number of
+** slots. The size of the buffer in the first argument must be greater than
+** or equal to the product of the second and third arguments.</dd>
+**
+** </dl>
+*/
+#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
/*
-** CAPI3REF: Enable Or Disable Extended Result Codes {F12200}
+** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
**
** The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. The extended result
@@ -1610,17 +1677,17 @@
**
** INVARIANTS:
**
-** {F12201} Each new [database connection] shall have the
+** {H12201} Each new [database connection] shall have the
** [extended result codes] feature disabled by default.
**
-** {F12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
+** {H12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
** [extended result codes] for the [database connection] D
** if the F parameter is true, or disable them if F is false.
*/
SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
-** CAPI3REF: Last Insert Rowid {F12220}
+** CAPI3REF: Last Insert Rowid {H12220} <S10700>
**
** Each entry in an SQLite table has a unique 64-bit signed
** integer key called the "rowid". The rowid is always available
@@ -1654,16 +1721,16 @@
**
** INVARIANTS:
**
-** {F12221} The [sqlite3_last_insert_rowid()] function returns the rowid
+** {H12221} The [sqlite3_last_insert_rowid()] function returns the rowid
** of the most recent successful INSERT performed on the same
** [database connection] and within the same or higher level
** trigger context, or zero if there have been no qualifying inserts.
**
-** {F12223} The [sqlite3_last_insert_rowid()] function returns the
+** {H12223} The [sqlite3_last_insert_rowid()] function returns the
** same value when called from the same trigger context
** immediately before and after a ROLLBACK.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12232} If a separate thread performs a new INSERT on the same
** database connection while the [sqlite3_last_insert_rowid()]
@@ -1675,7 +1742,7 @@
SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
-** CAPI3REF: Count The Number Of Rows Modified {F12240}
+** CAPI3REF: Count The Number Of Rows Modified {H12240} <S10600>
**
** This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
@@ -1725,18 +1792,18 @@
**
** INVARIANTS:
**
-** {F12241} The [sqlite3_changes()] function shall return the number of
+** {H12241} The [sqlite3_changes()] function shall return the number of
** row changes caused by the most recent INSERT, UPDATE,
** or DELETE statement on the same database connection and
** within the same or higher trigger context, or zero if there have
** not been any qualifying row changes.
**
-** {F12243} Statements of the form "DELETE FROM tablename" with no
+** {H12243} Statements of the form "DELETE FROM tablename" with no
** WHERE clause shall cause subsequent calls to
** [sqlite3_changes()] to return zero, regardless of the
** number of rows originally in the table.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12252} If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
@@ -1745,7 +1812,7 @@
SQLITE_API int sqlite3_changes(sqlite3*);
/*
-** CAPI3REF: Total Number Of Rows Modified {F12260}
+** CAPI3REF: Total Number Of Rows Modified {H12260} <S10600>
**
** This function returns the number of row changes caused by INSERT,
** UPDATE or DELETE statements since the [database connection] was opened.
@@ -1769,16 +1836,16 @@
**
** INVARIANTS:
**
-** {F12261} The [sqlite3_total_changes()] returns the total number
+** {H12261} The [sqlite3_total_changes()] returns the total number
** of row changes caused by INSERT, UPDATE, and/or DELETE
** statements on the same [database connection], in any
** trigger context, since the database connection was created.
**
-** {F12263} Statements of the form "DELETE FROM tablename" with no
+** {H12263} Statements of the form "DELETE FROM tablename" with no
** WHERE clause shall not change the value returned
** by [sqlite3_total_changes()].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12264} If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
@@ -1787,7 +1854,7 @@
SQLITE_API int sqlite3_total_changes(sqlite3*);
/*
-** CAPI3REF: Interrupt A Long-Running Query {F12270}
+** CAPI3REF: Interrupt A Long-Running Query {H12270} <S30500>
**
** This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
@@ -1814,14 +1881,14 @@
**
** INVARIANTS:
**
-** {F12271} The [sqlite3_interrupt()] interface will force all running
+** {H12271} The [sqlite3_interrupt()] interface will force all running
** SQL statements associated with the same database connection
** to halt after processing at most one additional row of data.
**
-** {F12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
+** {H12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
** will return [SQLITE_INTERRUPT].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12279} If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
@@ -1829,7 +1896,7 @@
SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
-** CAPI3REF: Determine If An SQL Statement Is Complete {F10510}
+** CAPI3REF: Determine If An SQL Statement Is Complete {H10510} <S70200>
**
** These routines are useful for command-line input to determine if the
** currently entered text seems to form complete a SQL statement or
@@ -1847,17 +1914,17 @@
**
** INVARIANTS:
**
-** {F10511} A successful evaluation of [sqlite3_complete()] or
+** {H10511} A successful evaluation of [sqlite3_complete()] or
** [sqlite3_complete16()] functions shall
** return a numeric 1 if and only if the last non-whitespace
** token in their input is a semicolon that is not in between
** the BEGIN and END of a CREATE TRIGGER statement.
**
-** {F10512} If a memory allocation error occurs during an invocation
+** {H10512} If a memory allocation error occurs during an invocation
** of [sqlite3_complete()] or [sqlite3_complete16()] then the
** routine shall return [SQLITE_NOMEM].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A10512} The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
@@ -1869,7 +1936,7 @@
SQLITE_API int sqlite3_complete16(const void *sql);
/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {F12310}
+** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {H12310} <S40400>
**
** This routine sets a callback function that might be invoked whenever
** an attempt is made to open a database table that another thread
@@ -1927,27 +1994,27 @@
**
** INVARIANTS:
**
-** {F12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
+** {H12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
** busy callback in the [database connection] D with a new
** a new busy handler C and application data pointer A.
**
-** {F12312} Newly created [database connections] shall have a busy
+** {H12312} Newly created [database connections] shall have a busy
** handler of NULL.
**
-** {F12314} When two or more [database connections] share a
+** {H12314} When two or more [database connections] share a
** [sqlite3_enable_shared_cache | common cache],
** the busy handler for the database connection currently using
** the cache shall be invoked when the cache encounters a lock.
**
-** {F12316} If a busy handler callback returns zero, then the SQLite interface
+** {H12316} If a busy handler callback returns zero, then the SQLite interface
** that provoked the locking event shall return [SQLITE_BUSY].
**
-** {F12318} SQLite shall invokes the busy handler with two arguments which
+** {H12318} SQLite shall invokes the busy handler with two arguments which
** are a copy of the pointer supplied by the 3rd parameter to
** [sqlite3_busy_handler()] and a count of the number of prior
** invocations of the busy handler for the same locking event.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12319} A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
@@ -1955,12 +2022,12 @@
SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
-** CAPI3REF: Set A Busy Timeout {F12340}
+** CAPI3REF: Set A Busy Timeout {H12340} <S40410>
**
** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked. The handler
** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. {F12343} After "ms" milliseconds of sleeping,
+** have accumulated. {H12343} After "ms" milliseconds of sleeping,
** the handler returns 0 which causes [sqlite3_step()] to return
** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
**
@@ -1974,15 +2041,15 @@
**
** INVARIANTS:
**
-** {F12341} The [sqlite3_busy_timeout()] function shall override any prior
+** {H12341} The [sqlite3_busy_timeout()] function shall override any prior
** [sqlite3_busy_timeout()] or [sqlite3_busy_handler()] setting
** on the same [database connection].
**
-** {F12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
+** {H12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
** or equal to zero, then the busy handler shall be cleared so that
** all subsequent locking events immediately return [SQLITE_BUSY].
**
-** {F12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
+** {H12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
** number N, then a busy handler shall be set that repeatedly calls
** the xSleep() method in the [sqlite3_vfs | VFS interface] until
** either the lock clears or until the cumulative sleep time
@@ -1991,7 +2058,7 @@
SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
-** CAPI3REF: Convenience Routines For Running Queries {F12370}
+** CAPI3REF: Convenience Routines For Running Queries {H12370} <S10000>
**
** Definition: A <b>result table</b> is memory data structure created by the
** [sqlite3_get_table()] interface. A result table records the
@@ -2060,32 +2127,32 @@
**
** INVARIANTS:
**
-** {F12371} If a [sqlite3_get_table()] fails a memory allocation, then
+** {H12371} If a [sqlite3_get_table()] fails a memory allocation, then
** it shall free the result table under construction, abort the
** query in process, skip any subsequent queries, set the
** *pazResult output pointer to NULL and return [SQLITE_NOMEM].
**
-** {F12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
+** {H12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
** then a successful invocation of [sqlite3_get_table()] shall
** write the number of columns in the
** result set of the query into *pnColumn.
**
-** {F12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
+** {H12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
** then a successful invocation of [sqlite3_get_table()] shall
** writes the number of rows in the
** result set of the query into *pnRow.
**
-** {F12376} A successful invocation of [sqlite3_get_table()] that computes
+** {H12376} A successful invocation of [sqlite3_get_table()] that computes
** N rows of result with C columns per row shall make *pazResult
** point to an array of pointers to (N+1)*C strings where the first
** C strings are column names as obtained from
** [sqlite3_column_name()] and the rest are column result values
** obtained from [sqlite3_column_text()].
**
-** {F12379} The values in the pazResult array returned by [sqlite3_get_table()]
+** {H12379} The values in the pazResult array returned by [sqlite3_get_table()]
** shall remain valid until cleared by [sqlite3_free_table()].
**
-** {F12382} When an error occurs during evaluation of [sqlite3_get_table()]
+** {H12382} When an error occurs during evaluation of [sqlite3_get_table()]
** the function shall set *pazResult to NULL, write an error message
** into memory obtained from [sqlite3_malloc()], make
** **pzErrmsg point to that error message, and return a
@@ -2102,7 +2169,7 @@
SQLITE_API void sqlite3_free_table(char **result);
/*
-** CAPI3REF: Formatted String Printing Functions {F17400}
+** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
**
** These routines are workalikes of the "printf()" family of functions
** from the standard C library.
@@ -2195,16 +2262,16 @@
**
** INVARIANTS:
**
-** {F17403} The [sqlite3_mprintf()] and [sqlite3_vmprintf()] interfaces
+** {H17403} The [sqlite3_mprintf()] and [sqlite3_vmprintf()] interfaces
** return either pointers to zero-terminated UTF-8 strings held in
** memory obtained from [sqlite3_malloc()] or NULL pointers if
** a call to [sqlite3_malloc()] fails.
**
-** {F17406} The [sqlite3_snprintf()] interface writes a zero-terminated
+** {H17406} The [sqlite3_snprintf()] interface writes a zero-terminated
** UTF-8 string into the buffer pointed to by the second parameter
** provided that the first parameter is greater than zero.
**
-** {F17407} The [sqlite3_snprintf()] interface does not write slots of
+** {H17407} The [sqlite3_snprintf()] interface does not write slots of
** its output buffer (the second parameter) outside the range
** of 0 through N-1 (where N is the first parameter)
** regardless of the length of the string
@@ -2215,7 +2282,7 @@
SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
/*
-** CAPI3REF: Memory Allocation Subsystem {F17300}
+** CAPI3REF: Memory Allocation Subsystem {H17300} <S20000>
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence
@@ -2262,7 +2329,7 @@
**
** The default implementation of the memory allocation subsystem uses
** the malloc(), realloc() and free() provided by the standard C library.
-** {F17382} However, if SQLite is compiled with the
+** {H17382} However, if SQLite is compiled with the
** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
** is an integer), then SQLite create a static array of at least
** <i>NNN</i> bytes in size and uses that array for all of its dynamic
@@ -2284,46 +2351,46 @@
**
** INVARIANTS:
**
-** {F17303} The [sqlite3_malloc(N)] interface returns either a pointer to
+** {H17303} The [sqlite3_malloc(N)] interface returns either a pointer to
** a newly checked-out block of at least N bytes of memory
** that is 8-byte aligned, or it returns NULL if it is unable
** to fulfill the request.
**
-** {F17304} The [sqlite3_malloc(N)] interface returns a NULL pointer if
+** {H17304} The [sqlite3_malloc(N)] interface returns a NULL pointer if
** N is less than or equal to zero.
**
-** {F17305} The [sqlite3_free(P)] interface releases memory previously
+** {H17305} The [sqlite3_free(P)] interface releases memory previously
** returned from [sqlite3_malloc()] or [sqlite3_realloc()],
** making it available for reuse.
**
-** {F17306} A call to [sqlite3_free(NULL)] is a harmless no-op.
+** {H17306} A call to [sqlite3_free(NULL)] is a harmless no-op.
**
-** {F17310} A call to [sqlite3_realloc(0,N)] is equivalent to a call
+** {H17310} A call to [sqlite3_realloc(0,N)] is equivalent to a call
** to [sqlite3_malloc(N)].
**
-** {F17312} A call to [sqlite3_realloc(P,0)] is equivalent to a call
+** {H17312} A call to [sqlite3_realloc(P,0)] is equivalent to a call
** to [sqlite3_free(P)].
**
-** {F17315} The SQLite core uses [sqlite3_malloc()], [sqlite3_realloc()],
+** {H17315} The SQLite core uses [sqlite3_malloc()], [sqlite3_realloc()],
** and [sqlite3_free()] for all of its memory allocation and
** deallocation needs.
**
-** {F17318} The [sqlite3_realloc(P,N)] interface returns either a pointer
+** {H17318} The [sqlite3_realloc(P,N)] interface returns either a pointer
** to a block of checked-out memory of at least N bytes in size
** that is 8-byte aligned, or a NULL pointer.
**
-** {F17321} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
+** {H17321} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
** copies the first K bytes of content from P into the newly
** allocated block, where K is the lesser of N and the size of
** the buffer P.
**
-** {F17322} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
+** {H17322} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
** releases the buffer P.
**
-** {F17323} When [sqlite3_realloc(P,N)] returns NULL, the buffer P is
+** {H17323} When [sqlite3_realloc(P,N)] returns NULL, the buffer P is
** not modified or released.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A17350} The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
** must be either NULL or else pointers obtained from a prior
@@ -2339,7 +2406,7 @@
SQLITE_API void sqlite3_free(void*);
/*
-** CAPI3REF: Memory Allocator Statistics {F17370}
+** CAPI3REF: Memory Allocator Statistics {H17370} <S30210>
**
** SQLite provides these two interfaces for reporting on the status
** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
@@ -2347,20 +2414,20 @@
**
** INVARIANTS:
**
-** {F17371} The [sqlite3_memory_used()] routine returns the number of bytes
+** {H17371} The [sqlite3_memory_used()] routine returns the number of bytes
** of memory currently outstanding (malloced but not freed).
**
-** {F17373} The [sqlite3_memory_highwater()] routine returns the maximum
+** {H17373} The [sqlite3_memory_highwater()] routine returns the maximum
** value of [sqlite3_memory_used()] since the high-water mark
** was last reset.
**
-** {F17374} The values returned by [sqlite3_memory_used()] and
+** {H17374} The values returned by [sqlite3_memory_used()] and
** [sqlite3_memory_highwater()] include any overhead
** added by SQLite in its implementation of [sqlite3_malloc()],
** but not overhead added by the any underlying system library
** routines that [sqlite3_malloc()] may call.
**
-** {F17375} The memory high-water mark is reset to the current value of
+** {H17375} The memory high-water mark is reset to the current value of
** [sqlite3_memory_used()] if and only if the parameter to
** [sqlite3_memory_highwater()] is true. The value returned
** by [sqlite3_memory_highwater(1)] is the high-water mark
@@ -2370,7 +2437,7 @@
SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
-** CAPI3REF: Pseudo-Random Number Generator {F17390}
+** CAPI3REF: Pseudo-Random Number Generator {H17390} <S20000>
**
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random ROWIDs when inserting new records into a table that
@@ -2389,13 +2456,13 @@
**
** INVARIANTS:
**
-** {F17392} The [sqlite3_randomness(N,P)] interface writes N bytes of
+** {H17392} The [sqlite3_randomness(N,P)] interface writes N bytes of
** high-quality pseudo-randomness into buffer P.
*/
SQLITE_API void sqlite3_randomness(int N, void *P);
/*
-** CAPI3REF: Compile-Time Authorization Callbacks {F12500}
+** CAPI3REF: Compile-Time Authorization Callbacks {H12500} <S70100>
**
** This routine registers a authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2459,55 +2526,55 @@
**
** INVARIANTS:
**
-** {F12501} The [sqlite3_set_authorizer(D,...)] interface registers a
+** {H12501} The [sqlite3_set_authorizer(D,...)] interface registers a
** authorizer callback with database connection D.
**
-** {F12502} The authorizer callback is invoked as SQL statements are
+** {H12502} The authorizer callback is invoked as SQL statements are
** being compiled.
**
-** {F12503} If the authorizer callback returns any value other than
+** {H12503} If the authorizer callback returns any value other than
** [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY], then
** the [sqlite3_prepare_v2()] or equivalent call that caused
** the authorizer callback to run shall fail with an
** [SQLITE_ERROR] error code and an appropriate error message.
**
-** {F12504} When the authorizer callback returns [SQLITE_OK], the operation
+** {H12504} When the authorizer callback returns [SQLITE_OK], the operation
** described is processed normally.
**
-** {F12505} When the authorizer callback returns [SQLITE_DENY], the
+** {H12505} When the authorizer callback returns [SQLITE_DENY], the
** [sqlite3_prepare_v2()] or equivalent call that caused the
** authorizer callback to run shall fail
** with an [SQLITE_ERROR] error code and an error message
** explaining that access is denied.
**
-** {F12506} If the authorizer code (the 2nd parameter to the authorizer
+** {H12506} If the authorizer code (the 2nd parameter to the authorizer
** callback) is [SQLITE_READ] and the authorizer callback returns
** [SQLITE_IGNORE], then the prepared statement is constructed to
** insert a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned.
**
-** {F12507} If the authorizer code (the 2nd parameter to the authorizer
+** {H12507} If the authorizer code (the 2nd parameter to the authorizer
** callback) is anything other than [SQLITE_READ], then
** a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY].
**
-** {F12510} The first parameter to the authorizer callback is a copy of
+** {H12510} The first parameter to the authorizer callback is a copy of
** the third parameter to the [sqlite3_set_authorizer()] interface.
**
-** {F12511} The second parameter to the callback is an integer
+** {H12511} The second parameter to the callback is an integer
** [SQLITE_COPY | action code] that specifies the particular action
** to be authorized.
**
-** {F12512} The third through sixth parameters to the callback are
+** {H12512} The third through sixth parameters to the callback are
** zero-terminated strings that contain
** additional details about the action to be authorized.
**
-** {F12520} Each call to [sqlite3_set_authorizer()] overrides
+** {H12520} Each call to [sqlite3_set_authorizer()] overrides
** any previously installed authorizer.
**
-** {F12521} A NULL authorizer means that no authorization
+** {H12521} A NULL authorizer means that no authorization
** callback is invoked.
**
-** {F12522} The default authorizer is NULL.
+** {H12522} The default authorizer is NULL.
*/
SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
@@ -2516,7 +2583,7 @@
);
/*
-** CAPI3REF: Authorizer Return Codes {F12590}
+** CAPI3REF: Authorizer Return Codes {H12590} <H12500>
**
** The [sqlite3_set_authorizer | authorizer callback function] must
** return either [SQLITE_OK] or one of these two constants in order
@@ -2528,7 +2595,7 @@
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
/*
-** CAPI3REF: Authorizer Action Codes {F12550}
+** CAPI3REF: Authorizer Action Codes {H12550} <H12500>
**
** The [sqlite3_set_authorizer()] interface registers a callback function
** that is invoked to authorize certain SQL statement actions. The
@@ -2548,21 +2615,21 @@
**
** INVARIANTS:
**
-** {F12551} The second parameter to an
+** {H12551} The second parameter to an
** [sqlite3_set_authorizer | authorizer callback] is always an integer
** [SQLITE_COPY | authorizer code] that specifies what action
** is being authorized.
**
-** {F12552} The 3rd and 4th parameters to the
+** {H12552} The 3rd and 4th parameters to the
** [sqlite3_set_authorizer | authorization callback]
** will be parameters or NULL depending on which
** [SQLITE_COPY | authorizer code] is used as the second parameter.
**
-** {F12553} The 5th parameter to the
+** {H12553} The 5th parameter to the
** [sqlite3_set_authorizer | authorizer callback] is the name
** of the database (example: "main", "temp", etc.) if applicable.
**
-** {F12554} The 6th parameter to the
+** {H12554} The 6th parameter to the
** [sqlite3_set_authorizer | authorizer callback] is the name
** of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
@@ -2603,7 +2670,8 @@
#define SQLITE_COPY 0 /* No longer used */
/*
-** CAPI3REF: Tracing And Profiling Functions {F12280}
+** CAPI3REF: Tracing And Profiling Functions {H12280} <S60400>
+** EXPERIMENTAL
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
@@ -2620,46 +2688,38 @@
** the original statement text and an estimate of wall-clock time
** of how long that statement took to run.
**
-** The sqlite3_profile() API is currently considered experimental and
-** is subject to change or removal in a future release.
-**
-** The trigger reporting feature of the trace callback is considered
-** experimental and is subject to change or removal in future releases.
-** Future versions of SQLite might also add new trace callback
-** invocations.
-**
** INVARIANTS:
**
-** {F12281} The callback function registered by [sqlite3_trace()] is
+** {H12281} The callback function registered by [sqlite3_trace()] is
** whenever an SQL statement first begins to execute and
** whenever a trigger subprogram first begins to run.
**
-** {F12282} Each call to [sqlite3_trace()] overrides the previously
+** {H12282} Each call to [sqlite3_trace()] overrides the previously
** registered trace callback.
**
-** {F12283} A NULL trace callback disables tracing.
+** {H12283} A NULL trace callback disables tracing.
**
-** {F12284} The first argument to the trace callback is a copy of
+** {H12284} The first argument to the trace callback is a copy of
** the pointer which was the 3rd argument to [sqlite3_trace()].
**
-** {F12285} The second argument to the trace callback is a
+** {H12285} The second argument to the trace callback is a
** zero-terminated UTF-8 string containing the original text
** of the SQL statement as it was passed into [sqlite3_prepare_v2()]
** or the equivalent, or an SQL comment indicating the beginning
** of a trigger subprogram.
**
-** {F12287} The callback function registered by [sqlite3_profile()] is invoked
+** {H12287} The callback function registered by [sqlite3_profile()] is invoked
** as each SQL statement finishes.
**
-** {F12288} The first parameter to the profile callback is a copy of
+** {H12288} The first parameter to the profile callback is a copy of
** the 3rd parameter to [sqlite3_profile()].
**
-** {F12289} The second parameter to the profile callback is a
+** {H12289} The second parameter to the profile callback is a
** zero-terminated UTF-8 string that contains the complete text of
** the SQL statement as it was processed by [sqlite3_prepare_v2()]
** or the equivalent.
**
-** {F12290} The third parameter to the profile callback is an estimate
+** {H12290} The third parameter to the profile callback is an estimate
** of the number of nanoseconds of wall-clock time required to
** run the SQL statement from start to finish.
*/
@@ -2668,7 +2728,7 @@
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
-** CAPI3REF: Query Progress Callbacks {F12910}
+** CAPI3REF: Query Progress Callbacks {H12910} <S60400>
**
** This routine configures a callback function - the
** progress callback - that is invoked periodically during long
@@ -2682,39 +2742,40 @@
**
** INVARIANTS:
**
-** {F12911} The callback function registered by sqlite3_progress_handler()
+** {H12911} The callback function registered by sqlite3_progress_handler()
** is invoked periodically during long running calls to
** [sqlite3_step()].
**
-** {F12912} The progress callback is invoked once for every N virtual
+** {H12912} The progress callback is invoked once for every N virtual
** machine opcodes, where N is the second argument to
** the [sqlite3_progress_handler()] call that registered
** the callback. If N is less than 1, sqlite3_progress_handler()
** acts as if a NULL progress handler had been specified.
**
-** {F12913} The progress callback itself is identified by the third
+** {H12913} The progress callback itself is identified by the third
** argument to sqlite3_progress_handler().
**
-** {F12914} The fourth argument to sqlite3_progress_handler() is a
+** {H12914} The fourth argument to sqlite3_progress_handler() is a
** void pointer passed to the progress callback
** function each time it is invoked.
**
-** {F12915} If a call to [sqlite3_step()] results in fewer than N opcodes
+** {H12915} If a call to [sqlite3_step()] results in fewer than N opcodes
** being executed, then the progress callback is never invoked.
**
-** {F12916} Every call to [sqlite3_progress_handler()]
+** {H12916} Every call to [sqlite3_progress_handler()]
** overwrites any previously registered progress handler.
**
-** {F12917} If the progress handler callback is NULL then no progress
+** {H12917} If the progress handler callback is NULL then no progress
** handler is invoked.
**
-** {F12918} If the progress callback returns a result other than 0, then
+** {H12918} If the progress callback returns a result other than 0, then
** the behavior is a if [sqlite3_interrupt()] had been called.
+** <S30500>
*/
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
-** CAPI3REF: Opening A New Database Connection {F12700}
+** CAPI3REF: Opening A New Database Connection {H12700} <S40200>
**
** These routines open an SQLite database file whose name is given by the
** filename argument. The filename argument is interpreted as UTF-8 for
@@ -2796,67 +2857,67 @@
**
** INVARIANTS:
**
-** {F12701} The [sqlite3_open()], [sqlite3_open16()], and
+** {H12701} The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces create a new
** [database connection] associated with
** the database file given in their first parameter.
**
-** {F12702} The filename argument is interpreted as UTF-8
+** {H12702} The filename argument is interpreted as UTF-8
** for [sqlite3_open()] and [sqlite3_open_v2()] and as UTF-16
** in the native byte order for [sqlite3_open16()].
**
-** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
+** {H12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()] writes a pointer to a new
** [database connection] into *ppDb.
**
-** {F12704} The [sqlite3_open()], [sqlite3_open16()], and
+** {H12704} The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces return [SQLITE_OK] upon success,
** or an appropriate [error code] on failure.
**
-** {F12706} The default text encoding for a new database created using
+** {H12706} The default text encoding for a new database created using
** [sqlite3_open()] or [sqlite3_open_v2()] will be UTF-8.
**
-** {F12707} The default text encoding for a new database created using
+** {H12707} The default text encoding for a new database created using
** [sqlite3_open16()] will be UTF-16.
**
-** {F12709} The [sqlite3_open(F,D)] interface is equivalent to
+** {H12709} The [sqlite3_open(F,D)] interface is equivalent to
** [sqlite3_open_v2(F,D,G,0)] where the G parameter is
** [SQLITE_OPEN_READWRITE]|[SQLITE_OPEN_CREATE].
**
-** {F12711} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
+** {H12711} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_READONLY] then the database is opened
** for reading only.
**
-** {F12712} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
+** {H12712} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_READWRITE] then the database is opened
** reading and writing if possible, or for reading only if the
** file is write protected by the operating system.
**
-** {F12713} If the G parameter to [sqlite3_open(v2(F,D,G,V)] omits the
+** {H12713} If the G parameter to [sqlite3_open(v2(F,D,G,V)] omits the
** bit value [SQLITE_OPEN_CREATE] and the database does not
** previously exist, an error is returned.
**
-** {F12714} If the G parameter to [sqlite3_open(v2(F,D,G,V)] contains the
+** {H12714} If the G parameter to [sqlite3_open(v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_CREATE] and the database does not
** previously exist, then an attempt is made to create and
** initialize the database.
**
-** {F12717} If the filename argument to [sqlite3_open()], [sqlite3_open16()],
+** {H12717} If the filename argument to [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()] is ":memory:", then an private,
** ephemeral, in-memory database is created for the connection.
** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
** in sqlite3_open_v2()?</todo>
**
-** {F12719} If the filename is NULL or an empty string, then a private,
+** {H12719} If the filename is NULL or an empty string, then a private,
** ephemeral on-disk database will be created.
** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
** in sqlite3_open_v2()?</todo>
**
-** {F12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
+** {H12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
** will use the [sqlite3_vfs] object identified by the V parameter,
** or the default [sqlite3_vfs] object if V is a NULL pointer.
**
-** {F12723} Two [database connections] will share a common cache if both were
+** {H12723} Two [database connections] will share a common cache if both were
** opened with the same VFS while [shared cache mode] was enabled and
** if both filenames compare equal using memcmp() after having been
** processed by the [sqlite3_vfs | xFullPathname] method of the VFS.
@@ -2877,7 +2938,7 @@
);
/*
-** CAPI3REF: Error Codes And Messages {F12800}
+** CAPI3REF: Error Codes And Messages {H12800} <S60200>
**
** The sqlite3_errcode() interface returns the numeric [result code] or
** [extended result code] for the most recent failed sqlite3_* API call
@@ -2898,24 +2959,24 @@
**
** INVARIANTS:
**
-** {F12801} The [sqlite3_errcode(D)] interface returns the numeric
+** {H12801} The [sqlite3_errcode(D)] interface returns the numeric
** [result code] or [extended result code] for the most recently
** failed interface call associated with the [database connection] D.
**
-** {F12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
+** {H12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
** interfaces return English-language text that describes
** the error in the mostly recently failed interface call,
** encoded as either UTF-8 or UTF-16 respectively.
**
-** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
+** {H12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
** are valid until the next SQLite interface call.
**
-** {F12808} Calls to API routines that do not return an error code
+** {H12808} Calls to API routines that do not return an error code
** (example: [sqlite3_data_count()]) do not
** change the error code or message returned by
** [sqlite3_errcode()], [sqlite3_errmsg()], or [sqlite3_errmsg16()].
**
-** {F12809} Interfaces that are not associated with a specific
+** {H12809} Interfaces that are not associated with a specific
** [database connection] (examples:
** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()]
** do not change the values returned by
@@ -2926,7 +2987,7 @@
SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
/*
-** CAPI3REF: SQL Statement Object {F13000}
+** CAPI3REF: SQL Statement Object {H13000} <H13010>
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement.
@@ -2952,7 +3013,7 @@
typedef struct sqlite3_stmt sqlite3_stmt;
/*
-** CAPI3REF: Run-time Limits {F12760}
+** CAPI3REF: Run-time Limits {H12760} <S20600>
**
** This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
@@ -2985,22 +3046,22 @@
**
** INVARIANTS:
**
-** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is
+** {H12762} A successful call to [sqlite3_limit(D,C,V)] where V is
** positive changes the limit on the size of construct C in the
** [database connection] D to the lesser of V and the hard upper
** bound on the size of C that is set at compile-time.
**
-** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
+** {H12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
** leaves the state of the [database connection] D unchanged.
**
-** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the
+** {H12769} A successful call to [sqlite3_limit(D,C,V)] returns the
** value of the limit on the size of construct C in the
** [database connection] D as it was prior to the call.
*/
SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
-** CAPI3REF: Run-Time Limit Categories {F12790}
+** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
** KEYWORDS: {limit category} {limit categories}
**
** These constants define various aspects of a [database connection]
@@ -3056,7 +3117,7 @@
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
/*
-** CAPI3REF: Compiling An SQL Statement {F13010}
+** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
@@ -3126,37 +3187,37 @@
**
** INVARIANTS:
**
-** {F13011} The [sqlite3_prepare(db,zSql,...)] and
+** {H13011} The [sqlite3_prepare(db,zSql,...)] and
** [sqlite3_prepare_v2(db,zSql,...)] interfaces interpret the
** text in their zSql parameter as UTF-8.
**
-** {F13012} The [sqlite3_prepare16(db,zSql,...)] and
+** {H13012} The [sqlite3_prepare16(db,zSql,...)] and
** [sqlite3_prepare16_v2(db,zSql,...)] interfaces interpret the
** text in their zSql parameter as UTF-16 in the native byte order.
**
-** {F13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
+** {H13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
** and its variants is less than zero, the SQL text is
** read from zSql is read up to the first zero terminator.
**
-** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
+** {H13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
** and its variants is non-negative, then at most nBytes bytes of
** SQL text is read from zSql.
**
-** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
+** {H13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
** if the zSql input text contains more than one SQL statement
** and pzTail is not NULL, then *pzTail is made to point to the
** first byte past the end of the first SQL statement in zSql.
** <todo>What does *pzTail point to if there is one statement?</todo>
**
-** {F13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
+** {H13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
** or one of its variants writes into *ppStmt a pointer to a new
** [prepared statement] or a pointer to NULL if zSql contains
** nothing other than whitespace or comments.
**
-** {F13019} The [sqlite3_prepare_v2()] interface and its variants return
+** {H13019} The [sqlite3_prepare_v2()] interface and its variants return
** [SQLITE_OK] or an appropriate [error code] upon failure.
**
-** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
+** {H13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
** variants returns an error (any value other than [SQLITE_OK]),
** they first set *ppStmt to NULL.
*/
@@ -3190,7 +3251,7 @@
);
/*
-** CAPIREF: Retrieving Statement SQL {F13100}
+** CAPIREF: Retrieving Statement SQL {H13100} <H13000>
**
** This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
@@ -3198,23 +3259,23 @@
**
** INVARIANTS:
**
-** {F13101} If the [prepared statement] passed as the argument to
+** {H13101} If the [prepared statement] passed as the argument to
** [sqlite3_sql()] was compiled using either [sqlite3_prepare_v2()] or
** [sqlite3_prepare16_v2()], then [sqlite3_sql()] returns
** a pointer to a zero-terminated string containing a UTF-8 rendering
** of the original SQL statement.
**
-** {F13102} If the [prepared statement] passed as the argument to
+** {H13102} If the [prepared statement] passed as the argument to
** [sqlite3_sql()] was compiled using either [sqlite3_prepare()] or
** [sqlite3_prepare16()], then [sqlite3_sql()] returns a NULL pointer.
**
-** {F13103} The string returned by [sqlite3_sql(S)] is valid until the
+** {H13103} The string returned by [sqlite3_sql(S)] is valid until the
** [prepared statement] S is deleted using [sqlite3_finalize(S)].
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Dynamically Typed Value Object {F15000}
+** CAPI3REF: Dynamically Typed Value Object {H15000} <S20200>
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
@@ -3253,7 +3314,7 @@
typedef struct Mem sqlite3_value;
/*
-** CAPI3REF: SQL Function Context Object {F16001}
+** CAPI3REF: SQL Function Context Object {H16001} <S20200>
**
** The context in which an SQL function executes is stored in an
** sqlite3_context object. A pointer to an sqlite3_context object
@@ -3267,7 +3328,7 @@
typedef struct sqlite3_context sqlite3_context;
/*
-** CAPI3REF: Binding Values To Prepared Statements {F13500}
+** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
@@ -3347,75 +3408,75 @@
**
** INVARIANTS:
**
-** {F13506} The [SQL statement compiler] recognizes tokens of the forms
+** {H13506} The [SQL statement compiler] recognizes tokens of the forms
** "?", "?NNN", "$VVV", ":VVV", and "@VVV" as SQL parameters,
** where NNN is any sequence of one or more digits
** and where VVV is any sequence of one or more alphanumeric
** characters or "::" optionally followed by a string containing
** no spaces and contained within parentheses.
**
-** {F13509} The initial value of an SQL parameter is NULL.
+** {H13509} The initial value of an SQL parameter is NULL.
**
-** {F13512} The index of an "?" SQL parameter is one larger than the
+** {H13512} The index of an "?" SQL parameter is one larger than the
** largest index of SQL parameter to the left, or 1 if
** the "?" is the leftmost SQL parameter.
**
-** {F13515} The index of an "?NNN" SQL parameter is the integer NNN.
+** {H13515} The index of an "?NNN" SQL parameter is the integer NNN.
**
-** {F13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
+** {H13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
** the same as the index of leftmost occurrences of the same
** parameter, or one more than the largest index over all
** parameters to the left if this is the first occurrence
** of this parameter, or 1 if this is the leftmost parameter.
**
-** {F13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
+** {H13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
** error if the index of an SQL parameter is less than 1
** or greater than the compile-time SQLITE_MAX_VARIABLE_NUMBER
** parameter.
**
-** {F13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
+** {H13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
** associate the value V with all SQL parameters having an
** index of N in the [prepared statement] S.
**
-** {F13527} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,...)]
+** {H13527} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,...)]
** override prior calls with the same values of S and N.
**
-** {F13530} Bindings established by [sqlite3_bind_text | sqlite3_bind(S,...)]
+** {H13530} Bindings established by [sqlite3_bind_text | sqlite3_bind(S,...)]
** persist across calls to [sqlite3_reset(S)].
**
-** {F13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds the first L
** bytes of the BLOB or string pointed to by V, when L
** is non-negative.
**
-** {F13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
+** {H13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds characters
** from V through the first zero character when L is negative.
**
-** {F13539} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13539} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
** constant [SQLITE_STATIC], SQLite assumes that the value V
** is held in static unmanaged space that will not change
** during the lifetime of the binding.
**
-** {F13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
** constant [SQLITE_TRANSIENT], the routine makes a
** private copy of the value V before it returns.
**
-** {F13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is a pointer to
** a function, SQLite invokes that function to destroy the
** value V after it has finished using the value V.
**
-** {F13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
+** {H13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
** is a BLOB of L bytes, or a zero-length BLOB if L is negative.
**
-** {F13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
+** {H13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
** be either a [protected sqlite3_value] object or an
** [unprotected sqlite3_value] object.
*/
@@ -3430,7 +3491,7 @@
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/*
-** CAPI3REF: Number Of SQL Parameters {F13600}
+** CAPI3REF: Number Of SQL Parameters {H13600} <S70300>
**
** This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
@@ -3449,14 +3510,14 @@
**
** INVARIANTS:
**
-** {F13601} The [sqlite3_bind_parameter_count(S)] interface returns
+** {H13601} The [sqlite3_bind_parameter_count(S)] interface returns
** the largest index of all SQL parameters in the
** [prepared statement] S, or 0 if S contains no SQL parameters.
*/
SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
-** CAPI3REF: Name Of A Host Parameter {F13620}
+** CAPI3REF: Name Of A Host Parameter {H13620} <S70300>
**
** This routine returns a pointer to the name of the n-th
** [SQL parameter] in a [prepared statement].
@@ -3482,7 +3543,7 @@
**
** INVARIANTS:
**
-** {F13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
+** {H13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
** a UTF-8 rendering of the name of the SQL parameter in
** the [prepared statement] S having index N, or
** NULL if there is no SQL parameter with index N or if the
@@ -3491,7 +3552,7 @@
SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
-** CAPI3REF: Index Of A Parameter With A Given Name {F13640}
+** CAPI3REF: Index Of A Parameter With A Given Name {H13640} <S70300>
**
** Return the index of an SQL parameter given its name. The
** index value returned is suitable for use as the second
@@ -3506,7 +3567,7 @@
**
** INVARIANTS:
**
-** {F13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
+** {H13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
** the index of SQL parameter in the [prepared statement]
** S whose name matches the UTF-8 string N, or 0 if there is
** no match.
@@ -3514,7 +3575,7 @@
SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement {F13660}
+** CAPI3REF: Reset All Bindings On A Prepared Statement {H13660} <S70300>
**
** Contrary to the intuition of many, [sqlite3_reset()] does not reset
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
@@ -3522,13 +3583,13 @@
**
** INVARIANTS:
**
-** {F13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
+** {H13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
** parameter bindings in the [prepared statement] S back to NULL.
*/
SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
-** CAPI3REF: Number Of Columns In A Result Set {F13710}
+** CAPI3REF: Number Of Columns In A Result Set {H13710} <S10700>
**
** Return the number of columns in the result set returned by the
** [prepared statement]. This routine returns 0 if pStmt is an SQL
@@ -3536,14 +3597,14 @@
**
** INVARIANTS:
**
-** {F13711} The [sqlite3_column_count(S)] interface returns the number of
+** {H13711} The [sqlite3_column_count(S)] interface returns the number of
** columns in the result set generated by the [prepared statement] S,
** or 0 if S does not generate a result set.
*/
SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Column Names In A Result Set {F13720}
+** CAPI3REF: Column Names In A Result Set {H13720} <S10700>
**
** These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. The sqlite3_column_name()
@@ -3568,31 +3629,31 @@
**
** INVARIANTS:
**
-** {F13721} A successful invocation of the [sqlite3_column_name(S,N)]
+** {H13721} A successful invocation of the [sqlite3_column_name(S,N)]
** interface returns the name of the Nth column (where 0 is
** the leftmost column) for the result set of the
** [prepared statement] S as a zero-terminated UTF-8 string.
**
-** {F13723} A successful invocation of the [sqlite3_column_name16(S,N)]
+** {H13723} A successful invocation of the [sqlite3_column_name16(S,N)]
** interface returns the name of the Nth column (where 0 is
** the leftmost column) for the result set of the
** [prepared statement] S as a zero-terminated UTF-16 string
** in the native byte order.
**
-** {F13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
+** {H13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
** interfaces return a NULL pointer if they are unable to
** allocate memory to hold their normal return strings.
**
-** {F13725} If the N parameter to [sqlite3_column_name(S,N)] or
+** {H13725} If the N parameter to [sqlite3_column_name(S,N)] or
** [sqlite3_column_name16(S,N)] is out of range, then the
** interfaces return a NULL pointer.
**
-** {F13726} The strings returned by [sqlite3_column_name(S,N)] and
+** {H13726} The strings returned by [sqlite3_column_name(S,N)] and
** [sqlite3_column_name16(S,N)] are valid until the next
** call to either routine with the same S and N parameters
** or until [sqlite3_finalize(S)] is called.
**
-** {F13727} When a result column of a [SELECT] statement contains
+** {H13727} When a result column of a [SELECT] statement contains
** an AS clause, the name of that column is the identifier
** to the right of the AS keyword.
*/
@@ -3600,7 +3661,7 @@
SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
-** CAPI3REF: Source Of Data In A Query Result {F13740}
+** CAPI3REF: Source Of Data In A Query Result {H13740} <S10700>
**
** These routines provide a means to determine what column of what
** table in which database a result of a [SELECT] statement comes from.
@@ -3638,50 +3699,50 @@
**
** INVARIANTS:
**
-** {F13741} The [sqlite3_column_database_name(S,N)] interface returns either
+** {H13741} The [sqlite3_column_database_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the database from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13742} The [sqlite3_column_database_name16(S,N)] interface returns either
+** {H13742} The [sqlite3_column_database_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the database
** from which the Nth result column of the [prepared statement] S is
** extracted, or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13743} The [sqlite3_column_table_name(S,N)] interface returns either
+** {H13743} The [sqlite3_column_table_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the table from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13744} The [sqlite3_column_table_name16(S,N)] interface returns either
+** {H13744} The [sqlite3_column_table_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the table
** from which the Nth result column of the [prepared statement] S is
** extracted, or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13745} The [sqlite3_column_origin_name(S,N)] interface returns either
+** {H13745} The [sqlite3_column_origin_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the table column from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
+** {H13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the table
** column from which the Nth result column of the
** [prepared statement] S is extracted, or NULL if the Nth column
** of S is a general expression or if unable to allocate memory
** to store the name.
**
-** {F13748} The return values from
+** {H13748} The return values from
** [sqlite3_column_database_name | column metadata interfaces]
** are valid for the lifetime of the [prepared statement]
** or until the encoding is changed by another metadata
** interface call for the same prepared statement and column.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A13751} If two or more threads call one or more
** [sqlite3_column_database_name | column metadata interfaces]
@@ -3696,7 +3757,7 @@
SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
-** CAPI3REF: Declared Datatype Of A Query Result {F13760}
+** CAPI3REF: Declared Datatype Of A Query Result {H13760} <S10700>
**
** The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
@@ -3726,18 +3787,18 @@
**
** INVARIANTS:
**
-** {F13761} A successful call to [sqlite3_column_decltype(S,N)] returns a
+** {H13761} A successful call to [sqlite3_column_decltype(S,N)] returns a
** zero-terminated UTF-8 string containing the declared datatype
** of the table column that appears as the Nth column (numbered
** from 0) of the result set to the [prepared statement] S.
**
-** {F13762} A successful call to [sqlite3_column_decltype16(S,N)]
+** {H13762} A successful call to [sqlite3_column_decltype16(S,N)]
** returns a zero-terminated UTF-16 native byte order string
** containing the declared datatype of the table column that appears
** as the Nth column (numbered from 0) of the result set to the
** [prepared statement] S.
**
-** {F13763} If N is less than 0 or N is greater than or equal to
+** {H13763} If N is less than 0 or N is greater than or equal to
** the number of columns in the [prepared statement] S,
** or if the Nth column of S is an expression or subquery rather
** than a table column, or if a memory allocation failure
@@ -3749,7 +3810,7 @@
SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
-** CAPI3REF: Evaluate An SQL Statement {F13200}
+** CAPI3REF: Evaluate An SQL Statement {H13200} <S10000>
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3815,24 +3876,24 @@
**
** INVARIANTS:
**
-** {F13202} If the [prepared statement] S is ready to be run, then
+** {H13202} If the [prepared statement] S is ready to be run, then
** [sqlite3_step(S)] advances that prepared statement until
** completion or until it is ready to return another row of the
** result set, or until an [sqlite3_interrupt | interrupt]
** or a run-time error occurs.
**
-** {F15304} When a call to [sqlite3_step(S)] causes the [prepared statement]
+** {H15304} When a call to [sqlite3_step(S)] causes the [prepared statement]
** S to run to completion, the function returns [SQLITE_DONE].
**
-** {F15306} When a call to [sqlite3_step(S)] stops because it is ready to
+** {H15306} When a call to [sqlite3_step(S)] stops because it is ready to
** return another row of the result set, it returns [SQLITE_ROW].
**
-** {F15308} If a call to [sqlite3_step(S)] encounters an
+** {H15308} If a call to [sqlite3_step(S)] encounters an
** [sqlite3_interrupt | interrupt] or a run-time error,
** it returns an appropriate error code that is not one of
** [SQLITE_OK], [SQLITE_ROW], or [SQLITE_DONE].
**
-** {F15310} If an [sqlite3_interrupt | interrupt] or a run-time error
+** {H15310} If an [sqlite3_interrupt | interrupt] or a run-time error
** occurs during a call to [sqlite3_step(S)]
** for a [prepared statement] S created using
** legacy interfaces [sqlite3_prepare()] or
@@ -3842,17 +3903,17 @@
SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
-** CAPI3REF: Number of columns in a result set {F13770}
+** CAPI3REF: Number of columns in a result set {H13770} <S10700>
**
** Returns the number of values in the current row of the result set.
**
** INVARIANTS:
**
-** {F13771} After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
+** {H13771} After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
** the [sqlite3_data_count(S)] routine will return the same value
** as the [sqlite3_column_count(S)] function.
**
-** {F13772} After [sqlite3_step(S)] has returned any value other than
+** {H13772} After [sqlite3_step(S)] has returned any value other than
** [SQLITE_ROW] or before [sqlite3_step(S)] has been called on the
** [prepared statement] for the first time since it was
** [sqlite3_prepare | prepared] or [sqlite3_reset | reset],
@@ -3861,10 +3922,10 @@
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Fundamental Datatypes {F10265}
+** CAPI3REF: Fundamental Datatypes {H10265} <S10110><S10120>
** KEYWORDS: SQLITE_TEXT
**
-** {F10266} Every value in SQLite has one of five fundamental datatypes:
+** {H10266} Every value in SQLite has one of five fundamental datatypes:
**
** <ul>
** <li> 64-bit signed integer
@@ -3893,7 +3954,7 @@
#define SQLITE3_TEXT 3
/*
-** CAPI3REF: Result Values From A Query {F13800}
+** CAPI3REF: Result Values From A Query {H13800} <S10700>
** KEYWORDS: {column access functions}
**
** These routines form the "result set query" interface.
@@ -4046,55 +4107,55 @@
**
** INVARIANTS:
**
-** {F13803} The [sqlite3_column_blob(S,N)] interface converts the
+** {H13803} The [sqlite3_column_blob(S,N)] interface converts the
** Nth column in the current row of the result set for
** the [prepared statement] S into a BLOB and then returns a
** pointer to the converted value.
**
-** {F13806} The [sqlite3_column_bytes(S,N)] interface returns the
+** {H13806} The [sqlite3_column_bytes(S,N)] interface returns the
** number of bytes in the BLOB or string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_column_blob(S,N)] or
** [sqlite3_column_text(S,N)].
**
-** {F13809} The [sqlite3_column_bytes16(S,N)] interface returns the
+** {H13809} The [sqlite3_column_bytes16(S,N)] interface returns the
** number of bytes in the string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_column_text16(S,N)].
**
-** {F13812} The [sqlite3_column_double(S,N)] interface converts the
+** {H13812} The [sqlite3_column_double(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a floating point value and
** returns a copy of that value.
**
-** {F13815} The [sqlite3_column_int(S,N)] interface converts the
+** {H13815} The [sqlite3_column_int(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a 64-bit signed integer and
** returns the lower 32 bits of that integer.
**
-** {F13818} The [sqlite3_column_int64(S,N)] interface converts the
+** {H13818} The [sqlite3_column_int64(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a 64-bit signed integer and
** returns a copy of that integer.
**
-** {F13821} The [sqlite3_column_text(S,N)] interface converts the
+** {H13821} The [sqlite3_column_text(S,N)] interface converts the
** Nth column in the current row of the result set for
** the [prepared statement] S into a zero-terminated UTF-8
** string and returns a pointer to that string.
**
-** {F13824} The [sqlite3_column_text16(S,N)] interface converts the
+** {H13824} The [sqlite3_column_text16(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a zero-terminated 2-byte
** aligned UTF-16 native byte order string and returns
** a pointer to that string.
**
-** {F13827} The [sqlite3_column_type(S,N)] interface returns
+** {H13827} The [sqlite3_column_type(S,N)] interface returns
** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
** the Nth column in the current row of the result set for
** the [prepared statement] S.
**
-** {F13830} The [sqlite3_column_value(S,N)] interface returns a
+** {H13830} The [sqlite3_column_value(S,N)] interface returns a
** pointer to an [unprotected sqlite3_value] object for the
** Nth column in the current row of the result set for
** the [prepared statement] S.
@@ -4111,7 +4172,7 @@
SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
-** CAPI3REF: Destroy A Prepared Statement Object {F13300}
+** CAPI3REF: Destroy A Prepared Statement Object {H13300} <S70300><S30100>
**
** The sqlite3_finalize() function is called to delete a [prepared statement].
** If the statement was executed successfully or not executed at all, then
@@ -4128,18 +4189,18 @@
**
** INVARIANTS:
**
-** {F11302} The [sqlite3_finalize(S)] interface destroys the
+** {H11302} The [sqlite3_finalize(S)] interface destroys the
** [prepared statement] S and releases all
** memory and file resources held by that object.
**
-** {F11304} If the most recent call to [sqlite3_step(S)] for the
+** {H11304} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned an error,
** then [sqlite3_finalize(S)] returns that same error.
*/
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Reset A Prepared Statement Object {F13330}
+** CAPI3REF: Reset A Prepared Statement Object {H13330} <S70300>
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
@@ -4147,25 +4208,25 @@
** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
** Use [sqlite3_clear_bindings()] to reset the bindings.
**
-** {F11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
+** {H11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
** back to the beginning of its program.
**
-** {F11334} If the most recent call to [sqlite3_step(S)] for the
+** {H11334} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
** or if [sqlite3_step(S)] has never before been called on S,
** then [sqlite3_reset(S)] returns [SQLITE_OK].
**
-** {F11336} If the most recent call to [sqlite3_step(S)] for the
+** {H11336} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
**
-** {F11338} The [sqlite3_reset(S)] interface does not change the values
+** {H11338} The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Create Or Redefine SQL Functions {F16100}
+** CAPI3REF: Create Or Redefine SQL Functions {H16100} <S20200>
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
@@ -4223,64 +4284,64 @@
**
** INVARIANTS:
**
-** {F16103} The [sqlite3_create_function16()] interface behaves exactly
+** {H16103} The [sqlite3_create_function16()] interface behaves exactly
** like [sqlite3_create_function()] in every way except that it
** interprets the zFunctionName argument as zero-terminated UTF-16
** native byte order instead of as zero-terminated UTF-8.
**
-** {F16106} A successful invocation of
+** {H16106} A successful invocation of
** the [sqlite3_create_function(D,X,N,E,...)] interface registers
** or replaces callback functions in the [database connection] D
** used to implement the SQL function named X with N parameters
** and having a preferred text encoding of E.
**
-** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
+** {H16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** replaces the P, F, S, and L values from any prior calls with
** the same D, X, N, and E values.
**
-** {F16112} The [sqlite3_create_function(D,X,...)] interface fails with
+** {H16112} The [sqlite3_create_function(D,X,...)] interface fails with
** a return code of [SQLITE_ERROR] if the SQL function name X is
** longer than 255 bytes exclusive of the zero terminator.
**
-** {F16118} Either F must be NULL and S and L are non-NULL or else F
+** {H16118} Either F must be NULL and S and L are non-NULL or else F
** is non-NULL and S and L are NULL, otherwise
** [sqlite3_create_function(D,X,N,E,P,F,S,L)] returns [SQLITE_ERROR].
**
-** {F16121} The [sqlite3_create_function(D,...)] interface fails with an
+** {H16121} The [sqlite3_create_function(D,...)] interface fails with an
** error code of [SQLITE_BUSY] if there exist [prepared statements]
** associated with the [database connection] D.
**
-** {F16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an
+** {H16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an
** error code of [SQLITE_ERROR] if parameter N (specifying the number
** of arguments to the SQL function being registered) is less
** than -1 or greater than 127.
**
-** {F16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)]
+** {H16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)]
** interface causes callbacks to be invoked for the SQL function
** named X when the number of arguments to the SQL function is
** exactly N.
**
-** {F16130} When N is -1, the [sqlite3_create_function(D,X,N,...)]
+** {H16130} When N is -1, the [sqlite3_create_function(D,X,N,...)]
** interface causes callbacks to be invoked for the SQL function
** named X with any number of arguments.
**
-** {F16133} When calls to [sqlite3_create_function(D,X,N,...)]
+** {H16133} When calls to [sqlite3_create_function(D,X,N,...)]
** specify multiple implementations of the same function X
** and when one implementation has N>=0 and the other has N=(-1)
** the implementation with a non-zero N is preferred.
**
-** {F16136} When calls to [sqlite3_create_function(D,X,N,E,...)]
+** {H16136} When calls to [sqlite3_create_function(D,X,N,E,...)]
** specify multiple implementations of the same function X with
** the same number of arguments N but with different
** encodings E, then the implementation where E matches the
** database encoding is preferred.
**
-** {F16139} For an aggregate SQL function created using
+** {H16139} For an aggregate SQL function created using
** [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finalizer
** function L will always be invoked exactly once if the
** step function S is called one or more times.
**
-** {F16142} When SQLite invokes either the xFunc or xStep function of
+** {H16142} When SQLite invokes either the xFunc or xStep function of
** an application-defined SQL function or aggregate created
** by [sqlite3_create_function()] or [sqlite3_create_function16()],
** then the array of [sqlite3_value] objects passed as the
@@ -4308,7 +4369,7 @@
);
/*
-** CAPI3REF: Text Encodings {F10267}
+** CAPI3REF: Text Encodings {H10267} <S50200> <H16100>
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
@@ -4321,11 +4382,12 @@
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
-** CAPI3REF: Obsolete Functions
+** CAPI3REF: Deprecated Functions
+** DEPRECATED
**
-** These functions are all now obsolete. In order to maintain
-** backwards compatibility with older code, we continue to support
-** these functions. However, new development projects should avoid
+** These functions are [deprecated]. In order to maintain
+** backwards compatibility with older code, these functions continue
+** to be supported. However, new applications should avoid
** the use of these functions. To help encourage people to avoid
** using these functions, we are not going to tell you want they do.
*/
@@ -4337,7 +4399,7 @@
SQLITE_API int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
/*
-** CAPI3REF: Obtaining SQL Function Parameter Values {F15100}
+** CAPI3REF: Obtaining SQL Function Parameter Values {H15100} <S20200>
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
@@ -4383,59 +4445,59 @@
**
** INVARIANTS:
**
-** {F15103} The [sqlite3_value_blob(V)] interface converts the
+** {H15103} The [sqlite3_value_blob(V)] interface converts the
** [protected sqlite3_value] object V into a BLOB and then
** returns a pointer to the converted value.
**
-** {F15106} The [sqlite3_value_bytes(V)] interface returns the
+** {H15106} The [sqlite3_value_bytes(V)] interface returns the
** number of bytes in the BLOB or string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_value_blob(V)] or
** [sqlite3_value_text(V)].
**
-** {F15109} The [sqlite3_value_bytes16(V)] interface returns the
+** {H15109} The [sqlite3_value_bytes16(V)] interface returns the
** number of bytes in the string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_value_text16(V)],
** [sqlite3_value_text16be(V)], or [sqlite3_value_text16le(V)].
**
-** {F15112} The [sqlite3_value_double(V)] interface converts the
+** {H15112} The [sqlite3_value_double(V)] interface converts the
** [protected sqlite3_value] object V into a floating point value and
** returns a copy of that value.
**
-** {F15115} The [sqlite3_value_int(V)] interface converts the
+** {H15115} The [sqlite3_value_int(V)] interface converts the
** [protected sqlite3_value] object V into a 64-bit signed integer and
** returns the lower 32 bits of that integer.
**
-** {F15118} The [sqlite3_value_int64(V)] interface converts the
+** {H15118} The [sqlite3_value_int64(V)] interface converts the
** [protected sqlite3_value] object V into a 64-bit signed integer and
** returns a copy of that integer.
**
-** {F15121} The [sqlite3_value_text(V)] interface converts the
+** {H15121} The [sqlite3_value_text(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated UTF-8
** string and returns a pointer to that string.
**
-** {F15124} The [sqlite3_value_text16(V)] interface converts the
+** {H15124} The [sqlite3_value_text16(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 native byte order
** string and returns a pointer to that string.
**
-** {F15127} The [sqlite3_value_text16be(V)] interface converts the
+** {H15127} The [sqlite3_value_text16be(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 big-endian
** string and returns a pointer to that string.
**
-** {F15130} The [sqlite3_value_text16le(V)] interface converts the
+** {H15130} The [sqlite3_value_text16le(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 little-endian
** string and returns a pointer to that string.
**
-** {F15133} The [sqlite3_value_type(V)] interface returns
+** {H15133} The [sqlite3_value_type(V)] interface returns
** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
** the [sqlite3_value] object V.
**
-** {F15136} The [sqlite3_value_numeric_type(V)] interface converts
+** {H15136} The [sqlite3_value_numeric_type(V)] interface converts
** the [protected sqlite3_value] object V into either an integer or
** a floating point value if it can do so without loss of
** information, and returns one of [SQLITE_NULL],
@@ -4457,7 +4519,7 @@
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
/*
-** CAPI3REF: Obtain Aggregate Function Context {F16210}
+** CAPI3REF: Obtain Aggregate Function Context {H16210} <S20200>
**
** The implementation of aggregate SQL functions use this routine to allocate
** a structure for storing their state.
@@ -4481,20 +4543,20 @@
**
** INVARIANTS:
**
-** {F16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
+** {H16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
** a particular instance of an aggregate function (for a particular
** context C) causes SQLite to allocate N bytes of memory,
** zero that memory, and return a pointer to the allocated memory.
**
-** {F16213} If a memory allocation error occurs during
+** {H16213} If a memory allocation error occurs during
** [sqlite3_aggregate_context(C,N)] then the function returns 0.
**
-** {F16215} Second and subsequent invocations of
+** {H16215} Second and subsequent invocations of
** [sqlite3_aggregate_context(C,N)] for the same context pointer C
** ignore the N parameter and return a pointer to the same
** block of memory returned by the first invocation.
**
-** {F16217} The memory allocated by [sqlite3_aggregate_context(C,N)] is
+** {H16217} The memory allocated by [sqlite3_aggregate_context(C,N)] is
** automatically freed on the next call to [sqlite3_reset()]
** or [sqlite3_finalize()] for the [prepared statement] containing
** the aggregate function associated with context C.
@@ -4502,7 +4564,7 @@
SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
-** CAPI3REF: User Data For Functions {F16240}
+** CAPI3REF: User Data For Functions {H16240} <S20200>
**
** The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4515,7 +4577,7 @@
**
** INVARIANTS:
**
-** {F16243} The [sqlite3_user_data(C)] interface returns a copy of the
+** {H16243} The [sqlite3_user_data(C)] interface returns a copy of the
** P pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
** registered the SQL function associated with [sqlite3_context] C.
@@ -4523,7 +4585,7 @@
SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
-** CAPI3REF: Database Connection For Functions {F16250}
+** CAPI3REF: Database Connection For Functions {H16250} <S60600><S20200>
**
** The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
@@ -4533,7 +4595,7 @@
**
** INVARIANTS:
**
-** {F16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
+** {H16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
** D pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
** registered the SQL function associated with [sqlite3_context] C.
@@ -4541,7 +4603,7 @@
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
-** CAPI3REF: Function Auxiliary Data {F16270}
+** CAPI3REF: Function Auxiliary Data {H16270} <S20200>
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
@@ -4584,27 +4646,27 @@
**
** INVARIANTS:
**
-** {F16272} The [sqlite3_get_auxdata(C,N)] interface returns a pointer
+** {H16272} The [sqlite3_get_auxdata(C,N)] interface returns a pointer
** to metadata associated with the Nth parameter of the SQL function
** whose context is C, or NULL if there is no metadata associated
** with that parameter.
**
-** {F16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
+** {H16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
** pointer P to the Nth parameter of the SQL function with context C.
**
-** {F16276} SQLite will invoke the destructor D with a single argument
+** {H16276} SQLite will invoke the destructor D with a single argument
** which is the metadata pointer P following a call to
** [sqlite3_set_auxdata(C,N,P,D)] when SQLite ceases to hold
** the metadata.
**
-** {F16277} SQLite ceases to hold metadata for an SQL function parameter
+** {H16277} SQLite ceases to hold metadata for an SQL function parameter
** when the value of that parameter changes.
**
-** {F16278} When [sqlite3_set_auxdata(C,N,P,D)] is invoked, the destructor
+** {H16278} When [sqlite3_set_auxdata(C,N,P,D)] is invoked, the destructor
** is called for any prior metadata associated with the same function
** context C and parameter N.
**
-** {F16279} SQLite will call destructors for any metadata it is holding
+** {H16279} SQLite will call destructors for any metadata it is holding
** in a particular [prepared statement] S when either
** [sqlite3_reset(S)] or [sqlite3_finalize(S)] is called.
*/
@@ -4613,7 +4675,7 @@
/*
-** CAPI3REF: Constants Defining Special Destructor Behavior {F10280}
+** CAPI3REF: Constants Defining Special Destructor Behavior {H10280} <S30100>
**
** These are special values for the destructor that is passed in as the
** final argument to routines like [sqlite3_result_blob()]. If the destructor
@@ -4631,7 +4693,7 @@
#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
/*
-** CAPI3REF: Setting The Result Of An SQL Function {F16400}
+** CAPI3REF: Setting The Result Of An SQL Function {H16400} <S20200>
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
@@ -4736,93 +4798,93 @@
**
** INVARIANTS:
**
-** {F16403} The default return value from any SQL function is NULL.
+** {H16403} The default return value from any SQL function is NULL.
**
-** {F16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
+** {H16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
** return value of function C to be a BLOB that is N bytes
** in length and with content pointed to by V.
**
-** {F16409} The [sqlite3_result_double(C,V)] interface changes the
+** {H16409} The [sqlite3_result_double(C,V)] interface changes the
** return value of function C to be the floating point value V.
**
-** {F16412} The [sqlite3_result_error(C,V,N)] interface changes the return
+** {H16412} The [sqlite3_result_error(C,V,N)] interface changes the return
** value of function C to be an exception with error code
** [SQLITE_ERROR] and a UTF-8 error message copied from V up to the
** first zero byte or until N bytes are read if N is positive.
**
-** {F16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
+** {H16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
** value of function C to be an exception with error code
** [SQLITE_ERROR] and a UTF-16 native byte order error message
** copied from V up to the first zero terminator or until N bytes
** are read if N is positive.
**
-** {F16418} The [sqlite3_result_error_toobig(C)] interface changes the return
+** {H16418} The [sqlite3_result_error_toobig(C)] interface changes the return
** value of the function C to be an exception with error code
** [SQLITE_TOOBIG] and an appropriate error message.
**
-** {F16421} The [sqlite3_result_error_nomem(C)] interface changes the return
+** {H16421} The [sqlite3_result_error_nomem(C)] interface changes the return
** value of the function C to be an exception with error code
** [SQLITE_NOMEM] and an appropriate error message.
**
-** {F16424} The [sqlite3_result_error_code(C,E)] interface changes the return
+** {H16424} The [sqlite3_result_error_code(C,E)] interface changes the return
** value of the function C to be an exception with error code E.
** The error message text is unchanged.
**
-** {F16427} The [sqlite3_result_int(C,V)] interface changes the
+** {H16427} The [sqlite3_result_int(C,V)] interface changes the
** return value of function C to be the 32-bit integer value V.
**
-** {F16430} The [sqlite3_result_int64(C,V)] interface changes the
+** {H16430} The [sqlite3_result_int64(C,V)] interface changes the
** return value of function C to be the 64-bit integer value V.
**
-** {F16433} The [sqlite3_result_null(C)] interface changes the
+** {H16433} The [sqlite3_result_null(C)] interface changes the
** return value of function C to be NULL.
**
-** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
+** {H16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
** return value of function C to be the UTF-8 string
** V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
+** {H16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 native byte order
** string V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
+** {H16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 big-endian
** string V up to the first zero if N is negative
** or the first N bytes or V if N is non-negative.
**
-** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
+** {H16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 little-endian
** string V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16448} The [sqlite3_result_value(C,V)] interface changes the
+** {H16448} The [sqlite3_result_value(C,V)] interface changes the
** return value of function C to be the [unprotected sqlite3_value]
** object V.
**
-** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
+** {H16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
** return value of function C to be an N-byte BLOB of all zeros.
**
-** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
+** {H16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
** interfaces make a copy of their error message strings before
** returning.
**
-** {F16457} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16457} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is the constant [SQLITE_STATIC]
** then no destructor is ever called on the pointer V and SQLite
** assumes that V is immutable.
**
-** {F16460} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16460} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is the constant
** [SQLITE_TRANSIENT] then the interfaces makes a copy of the
** content of V and retains the copy.
**
-** {F16463} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16463} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is some value other than
@@ -4848,7 +4910,7 @@
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
/*
-** CAPI3REF: Define New Collating Sequences {F16600}
+** CAPI3REF: Define New Collating Sequences {H16600} <S20300>
**
** These functions are used to add new collation sequences to the
** [database connection] specified as the first argument.
@@ -4891,49 +4953,49 @@
**
** INVARIANTS:
**
-** {F16603} A successful call to the
+** {H16603} A successful call to the
** [sqlite3_create_collation_v2(B,X,E,P,F,D)] interface
** registers function F as the comparison function used to
** implement collation X on the [database connection] B for
** databases having encoding E.
**
-** {F16604} SQLite understands the X parameter to
+** {H16604} SQLite understands the X parameter to
** [sqlite3_create_collation_v2(B,X,E,P,F,D)] as a zero-terminated
** UTF-8 string in which case is ignored for ASCII characters and
** is significant for non-ASCII characters.
**
-** {F16606} Successive calls to [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16606} Successive calls to [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** with the same values for B, X, and E, override prior values
** of P, F, and D.
**
-** {F16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** is not NULL then it is called with argument P when the
** collating function is dropped by SQLite.
**
-** {F16612} A collating function is dropped when it is overloaded.
+** {H16612} A collating function is dropped when it is overloaded.
**
-** {F16615} A collating function is dropped when the database connection
+** {H16615} A collating function is dropped when the database connection
** is closed using [sqlite3_close()].
**
-** {F16618} The pointer P in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16618} The pointer P in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** is passed through as the first parameter to the comparison
** function F for all subsequent invocations of F.
**
-** {F16621} A call to [sqlite3_create_collation(B,X,E,P,F)] is exactly
+** {H16621} A call to [sqlite3_create_collation(B,X,E,P,F)] is exactly
** the same as a call to [sqlite3_create_collation_v2()] with
** the same parameters and a NULL destructor.
**
-** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
+** {H16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
** SQLite uses the comparison function F for all text comparison
** operations on the [database connection] B on text values that
** use the collating sequence named X.
**
-** {F16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
+** {H16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
** as [sqlite3_create_collation(B,X,E,P,F)] except that the
** collation name X is understood as UTF-16 in native byte order
** instead of UTF-8.
**
-** {F16630} When multiple comparison functions are available for the same
+** {H16630} When multiple comparison functions are available for the same
** collating sequence, SQLite chooses the one whose text encoding
** requires the least amount of conversion from the default
** text encoding of the database.
@@ -4962,7 +5024,7 @@
);
/*
-** CAPI3REF: Collation Needed Callbacks {F16700}
+** CAPI3REF: Collation Needed Callbacks {H16700} <S20300>
**
** To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
@@ -4971,7 +5033,7 @@
**
** If the function is registered using the sqlite3_collation_needed() API,
** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used,
+** encoded in UTF-8. {H16703} If sqlite3_collation_needed16() is used,
** the names are passed as UTF-16 in machine native byte order.
** A call to either function replaces any existing callback.
**
@@ -4989,18 +5051,18 @@
**
** INVARIANTS:
**
-** {F16702} A successful call to [sqlite3_collation_needed(D,P,F)]
+** {H16702} A successful call to [sqlite3_collation_needed(D,P,F)]
** or [sqlite3_collation_needed16(D,P,F)] causes
** the [database connection] D to invoke callback F with first
** parameter P whenever it needs a comparison function for a
** collating sequence that it does not know about.
**
-** {F16704} Each successful call to [sqlite3_collation_needed()] or
+** {H16704} Each successful call to [sqlite3_collation_needed()] or
** [sqlite3_collation_needed16()] overrides the callback registered
** on the same [database connection] by prior calls to either
** interface.
**
-** {F16706} The name of the requested collating function passed in the
+** {H16706} The name of the requested collating function passed in the
** 4th parameter to the callback is in UTF-8 if the callback
** was registered using [sqlite3_collation_needed()] and
** is in UTF-16 native byte order if the callback was
@@ -5043,7 +5105,7 @@
);
/*
-** CAPI3REF: Suspend Execution For A Short Time {F10530}
+** CAPI3REF: Suspend Execution For A Short Time {H10530} <S40410>
**
** The sqlite3_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.
@@ -5058,19 +5120,19 @@
**
** INVARIANTS:
**
-** {F10533} The [sqlite3_sleep(M)] interface invokes the xSleep
+** {H10533} The [sqlite3_sleep(M)] interface invokes the xSleep
** method of the default [sqlite3_vfs|VFS] in order to
** suspend execution of the current thread for at least
** M milliseconds.
**
-** {F10536} The [sqlite3_sleep(M)] interface returns the number of
+** {H10536} The [sqlite3_sleep(M)] interface returns the number of
** milliseconds of sleep actually requested of the operating
** system, which might be larger than the parameter M.
*/
SQLITE_API int sqlite3_sleep(int);
/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files {F10310}
+** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} <S20000>
**
** If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all temporary files
@@ -5086,7 +5148,7 @@
SQLITE_API char *sqlite3_temp_directory;
/*
-** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode {F12930}
+** CAPI3REF: Test For Auto-Commit Mode {H12930} <S60200>
** KEYWORDS: {autocommit mode}
**
** The sqlite3_get_autocommit() interface returns non-zero or
@@ -5104,18 +5166,18 @@
**
** INVARIANTS:
**
-** {F12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or
+** {H12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or
** zero if the [database connection] D is or is not in autocommit
** mode, respectively.
**
-** {F12932} Autocommit mode is on by default.
+** {H12932} Autocommit mode is on by default.
**
-** {F12933} Autocommit mode is disabled by a successful [BEGIN] statement.
+** {H12933} Autocommit mode is disabled by a successful [BEGIN] statement.
**
-** {F12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
+** {H12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
** statement.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12936} If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
@@ -5124,7 +5186,7 @@
SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120}
+** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} <S60600>
**
** The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. The database handle returned by
@@ -5134,14 +5196,14 @@
**
** INVARIANTS:
**
-** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
+** {H13123} The [sqlite3_db_handle(S)] interface returns a pointer
** to the [database connection] associated with the
** [prepared statement] S.
*/
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
-** CAPI3REF: Find the next prepared statement {F13140}
+** CAPI3REF: Find the next prepared statement {H13140} <S60600>
**
** This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. If pStmt is NULL
@@ -5151,28 +5213,34 @@
**
** INVARIANTS:
**
-** {F13143} If D is a [database connection] that holds one or more
+** {H13143} If D is a [database connection] that holds one or more
** unfinalized [prepared statements] and S is a NULL pointer,
** then [sqlite3_next_stmt(D, S)] routine shall return a pointer
** to one of the prepared statements associated with D.
**
-** {F13146} If D is a [database connection] that holds no unfinalized
+** {H13146} If D is a [database connection] that holds no unfinalized
** [prepared statements] and S is a NULL pointer, then
** [sqlite3_next_stmt(D, S)] routine shall return a NULL pointer.
**
-** {F13149} If S is a [prepared statement] in the [database connection] D
+** {H13149} If S is a [prepared statement] in the [database connection] D
** and S is not the last prepared statement in D, then
** [sqlite3_next_stmt(D, S)] routine shall return a pointer
** to the next prepared statement in D after S.
**
-** {F13152} If S is the last [prepared statement] in the
+** {H13152} If S is the last [prepared statement] in the
** [database connection] D then the [sqlite3_next_stmt(D, S)]
** routine shall return a NULL pointer.
+**
+** ASSUMPTIONS:
+**
+** {A13154} The [database connection] pointer D in a call to
+** [sqlite3_next_stmt(D,S)] must refer to an open database
+** connection and in particular must not be a NULL pointer.
*/
SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
+** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
**
** The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is committed.
@@ -5202,37 +5270,37 @@
**
** INVARIANTS:
**
-** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
+** {H12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
** callback function F to be invoked with argument P whenever
** a transaction commits on the [database connection] D.
**
-** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
+** {H12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
** from the previous call with the same [database connection] D,
** or NULL on the first call for a particular database connection D.
**
-** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback
+** {H12953} Each call to [sqlite3_commit_hook()] overwrites the callback
** registered by prior calls.
**
-** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
+** {H12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
** then the commit hook callback is canceled and no callback
** is invoked when a transaction commits.
**
-** {F12955} If the commit callback returns non-zero then the commit is
+** {H12955} If the commit callback returns non-zero then the commit is
** converted into a rollback.
**
-** {F12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
+** {H12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
** callback function F to be invoked with argument P whenever
** a transaction rolls back on the [database connection] D.
**
-** {F12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
+** {H12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
** argument from the previous call with the same
** [database connection] D, or NULL on the first call
** for a particular database connection D.
**
-** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
+** {H12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
** registered by prior calls.
**
-** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
+** {H12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
** then the rollback hook callback is canceled and no callback
** is invoked when a transaction rolls back.
*/
@@ -5240,7 +5308,7 @@
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
-** CAPI3REF: Data Change Notification Callbacks {F12970}
+** CAPI3REF: Data Change Notification Callbacks {H12970} <S60400>
**
** The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
@@ -5268,33 +5336,33 @@
**
** INVARIANTS:
**
-** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
+** {H12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
** function F to be invoked with first parameter P whenever
** a table row is modified, inserted, or deleted on
** the [database connection] D.
**
-** {F12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
+** {H12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
** of P for the previous call on the same [database connection] D,
** or NULL for the first call.
**
-** {F12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)]
+** {H12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)]
** is NULL then the no update callbacks are made.
**
-** {F12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls
+** {H12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls
** to the same interface on the same [database connection] D.
**
-** {F12979} The update hook callback is not invoked when internal system
+** {H12979} The update hook callback is not invoked when internal system
** tables such as sqlite_master and sqlite_sequence are modified.
**
-** {F12981} The second parameter to the update callback
+** {H12981} The second parameter to the update callback
** is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
** depending on the operation that caused the callback to be invoked.
**
-** {F12983} The third and fourth arguments to the callback contain pointers
+** {H12983} The third and fourth arguments to the callback contain pointers
** to zero-terminated UTF-8 strings which are the names of the
** database and table that is being updated.
-** {F12985} The final callback parameter is the rowid of the row after
+** {H12985} The final callback parameter is the rowid of the row after
** the change occurs.
*/
SQLITE_API void *sqlite3_update_hook(
@@ -5304,7 +5372,7 @@
);
/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330}
+** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
** KEYWORDS: {shared cache} {shared cache mode}
**
** This routine enables or disables the sharing of the database cache
@@ -5334,22 +5402,22 @@
**
** INVARIANTS:
**
-** {F10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
+** {H10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
** will enable or disable shared cache mode for any subsequently
** created [database connection] in the same process.
**
-** {F10336} When shared cache is enabled, the [sqlite3_create_module()]
+** {H10336} When shared cache is enabled, the [sqlite3_create_module()]
** interface will always return an error.
**
-** {F10337} The [sqlite3_enable_shared_cache(B)] interface returns
+** {H10337} The [sqlite3_enable_shared_cache(B)] interface returns
** [SQLITE_OK] if shared cache was enabled or disabled successfully.
**
-** {F10339} Shared cache is disabled by default.
+** {H10339} Shared cache is disabled by default.
*/
SQLITE_API int sqlite3_enable_shared_cache(int);
/*
-** CAPI3REF: Attempt To Free Heap Memory {F17340}
+** CAPI3REF: Attempt To Free Heap Memory {H17340} <S30220>
**
** The sqlite3_release_memory() interface attempts to free N bytes
** of heap memory by deallocating non-essential memory allocations
@@ -5360,18 +5428,18 @@
**
** INVARIANTS:
**
-** {F17341} The [sqlite3_release_memory(N)] interface attempts to
+** {H17341} The [sqlite3_release_memory(N)] interface attempts to
** free N bytes of heap memory by deallocating non-essential
** memory allocations held by the database library.
**
-** {F16342} The [sqlite3_release_memory(N)] returns the number
+** {H16342} The [sqlite3_release_memory(N)] returns the number
** of bytes actually freed, which might be more or less
** than the amount requested.
*/
SQLITE_API int sqlite3_release_memory(int);
/*
-** CAPI3REF: Impose A Limit On Heap Size {F17350}
+** CAPI3REF: Impose A Limit On Heap Size {H17350} <S30220>
**
** The sqlite3_soft_heap_limit() interface places a "soft" limit
** on the amount of heap memory that may be allocated by SQLite.
@@ -5402,36 +5470,36 @@
**
** INVARIANTS:
**
-** {F16351} The [sqlite3_soft_heap_limit(N)] interface places a soft limit
+** {H16351} The [sqlite3_soft_heap_limit(N)] interface places a soft limit
** of N bytes on the amount of heap memory that may be allocated
** using [sqlite3_malloc()] or [sqlite3_realloc()] at any point
** in time.
**
-** {F16352} If a call to [sqlite3_malloc()] or [sqlite3_realloc()] would
+** {H16352} If a call to [sqlite3_malloc()] or [sqlite3_realloc()] would
** cause the total amount of allocated memory to exceed the
** soft heap limit, then [sqlite3_release_memory()] is invoked
** in an attempt to reduce the memory usage prior to proceeding
** with the memory allocation attempt.
**
-** {F16353} Calls to [sqlite3_malloc()] or [sqlite3_realloc()] that trigger
+** {H16353} Calls to [sqlite3_malloc()] or [sqlite3_realloc()] that trigger
** attempts to reduce memory usage through the soft heap limit
** mechanism continue even if the attempt to reduce memory
** usage is unsuccessful.
**
-** {F16354} A negative or zero value for N in a call to
+** {H16354} A negative or zero value for N in a call to
** [sqlite3_soft_heap_limit(N)] means that there is no soft
** heap limit and [sqlite3_release_memory()] will only be
** called when memory is completely exhausted.
**
-** {F16355} The default value for the soft heap limit is zero.
+** {H16355} The default value for the soft heap limit is zero.
**
-** {F16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the
+** {H16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the
** values set by all prior calls.
*/
SQLITE_API void sqlite3_soft_heap_limit(int);
/*
-** CAPI3REF: Extract Metadata About A Column Of A Table {F12850}
+** CAPI3REF: Extract Metadata About A Column Of A Table {H12850} <S60300>
**
** This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
@@ -5505,28 +5573,28 @@
);
/*
-** CAPI3REF: Load An Extension {F12600}
+** CAPI3REF: Load An Extension {H12600} <S20500>
**
** This interface loads an SQLite extension library from the named file.
**
-** {F12601} The sqlite3_load_extension() interface attempts to load an
+** {H12601} The sqlite3_load_extension() interface attempts to load an
** SQLite extension library contained in the file zFile.
**
-** {F12602} The entry point is zProc.
+** {H12602} The entry point is zProc.
**
-** {F12603} zProc may be 0, in which case the name of the entry point
+** {H12603} zProc may be 0, in which case the name of the entry point
** defaults to "sqlite3_extension_init".
**
-** {F12604} The sqlite3_load_extension() interface shall return
+** {H12604} The sqlite3_load_extension() interface shall return
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
**
-** {F12605} If an error occurs and pzErrMsg is not 0, then the
+** {H12605} If an error occurs and pzErrMsg is not 0, then the
** [sqlite3_load_extension()] interface shall attempt to
** fill *pzErrMsg with error message text stored in memory
** obtained from [sqlite3_malloc()]. {END} The calling function
** should free this memory by calling [sqlite3_free()].
**
-** {F12606} Extension loading must be enabled using
+** {H12606} Extension loading must be enabled using
** [sqlite3_enable_load_extension()] prior to calling this API,
** otherwise an error will be returned.
*/
@@ -5538,7 +5606,7 @@
);
/*
-** CAPI3REF: Enable Or Disable Extension Loading {F12620}
+** CAPI3REF: Enable Or Disable Extension Loading {H12620} <S20500>
**
** So as not to open security holes in older applications that are
** unprepared to deal with extension loading, and as a means of disabling
@@ -5547,16 +5615,16 @@
**
** Extension loading is off by default. See ticket #1863.
**
-** {F12621} Call the sqlite3_enable_load_extension() routine with onoff==1
+** {H12621} Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
**
-** {F12622} Extension loading is off by default.
+** {H12622} Extension loading is off by default.
*/
SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
-** CAPI3REF: Make Arrangements To Automatically Load An Extension {F12640}
+** CAPI3REF: Automatically Load An Extensions {H12640} <S20500>
**
** This API can be invoked at program startup in order to register
** one or more statically linked extensions that will be available
@@ -5567,32 +5635,32 @@
** on your program and it reports a leak because of this array, invoke
** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
**
-** {F12641} This function registers an extension entry point that is
+** {H12641} This function registers an extension entry point that is
** automatically invoked whenever a new [database connection]
** is opened using [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()].
**
-** {F12642} Duplicate extensions are detected so calling this routine
+** {H12642} Duplicate extensions are detected so calling this routine
** multiple times with the same extension is harmless.
**
-** {F12643} This routine stores a pointer to the extension in an array
+** {H12643} This routine stores a pointer to the extension in an array
** that is obtained from [sqlite3_malloc()].
**
-** {F12644} Automatic extensions apply across all threads.
+** {H12644} Automatic extensions apply across all threads.
*/
SQLITE_API int sqlite3_auto_extension(void *xEntryPoint);
/*
-** CAPI3REF: Reset Automatic Extension Loading {F12660}
+** CAPI3REF: Reset Automatic Extension Loading {H12660} <S20500>
**
** This function disables all previously registered automatic
** extensions. {END} It undoes the effect of all prior
** [sqlite3_auto_extension()] calls.
**
-** {F12661} This function disables all previously registered
+** {H12661} This function disables all previously registered
** automatic extensions.
**
-** {F12662} This function disables automatic extensions in all threads.
+** {H12662} This function disables automatic extensions in all threads.
*/
SQLITE_API void sqlite3_reset_auto_extension(void);
@@ -5616,8 +5684,9 @@
typedef struct sqlite3_module sqlite3_module;
/*
-** CAPI3REF: Virtual Table Object {F18000}
+** CAPI3REF: Virtual Table Object {H18000} <S20400>
** KEYWORDS: sqlite3_module
+** EXPERIMENTAL
**
** A module is a class of virtual tables. Each module is defined
** by an instance of the following structure. This structure consists
@@ -5653,13 +5722,13 @@
int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
void **ppArg);
-
int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
};
/*
-** CAPI3REF: Virtual Table Indexing Information {F18100}
+** CAPI3REF: Virtual Table Indexing Information {H18100} <S20400>
** KEYWORDS: sqlite3_index_info
+** EXPERIMENTAL
**
** The sqlite3_index_info structure and its substructures is used to
** pass information into and receive the reply from the xBestIndex
@@ -5722,7 +5791,6 @@
int iColumn; /* Column number */
unsigned char desc; /* True for DESC. False for ASC. */
} *aOrderBy; /* The ORDER BY clause */
-
/* Outputs */
struct sqlite3_index_constraint_usage {
int argvIndex; /* if >0, constraint is part of argv to xFilter */
@@ -5742,7 +5810,8 @@
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
-** CAPI3REF: Register A Virtual Table Implementation {F18200}
+** CAPI3REF: Register A Virtual Table Implementation {H18200} <S20400>
+** EXPERIMENTAL
**
** This routine is used to register a new module name with a
** [database connection]. Module names must be registered before
@@ -5760,7 +5829,8 @@
);
/*
-** CAPI3REF: Register A Virtual Table Implementation {F18210}
+** CAPI3REF: Register A Virtual Table Implementation {H18210} <S20400>
+** EXPERIMENTAL
**
** This routine is identical to the [sqlite3_create_module()] method above,
** except that it allows a destructor function to be specified. It is
@@ -5775,8 +5845,9 @@
);
/*
-** CAPI3REF: Virtual Table Instance Object {F18010}
+** CAPI3REF: Virtual Table Instance Object {H18010} <S20400>
** KEYWORDS: sqlite3_vtab
+** EXPERIMENTAL
**
** Every module implementation uses a subclass of the following structure
** to describe a particular instance of the module. Each subclass will
@@ -5805,8 +5876,9 @@
};
/*
-** CAPI3REF: Virtual Table Cursor Object {F18020}
+** CAPI3REF: Virtual Table Cursor Object {H18020} <S20400>
** KEYWORDS: sqlite3_vtab_cursor
+** EXPERIMENTAL
**
** Every module implementation uses a subclass of the following structure
** to describe cursors that point into the virtual table and are used
@@ -5826,7 +5898,8 @@
};
/*
-** CAPI3REF: Declare The Schema Of A Virtual Table {F18280}
+** CAPI3REF: Declare The Schema Of A Virtual Table {H18280} <S20400>
+** EXPERIMENTAL
**
** The xCreate and xConnect methods of a module use the following API
** to declare the format (the names and datatypes of the columns) of
@@ -5838,7 +5911,8 @@
SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
/*
-** CAPI3REF: Overload A Function For A Virtual Table {F18300}
+** CAPI3REF: Overload A Function For A Virtual Table {H18300} <S20400>
+** EXPERIMENTAL
**
** Virtual tables can provide alternative implementations of functions
** using the xFindFunction method. But global versions of those functions
@@ -5870,7 +5944,7 @@
*/
/*
-** CAPI3REF: A Handle To An Open BLOB {F17800}
+** CAPI3REF: A Handle To An Open BLOB {H17800} <S30230>
** KEYWORDS: {BLOB handle} {BLOB handles}
**
** An instance of this object represents an open BLOB on which
@@ -5884,7 +5958,7 @@
typedef struct sqlite3_blob sqlite3_blob;
/*
-** CAPI3REF: Open A BLOB For Incremental I/O {F17810}
+** CAPI3REF: Open A BLOB For Incremental I/O {H17810} <S30230>
**
** This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
@@ -5922,28 +5996,28 @@
**
** INVARIANTS:
**
-** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
+** {H17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
** interface shall open an [sqlite3_blob] object P on the BLOB
** in column C of the table T in the database B on
** the [database connection] D.
**
-** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
+** {H17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
** a new transaction on the [database connection] D if that
** connection is not already in a transaction.
**
-** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
+** {H17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
** the BLOB for read and write access if and only if the F
** parameter is non-zero.
**
-** {F17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
+** {H17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
** success and an appropriate [error code] on failure.
**
-** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
+** {H17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error.
**
-** {F17824} If any column in the row that a [sqlite3_blob] has open is
+** {H17824} If any column in the row that a [sqlite3_blob] has open is
** changed by a separate [UPDATE] or [DELETE] statement or by
** an [ON CONFLICT] side effect, then the [sqlite3_blob] shall
** be marked as invalid.
@@ -5959,7 +6033,7 @@
);
/*
-** CAPI3REF: Close A BLOB Handle {F17830}
+** CAPI3REF: Close A BLOB Handle {H17830} <S30230>
**
** Closes an open [BLOB handle].
**
@@ -5971,7 +6045,7 @@
**
** Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. {F17833} Any errors that occur during
+** at the time when the BLOB is closed. {H17833} Any errors that occur during
** closing are reported as a non-zero return value.
**
** The BLOB is closed unconditionally. Even if this routine returns
@@ -5979,37 +6053,37 @@
**
** INVARIANTS:
**
-** {F17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
+** {H17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
** object P previously opened using [sqlite3_blob_open()].
**
-** {F17836} Closing an [sqlite3_blob] object using
+** {H17836} Closing an [sqlite3_blob] object using
** [sqlite3_blob_close()] shall cause the current transaction to
** commit if there are no other open [sqlite3_blob] objects
** or [prepared statements] on the same [database connection] and
** the database connection is in [autocommit mode].
**
-** {F17839} The [sqlite3_blob_close(P)] interfaces shall close the
+** {H17839} The [sqlite3_blob_close(P)] interfaces shall close the
** [sqlite3_blob] object P unconditionally, even if
** [sqlite3_blob_close(P)] returns something other than [SQLITE_OK].
*/
SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
-** CAPI3REF: Return The Size Of An Open BLOB {F17840}
+** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
**
** Returns the size in bytes of the BLOB accessible via the open
** []BLOB handle] in its only argument.
**
** INVARIANTS:
**
-** {F17843} The [sqlite3_blob_bytes(P)] interface returns the size
+** {H17843} The [sqlite3_blob_bytes(P)] interface returns the size
** in bytes of the BLOB that the [sqlite3_blob] object P
** refers to.
*/
SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
-** CAPI3REF: Read Data From A BLOB Incrementally {F17850}
+** CAPI3REF: Read Data From A BLOB Incrementally {H17850} <S30230>
**
** This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -6027,31 +6101,31 @@
**
** INVARIANTS:
**
-** {F17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)]
+** {H17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)]
** shall reads N bytes of data out of the BLOB referenced by
** [BLOB handle] P beginning at offset X and store those bytes
** into buffer Z.
**
-** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
+** {H17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
** is less than N+X bytes, then the function shall leave the
** Z buffer unchanged and return [SQLITE_ERROR].
**
-** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
+** {H17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
** then the function shall leave the Z buffer unchanged
** and return [SQLITE_ERROR].
**
-** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
+** {H17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
** if N bytes are successfully read into buffer Z.
**
-** {F17863} If the [BLOB handle] P is expired and X and N are within bounds
+** {H17863} If the [BLOB handle] P is expired and X and N are within bounds
** then [sqlite3_blob_read(P,Z,N,X)] shall leave the Z buffer
** unchanged and return [SQLITE_ABORT].
**
-** {F17865} If the requested read could not be completed,
+** {H17865} If the requested read could not be completed,
** the [sqlite3_blob_read(P,Z,N,X)] interface shall return an
** appropriate [error code] or [extended error code].
**
-** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
+** {H17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error, where D is the
@@ -6060,7 +6134,7 @@
SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
-** CAPI3REF: Write Data Into A BLOB Incrementally {F17870}
+** CAPI3REF: Write Data Into A BLOB Incrementally {H17870} <S30230>
**
** This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
@@ -6088,39 +6162,39 @@
**
** INVARIANTS:
**
-** {F17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
+** {H17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
** shall write N bytes of data from buffer Z into the BLOB
** referenced by [BLOB handle] P beginning at offset X into
** the BLOB.
**
-** {F17874} In the absence of other overridding changes, the changes
+** {H17874} In the absence of other overridding changes, the changes
** written to a BLOB by [sqlite3_blob_write()] shall
** remain in effect after the associated [BLOB handle] expires.
**
-** {F17875} If the [BLOB handle] P was opened for reading only then
+** {H17875} If the [BLOB handle] P was opened for reading only then
** an invocation of [sqlite3_blob_write(P,Z,N,X)] shall leave
** the referenced BLOB unchanged and return [SQLITE_READONLY].
**
-** {F17876} If the size of the BLOB referenced by [BLOB handle] P is
+** {H17876} If the size of the BLOB referenced by [BLOB handle] P is
** less than N+X bytes then [sqlite3_blob_write(P,Z,N,X)] shall
** leave the BLOB unchanged and return [SQLITE_ERROR].
**
-** {F17877} If the [BLOB handle] P is expired and X and N are within bounds
+** {H17877} If the [BLOB handle] P is expired and X and N are within bounds
** then [sqlite3_blob_read(P,Z,N,X)] shall leave the BLOB
** unchanged and return [SQLITE_ABORT].
**
-** {F17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
+** {H17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
** shall leave the BLOB referenced by [BLOB handle] P unchanged
** and return [SQLITE_ERROR].
**
-** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
+** {H17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
** [SQLITE_OK] if N bytes where successfully written into the BLOB.
**
-** {F17885} If the requested write could not be completed,
+** {H17885} If the requested write could not be completed,
** the [sqlite3_blob_write(P,Z,N,X)] interface shall return an
** appropriate [error code] or [extended error code].
**
-** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
+** {H17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error.
@@ -6128,7 +6202,7 @@
SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
-** CAPI3REF: Virtual File System Objects {F11200}
+** CAPI3REF: Virtual File System Objects {H11200} <S20100>
**
** A virtual filesystem (VFS) is an [sqlite3_vfs] object
** that SQLite uses to interact
@@ -6158,27 +6232,27 @@
**
** INVARIANTS:
**
-** {F11203} The [sqlite3_vfs_find(N)] interface returns a pointer to the
+** {H11203} The [sqlite3_vfs_find(N)] interface returns a pointer to the
** registered [sqlite3_vfs] object whose name exactly matches
** the zero-terminated UTF-8 string N, or it returns NULL if
** there is no match.
**
-** {F11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
+** {H11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
** the function returns a pointer to the default [sqlite3_vfs]
** object if there is one, or NULL if there is no default
** [sqlite3_vfs] object.
**
-** {F11209} The [sqlite3_vfs_register(P,F)] interface registers the
+** {H11209} The [sqlite3_vfs_register(P,F)] interface registers the
** well-formed [sqlite3_vfs] object P using the name given
** by the zName field of the object.
**
-** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register
+** {H11212} Using the [sqlite3_vfs_register(P,F)] interface to register
** the same [sqlite3_vfs] object multiple times is a harmless no-op.
**
-** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
+** {H11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
** object P the default [sqlite3_vfs] object if F is non-zero.
**
-** {F11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
+** {H11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
** [sqlite3_vfs] object P so that it is no longer returned by
** subsequent calls to [sqlite3_vfs_find()].
*/
@@ -6187,7 +6261,7 @@
SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
-** CAPI3REF: Mutexes {F17000}
+** CAPI3REF: Mutexes {H17000} <S20000>
**
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
@@ -6220,10 +6294,10 @@
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
-** {F17011} The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. {F17012} If it returns NULL
-** that means that a mutex could not be allocated. {F17013} SQLite
-** will unwind its stack and return an error. {F17014} The argument
+** {H17011} The sqlite3_mutex_alloc() routine allocates a new
+** mutex and returns a pointer to it. {H17012} If it returns NULL
+** that means that a mutex could not be allocated. {H17013} SQLite
+** will unwind its stack and return an error. {H17014} The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
@@ -6237,17 +6311,17 @@
** <li> SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
-** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
+** {H17015} The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. {F17016} But SQLite will only request a recursive mutex in
+** not want to. {H17016} But SQLite will only request a recursive mutex in
** cases where it really needs one. {END} If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
-** {F17017} The other allowed parameters to sqlite3_mutex_alloc() each return
+** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex. {END} Four static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
@@ -6255,41 +6329,41 @@
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
-** {F17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
+** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. {F17034} But for the static
+** returns a different mutex on every call. {H17034} But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
-** {F17019} The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. {F17020} SQLite is careful to deallocate every
+** {H17019} The sqlite3_mutex_free() routine deallocates a previously
+** allocated dynamic mutex. {H17020} SQLite is careful to deallocate every
** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
** use when they are deallocated. {A17022} Attempting to deallocate a static
-** mutex results in undefined behavior. {F17023} SQLite never deallocates
+** mutex results in undefined behavior. {H17023} SQLite never deallocates
** a static mutex. {END}
**
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. {F17024} If another thread is already within the mutex,
+** to enter a mutex. {H17024} If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {F17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. {F17026} Mutexes created using
+** SQLITE_BUSY. {H17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
+** upon successful entry. {H17026} Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** {F17027} In such cases the,
+** {H17027} In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. {A17028} If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
-** {F17029} SQLite will never exhibit
+** {H17029} SQLite will never exhibit
** such behavior in its own use of mutexes.
**
** Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. {F17030} The SQLite core only ever uses
+** will always return SQLITE_BUSY. {H17030} The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
**
-** {F17031} The sqlite3_mutex_leave() routine exits a mutex that was
+** {H17031} The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. {A17032} The behavior
** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. {F17033} SQLite will
+** calling thread or is not currently allocated. {H17033} SQLite will
** never do either. {END}
**
** If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
@@ -6305,7 +6379,8 @@
SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
-** CAPI3REF: Mutex Methods Object {F17120}
+** CAPI3REF: Mutex Methods Object {H17120} <S20130>
+** EXPERIMENTAL
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
@@ -6322,14 +6397,14 @@
**
** The xMutexInit method defined by this structure is invoked as
** part of system initialization by the sqlite3_initialize() function.
-** {F17001} The xMutexInit routine shall be called by SQLite once for each
+** {H17001} The xMutexInit routine shall be called by SQLite once for each
** effective call to [sqlite3_initialize()].
**
** The xMutexEnd method defined by this structure is invoked as
** part of system shutdown by the sqlite3_shutdown() function. The
** implementation of this method is expected to release all outstanding
** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. {F17003} The xMutexEnd()
+** those obtained by the xMutexInit method. {H17003} The xMutexEnd()
** interface shall be invoked once for each call to [sqlite3_shutdown()].
**
** The remaining seven methods defined by this structure (xMutexAlloc,
@@ -6368,18 +6443,18 @@
};
/*
-** CAPI3REF: Mutex Verification Routines {F17080}
+** CAPI3REF: Mutex Verification Routines {H17080} <S20130> <S30800>
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. {F17081} The SQLite core
+** are intended for use inside assert() statements. {H17081} The SQLite core
** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. {F17082} The core only
+** are advised to follow the lead of the core. {H17082} The core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag. {A17087} External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
-** {F17083} These routines should return true if the mutex in their argument
+** {H17083} These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** {X17084} The implementation is not required to provided versions of these
@@ -6387,23 +6462,27 @@
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
-** {F17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
+** {H17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1. {END} This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist. But the
** the reason the mutex does not exist is because the build is not
** using mutexes. And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. {F17086} The sqlite3_mutex_notheld()
+** the appropriate thing to do. {H17086} The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
/*
-** CAPI3REF: Mutex Types {F17001}
+** CAPI3REF: Mutex Types {H17001} <H17000>
**
-** {F17002} The [sqlite3_mutex_alloc()] interface takes a single argument
+** The [sqlite3_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
+**
+** The set of static mutexes may change from one SQLite release to the
+** next. Applications that override the built-in mutex logic must be
+** prepared to accommodate additional static mutexes.
*/
#define SQLITE_MUTEX_FAST 0
#define SQLITE_MUTEX_RECURSIVE 1
@@ -6415,21 +6494,21 @@
#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */
/*
-** CAPI3REF: Low-Level Control Of Database Files {F11300}
+** CAPI3REF: Low-Level Control Of Database Files {H11300} <S30800>
**
-** {F11301} The [sqlite3_file_control()] interface makes a direct call to the
+** {H11301} The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. {F11302} The
+** with a particular database identified by the second argument. {H11302} The
** name of the database is the name assigned to the database by the
** <a href="lang_attach.html">ATTACH</a> SQL command that opened the
-** database. {F11303} To control the main database file, use the name "main"
-** or a NULL pointer. {F11304} The third and fourth parameters to this routine
+** database. {H11303} To control the main database file, use the name "main"
+** or a NULL pointer. {H11304} The third and fourth parameters to this routine
** are passed directly through to the second and third parameters of
-** the xFileControl method. {F11305} The return value of the xFileControl
+** the xFileControl method. {H11305} The return value of the xFileControl
** method becomes the return value of this routine.
**
-** {F11306} If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. {F11307} This error
+** {H11306} If the second parameter (zDbName) does not match the name of any
+** open database file, then SQLITE_ERROR is returned. {H11307} This error
** code is not remembered and will not be recalled by [sqlite3_errcode()]
** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
** also return SQLITE_ERROR. {A11309} There is no way to distinguish between
@@ -6441,7 +6520,7 @@
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
-** CAPI3REF: Testing Interface {F11400}
+** CAPI3REF: Testing Interface {H11400} <S30800>
**
** The sqlite3_test_control() interface is used to read out internal
** state of SQLite and to inject faults into SQLite for testing
@@ -6460,7 +6539,7 @@
SQLITE_API int sqlite3_test_control(int op, ...);
/*
-** CAPI3REF: Testing Interface Operation Codes {F11410}
+** CAPI3REF: Testing Interface Operation Codes {H11410} <H11400>
**
** These constants are the valid operation code parameters used
** as the first argument to [sqlite3_test_control()].
@@ -6478,7 +6557,8 @@
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
/*
-** CAPI3REF: SQLite Runtime Status {F17200}
+** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
+** EXPERIMENTAL
**
** This interface is used to retrieve runtime status information
** about the preformance of SQLite, and optionally to reset various
@@ -6504,13 +6584,33 @@
** and it is possible that another thread might change the parameter
** in between the times when *pCurrent and *pHighwater are written.
**
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** See also: [sqlite3_db_status()]
*/
SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
/*
-** CAPI3REF: Status Parameters {F17250}
+** CAPI3REF: Database Connection Status {H17201} <S60200>
+** EXPERIMENTAL
+**
+** This interface is used to retrieve runtime status information
+** about a single [database connection]. The first argument is the
+** database connection object to be interrogated. The second argument
+** is the parameter to interrogate. Currently, the only allowed value
+** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
+** Additional options will likely appear in future releases of SQLite.
+**
+** The current value of the request parameter is written into *pCur
+** and the highest instantaneous value is written into *pHiwtr. If
+** the resetFlg is true, then the highest instantaneous value is
+** reset back down to the current value.
+**
+** See also: [sqlite3_status()].
+*/
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters {H17250} <H17200>
+** EXPERIMENTAL
**
** These integer constants designate various run-time status parameters
** that can be returned by [sqlite3_status()].
@@ -6526,35 +6626,61 @@
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>
**
+** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
+** internal equivalents). Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
+**
** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
** <dd>This parameter returns the number of pages used out of the
-** page cache buffer configured using [SQLITE_CONFIG_PAGECACHE]. The
+** [pagecache memory allocator] that was configured using
+** [SQLITE_CONFIG_PAGECACHE]. The
** value returned is in pages, not in bytes.</dd>
**
** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of page cache
** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+** buffer and where forced to overflow to [sqlite3_malloc()]. The
+** returned value includes allocations that overflowed because they
+** where too large (they were larger than the "sz" parameter to
+** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
+** no space was left in the page cache.</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [pagecache memory allocator]. Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
**
** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>This parameter returns the number of allocations used out of the
-** scratch allocation lookaside buffer configured using
+** [scratch memory allocator] configured using
** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one allocation
+** in bytes. Since a single thread may only have one scratch allocation
** outstanding at time, this parameter also reports the number of threads
** using scratch memory at the same time.</dd>
**
** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of scratch memory
** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+** buffer and where forced to overflow to [sqlite3_malloc()]. The values
+** returned include overflows because the requested allocation was too
+** larger (that is, because the requested allocation was larger than the
+** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
+** slots were available.
+** </dd>
**
-** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). The value of interest is return in the
-** *pHighwater parameter to [sqlite3_status()]. The value written
-** into the *pCurrent parameter is undefined.</dd>
+** handed to [scratch memory allocator]. Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
+**
+** <dt>SQLITE_STATUS_PARSER_STACK</dt>
+** <dd>This parameter records the deepest parser stack. It is only
+** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>
** </dl>
**
** New status parameters may be added from time to time.
@@ -6565,7 +6691,23 @@
#define SQLITE_STATUS_SCRATCH_USED 3
#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
#define SQLITE_STATUS_MALLOC_SIZE 5
+#define SQLITE_STATUS_PARSER_STACK 6
+#define SQLITE_STATUS_PAGECACHE_SIZE 7
+#define SQLITE_STATUS_SCRATCH_SIZE 8
+/*
+** CAPI3REF: Status Parameters for database connections {H17275} <H17200>
+** EXPERIMENTAL
+**
+** Status verbs for [sqlite3_db_status()].
+**
+** <dl>
+** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
+** <dd>This parameter returns the number of lookaside memory slots currently
+** checked out.</dd>
+** </dl>
+*/
+#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
/*
** Undo the hack that converts floating point types to integer for
@@ -7061,6 +7203,12 @@
#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
/*
+** The following value as a destructor means to use sqlite3DbFree().
+** This is an internal extension to SQLITE_STATIC and SQLITE_TRANSIENT.
+*/
+#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3DbFree)
+
+/*
** Forward references to structures
*/
typedef struct AggInfo AggInfo;
@@ -7078,6 +7226,8 @@
typedef struct Index Index;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
+typedef struct Lookaside Lookaside;
+typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
@@ -7341,7 +7491,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
-** $Id: vdbe.h,v 1.134 2008/06/25 00:12:41 drh Exp $
+** $Id: vdbe.h,v 1.135 2008/08/01 20:10:08 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -7683,7 +7833,7 @@
SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*, int);
+SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
@@ -7730,7 +7880,7 @@
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
-** @(#) $Id: pager.h,v 1.76 2008/06/07 08:58:22 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.77 2008/07/16 18:17:56 danielk1977 Exp $
*/
#ifndef _PAGER_H_
@@ -7822,7 +7972,7 @@
SQLITE_PRIVATE const char *sqlite3PagerDirname(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno);
+SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *);
SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *);
SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
@@ -8309,6 +8459,33 @@
#define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1)
/*
+** Lookaside malloc is a set of fixed-size buffers that can be used
+** to satisify small transient memory allocation requests for objects
+** associated with a particular database connection. The use of
+** lookaside malloc provides a significant performance enhancement
+** (approx 10%) by avoiding numerous malloc/free requests while parsing
+** SQL statements.
+**
+** The Lookaside structure holds configuration information about the
+** lookaside malloc subsystem. Each available memory allocation in
+** the lookaside subsystem is stored on a linked list of LookasideSlot
+** objects.
+*/
+struct Lookaside {
+ u16 sz; /* Size of each buffer in bytes */
+ u8 bEnabled; /* True if use lookaside. False to ignore it */
+ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
+ int nOut; /* Number of buffers currently checked out */
+ int mxOut; /* Highwater mark for nOut */
+ LookasideSlot *pFree; /* List if available buffers */
+ void *pStart; /* First byte of available memory space */
+ void *pEnd; /* First byte past end of available space */
+};
+struct LookasideSlot {
+ LookasideSlot *pNext; /* Next buffer in the list of free buffers */
+};
+
+/*
** Each database is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an
@@ -8387,6 +8564,7 @@
int isInterrupted; /* True if sqlite3_interrupt has been called */
double notUsed1; /* Spacer */
} u1;
+ Lookaside lookaside; /* Lookaside malloc configuration */
#ifndef SQLITE_OMIT_AUTHORIZATION
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
/* Access authorization function */
@@ -8626,6 +8804,7 @@
** of a SELECT statement.
*/
struct Table {
+ sqlite3 *db; /* Associated database connection. Might be NULL. */
char *zName; /* Name of the table */
int nCol; /* Number of columns in this table */
Column *aCol; /* Information about each column */
@@ -9503,10 +9682,11 @@
** do not necessarily know how big the string will be in the end.
*/
struct StrAccum {
- char *zBase; /* A base allocation. Not from malloc. */
- char *zText; /* The string collected so far */
- int nChar; /* Length of the string so far */
- int nAlloc; /* Amount of space allocated in zText */
+ sqlite3 *db; /* Optional database for lookaside. Can be NULL */
+ char *zBase; /* A base allocation. Not from malloc. */
+ char *zText; /* The string collected so far */
+ int nChar; /* Length of the string so far */
+ int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed string length */
u8 mallocFailed; /* Becomes true if any memory allocation fails */
u8 useMalloc; /* True if zText is enlargable using realloc */
@@ -9534,6 +9714,8 @@
int bCoreMutex; /* True to enable core mutexing */
int bFullMutex; /* True to enable full mutexing */
int mxStrlen; /* Maximum string length */
+ int szLookaside; /* Default lookaside buffer size */
+ int nLookaside; /* Default lookaside buffer count */
sqlite3_mem_methods m; /* Low-level memory allocation interface */
sqlite3_mutex_methods mutex; /* Low-level mutex interface */
void *pHeap; /* Heap storage space */
@@ -9548,6 +9730,8 @@
int isInit; /* True after initialization has finished */
int isMallocInit; /* True after malloc is initialized */
sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
+ int nSmall; /* alloc size threshold used by mem6.c */
+ int mxParserStack; /* maximum depth of the parser stack */
};
/*
@@ -9587,21 +9771,23 @@
SQLITE_PRIVATE void *sqlite3MallocZero(int);
SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
-SQLITE_PRIVATE char *sqlite3StrDup(const char*);
-SQLITE_PRIVATE char *sqlite3StrNDup(const char*, int);
SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int);
SQLITE_PRIVATE void *sqlite3Realloc(void*, int);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int);
-SQLITE_PRIVATE int sqlite3MallocSize(void *);
+SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
+SQLITE_PRIVATE int sqlite3MallocSize(void*);
+SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
SQLITE_PRIVATE void sqlite3ScratchFree(void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetDefault(void);
SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys6(void);
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#ifndef SQLITE_MUTEX_NOOP
@@ -9621,6 +9807,7 @@
SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
+SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
#endif
@@ -9646,9 +9833,9 @@
SQLITE_PRIVATE void sqlite3ExprSpan(Expr*,Token*,Token*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprDelete(Expr*);
+SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*,Token*);
-SQLITE_PRIVATE void sqlite3ExprListDelete(ExprList*);
+SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -9693,15 +9880,15 @@
Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
-SQLITE_PRIVATE void sqlite3IdListDelete(IdList*);
-SQLITE_PRIVATE void sqlite3SrcListDelete(SrcList*);
+SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
+SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Token*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,int,Expr*,Expr*);
-SQLITE_PRIVATE void sqlite3SelectDelete(Select*);
+SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
@@ -9790,17 +9977,17 @@
SQLITE_PRIVATE int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
int, int, u32*, u32*);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(TriggerStep*);
+SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
ExprList*,Select*,int);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
-SQLITE_PRIVATE void sqlite3DeleteTrigger(Trigger*);
+SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
#else
# define sqlite3TriggersExist(A,B,C,D,E,F) 0
-# define sqlite3DeleteTrigger(A)
+# define sqlite3DeleteTrigger(A,B)
# define sqlite3DropTriggerPtr(A,B)
# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K) 0
@@ -9951,6 +10138,9 @@
SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
+#ifdef YYTRACKMAXSTACKDEPTH
+SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
+#endif
SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3*);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -9971,12 +10161,12 @@
#ifdef SQLITE_OMIT_VIRTUALTABLE
# define sqlite3VtabClear(X)
-# define sqlite3VtabSync(X,Y) (Y)
+# define sqlite3VtabSync(X,Y) SQLITE_OK
# define sqlite3VtabRollback(X)
# define sqlite3VtabCommit(X)
#else
SQLITE_PRIVATE void sqlite3VtabClear(Table*);
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, int rc);
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
#endif
@@ -10081,7 +10271,7 @@
**
** This file contains definitions of global variables and contants.
**
-** $Id: global.c,v 1.3 2008/07/08 14:52:10 drh Exp $
+** $Id: global.c,v 1.4 2008/07/28 19:34:53 drh Exp $
*/
@@ -10134,7 +10324,15 @@
** The following singleton contains the global configuration for
** the SQLite library.
*/
-SQLITE_PRIVATE struct Sqlite3Config sqlite3Config = { 1, 1, 1, 0x7ffffffe };
+SQLITE_PRIVATE struct Sqlite3Config sqlite3Config = {
+ 1, /* bMemstat */
+ 1, /* bCoreMutex */
+ 1, /* bFullMutex */
+ 0x7ffffffe, /* mxStrlen */
+ 100, /* szLookaside */
+ 500, /* nLookaside */
+ /* Other fields all default to zero */
+};
/************** End of global.c **********************************************/
/************** Begin file status.c ******************************************/
@@ -10153,15 +10351,15 @@
** This module implements the sqlite3_status() interface and related
** functionality.
**
-** $Id: status.c,v 1.3 2008/07/11 16:15:18 drh Exp $
+** $Id: status.c,v 1.7 2008/08/05 17:53:23 drh Exp $
*/
/*
** Variables in which to record status information.
*/
static struct {
- int nowValue[6]; /* Current value */
- int mxValue[6]; /* Maximum value */
+ int nowValue[9]; /* Current value */
+ int mxValue[9]; /* Maximum value */
} sqlite3Stat;
@@ -10223,6 +10421,32 @@
return SQLITE_OK;
}
+/*
+** Query status information for a single database connection
+*/
+SQLITE_API int sqlite3_db_status(
+ sqlite3 *db, /* The database connection whose status is desired */
+ int op, /* Status verb */
+ int *pCurrent, /* Write current value here */
+ int *pHighwater, /* Write high-water mark here */
+ int resetFlag /* Reset high-water mark if true */
+){
+ switch( op ){
+ case SQLITE_DBSTATUS_LOOKASIDE_USED: {
+ *pCurrent = db->lookaside.nOut;
+ *pHighwater = db->lookaside.mxOut;
+ if( resetFlag ){
+ db->lookaside.mxOut = db->lookaside.nOut;
+ }
+ break;
+ }
+ default: {
+ return SQLITE_ERROR;
+ }
+ }
+ return SQLITE_OK;
+}
+
/************** End of status.c **********************************************/
/************** Begin file date.c ********************************************/
/*
@@ -10243,7 +10467,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.85 2008/06/18 17:09:10 danielk1977 Exp $
+** $Id: date.c,v 1.87 2008/07/28 19:34:53 drh Exp $
**
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
@@ -10777,7 +11001,9 @@
p->iJD = p->iJD/86400.0 + 2440587.5*86400000.0;
clearYMD_HMS_TZ(p);
rc = 0;
- }else if( strcmp(z, "utc")==0 ){
+ }
+#ifndef SQLITE_OMIT_LOCALTIME
+ else if( strcmp(z, "utc")==0 ){
double c1;
computeJD(p);
c1 = localtimeOffset(p);
@@ -10786,6 +11012,7 @@
p->iJD += c1 - localtimeOffset(p);
rc = 0;
}
+#endif
break;
}
case 'w': {
@@ -11070,9 +11297,11 @@
u64 n;
int i, j;
char *z;
+ sqlite3 *db;
const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
char zBuf[100];
if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
+ db = sqlite3_context_db_handle(context);
for(i=0, n=1; zFmt[i]; i++, n++){
if( zFmt[i]=='%' ){
switch( zFmt[i+1] ){
@@ -11108,11 +11337,11 @@
}
if( n<sizeof(zBuf) ){
z = zBuf;
- }else if( n>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){
+ }else if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
return;
}else{
- z = sqlite3Malloc( n );
+ z = sqlite3DbMallocRaw(db, n);
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
@@ -11177,7 +11406,7 @@
}
z[j] = 0;
sqlite3_result_text(context, z, -1,
- z==zBuf ? SQLITE_TRANSIENT : sqlite3_free);
+ z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
}
/*
@@ -11328,7 +11557,7 @@
** This file contains OS interface code that is common to all
** architectures.
**
-** $Id: os.c,v 1.119 2008/06/26 18:16:06 drh Exp $
+** $Id: os.c,v 1.120 2008/07/28 19:34:53 drh Exp $
*/
#define _SQLITE_OS_C_ 1
#undef _SQLITE_OS_C_
@@ -11350,7 +11579,7 @@
** sqlite3OsLock()
**
*/
-#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
+#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) && 0
#define DO_OS_MALLOC_TEST if (1) { \
void *pTstAlloc = sqlite3Malloc(10); \
if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
@@ -11684,7 +11913,7 @@
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
-** $Id: mem1.c,v 1.23 2008/06/23 15:10:25 danielk1977 Exp $
+** $Id: mem1.c,v 1.25 2008/07/25 08:49:00 danielk1977 Exp $
*/
/*
@@ -11786,13 +12015,7 @@
return;
}
-/*
-** This routine is the only routine in this file with external linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3Config.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetDefault(void){
static const sqlite3_mem_methods defaultMethods = {
sqlite3MemMalloc,
sqlite3MemFree,
@@ -11803,7 +12026,17 @@
sqlite3MemShutdown,
0
};
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
+ return &defaultMethods;
+}
+
+/*
+** This routine is the only routine in this file with external linkage.
+**
+** Populate the low-level memory allocation function pointers in
+** sqlite3Config.m with pointers to the routines in this file.
+*/
+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+ sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetDefault());
}
#endif /* SQLITE_SYSTEM_MALLOC */
@@ -11831,7 +12064,7 @@
** This file contains implementations of the low-level memory allocation
** routines specified in the sqlite3_mem_methods object.
**
-** $Id: mem2.c,v 1.34 2008/07/10 18:13:42 drh Exp $
+** $Id: mem2.c,v 1.37 2008/07/25 08:49:00 danielk1977 Exp $
*/
/*
@@ -11923,14 +12156,37 @@
/*
** Gather statistics on the sizes of memory allocations.
- ** sizeCnt[i] is the number of allocation attempts of i*8
+ ** nAlloc[i] is the number of allocation attempts of i*8
** bytes. i==NCSIZE is the number of allocation attempts for
** sizes more than NCSIZE*8 bytes.
*/
- int sizeCnt[NCSIZE];
+ int nAlloc[NCSIZE]; /* Total number of allocations */
+ int nCurrent[NCSIZE]; /* Current number of allocations */
+ int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */
} mem;
+
+/*
+** Adjust memory usage statistics
+*/
+static void adjustStats(int iSize, int increment){
+ int i = ((iSize+7)&~7)/8;
+ if( i>NCSIZE-1 ){
+ i = NCSIZE - 1;
+ }
+ if( increment>0 ){
+ mem.nAlloc[i]++;
+ mem.nCurrent[i]++;
+ if( mem.nCurrent[i]>mem.mxCurrent[i] ){
+ mem.mxCurrent[i] = mem.nCurrent[i];
+ }
+ }else{
+ mem.nCurrent[i]--;
+ assert( mem.nCurrent[i]>=0 );
+ }
+}
+
/*
** Given an allocation, find the MemBlockHdr for that allocation.
**
@@ -12008,11 +12264,6 @@
sqlite3_mutex_enter(mem.mutex);
assert( mem.disallow==0 );
nReserve = (nByte+7)&~7;
- if( nReserve/8>NCSIZE-1 ){
- mem.sizeCnt[NCSIZE-1]++;
- }else{
- mem.sizeCnt[nReserve/8]++;
- }
totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
mem.nBacktrace*sizeof(void*) + mem.nTitle;
p = malloc(totalSize);
@@ -12045,6 +12296,7 @@
memcpy(z, mem.zTitle, mem.nTitle);
}
pHdr->iSize = nByte;
+ adjustStats(nByte, +1);
pInt = (int*)&pHdr[1];
pInt[nReserve/sizeof(int)] = REARGUARD;
memset(pInt, 0x65, nReserve);
@@ -12082,6 +12334,7 @@
}
z = (char*)pBt;
z -= pHdr->nTitle;
+ adjustStats(pHdr->iSize, -1);
memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
pHdr->iSize + sizeof(int) + pHdr->nTitle);
free(z);
@@ -12114,11 +12367,7 @@
}
-/*
-** Populate the low-level memory allocation function pointers in
-** sqlite3Config.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetDefault(void){
static const sqlite3_mem_methods defaultMethods = {
sqlite3MemMalloc,
sqlite3MemFree,
@@ -12129,7 +12378,15 @@
sqlite3MemShutdown,
0
};
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
+ return &defaultMethods;
+}
+
+/*
+** Populate the low-level memory allocation function pointers in
+** sqlite3Config.m with pointers to the routines in this file.
+*/
+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+ sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetDefault());
}
/*
@@ -12200,12 +12457,15 @@
}
fprintf(out, "COUNTS:\n");
for(i=0; i<NCSIZE-1; i++){
- if( mem.sizeCnt[i] ){
- fprintf(out, " %3d: %d\n", i*8+8, mem.sizeCnt[i]);
+ if( mem.nAlloc[i] ){
+ fprintf(out, " %5d: %10d %10d %10d\n",
+ i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
}
}
- if( mem.sizeCnt[NCSIZE-1] ){
- fprintf(out, " >%3d: %d\n", NCSIZE*8, mem.sizeCnt[NCSIZE-1]);
+ if( mem.nAlloc[NCSIZE-1] ){
+ fprintf(out, " %5d: %10d %10d %10d\n",
+ NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
+ mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
}
fclose(out);
}
@@ -12217,7 +12477,7 @@
int i;
int nTotal = 0;
for(i=0; i<NCSIZE; i++){
- nTotal += mem.sizeCnt[i];
+ nTotal += mem.nAlloc[i];
}
return nTotal;
}
@@ -12252,7 +12512,7 @@
** This version of the memory allocation subsystem is included
** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
**
-** $Id: mem3.c,v 1.19 2008/07/16 12:25:32 drh Exp $
+** $Id: mem3.c,v 1.20 2008/07/18 18:56:17 drh Exp $
*/
/*
@@ -12366,7 +12626,6 @@
*/
u32 nPool;
Mem3Block *aPool;
- /* Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2]; */
} mem3;
/*
@@ -12699,6 +12958,30 @@
}
/*
+** Return the size of an outstanding allocation, in bytes. The
+** size returned omits the 8-byte header overhead. This only
+** works for chunks that are currently checked out.
+*/
+static int memsys3Size(void *p){
+ Mem3Block *pBlock;
+ if( p==0 ) return 0;
+ pBlock = (Mem3Block*)p;
+ assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
+ return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
+}
+
+/*
+** Round up a request size to the next valid allocation size.
+*/
+static int memsys3Roundup(int n){
+ if( n<=12 ){
+ return 12;
+ }else{
+ return ((n+11)&~7) - 4;
+ }
+}
+
+/*
** Allocate nBytes of memory.
*/
static void *memsys3Malloc(int nBytes){
@@ -12721,19 +13004,6 @@
}
/*
-** Return the size of an outstanding allocation, in bytes. The
-** size returned omits the 8-byte header overhead. This only
-** works for chunks that are currently checked out.
-*/
-static int memsys3Size(void *p){
- Mem3Block *pBlock;
- if( p==0 ) return 0;
- pBlock = (Mem3Block*)p;
- assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
- return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
-}
-
-/*
** Change the size of an existing memory allocation
*/
void *memsys3Realloc(void *pPrior, int nBytes){
@@ -12765,13 +13035,6 @@
}
/*
-** Round up a request size to the next valid allocation size.
-*/
-static int memsys3Roundup(int n){
- return (n+7) & ~7;
-}
-
-/*
** Initialize this module.
*/
static int memsys3Init(void *NotUsed){
@@ -13424,6 +13687,504 @@
#endif /* SQLITE_ENABLE_MEMSYS5 */
/************** End of mem5.c ************************************************/
+/************** Begin file mem6.c ********************************************/
+/*
+** 2008 July 24
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains an alternative memory allocation system for SQLite.
+** This system is implemented as a wrapper around the system provided
+** by the operating system - vanilla malloc(), realloc() and free().
+**
+** This system differentiates between requests for "small" allocations
+** (by default those of 128 bytes or less) and "large" allocations (all
+** others). The 256 byte threshhold is configurable at runtime.
+**
+** All requests for large allocations are passed through to the
+** default system.
+**
+** Requests for small allocations are met by allocating space within
+** one or more larger "chunks" of memory obtained from the default
+** memory allocation system. Chunks of memory are usually 64KB or
+** larger. The algorithm used to manage space within each chunk is
+** the same as that used by mem5.c.
+**
+** This strategy is designed to prevent the default memory allocation
+** system (usually the system malloc) from suffering from heap
+** fragmentation. On some systems, heap fragmentation can cause a
+** significant real-time slowdown.
+**
+** $Id: mem6.c,v 1.7 2008/07/28 19:34:53 drh Exp $
+*/
+
+#ifdef SQLITE_ENABLE_MEMSYS6
+
+
+/*
+** Maximum size of any "small" allocation is ((1<<LOGMAX)*Mem6Chunk.nAtom).
+** Mem6Chunk.nAtom is always at least 8, so this is not a practical
+** limitation
+*/
+#define LOGMAX 30
+
+/*
+** Default value for the "small" allocation size threshold.
+*/
+#define SMALL_MALLOC_DEFAULT_THRESHOLD 256
+
+/*
+** Minimum size for a memory chunk.
+*/
+#define MIN_CHUNKSIZE (1<<16)
+
+#define LOG2_MINALLOC 4
+
+
+typedef struct Mem6Chunk Mem6Chunk;
+typedef struct Mem6Link Mem6Link;
+
+/*
+** A minimum allocation is an instance of the following structure.
+** Larger allocations are an array of these structures where the
+** size of the array is a power of 2.
+*/
+struct Mem6Link {
+ int next; /* Index of next free chunk */
+ int prev; /* Index of previous free chunk */
+};
+
+/*
+** Masks used for mem5.aCtrl[] elements.
+*/
+#define CTRL_LOGSIZE 0x1f /* Log2 Size of this block relative to POW2_MIN */
+#define CTRL_FREE 0x20 /* True if not checked out */
+
+struct Mem6Chunk {
+ Mem6Chunk *pNext;
+
+ /*
+ ** Lists of free blocks of various sizes.
+ */
+ int aiFreelist[LOGMAX+1];
+
+ int nCheckedOut; /* Number of currently outstanding allocations */
+
+ /*
+ ** Space for tracking which blocks are checked out and the size
+ ** of each block. One byte per block.
+ */
+ u8 *aCtrl;
+
+ /*
+ ** Memory available for allocation
+ */
+ int nAtom; /* Smallest possible allocation in bytes */
+ int nBlock; /* Number of nAtom sized blocks in zPool */
+ u8 *zPool; /* Pointer to memory chunk from which allocations are made */
+};
+
+#define MEM6LINK(idx) ((Mem6Link *)(&pChunk->zPool[(idx)*pChunk->nAtom]))
+
+struct Mem6Global {
+ int nMinAlloc; /* Minimum allowed allocation size */
+ int nThreshold; /* Allocs larger than this go to malloc() */
+ int nLogThreshold; /* log2 of (nThreshold/nMinAlloc) */
+ sqlite3_mutex *mutex;
+ Mem6Chunk *pChunk; /* Singly linked list of all memory chunks */
+} mem6;
+
+/*
+** Unlink the chunk at pChunk->aPool[i] from list it is currently
+** on. It should be found on pChunk->aiFreelist[iLogsize].
+*/
+static void memsys6Unlink(Mem6Chunk *pChunk, int i, int iLogsize){
+ int next, prev;
+ assert( i>=0 && i<pChunk->nBlock );
+ assert( iLogsize>=0 && iLogsize<=mem6.nLogThreshold );
+ assert( (pChunk->aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
+
+ next = MEM6LINK(i)->next;
+ prev = MEM6LINK(i)->prev;
+ if( prev<0 ){
+ pChunk->aiFreelist[iLogsize] = next;
+ }else{
+ MEM6LINK(prev)->next = next;
+ }
+ if( next>=0 ){
+ MEM6LINK(next)->prev = prev;
+ }
+}
+
+/*
+** Link the chunk at mem5.aPool[i] so that is on the iLogsize
+** free list.
+*/
+static void memsys6Link(Mem6Chunk *pChunk, int i, int iLogsize){
+ int x;
+ assert( i>=0 && i<pChunk->nBlock );
+ assert( iLogsize>=0 && iLogsize<=mem6.nLogThreshold );
+ assert( (pChunk->aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
+
+ x = MEM6LINK(i)->next = pChunk->aiFreelist[iLogsize];
+ MEM6LINK(i)->prev = -1;
+ if( x>=0 ){
+ assert( x<pChunk->nBlock );
+ MEM6LINK(x)->prev = i;
+ }
+ pChunk->aiFreelist[iLogsize] = i;
+}
+
+
+/*
+** Find the first entry on the freelist iLogsize. Unlink that
+** entry and return its index.
+*/
+static int memsys6UnlinkFirst(Mem6Chunk *pChunk, int iLogsize){
+ int i;
+ int iFirst;
+
+ assert( iLogsize>=0 && iLogsize<=mem6.nLogThreshold );
+ i = iFirst = pChunk->aiFreelist[iLogsize];
+ assert( iFirst>=0 );
+ memsys6Unlink(pChunk, iFirst, iLogsize);
+ return iFirst;
+}
+
+static int roundupLog2(int n){
+ static const char LogTable256[256] = {
+ 0, /* 1 */
+ 1, /* 2 */
+ 2, 2, /* 3..4 */
+ 3, 3, 3, 3, /* 5..8 */
+ 4, 4, 4, 4, 4, 4, 4, 4, /* 9..16 */
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* 17..32 */
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, /* 33..64 */
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* 65..128 */
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* 129..256 */
+ };
+
+ assert(n<=(1<<16) && n>0);
+ if( n<=256 ) return LogTable256[n-1];
+ return LogTable256[(n>>8) - ((n&0xFF)?0:1)] + 8;
+}
+
+/*
+** Allocate and return a block of (pChunk->nAtom << iLogsize) bytes from chunk
+** pChunk. If the allocation request cannot be satisfied, return 0.
+*/
+static void *chunkMalloc(Mem6Chunk *pChunk, int iLogsize){
+ int i; /* Index of a mem5.aPool[] slot */
+ int iBin; /* Index into mem5.aiFreelist[] */
+
+ /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
+ ** block. If not, then split a block of the next larger power of
+ ** two in order to create a new free block of size iLogsize.
+ */
+ for(iBin=iLogsize; pChunk->aiFreelist[iBin]<0 && iBin<=mem6.nLogThreshold; iBin++){}
+ if( iBin>mem6.nLogThreshold ) return 0;
+ i = memsys6UnlinkFirst(pChunk, iBin);
+ while( iBin>iLogsize ){
+ int newSize;
+ iBin--;
+ newSize = 1 << iBin;
+ pChunk->aCtrl[i+newSize] = CTRL_FREE | iBin;
+ memsys6Link(pChunk, i+newSize, iBin);
+ }
+ pChunk->aCtrl[i] = iLogsize;
+
+ /* Return a pointer to the allocated memory. */
+ pChunk->nCheckedOut++;
+ return (void*)&pChunk->zPool[i*pChunk->nAtom];
+}
+
+/*
+** Free the allocation pointed to by p, which is guaranteed to be non-zero
+** and a part of chunk object pChunk.
+*/
+static void chunkFree(Mem6Chunk *pChunk, void *pOld){
+ u32 size, iLogsize;
+ int iBlock;
+
+ /* Set iBlock to the index of the block pointed to by pOld in
+ ** the array of pChunk->nAtom byte blocks pointed to by pChunk->zPool.
+ */
+ iBlock = ((u8 *)pOld-pChunk->zPool)/pChunk->nAtom;
+
+ /* Check that the pointer pOld points to a valid, non-free block. */
+ assert( iBlock>=0 && iBlock<pChunk->nBlock );
+ assert( ((u8 *)pOld-pChunk->zPool)%pChunk->nAtom==0 );
+ assert( (pChunk->aCtrl[iBlock] & CTRL_FREE)==0 );
+
+ iLogsize = pChunk->aCtrl[iBlock] & CTRL_LOGSIZE;
+ size = 1<<iLogsize;
+ assert( iBlock+size-1<pChunk->nBlock );
+
+ pChunk->aCtrl[iBlock] |= CTRL_FREE;
+ pChunk->aCtrl[iBlock+size-1] |= CTRL_FREE;
+
+ pChunk->aCtrl[iBlock] = CTRL_FREE | iLogsize;
+ while( iLogsize<mem6.nLogThreshold ){
+ int iBuddy;
+ if( (iBlock>>iLogsize) & 1 ){
+ iBuddy = iBlock - size;
+ }else{
+ iBuddy = iBlock + size;
+ }
+ assert( iBuddy>=0 );
+ if( (iBuddy+(1<<iLogsize))>pChunk->nBlock ) break;
+ if( pChunk->aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
+ memsys6Unlink(pChunk, iBuddy, iLogsize);
+ iLogsize++;
+ if( iBuddy<iBlock ){
+ pChunk->aCtrl[iBuddy] = CTRL_FREE | iLogsize;
+ pChunk->aCtrl[iBlock] = 0;
+ iBlock = iBuddy;
+ }else{
+ pChunk->aCtrl[iBlock] = CTRL_FREE | iLogsize;
+ pChunk->aCtrl[iBuddy] = 0;
+ }
+ size *= 2;
+ }
+ pChunk->nCheckedOut--;
+ memsys6Link(pChunk, iBlock, iLogsize);
+}
+
+/*
+** Return the actual size of the block pointed to by p, which is guaranteed
+** to have been allocated from chunk pChunk.
+*/
+static int chunkSize(Mem6Chunk *pChunk, void *p){
+ int iSize = 0;
+ if( p ){
+ int i = ((u8 *)p-pChunk->zPool)/pChunk->nAtom;
+ assert( i>=0 && i<pChunk->nBlock );
+ iSize = pChunk->nAtom * (1 << (pChunk->aCtrl[i]&CTRL_LOGSIZE));
+ }
+ return iSize;
+}
+
+/*
+** Return true if there are currently no outstanding allocations.
+*/
+static int chunkIsEmpty(Mem6Chunk *pChunk){
+ return (pChunk->nCheckedOut==0);
+}
+
+/*
+** Initialize the buffer zChunk, which is nChunk bytes in size, as
+** an Mem6Chunk object. Return a copy of the zChunk pointer.
+*/
+static Mem6Chunk *chunkInit(u8 *zChunk, int nChunk, int nMinAlloc){
+ int ii;
+ int iOffset;
+ Mem6Chunk *pChunk = (Mem6Chunk *)zChunk;
+
+ assert( nChunk>sizeof(Mem6Chunk) );
+ assert( nMinAlloc>sizeof(Mem6Link) );
+
+ memset(pChunk, 0, sizeof(Mem6Chunk));
+ pChunk->nAtom = nMinAlloc;
+ pChunk->nBlock = ((nChunk-sizeof(Mem6Chunk)) / (pChunk->nAtom+sizeof(u8)));
+
+ pChunk->zPool = (u8 *)&pChunk[1];
+ pChunk->aCtrl = &pChunk->zPool[pChunk->nBlock*pChunk->nAtom];
+
+ for(ii=0; ii<=mem6.nLogThreshold; ii++){
+ pChunk->aiFreelist[ii] = -1;
+ }
+
+ iOffset = 0;
+ for(ii=mem6.nLogThreshold; ii>=0; ii--){
+ int nAlloc = (1<<ii);
+ while( (iOffset+nAlloc)<=pChunk->nBlock ){
+ pChunk->aCtrl[iOffset] = ii | CTRL_FREE;
+ memsys6Link(pChunk, iOffset, ii);
+ iOffset += nAlloc;
+ }
+ }
+
+ return pChunk;
+}
+
+
+static void mem6Enter(void){
+ sqlite3_mutex_enter(mem6.mutex);
+}
+
+static void mem6Leave(void){
+ sqlite3_mutex_leave(mem6.mutex);
+}
+
+/*
+** Based on the number and size of the currently allocated chunks, return
+** the size of the next chunk to allocate, in bytes.
+*/
+static int nextChunkSize(void){
+ int iTotal = MIN_CHUNKSIZE;
+ Mem6Chunk *p;
+ for(p=mem6.pChunk; p; p=p->pNext){
+ iTotal = iTotal*2;
+ }
+ return iTotal;
+}
+
+static void freeChunk(Mem6Chunk *pChunk){
+ Mem6Chunk **pp = &mem6.pChunk;
+ for( pp=&mem6.pChunk; *pp!=pChunk; pp = &(*pp)->pNext );
+ *pp = (*pp)->pNext;
+ free(pChunk);
+}
+
+static void *memsys6Malloc(int nByte){
+ Mem6Chunk *pChunk;
+ void *p = 0;
+ int nTotal = nByte+8;
+ int iOffset = 0;
+
+ if( nTotal>mem6.nThreshold ){
+ p = malloc(nTotal);
+ }else{
+ int iLogsize = 0;
+ if( nTotal>(1<<LOG2_MINALLOC) ){
+ iLogsize = roundupLog2(nTotal) - LOG2_MINALLOC;
+ }
+ mem6Enter();
+ for(pChunk=mem6.pChunk; pChunk; pChunk=pChunk->pNext){
+ p = chunkMalloc(pChunk, iLogsize);
+ if( p ){
+ break;
+ }
+ }
+ if( !p ){
+ int iSize = nextChunkSize();
+ p = malloc(iSize);
+ if( p ){
+ pChunk = chunkInit((u8 *)p, iSize, mem6.nMinAlloc);
+ pChunk->pNext = mem6.pChunk;
+ mem6.pChunk = pChunk;
+ p = chunkMalloc(pChunk, iLogsize);
+ assert(p);
+ }
+ }
+ iOffset = ((u8*)p - (u8*)pChunk);
+ mem6Leave();
+ }
+
+ if( !p ){
+ return 0;
+ }
+ ((u32 *)p)[0] = iOffset;
+ ((u32 *)p)[1] = nByte;
+ return &((u32 *)p)[2];
+}
+
+static int memsys6Size(void *pPrior){
+ if( pPrior==0 ) return 0;
+ return ((u32*)pPrior)[-1];
+}
+
+static void memsys6Free(void *pPrior){
+ int iSlot;
+ void *p = &((u32 *)pPrior)[-2];
+ iSlot = ((u32 *)p)[0];
+ if( iSlot ){
+ Mem6Chunk *pChunk;
+ mem6Enter();
+ pChunk = (Mem6Chunk *)(&((u8 *)p)[-1 * iSlot]);
+ chunkFree(pChunk, p);
+ if( chunkIsEmpty(pChunk) ){
+ freeChunk(pChunk);
+ }
+ mem6Leave();
+ }else{
+ free(p);
+ }
+}
+
+static void *memsys6Realloc(void *p, int nByte){
+ void *p2;
+
+ if( p && nByte<=memsys6Size(p) ){
+ p2 = p;
+ }else{
+ p2 = memsys6Malloc(nByte);
+ if( p && p2 ){
+ memcpy(p2, p, memsys6Size(p));
+ memsys6Free(p);
+ }
+ }
+
+ return p2;
+}
+
+static int memsys6Roundup(int n){
+ if( n>mem6.nThreshold ){
+ return n;
+ }else{
+ return (1<<roundupLog2(n));
+ }
+}
+
+static int memsys6Init(void *pCtx){
+ u8 bMemstat = sqlite3Config.bMemstat;
+ mem6.nMinAlloc = (1 << LOG2_MINALLOC);
+ mem6.pChunk = 0;
+ mem6.nThreshold = sqlite3Config.nSmall;
+ if( mem6.nThreshold<=0 ){
+ mem6.nThreshold = SMALL_MALLOC_DEFAULT_THRESHOLD;
+ }
+ mem6.nLogThreshold = roundupLog2(mem6.nThreshold) - LOG2_MINALLOC;
+ if( !bMemstat ){
+ mem6.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+ }
+ return SQLITE_OK;
+}
+
+static void memsys6Shutdown(void *pCtx){
+ memset(&mem6, 0, sizeof(mem6));
+}
+
+/*
+** This routine is the only routine in this file with external
+** linkage. It returns a pointer to a static sqlite3_mem_methods
+** struct populated with the memsys6 methods.
+*/
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys6(void){
+ static const sqlite3_mem_methods memsys6Methods = {
+ memsys6Malloc,
+ memsys6Free,
+ memsys6Realloc,
+ memsys6Size,
+ memsys6Roundup,
+ memsys6Init,
+ memsys6Shutdown,
+ 0
+ };
+ return &memsys6Methods;
+}
+
+#endif
+
+/************** End of mem6.c ************************************************/
/************** Begin file mutex.c *******************************************/
/*
** 2007 August 14
@@ -14562,7 +15323,7 @@
**
** Memory allocation functions used throughout sqlite.
**
-** $Id: malloc.c,v 1.28 2008/07/14 12:38:21 drh Exp $
+** $Id: malloc.c,v 1.34 2008/08/05 17:53:23 drh Exp $
*/
/*
@@ -14659,9 +15420,10 @@
if( sqlite3Config.bCoreMutex ){
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
}
- if( sqlite3Config.pScratch && sqlite3Config.szScratch>=3000
- && sqlite3Config.nScratch>0 ){
+ if( sqlite3Config.pScratch && sqlite3Config.szScratch>=100
+ && sqlite3Config.nScratch>=0 ){
int i;
+ sqlite3Config.szScratch -= 4;
mem0.aScratchFree = (u32*)&((char*)sqlite3Config.pScratch)
[sqlite3Config.szScratch*sqlite3Config.nScratch];
for(i=0; i<sqlite3Config.nScratch; i++){ mem0.aScratchFree[i] = i; }
@@ -14671,8 +15433,13 @@
sqlite3Config.szScratch = 0;
}
if( sqlite3Config.pPage && sqlite3Config.szPage>=512
- && sqlite3Config.nPage>0 ){
+ && sqlite3Config.nPage>=1 ){
int i;
+ int overhead;
+ int sz = sqlite3Config.szPage;
+ int n = sqlite3Config.nPage;
+ overhead = (4*n + sz - 1)/sz;
+ sqlite3Config.nPage -= overhead;
mem0.aPageFree = (u32*)&((char*)sqlite3Config.pPage)
[sqlite3Config.szPage*sqlite3Config.nPage];
for(i=0; i<sqlite3Config.nPage; i++){ mem0.aPageFree[i] = i; }
@@ -14771,7 +15538,10 @@
sqlite3MallocAlarm(nFull);
p = sqlite3Config.m.xMalloc(nFull);
}
- if( p ) sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
+ if( p ){
+ nFull = sqlite3MallocSize(p);
+ sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
+ }
*pp = p;
return nFull;
}
@@ -14850,6 +15620,7 @@
sqlite3_mutex_leave(mem0.mutex);
i *= sqlite3Config.szScratch;
sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
+ sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
p = (void*)&((char*)sqlite3Config.pScratch)[i];
}
}
@@ -14862,6 +15633,7 @@
scratch_overflow:
if( sqlite3Config.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
+ sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
n = mallocWithAlarm(n, &p);
if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
sqlite3_mutex_leave(mem0.mutex);
@@ -14936,6 +15708,7 @@
i = mem0.aPageFree[--mem0.nPageFree];
sqlite3_mutex_leave(mem0.mutex);
i *= sqlite3Config.szPage;
+ sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
p = (void*)&((char*)sqlite3Config.pPage)[i];
}
@@ -14945,6 +15718,7 @@
page_overflow:
if( sqlite3Config.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
+ sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n);
n = mallocWithAlarm(n, &p);
if( p ) sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, n);
sqlite3_mutex_leave(mem0.mutex);
@@ -14987,7 +15761,7 @@
mem0.aPageFree[mem0.nPageFree++] = i;
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
sqlite3_mutex_leave(mem0.mutex);
-#ifndef NDEBUG
+#if !defined(NDEBUG) && 0
/* Assert that a duplicate was not just inserted into aPageFree[]. */
for(i=0; i<mem0.nPageFree-1; i++){
assert( mem0.aPageFree[i]!=mem0.aPageFree[mem0.nPageFree-1] );
@@ -14998,12 +15772,26 @@
}
/*
+** TRUE if p is a lookaside memory allocation from db
+*/
+static int isLookaside(sqlite3 *db, void *p){
+ return db && p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
+}
+
+/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
SQLITE_PRIVATE int sqlite3MallocSize(void *p){
return sqlite3Config.m.xSize(p);
}
+SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
+ if( isLookaside(db, p) ){
+ return db->lookaside.sz;
+ }else{
+ return sqlite3Config.m.xSize(p);
+ }
+}
/*
** Free memory previously obtained from sqlite3Malloc().
@@ -15021,6 +15809,21 @@
}
/*
+** Free memory that might be associated with a particular database
+** connection.
+*/
+SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
+ if( isLookaside(db, p) ){
+ LookasideSlot *pBuf = (LookasideSlot*)p;
+ pBuf->pNext = db->lookaside.pFree;
+ db->lookaside.pFree = pBuf;
+ db->lookaside.nOut--;
+ }else{
+ sqlite3_free(p);
+ }
+}
+
+/*
** Change the size of an existing memory allocation
*/
SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
@@ -15051,6 +15854,7 @@
pNew = sqlite3Config.m.xRealloc(pOld, nNew);
}
if( pNew ){
+ nNew = sqlite3MallocSize(pNew);
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
}
}
@@ -15101,26 +15905,53 @@
** the mallocFailed flag in the connection pointer.
*/
SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
- void *p = 0;
- if( !db || db->mallocFailed==0 ){
- p = sqlite3Malloc(n);
- if( !p && db ){
- db->mallocFailed = 1;
+ void *p;
+ if( db ){
+ LookasideSlot *pBuf;
+ if( db->mallocFailed ){
+ return 0;
+ }
+ if( db->lookaside.bEnabled && n<=db->lookaside.sz
+ && (pBuf = db->lookaside.pFree)!=0 ){
+ db->lookaside.pFree = pBuf->pNext;
+ db->lookaside.nOut++;
+ if( db->lookaside.nOut>db->lookaside.mxOut ){
+ db->lookaside.mxOut = db->lookaside.nOut;
+ }
+ return (void*)pBuf;
}
}
+ p = sqlite3Malloc(n);
+ if( !p && db ){
+ db->mallocFailed = 1;
+ }
return p;
}
/*
** Resize the block of memory pointed to by p to n bytes. If the
-** resize fails, set the mallocFailed flag inthe connection object.
+** resize fails, set the mallocFailed flag in the connection object.
*/
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
void *pNew = 0;
if( db->mallocFailed==0 ){
- pNew = sqlite3_realloc(p, n);
- if( !pNew ){
- db->mallocFailed = 1;
+ if( p==0 ){
+ return sqlite3DbMallocRaw(db, n);
+ }
+ if( isLookaside(db, p) ){
+ if( n<=db->lookaside.sz ){
+ return p;
+ }
+ pNew = sqlite3DbMallocRaw(db, n);
+ if( pNew ){
+ memcpy(pNew, p, db->lookaside.sz);
+ sqlite3DbFree(db, p);
+ }
+ }else{
+ pNew = sqlite3_realloc(p, n);
+ if( !pNew ){
+ db->mallocFailed = 1;
+ }
}
}
return pNew;
@@ -15134,7 +15965,7 @@
void *pNew;
pNew = sqlite3DbRealloc(db, p, n);
if( !pNew ){
- sqlite3_free(p);
+ sqlite3DbFree(db, p);
}
return pNew;
}
@@ -15146,37 +15977,30 @@
** called via macros that record the current file and line number in the
** ThreadData structure.
*/
-SQLITE_PRIVATE char *sqlite3StrDup(const char *z){
+SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
char *zNew;
- int n;
- if( z==0 ) return 0;
+ size_t n;
+ if( z==0 ){
+ return 0;
+ }
n = strlen(z)+1;
- zNew = sqlite3Malloc(n);
- if( zNew ) memcpy(zNew, z, n);
- return zNew;
-}
-SQLITE_PRIVATE char *sqlite3StrNDup(const char *z, int n){
- char *zNew;
- if( z==0 ) return 0;
- zNew = sqlite3Malloc(n+1);
+ assert( (n&0x7fffffff)==n );
+ zNew = sqlite3DbMallocRaw(db, (int)n);
if( zNew ){
memcpy(zNew, z, n);
- zNew[n] = 0;
- }
- return zNew;
-}
-
-SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
- char *zNew = sqlite3StrDup(z);
- if( z && !zNew ){
- db->mallocFailed = 1;
}
return zNew;
}
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
- char *zNew = sqlite3StrNDup(z, n);
- if( z && !zNew ){
- db->mallocFailed = 1;
+ char *zNew;
+ if( z==0 ){
+ return 0;
+ }
+ assert( (n&0x7fffffff)==n );
+ zNew = sqlite3DbMallocRaw(db, n+1);
+ if( zNew ){
+ memcpy(zNew, z, n);
+ zNew[n] = 0;
}
return zNew;
}
@@ -15193,7 +16017,7 @@
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
- sqlite3_free(*pz);
+ sqlite3DbFree(db, *pz);
*pz = z;
}
@@ -15234,7 +16058,7 @@
** an historical reference. Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
-** $Id: printf.c,v 1.92 2008/07/15 00:27:35 drh Exp $
+** $Id: printf.c,v 1.93 2008/07/28 19:34:53 drh Exp $
**
**************************************************************************
**
@@ -15974,7 +16798,7 @@
}else{
p->nAlloc = szNew;
}
- zNew = sqlite3Malloc( p->nAlloc );
+ zNew = sqlite3DbMallocRaw(p->db, p->nAlloc );
if( zNew ){
memcpy(zNew, p->zText, p->nChar);
sqlite3StrAccumReset(p);
@@ -15999,7 +16823,7 @@
if( p->zText ){
p->zText[p->nChar] = 0;
if( p->useMalloc && p->zText==p->zBase ){
- p->zText = sqlite3Malloc( p->nChar+1 );
+ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
@@ -16015,7 +16839,7 @@
*/
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
if( p->zText!=p->zBase ){
- sqlite3_free(p->zText);
+ sqlite3DbFree(p->db, p->zText);
}
p->zText = 0;
}
@@ -16025,6 +16849,7 @@
*/
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
p->zText = p->zBase = zBase;
+ p->db = 0;
p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
@@ -16043,6 +16868,7 @@
StrAccum acc;
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
+ acc.db = db;
sqlite3VXPrintf(&acc, 1, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.mallocFailed && db ){
@@ -16065,6 +16891,24 @@
}
/*
+** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
+** the string and before returnning. This routine is intended to be used
+** to modify an existing string. For example:
+**
+** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
+**
+*/
+SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ va_start(ap, zFormat);
+ z = sqlite3VMPrintf(db, zFormat, ap);
+ va_end(ap);
+ sqlite3DbFree(db, zStr);
+ return z;
+}
+
+/*
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.
*/
@@ -16281,7 +17125,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.62 2008/06/27 18:59:45 mihailim Exp $
+** $Id: utf.c,v 1.63 2008/07/29 11:25:14 danielk1977 Exp $
**
** Notes on UTF-8:
**
@@ -16323,7 +17167,7 @@
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
-** $Id: vdbeInt.h,v 1.149 2008/06/25 00:12:41 drh Exp $
+** $Id: vdbeInt.h,v 1.153 2008/08/02 03:50:39 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
@@ -16553,6 +17397,7 @@
typedef struct Fifo Fifo;
struct Fifo {
int nEntry; /* Total number of entries */
+ sqlite3 *db; /* The associated database connection */
FifoPage *pFirst; /* First page on the list */
FifoPage *pLast; /* Last page on the list */
};
@@ -16625,7 +17470,6 @@
Mem *pResultSet; /* Pointer to an array of results */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 changeCntOn; /* True to update the change-counter */
- u8 aborted; /* True if ROLLBACK in another VM causes an abort */
u8 expired; /* True if the VM needs to be recompiled */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
@@ -16698,7 +17542,7 @@
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(Cursor*,UnpackedRecord *,int,const unsigned char*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-SQLITE_PRIVATE int sqlite3VdbeIdxRowidLen(const u8*);
+SQLITE_PRIVATE int sqlite3VdbeIdxRowidLen(const u8*, int, int*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
@@ -16714,7 +17558,6 @@
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemDynamicify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int);
SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
@@ -16742,7 +17585,7 @@
SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo*);
+SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo*, sqlite3*);
SQLITE_PRIVATE int sqlite3VdbeFifoPush(Fifo*, i64);
SQLITE_PRIVATE int sqlite3VdbeFifoPop(Fifo*, i64*);
SQLITE_PRIVATE void sqlite3VdbeFifoClear(Fifo*);
@@ -16873,27 +17716,31 @@
** for unicode values 0x80 and greater. It do not change over-length
** encodings to 0xfffd as some systems recommend.
*/
+#define READ_UTF8(zIn, zTerm, c) \
+ c = *(zIn++); \
+ if( c>=0xc0 ){ \
+ c = sqlite3UtfTrans1[c-0xc0]; \
+ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
+ c = (c<<6) + (0x3f & *(zIn++)); \
+ } \
+ if( c<0x80 \
+ || (c&0xFFFFF800)==0xD800 \
+ || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
+ }
SQLITE_PRIVATE int sqlite3Utf8Read(
const unsigned char *z, /* First byte of UTF-8 character */
const unsigned char *zTerm, /* Pretend this byte is 0x00 */
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
){
- int c = *(z++);
- if( c>=0xc0 ){
- c = sqlite3UtfTrans1[c-0xc0];
- while( z!=zTerm && (*z & 0xc0)==0x80 ){
- c = (c<<6) + (0x3f & *(z++));
- }
- if( c<0x80
- || (c&0xFFFFF800)==0xD800
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
- }
+ int c;
+ READ_UTF8(z, zTerm, c);
*pzNext = z;
return c;
}
+
/*
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
@@ -16987,14 +17834,16 @@
if( desiredEnc==SQLITE_UTF16LE ){
/* UTF-8 -> UTF-16 Little-endian */
while( zIn<zTerm ){
- c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn);
+ /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
+ READ_UTF8(zIn, zTerm, c);
WRITE_UTF16LE(z, c);
}
}else{
assert( desiredEnc==SQLITE_UTF16BE );
/* UTF-8 -> UTF-16 Big-endian */
while( zIn<zTerm ){
- c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn);
+ /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
+ READ_UTF8(zIn, zTerm, c);
WRITE_UTF16BE(z, c);
}
}
@@ -17260,12 +18109,12 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.238 2008/07/11 16:19:10 drh Exp $
+** $Id: util.c,v 1.241 2008/07/28 19:34:54 drh Exp $
*/
/*
-** Return true if the floating point value is Not a Number.
+** Return true if the floating point value is Not a Number (NaN).
*/
SQLITE_PRIVATE int sqlite3IsNaN(double x){
/* This NaN test sometimes fails if compiled on GCC with -ffast-math.
@@ -17276,6 +18125,14 @@
** -O option since it can result in incorrect output for programs
** which depend on an exact implementation of IEEE or ISO
** rules/specifications for math functions.
+ **
+ ** Under MSVC, this NaN test may fail if compiled with a floating-
+ ** point precision mode other than /fp:precise. From the MSDN
+ ** documentation:
+ **
+ ** The compiler [with /fp:precise] will properly handle comparisons
+ ** involving NaN. For example, x != x evaluates to true if x is NaN
+ ** ...
*/
#ifdef __FAST_MATH__
# error SQLite will not work correctly with the -ffast-math option of GCC.
@@ -17291,11 +18148,15 @@
*/
SQLITE_PRIVATE int sqlite3Strlen(sqlite3 *db, const char *z){
const char *z2 = z;
+ int len;
+ size_t x;
while( *z2 ){ z2++; }
- if( z2 > &z[db->aLimit[SQLITE_LIMIT_LENGTH]] ){
+ x = z2 - z;
+ len = 0x7fffffff & x;
+ if( len!=x || len > db->aLimit[SQLITE_LIMIT_LENGTH] ){
return db->aLimit[SQLITE_LIMIT_LENGTH];
}else{
- return (int)(z2 - z);
+ return len;
}
}
@@ -17329,7 +18190,7 @@
va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
- sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3_free);
+ sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
}else{
sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
}
@@ -17355,10 +18216,11 @@
*/
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
va_list ap;
+ sqlite3 *db = pParse->db;
pParse->nErr++;
- sqlite3_free(pParse->zErrMsg);
+ sqlite3DbFree(db, pParse->zErrMsg);
va_start(ap, zFormat);
- pParse->zErrMsg = sqlite3VMPrintf(pParse->db, zFormat, ap);
+ pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
if( pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
@@ -17369,7 +18231,7 @@
** Clear the error message in pParse, if any
*/
SQLITE_PRIVATE void sqlite3ErrorClear(Parse *pParse){
- sqlite3_free(pParse->zErrMsg);
+ sqlite3DbFree(pParse->db, pParse->zErrMsg);
pParse->zErrMsg = 0;
pParse->nErr = 0;
}
@@ -18775,7 +19637,7 @@
**
** This file contains code that is specific to OS/2.
**
-** $Id: os_os2.c,v 1.50 2008/07/15 22:59:05 pweilbacher Exp $
+** $Id: os_os2.c,v 1.55 2008/07/29 18:49:29 pweilbacher Exp $
*/
@@ -18909,7 +19771,7 @@
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
-** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_
@@ -18950,6 +19812,21 @@
return val;
}
+#elif (defined(__GNUC__) && defined(__ppc__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned long long retval;
+ unsigned long junk;
+ __asm__ __volatile__ ("\n\
+ 1: mftbu %1\n\
+ mftb %L0\n\
+ mftbu %0\n\
+ cmpw %0,%1\n\
+ bne 1b"
+ : "=r" (retval), "=r" (junk));
+ return retval;
+ }
+
#else
#error Need implementation of sqlite3Hwtime() for your platform.
@@ -19537,7 +20414,6 @@
** Helper function to initialize the conversion objects from and to UTF-8.
*/
static void initUconvObjects( void ){
- printf("init them\n");
if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
ucUtf8 = NULL;
if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
@@ -19548,7 +20424,6 @@
** Helper function to free the conversion objects from and to UTF-8.
*/
static void freeUconvObjects( void ){
- printf("free them\n");
if ( ucUtf8 )
UniFreeUconvObject( ucUtf8 );
if ( uclCp )
@@ -19566,7 +20441,6 @@
static char *convertUtf8PathToCp( const char *in ){
UniChar tempPath[CCHMAXPATH];
char *out = (char *)calloc( CCHMAXPATH, 1 );
-printf("convertUtf8PathToCp(%s)\n", in);
if( !out )
return NULL;
@@ -19581,7 +20455,6 @@
/* conversion for current codepage which can be used for paths */
UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
- printf("%s -> Cp = %s\n", in, out);
return out;
}
@@ -19597,7 +20470,6 @@
char *convertCpPathToUtf8( const char *in ){
UniChar tempPath[CCHMAXPATH];
char *out = (char *)calloc( CCHMAXPATH, 1 );
-printf("convertCpPathToUtf8(%s)\n", in);
if( !out )
return NULL;
@@ -19612,7 +20484,6 @@
/* determine string for the conversion of UTF-8 which is CP1208 */
UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
- printf("%s -> Utf8 = %s\n", in, out);
return out;
}
@@ -19697,6 +20568,30 @@
/*
+** Turn a relative pathname into a full pathname. Write the full
+** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname
+** bytes in size.
+*/
+static int os2FullPathname(
+ sqlite3_vfs *pVfs, /* Pointer to vfs object */
+ const char *zRelative, /* Possibly relative input path */
+ int nFull, /* Size of output buffer in bytes */
+ char *zFull /* Output buffer */
+){
+ char *zRelativeCp = convertUtf8PathToCp( zRelative );
+ char zFullCp[CCHMAXPATH] = "\0";
+ char *zFullUTF;
+ APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp,
+ CCHMAXPATH );
+ free( zRelativeCp );
+ zFullUTF = convertCpPathToUtf8( zFullCp );
+ sqlite3_snprintf( nFull, zFull, zFullUTF );
+ free( zFullUTF );
+ return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
+}
+
+
+/*
** Open a file.
*/
static int os2Open(
@@ -19762,9 +20657,11 @@
if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL
| SQLITE_OPEN_SUBJOURNAL) ){
char pathUtf8[CCHMAXPATH];
- /*ulFileAttribute = FILE_HIDDEN; //for debugging, we want to make sure it is deleted*/
+#ifdef NDEBUG /* when debugging we want to make sure it is deleted */
+ ulFileAttribute = FILE_HIDDEN;
+#endif
ulFileAttribute = FILE_NORMAL;
- sqlite3OsFullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
+ os2FullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
OSTRACE1( "OPEN hidden/delete on close file attributes\n" );
}else{
@@ -19796,7 +20693,7 @@
pFile->pathToDel = NULL;
if( flags & SQLITE_OPEN_READWRITE ){
OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) );
- return os2Open( 0, zName, id,
+ return os2Open( pVfs, zName, id,
((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE),
pOutFlags );
}else{
@@ -19869,29 +20766,6 @@
}
-/*
-** Turn a relative pathname into a full pathname. Write the full
-** pathname into zFull[]. zFull[] will be at least pVfs->mxPathname
-** bytes in size.
-*/
-static int os2FullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zRelative, /* Possibly relative input path */
- int nFull, /* Size of output buffer in bytes */
- char *zFull /* Output buffer */
-){
- char *zRelativeCp = convertUtf8PathToCp( zRelative );
- char zFullCp[CCHMAXPATH];
- char *zFullUTF;
- APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp,
- CCHMAXPATH );
- free( zRelativeCp );
- zFullUTF = convertCpPathToUtf8( zFullCp );
- sqlite3_snprintf( nFull, zFull, zFullUTF );
- free( zFullUTF );
- return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-}
-
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
@@ -20068,8 +20942,6 @@
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int sqlite3_os_init(void){
- initUconvObjects();
-
static sqlite3_vfs os2Vfs = {
1, /* iVersion */
sizeof(os2File), /* szOsFile */
@@ -20092,6 +20964,7 @@
os2GetLastError /* xGetLastError */
};
sqlite3_vfs_register(&os2Vfs, 1);
+ initUconvObjects();
return SQLITE_OK;
}
SQLITE_API int sqlite3_os_end(void){
@@ -20117,7 +20990,7 @@
**
** This file contains code that is specific to Unix systems.
**
-** $Id: os_unix.c,v 1.193 2008/07/10 00:32:42 drh Exp $
+** $Id: os_unix.c,v 1.195 2008/07/30 17:28:04 drh Exp $
*/
#if SQLITE_OS_UNIX /* This file is used on unix only */
@@ -20312,7 +21185,7 @@
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
-** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_
@@ -20353,6 +21226,21 @@
return val;
}
+#elif (defined(__GNUC__) && defined(__ppc__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned long long retval;
+ unsigned long junk;
+ __asm__ __volatile__ ("\n\
+ 1: mftbu %1\n\
+ mftb %L0\n\
+ mftbu %0\n\
+ cmpw %0,%1\n\
+ bne 1b"
+ : "=r" (retval), "=r" (junk));
+ return retval;
+ }
+
#else
#error Need implementation of sqlite3Hwtime() for your platform.
@@ -20630,6 +21518,7 @@
int cnt; /* Number of SHARED locks held */
int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
int nRef; /* Number of pointers to this structure */
+ struct lockInfo *pNext, *pPrev; /* List of all lockInfo objects */
};
/*
@@ -20655,15 +21544,17 @@
int nLock; /* Number of outstanding locks */
int nPending; /* Number of pending close() operations */
int *aPending; /* Malloced space holding fd's awaiting a close() */
+ struct openCnt *pNext, *pPrev; /* List of all openCnt objects */
};
-/*
-** These hash tables map inodes and file descriptors (really, lockKey and
-** openKey structures) into lockInfo and openCnt structures. Access to
-** these hash tables must be protected by a mutex.
+/*
+** List of all lockInfo and openCnt objects. This used to be a hash
+** table. But the number of objects is rarely more than a dozen and
+** never exceeds a few thousand. And lookup is not on a critical
+** path oo a simple linked list will suffice.
*/
-static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
-static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
+static struct lockInfo *lockList = 0;
+static struct openCnt *openList = 0;
/*
** The locking styles are associated with the different file locking
@@ -20681,9 +21572,9 @@
** file systems that are known to be unsupported
*/
#define LOCKING_STYLE_POSIX 1
-#define LOCKING_STYLE_FLOCK 2
+#define LOCKING_STYLE_NONE 2
#define LOCKING_STYLE_DOTFILE 3
-#define LOCKING_STYLE_NONE 4
+#define LOCKING_STYLE_FLOCK 4
#define LOCKING_STYLE_AFP 5
/*
@@ -20842,7 +21733,17 @@
if( pLock ){
pLock->nRef--;
if( pLock->nRef==0 ){
- sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
+ if( pLock->pPrev ){
+ assert( pLock->pPrev->pNext==pLock );
+ pLock->pPrev->pNext = pLock->pNext;
+ }else{
+ assert( lockList==pLock );
+ lockList = pLock->pNext;
+ }
+ if( pLock->pNext ){
+ assert( pLock->pNext->pPrev==pLock );
+ pLock->pNext->pPrev = pLock->pPrev;
+ }
sqlite3_free(pLock);
}
}
@@ -20855,8 +21756,18 @@
if( pOpen ){
pOpen->nRef--;
if( pOpen->nRef==0 ){
- sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
- free(pOpen->aPending);
+ if( pOpen->pPrev ){
+ assert( pOpen->pPrev->pNext==pOpen );
+ pOpen->pPrev->pNext = pOpen->pNext;
+ }else{
+ assert( openList==pOpen );
+ openList = pOpen->pNext;
+ }
+ if( pOpen->pNext ){
+ assert( pOpen->pNext->pPrev==pOpen );
+ pOpen->pNext->pPrev = pOpen->pPrev;
+ }
+ sqlite3_free(pOpen->aPending);
sqlite3_free(pOpen);
}
}
@@ -20970,6 +21881,24 @@
return SQLITE_IOERR;
}
+ /* On OS X on an msdos filesystem, the inode number is reported
+ ** incorrectly for zero-size files. See ticket #3260. To work
+ ** around this problem (we consider it a bug in OS X, not SQLite)
+ ** we always increase the file size to 1 by writing a single byte
+ ** prior to accessing the inode number. The one byte written is
+ ** an ASCII 'S' character which also happens to be the first byte
+ ** in the header of every SQLite database. In this way, if there
+ ** is a race condition such that another thread has already populated
+ ** the first page of the database, no damage is done.
+ */
+ if( statbuf.st_size==0 ){
+ write(fd, "S", 1);
+ rc = fstat(fd, &statbuf);
+ if( rc!=0 ){
+ return SQLITE_IOERR;
+ }
+ }
+
memset(&key1, 0, sizeof(key1));
key1.dev = statbuf.st_dev;
key1.ino = statbuf.st_ino;
@@ -20982,9 +21911,11 @@
memset(&key2, 0, sizeof(key2));
key2.dev = statbuf.st_dev;
key2.ino = statbuf.st_ino;
- pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
+ pLock = lockList;
+ while( pLock && memcmp(&key1, &pLock->key, sizeof(key1)) ){
+ pLock = pLock->pNext;
+ }
if( pLock==0 ){
- struct lockInfo *pOld;
pLock = sqlite3_malloc( sizeof(*pLock) );
if( pLock==0 ){
rc = SQLITE_NOMEM;
@@ -20994,21 +21925,20 @@
pLock->nRef = 1;
pLock->cnt = 0;
pLock->locktype = 0;
- pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
- if( pOld!=0 ){
- assert( pOld==pLock );
- sqlite3_free(pLock);
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
+ pLock->pNext = lockList;
+ pLock->pPrev = 0;
+ if( lockList ) lockList->pPrev = pLock;
+ lockList = pLock;
}else{
pLock->nRef++;
}
*ppLock = pLock;
if( ppOpen!=0 ){
- pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
+ pOpen = openList;
+ while( pOpen && memcmp(&key2, &pOpen->key, sizeof(key2)) ){
+ pOpen = pOpen->pNext;
+ }
if( pOpen==0 ){
- struct openCnt *pOld;
pOpen = sqlite3_malloc( sizeof(*pOpen) );
if( pOpen==0 ){
releaseLockInfo(pLock);
@@ -21020,14 +21950,10 @@
pOpen->nLock = 0;
pOpen->nPending = 0;
pOpen->aPending = 0;
- pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
- if( pOld!=0 ){
- assert( pOld==pOpen );
- sqlite3_free(pOpen);
- releaseLockInfo(pLock);
- rc = SQLITE_NOMEM;
- goto exit_findlockinfo;
- }
+ pOpen->pNext = openList;
+ pOpen->pPrev = 0;
+ if( openList ) openList->pPrev = pOpen;
+ openList = pOpen;
}else{
pOpen->nRef++;
}
@@ -21391,6 +22317,16 @@
return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
+
+ /* When opening a zero-size database, the findLockInfo() procedure
+ ** writes a single byte into that file in order to work around a bug
+ ** in the OS-X msdos filesystem. In order to avoid problems with upper
+ ** layers, we need to report this file size as zero even though it is
+ ** really 1. Ticket #3260.
+ */
+ if( *pSize==1 ) *pSize = 0;
+
+
return SQLITE_OK;
}
@@ -21743,7 +22679,7 @@
for(i=0; i<pOpen->nPending; i++){
close(pOpen->aPending[i]);
}
- free(pOpen->aPending);
+ sqlite3_free(pOpen->aPending);
pOpen->nPending = 0;
pOpen->aPending = 0;
}
@@ -21792,7 +22728,7 @@
*/
int *aNew;
struct openCnt *pOpen = pFile->pOpen;
- aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+ aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
if( aNew==0 ){
/* If a malloc fails, just leak the file descriptor */
}else{
@@ -22289,7 +23225,7 @@
}
-#pragma mark No locking
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
** The nolockLockingContext is void
@@ -22316,8 +23252,6 @@
return closeUnixFile(id);
}
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
/*
** Information and control of an open file handle.
@@ -22366,8 +23300,13 @@
int h, /* Open file descriptor of file being opened */
int dirfd, /* Directory file descriptor */
sqlite3_file *pId, /* Write to the unixFile structure here */
- const char *zFilename /* Name of the file being opened */
+ const char *zFilename, /* Name of the file being opened */
+ int noLock /* Omit locking if true */
){
+ int eLockingStyle;
+ unixFile *pNew = (unixFile *)pId;
+ int rc = SQLITE_OK;
+
/* Macro to define the static contents of an sqlite3_io_methods
** structure for a unix backend file. Different locking methods
** require different functions for the xClose, xLock, xUnlock and
@@ -22390,17 +23329,21 @@
}
static sqlite3_io_methods aIoMethod[] = {
IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock)
+ ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
#ifdef SQLITE_ENABLE_LOCKING_STYLE
- ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
,IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock)
- ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
+ ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
,IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock)
#endif
};
-
- int eLockingStyle;
- unixFile *pNew = (unixFile *)pId;
- int rc = SQLITE_OK;
+ /* The order of the IOMETHODS macros above is important. It must be the
+ ** same order as the LOCKING_STYLE numbers
+ */
+ assert(LOCKING_STYLE_POSIX==1);
+ assert(LOCKING_STYLE_NONE==2);
+ assert(LOCKING_STYLE_DOTFILE==3);
+ assert(LOCKING_STYLE_FLOCK==4);
+ assert(LOCKING_STYLE_AFP==5);
assert( pNew->pLock==NULL );
assert( pNew->pOpen==NULL );
@@ -22410,12 +23353,11 @@
pNew->dirfd = dirfd;
SET_THREADID(pNew);
- assert(LOCKING_STYLE_POSIX==1);
- assert(LOCKING_STYLE_FLOCK==2);
- assert(LOCKING_STYLE_DOTFILE==3);
- assert(LOCKING_STYLE_NONE==4);
- assert(LOCKING_STYLE_AFP==5);
- eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+ if( noLock ){
+ eLockingStyle = LOCKING_STYLE_NONE;
+ }else{
+ eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+ }
switch( eLockingStyle ){
@@ -22599,6 +23541,7 @@
int dirfd = -1; /* Directory file descriptor */
int oflags = 0; /* Flags to pass to open() */
int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int noLock; /* True to omit locking primitives */
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
@@ -22694,7 +23637,8 @@
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif
- return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath);
+ noLock = eType!=SQLITE_OPEN_MAIN_DB;
+ return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock);
}
/*
@@ -23028,7 +23972,7 @@
**
** This file contains code that is specific to windows.
**
-** $Id: os_win.c,v 1.129 2008/06/26 10:41:19 danielk1977 Exp $
+** $Id: os_win.c,v 1.132 2008/07/31 01:34:34 shane Exp $
*/
#if SQLITE_OS_WIN /* This file is used for windows only */
@@ -23167,7 +24111,7 @@
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
-** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_
@@ -23208,6 +24152,21 @@
return val;
}
+#elif (defined(__GNUC__) && defined(__ppc__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned long long retval;
+ unsigned long junk;
+ __asm__ __volatile__ ("\n\
+ 1: mftbu %1\n\
+ mftb %L0\n\
+ mftbu %0\n\
+ cmpw %0,%1\n\
+ bne 1b"
+ : "=r" (retval), "=r" (junk));
+ return retval;
+ }
+
#else
#error Need implementation of sqlite3Hwtime() for your platform.
@@ -24314,7 +25273,7 @@
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
- int i, j;
+ size_t i, j;
char zTempPath[MAX_PATH+1];
if( sqlite3_temp_directory ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
@@ -24355,6 +25314,36 @@
return SQLITE_OK;
}
+/*
+** The return value of getLastErrorMsg
+** is zero if the error message fits in the buffer, or non-zero
+** otherwise (if the message was truncated).
+*/
+static int getLastErrorMsg(int nBuf, char *zBuf){
+ DWORD error = GetLastError();
+
+#if SQLITE_OS_WINCE
+ sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
+#else
+ /* FormatMessage returns 0 on failure. Otherwise it
+ ** returns the number of TCHARs written to the output
+ ** buffer, excluding the terminating null char.
+ */
+ if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ error,
+ 0,
+ zBuf,
+ nBuf-1,
+ 0))
+ {
+ sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
+ }
+#endif
+
+ return 0;
+}
+
/*
** Open a file.
@@ -24435,9 +25424,6 @@
NULL
);
}else{
-#if SQLITE_OS_WINCE
- return SQLITE_NOMEM;
-#else
h = CreateFileA((char*)zConverted,
dwDesiredAccess,
dwShareMode,
@@ -24446,7 +25432,6 @@
dwFlagsAndAttributes,
NULL
);
-#endif
}
if( h==INVALID_HANDLE_VALUE ){
free(zConverted);
@@ -24493,7 +25478,7 @@
** Note that windows does not allow a file to be deleted if some other
** process has it open. Sometimes a virus scanner or indexing program
** will open a journal file shortly after it is created in order to do
-** whatever does. While this other process is holding the
+** whatever it does. While this other process is holding the
** file open, we will be unable to delete it. To work around this
** problem, we delay 100 milliseconds and try to delete again. Up
** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
@@ -24507,6 +25492,7 @@
){
int cnt = 0;
int rc;
+ DWORD error;
void *zConverted = convertUtf8Filename(zFilename);
if( zConverted==0 ){
return SQLITE_NOMEM;
@@ -24515,21 +25501,22 @@
if( isNT() ){
do{
DeleteFileW(zConverted);
- }while( (rc = GetFileAttributesW(zConverted))!=0xffffffff
- && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
+ }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
+ || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
+ && (cnt++ < MX_DELETION_ATTEMPTS)
+ && (Sleep(100), 1) );
}else{
-#if SQLITE_OS_WINCE
- return SQLITE_NOMEM;
-#else
do{
DeleteFileA(zConverted);
- }while( (rc = GetFileAttributesA(zConverted))!=0xffffffff
- && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
-#endif
+ }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
+ || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
+ && (cnt++ < MX_DELETION_ATTEMPTS)
+ && (Sleep(100), 1) );
}
free(zConverted);
OSTRACE2("DELETE \"%s\"\n", zFilename);
- return rc==0xffffffff ? SQLITE_OK : SQLITE_IOERR_DELETE;
+ return ( (rc==INVALID_FILE_ATTRIBUTES)
+ && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
}
/*
@@ -24550,17 +25537,13 @@
if( isNT() ){
attr = GetFileAttributesW((WCHAR*)zConverted);
}else{
-#if SQLITE_OS_WINCE
- return SQLITE_NOMEM;
-#else
attr = GetFileAttributesA((char*)zConverted);
-#endif
}
free(zConverted);
switch( flags ){
case SQLITE_ACCESS_READ:
case SQLITE_ACCESS_EXISTS:
- rc = attr!=0xffffffff;
+ rc = attr!=INVALID_FILE_ATTRIBUTES;
break;
case SQLITE_ACCESS_READWRITE:
rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
@@ -24654,34 +25637,13 @@
if( isNT() ){
h = LoadLibraryW((WCHAR*)zConverted);
}else{
-#if SQLITE_OS_WINCE
- return 0;
-#else
h = LoadLibraryA((char*)zConverted);
-#endif
}
free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-#if SQLITE_OS_WINCE
- int error = GetLastError();
- if( error>0x7FFFFFF ){
- sqlite3_snprintf(nBuf, zBufOut, "OsError 0x%x", error);
- }else{
- sqlite3_snprintf(nBuf, zBufOut, "OsError %d", error);
- }
-#else
- FormatMessageA(
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- GetLastError(),
- 0,
- zBufOut,
- nBuf-1,
- 0
- );
-#endif
+ getLastErrorMsg(nBuf, zBufOut);
}
void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
#if SQLITE_OS_WINCE
@@ -24765,7 +25727,10 @@
#if SQLITE_OS_WINCE
SYSTEMTIME time;
GetSystemTime(&time);
- SystemTimeToFileTime(&time,&ft);
+ /* if SystemTimeToFileTime() fails, it returns zero. */
+ if (!SystemTimeToFileTime(&time,&ft)){
+ return 1;
+ }
#else
GetSystemTimeAsFileTime( &ft );
#endif
@@ -24779,8 +25744,38 @@
return 0;
}
+/*
+** The idea is that this function works like a combination of
+** GetLastError() and FormatMessage() on windows (or errno and
+** strerror_r() on unix). After an error is returned by an OS
+** function, SQLite calls this function with zBuf pointing to
+** a buffer of nBuf bytes. The OS layer should populate the
+** buffer with a nul-terminated UTF-8 encoded error message
+** describing the last IO error to have occured within the calling
+** thread.
+**
+** If the error message is too large for the supplied buffer,
+** it should be truncated. The return value of xGetLastError
+** is zero if the error message fits in the buffer, or non-zero
+** otherwise (if the message was truncated). If non-zero is returned,
+** then it is not necessary to include the nul-terminator character
+** in the output buffer.
+**
+** Not supplying an error message will have no adverse effect
+** on SQLite. It is fine to have an implementation that never
+** returns an error message:
+**
+** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+** assert(zBuf[0]=='\0');
+** return 0;
+** }
+**
+** However if an error message is supplied, it will be incorporated
+** by sqlite into the error message available to the user using
+** sqlite3_errmsg(), possibly making IO errors easier to debug.
+*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- return 0;
+ return getLastErrorMsg(nBuf, zBuf);
}
/*
@@ -25166,7 +26161,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.465 2008/07/11 03:34:10 drh Exp $
+** @(#) $Id: pager.c,v 1.469 2008/08/02 03:50:39 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
@@ -26041,7 +27036,7 @@
u32 len;
i64 szJ;
u32 cksum;
- int i;
+ u32 u; /* Unsigned loop counter */
unsigned char aMagic[8]; /* A buffer to hold the magic header */
zMaster[0] = '\0';
@@ -26069,8 +27064,8 @@
zMaster[len] = '\0';
/* See if the checksum matches the master journal name */
- for(i=0; i<len; i++){
- cksum -= zMaster[i];
+ for(u=0; u<len; u++){
+ cksum -= zMaster[u];
}
if( cksum ){
/* If the checksum doesn't add up, then one or more of the disk sectors
@@ -26993,7 +27988,7 @@
sqlite3_vfs *pVfs = pPager->pVfs;
i64 szJ; /* Size of the journal file in bytes */
u32 nRec; /* Number of Records in the journal */
- u32 i; /* Loop counter */
+ u32 u; /* Unsigned loop counter */
Pgno mxPg = 0; /* Size of the original file in pages */
int rc; /* Result code of a subroutine */
int res = 1; /* Value returned by sqlite3OsAccess() */
@@ -27076,7 +28071,7 @@
/* Copy original pages out of the journal and back into the database file.
*/
- for(i=0; i<nRec; i++){
+ for(u=0; u<nRec; u++){
rc = pager_playback_one_page(pPager, pPager->jfd, pPager->journalOff, 1);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){
@@ -28289,11 +29284,11 @@
** is hot. The pager_playback() routine will discover that the
** journal file is not really hot and will no-op.
*/
-static int hasHotJournal(Pager *pPager){
+static int hasHotJournal(Pager *pPager, int *pExists){
sqlite3_vfs *pVfs = pPager->pVfs;
- int res = 0;
+ int rc = SQLITE_OK;
+ *pExists = 0;
if( pPager->useJournal && pPager->fd->pMethods ){
- int rc;
int exists;
int locked;
@@ -28305,16 +29300,17 @@
if( rc==SQLITE_OK && exists && !locked ){
int nPage;
rc = sqlite3PagerPagecount(pPager, &nPage);
- if( rc==SQLITE_OK && nPage==0 ){
- sqlite3OsDelete(pVfs, pPager->zJournal, 0);
- exists = 0;
+ if( rc==SQLITE_OK ){
+ if( nPage==0 ){
+ sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ }else{
+ *pExists = 1;
+ }
}
}
-
- res = (rc!=SQLITE_OK ? -1 : (exists && !locked));
}
- return res;
+ return rc;
}
/*
@@ -28580,7 +29576,7 @@
*/
static int pagerSharedLock(Pager *pPager){
int rc = SQLITE_OK;
- int isHot = 0;
+ int isErrorReset = 0;
/* If this database is opened for exclusive access, has no outstanding
** page references and is in an error-state, now is the chance to clear
@@ -28589,7 +29585,7 @@
*/
if( !MEMDB && pPager->exclusiveMode && pPager->nRef==0 && pPager->errCode ){
if( pPager->journalOpen ){
- isHot = 1;
+ isErrorReset = 1;
}
pPager->errCode = SQLITE_OK;
pager_reset(pPager);
@@ -28603,9 +29599,10 @@
return pPager->errCode;
}
- if( pPager->state==PAGER_UNLOCK || isHot ){
+ if( pPager->state==PAGER_UNLOCK || isErrorReset ){
sqlite3_vfs *pVfs = pPager->pVfs;
if( !MEMDB ){
+ int isHotJournal;
assert( pPager->nRef==0 );
if( !pPager->noReadlock ){
rc = pager_wait_on_lock(pPager, SHARED_LOCK);
@@ -28619,12 +29616,13 @@
/* If a journal file exists, and there is no RESERVED lock on the
** database file, then it either needs to be played back or deleted.
*/
- rc = hasHotJournal(pPager);
- if( rc<0 ){
- rc = SQLITE_IOERR_NOMEM;
- goto failed;
+ if( !isErrorReset ){
+ rc = hasHotJournal(pPager, &isHotJournal);
+ if( rc!=SQLITE_OK ){
+ goto failed;
+ }
}
- if( rc==1 || isHot ){
+ if( isErrorReset || isHotJournal ){
/* Get an EXCLUSIVE lock on the database file. At this point it is
** important that a RESERVED lock is not obtained on the way to the
** EXCLUSIVE lock. If it were, another process might open the
@@ -28651,7 +29649,7 @@
** OsTruncate() call used in exclusive-access mode also requires
** a read/write file handle.
*/
- if( !isHot && pPager->journalOpen==0 ){
+ if( !isErrorReset && pPager->journalOpen==0 ){
int res;
rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
if( rc==SQLITE_OK ){
@@ -29722,6 +30720,9 @@
u32 change_counter;
int rc = SQLITE_OK;
+#ifndef SQLITE_ENABLE_ATOMIC_WRITE
+ assert( isDirect==0 ); /* isDirect is only true for atomic writes */
+#endif
if( !pPager->changeCountDone ){
/* Open page 1 of the file for writing. */
rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
@@ -29740,10 +30741,12 @@
change_counter++;
put32bits(((char*)PGHDR_TO_DATA(pPgHdr))+24, change_counter);
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
if( isDirect && pPager->fd->pMethods ){
const void *zBuf = PGHDR_TO_DATA(pPgHdr);
rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
}
+#endif
/* Release the page reference. */
sqlite3PagerUnref(pPgHdr);
@@ -30329,8 +31332,13 @@
** required that a statement transaction was not active, but this restriction
** has been removed (CREATE INDEX needs to move a page when a statement
** transaction is active).
+**
+** If the fourth argument, isCommit, is non-zero, then this page is being
+** moved as part of a database reorganization just before the transaction
+** is being committed. In this case, it is guaranteed that the database page
+** pPg refers to will not be written to again within this transaction.
*/
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
+SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
PgHdr *pPgOld; /* The page being overwritten. */
int h;
Pgno needSyncPgno = 0;
@@ -30343,7 +31351,15 @@
IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
pager_get_content(pPg);
- if( pPg->needSync ){
+
+ /* If the journal needs to be sync()ed before page pPg->pgno can
+ ** be written to, store pPg->pgno in local variable needSyncPgno.
+ **
+ ** If the isCommit flag is set, there is no need to remember that
+ ** the journal needs to be sync()ed before database page pPg->pgno
+ ** can be written to. The caller has already promised not to write to it.
+ */
+ if( pPg->needSync && !isCommit ){
needSyncPgno = pPg->pgno;
assert( pPg->inJournal || (int)pgno>pPager->origDbSize );
assert( pPg->dirty );
@@ -30390,8 +31406,9 @@
/* If needSyncPgno is non-zero, then the journal file needs to be
** sync()ed before any data is written to database file page needSyncPgno.
** Currently, no such page exists in the page-cache and the
- ** Pager.pInJournal bit has been set. This needs to be remedied by loading
- ** the page into the pager-cache and setting the PgHdr.needSync flag.
+ ** "is journaled" bitvec flag has been set. This needs to be remedied by
+ ** loading the page into the pager-cache and setting the PgHdr.needSync
+ ** flag.
**
** If the attempt to load the page into the page-cache fails, (due
** to a malloc() or IO failure), clear the bit in the pInJournal[]
@@ -30533,7 +31550,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btreeInt.h,v 1.26 2008/07/12 14:52:20 drh Exp $
+** $Id: btreeInt.h,v 1.30 2008/08/01 20:10:08 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -30794,8 +31811,6 @@
u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
u8 intKey; /* True if intkey flag is set */
u8 leaf; /* True if leaf flag is set */
- u8 zeroData; /* True if table stores keys only */
- u8 leafData; /* True if tables stores data on leaves only */
u8 hasData; /* True if this page stores data */
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
@@ -30805,6 +31820,7 @@
u16 idxParent; /* Index in parent of this node */
u16 nFree; /* Number of free bytes on the page */
u16 nCell; /* Number of cells on this page, local and ovfl */
+ u16 maskPage; /* Mask for page offset */
struct _OvflCell { /* Cells that will not fit on aData[] */
u8 *pCell; /* Pointers to the body of the overflow cell */
u16 idx; /* Insert this cell before idx-th non-overflow cell */
@@ -31047,7 +32063,7 @@
** this test.
*/
#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
-#define PTRMAP_PTROFFSET(pBt, pgno) (5*(pgno-ptrmapPageno(pBt, pgno)-1))
+#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
/*
@@ -31121,6 +32137,7 @@
int *anRef; /* Number of times each page is referenced */
int mxErr; /* Stop accumulating errors when this reaches zero */
int nErr; /* Number of messages written to zErrMsg so far */
+ int mallocFailed; /* A memory allocation error has occurred */
StrAccum errMsg; /* Accumulate the error message text here */
};
@@ -31458,7 +32475,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.482 2008/07/12 14:52:20 drh Exp $
+** $Id: btree.c,v 1.495 2008/08/02 17:36:46 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
@@ -31906,7 +32923,7 @@
if( rc!=SQLITE_OK ){
return rc;
}
- offset = PTRMAP_PTROFFSET(pBt, key);
+ offset = PTRMAP_PTROFFSET(iPtrmap, key);
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
@@ -31945,7 +32962,7 @@
}
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
- offset = PTRMAP_PTROFFSET(pBt, key);
+ offset = PTRMAP_PTROFFSET(iPtrmap, key);
assert( pEType!=0 );
*pEType = pPtrmap[offset];
if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
@@ -31955,7 +32972,11 @@
return SQLITE_OK;
}
-#endif /* SQLITE_OMIT_AUTOVACUUM */
+#else /* if defined SQLITE_OMIT_AUTOVACUUM */
+ #define ptrmapPut(w,x,y,z) SQLITE_OK
+ #define ptrmapGet(w,x,y,z) SQLITE_OK
+ #define ptrmapPutOvfl(y,z) SQLITE_OK
+#endif
/*
** Given a btree page and a cell index (0 means the first cell on
@@ -31964,8 +32985,8 @@
**
** This routine works only for pages that do not contain overflow cells.
*/
-#define findCell(pPage, iCell) \
- ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)]))
+#define findCell(P,I) \
+ ((P)->aData + ((P)->maskPage & get2byte(&(P)->aData[(P)->cellOffset+2*(I)])))
/*
** This a more complex version of findCell() that works for
@@ -32012,31 +33033,30 @@
assert( pPage->leaf==0 || pPage->leaf==1 );
n = pPage->childPtrSize;
assert( n==4-4*pPage->leaf );
- if( pPage->hasData ){
- n += getVarint32(&pCell[n], nPayload);
- }else{
- nPayload = 0;
- }
- pInfo->nData = nPayload;
if( pPage->intKey ){
- n += getVarint(&pCell[n], (u64 *)&pInfo->nKey);
+ if( pPage->hasData ){
+ n += getVarint32(&pCell[n], nPayload);
+ }else{
+ nPayload = 0;
+ }
+ n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
+ pInfo->nData = nPayload;
}else{
- u32 x;
- n += getVarint32(&pCell[n], x);
- pInfo->nKey = x;
- nPayload += x;
+ pInfo->nData = 0;
+ n += getVarint32(&pCell[n], nPayload);
+ pInfo->nKey = nPayload;
}
pInfo->nPayload = nPayload;
pInfo->nHeader = n;
- if( nPayload<=pPage->maxLocal ){
+ if( likely(nPayload<=pPage->maxLocal) ){
/* This is the (easy) common case where the entire payload fits
** on the local page. No overflow is required.
*/
int nSize; /* Total size of cell content in bytes */
+ nSize = nPayload + n;
pInfo->nLocal = nPayload;
pInfo->iOverflow = 0;
- nSize = nPayload + n;
- if( nSize<4 ){
+ if( (nSize & ~3)==0 ){
nSize = 4; /* Minimum cell size is 4 */
}
pInfo->nSize = nSize;
@@ -32319,27 +33339,38 @@
/*
** Decode the flags byte (the first byte of the header) for a page
** and initialize fields of the MemPage structure accordingly.
+**
+** Only the following combinations are supported. Anything different
+** indicates a corrupt database files:
+**
+** PTF_ZERODATA
+** PTF_ZERODATA | PTF_LEAF
+** PTF_LEAFDATA | PTF_INTKEY
+** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
*/
-static void decodeFlags(MemPage *pPage, int flagByte){
+static int decodeFlags(MemPage *pPage, int flagByte){
BtShared *pBt; /* A copy of pPage->pBt */
assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0;
- pPage->zeroData = (flagByte & PTF_ZERODATA)!=0;
- pPage->leaf = (flagByte & PTF_LEAF)!=0;
- pPage->childPtrSize = 4*(pPage->leaf==0);
+ pPage->leaf = flagByte>>3; assert( PTF_LEAF == 1<<3 );
+ flagByte &= ~PTF_LEAF;
+ pPage->childPtrSize = 4-4*pPage->leaf;
pBt = pPage->pBt;
- if( flagByte & PTF_LEAFDATA ){
- pPage->leafData = 1;
+ if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
+ pPage->intKey = 1;
+ pPage->hasData = pPage->leaf;
pPage->maxLocal = pBt->maxLeaf;
pPage->minLocal = pBt->minLeaf;
- }else{
- pPage->leafData = 0;
+ }else if( flagByte==PTF_ZERODATA ){
+ pPage->intKey = 0;
+ pPage->hasData = 0;
pPage->maxLocal = pBt->maxLocal;
pPage->minLocal = pBt->minLocal;
+ }else{
+ return SQLITE_CORRUPT_BKPT;
}
- pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
+ return SQLITE_OK;
}
/*
@@ -32367,9 +33398,6 @@
int cellOffset; /* Offset from start of page to first cell pointer */
int nFree; /* Number of unused bytes on the page */
int top; /* First byte of the cell content area */
- u8 *pOff; /* Iterator used to check all cell offsets are in range */
- u8 *pEnd; /* Pointer to end of cell offset array */
- u8 mask; /* Mask of bits that must be zero in MSB of cell offsets */
pBt = pPage->pBt;
assert( pBt!=0 );
@@ -32389,7 +33417,9 @@
}
hdr = pPage->hdrOffset;
data = pPage->aData;
- decodeFlags(pPage, data[hdr]);
+ if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
+ assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
+ pPage->maskPage = pBt->pageSize - 1;
pPage->nOverflow = 0;
pPage->idxShift = 0;
usableSize = pBt->usableSize;
@@ -32429,13 +33459,25 @@
return SQLITE_CORRUPT_BKPT;
}
- /* Check that all the offsets in the cell offset array are within range. */
- mask = ~(((u8)(pBt->pageSize>>8))-1);
- pEnd = &data[cellOffset + pPage->nCell*2];
- for(pOff=&data[cellOffset]; pOff!=pEnd && !((*pOff)&mask); pOff+=2);
- if( pOff!=pEnd ){
- return SQLITE_CORRUPT_BKPT;
+#if 0
+ /* Check that all the offsets in the cell offset array are within range.
+ **
+ ** Omitting this consistency check and using the pPage->maskPage mask
+ ** to prevent overrunning the page buffer in findCell() results in a
+ ** 2.5% performance gain.
+ */
+ {
+ u8 *pOff; /* Iterator used to check all cell offsets are in range */
+ u8 *pEnd; /* Pointer to end of cell offset array */
+ u8 mask; /* Mask of bits that must be zero in MSB of cell offsets */
+ mask = ~(((u8)(pBt->pageSize>>8))-1);
+ pEnd = &data[cellOffset + pPage->nCell*2];
+ for(pOff=&data[cellOffset]; pOff!=pEnd && !((*pOff)&mask); pOff+=2);
+ if( pOff!=pEnd ){
+ return SQLITE_CORRUPT_BKPT;
+ }
}
+#endif
pPage->isInit = 1;
return SQLITE_OK;
@@ -32456,7 +33498,7 @@
assert( sqlite3PagerGetData(pPage->pDbPage) == data );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( sqlite3_mutex_held(pBt->mutex) );
- memset(&data[hdr], 0, pBt->usableSize - hdr);
+ /*memset(&data[hdr], 0, pBt->usableSize - hdr);*/
data[hdr] = flags;
first = hdr + 8 + 4*((flags&PTF_LEAF)==0);
memset(&data[hdr+1], 0, 4);
@@ -32467,6 +33509,8 @@
pPage->hdrOffset = hdr;
pPage->cellOffset = first;
pPage->nOverflow = 0;
+ assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
+ pPage->maskPage = pBt->pageSize - 1;
pPage->idxShift = 0;
pPage->nCell = 0;
pPage->isInit = 1;
@@ -33440,6 +34484,18 @@
return rc;
}
+/*
+** Return the size of the database file in pages. Or return -1 if
+** there is any kind of error.
+*/
+static int pagerPagecount(Pager *pPager){
+ int rc;
+ int nPage;
+ rc = sqlite3PagerPagecount(pPager, &nPage);
+ return (rc==SQLITE_OK?nPage:-1);
+}
+
+
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
@@ -33560,7 +34616,8 @@
MemPage *pDbPage, /* Open page to move */
u8 eType, /* Pointer map 'type' entry for pDbPage */
Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
- Pgno iFreePage /* The location to move pDbPage to */
+ Pgno iFreePage, /* The location to move pDbPage to */
+ int isCommit
){
MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */
Pgno iDbPage = pDbPage->pgno;
@@ -33575,7 +34632,7 @@
/* Move page iDbPage from its current location to page number iFreePage */
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
iDbPage, iFreePage, iPtrPage, eType));
- rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage);
+ rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -33627,13 +34684,6 @@
return rc;
}
-static int pagerPagecount(Pager *pPager){
- int rc;
- int nPage;
- rc = sqlite3PagerPagecount(pPager, &nPage);
- return (rc==SQLITE_OK?nPage:-1);
-}
-
/* Forward declaration required by incrVacuumStep(). */
static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
@@ -33725,7 +34775,7 @@
rc = sqlite3PagerWrite(pLastPg->pDbPage);
if( rc==SQLITE_OK ){
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg);
+ rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
}
releasePage(pLastPg);
if( rc!=SQLITE_OK ){
@@ -35204,7 +36254,7 @@
}
if( c==0 ){
pCur->info.nKey = nCellKey;
- if( pPage->leafData && !pPage->leaf ){
+ if( pPage->intKey && !pPage->leaf ){
lwr = pCur->idx;
upr = lwr - 1;
break;
@@ -35331,7 +36381,7 @@
pPage = pCur->pPage;
}while( pCur->idx>=pPage->nCell );
*pRes = 0;
- if( pPage->leafData ){
+ if( pPage->intKey ){
rc = sqlite3BtreeNext(pCur, pRes);
}else{
rc = SQLITE_OK;
@@ -35398,7 +36448,7 @@
pCur->idx--;
pCur->info.nSize = 0;
pCur->validNKey = 0;
- if( pPage->leafData && !pPage->leaf ){
+ if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, pRes);
}else{
rc = SQLITE_OK;
@@ -35702,15 +36752,13 @@
memset(pPage->aData, 0, pPage->pBt->pageSize);
#endif
-#ifndef SQLITE_OMIT_AUTOVACUUM
/* If the database supports auto-vacuum, write an entry in the pointer-map
** to indicate that the page is free.
*/
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
if( rc ) return rc;
}
-#endif
if( n==0 ){
/* This is the first free page */
@@ -35941,12 +36989,23 @@
return SQLITE_OK;
}
+
/*
** Change the MemPage.pParent pointer on the page whose number is
** given in the second argument so that MemPage.pParent holds the
** pointer in the third argument.
-*/
-static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
+**
+** If the final argument, updatePtrmap, is non-zero and the database
+** is an auto-vacuum database, then the pointer-map entry for pgno
+** is updated.
+*/
+static int reparentPage(
+ BtShared *pBt, /* B-Tree structure */
+ Pgno pgno, /* Page number of child being adopted */
+ MemPage *pNewParent, /* New parent of pgno */
+ int idx, /* Index of child page pgno in pNewParent */
+ int updatePtrmap /* If true, update pointer-map for pgno */
+){
MemPage *pThis;
DbPage *pDbPage;
@@ -35969,11 +37028,26 @@
sqlite3PagerUnref(pDbPage);
}
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM && updatePtrmap ){
return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno);
}
+
+#ifndef NDEBUG
+ /* If the updatePtrmap flag was clear, assert that the entry in the
+ ** pointer-map is already correct.
+ */
+ if( ISAUTOVACUUM ){
+ pDbPage = sqlite3PagerLookup(pBt->pPager,PTRMAP_PAGENO(pBt,pgno));
+ if( pDbPage ){
+ u8 eType;
+ Pgno ii;
+ int rc = ptrmapGet(pBt, pgno, &eType, &ii);
+ assert( rc==SQLITE_OK && ii==pNewParent->pgno && eType==PTRMAP_BTREE );
+ sqlite3PagerUnref(pDbPage);
+ }
+ }
#endif
+
return SQLITE_OK;
}
@@ -35988,23 +37062,26 @@
**
** This routine gets called after you memcpy() one page into
** another.
+**
+** If updatePtrmap is true, then the pointer-map entries for all child
+** pages of pPage are updated.
*/
-static int reparentChildPages(MemPage *pPage){
- int i;
- BtShared *pBt = pPage->pBt;
+static int reparentChildPages(MemPage *pPage, int updatePtrmap){
int rc = SQLITE_OK;
-
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- if( pPage->leaf ) return SQLITE_OK;
+ if( !pPage->leaf ){
+ int i;
+ BtShared *pBt = pPage->pBt;
+ Pgno iRight = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- for(i=0; i<pPage->nCell; i++){
- u8 *pCell = findCell(pPage, i);
- rc = reparentPage(pBt, get4byte(pCell), pPage, i);
- if( rc!=SQLITE_OK ) return rc;
+ for(i=0; i<pPage->nCell; i++){
+ u8 *pCell = findCell(pPage, i);
+ rc = reparentPage(pBt, get4byte(pCell), pPage, i, updatePtrmap);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ rc = reparentPage(pBt, iRight, pPage, i, updatePtrmap);
+ pPage->idxShift = 0;
}
- rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]),
- pPage, i);
- pPage->idxShift = 0;
return rc;
}
@@ -36275,12 +37352,11 @@
put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
-#ifndef SQLITE_OMIT_AUTOVACUUM
/* If this is an auto-vacuum database, update the pointer map
** with entries for the new page, and any pointer from the
** cell on the page to an overflow page.
*/
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
if( rc==SQLITE_OK ){
rc = ptrmapPutOvfl(pNew, 0);
@@ -36290,7 +37366,6 @@
return rc;
}
}
-#endif
/* Release the reference to the new page and balance the parent page,
** in case the divider cell inserted caused it to become overfull.
@@ -36362,9 +37437,7 @@
u8 *aCopy[NB]; /* Space for holding data of apCopy[] */
u8 *aSpace1; /* Space for copies of dividers cells before balance */
u8 *aSpace2 = 0; /* Space for overflow dividers cells after balance */
-#ifndef SQLITE_OMIT_AUTOVACUUM
u8 *aFrom = 0;
-#endif
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
@@ -36393,12 +37466,12 @@
*/
if( pPage->leaf &&
pPage->intKey &&
- pPage->leafData &&
pPage->nOverflow==1 &&
pPage->aOvfl[0].idx==pPage->nCell &&
pPage->pParent->pgno!=1 &&
get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
){
+ assert( pPage->intKey );
/*
** TODO: Check the siblings to the left of pPage. It may be that
** they are not full and no new page is required.
@@ -36500,11 +37573,9 @@
}
aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
assert( ((aSpace1 - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
aFrom = &aSpace1[pBt->pageSize];
}
-#endif
aSpace2 = sqlite3PageMalloc(pBt->pageSize);
if( aSpace2==0 ){
rc = SQLITE_NOMEM;
@@ -36542,16 +37613,15 @@
*/
nCell = 0;
leafCorrection = pPage->leaf*4;
- leafData = pPage->leafData && pPage->leaf;
+ leafData = pPage->hasData;
for(i=0; i<nOld; i++){
MemPage *pOld = apCopy[i];
int limit = pOld->nCell+pOld->nOverflow;
for(j=0; j<limit; j++){
assert( nCell<nMaxCells );
apCell[nCell] = findOverflowCell(pOld, j);
- szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
+ if( ISAUTOVACUUM ){
int a;
aFrom[nCell] = i;
for(a=0; a<pOld->nOverflow; a++){
@@ -36561,7 +37631,6 @@
}
}
}
-#endif
nCell++;
}
if( i<nOld-1 ){
@@ -36583,11 +37652,9 @@
assert( iSpace1<=pBt->pageSize );
memcpy(pTemp, apDiv[i], sz);
apCell[nCell] = pTemp+leafCorrection;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
aFrom[nCell] = 0xFF;
}
-#endif
dropCell(pParent, nxDiv, sz);
szCell[nCell] -= leafCorrection;
assert( get4byte(pTemp)==pgnoOld[i] );
@@ -36769,24 +37836,25 @@
assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
assert( pNew->nOverflow==0 );
-#ifndef SQLITE_OMIT_AUTOVACUUM
/* If this is an auto-vacuum database, update the pointer map entries
** that point to the siblings that were rearranged. These can be: left
** children of cells, the right-child of the page, or overflow pages
** pointed to by cells.
*/
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
for(k=j; k<cntNew[i]; k++){
assert( k<nMaxCells );
if( aFrom[k]==0xFF || apCopy[aFrom[k]]->pgno!=pNew->pgno ){
rc = ptrmapPutOvfl(pNew, k-j);
+ if( rc==SQLITE_OK && leafCorrection==0 ){
+ rc = ptrmapPut(pBt, get4byte(apCell[k]), PTRMAP_BTREE, pNew->pgno);
+ }
if( rc!=SQLITE_OK ){
goto balance_cleanup;
}
}
}
}
-#endif
j = cntNew[i];
@@ -36804,6 +37872,14 @@
pTemp = &aSpace2[iSpace2];
if( !pNew->leaf ){
memcpy(&pNew->aData[8], pCell, 4);
+ if( ISAUTOVACUUM
+ && (aFrom[j]==0xFF || apCopy[aFrom[j]]->pgno!=pNew->pgno)
+ ){
+ rc = ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
+ }
}else if( leafData ){
/* If the tree is a leaf-data tree, and the siblings are leaves,
** then there is no divider cell in apCell[]. Instead, the divider
@@ -36840,27 +37916,41 @@
rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
if( rc!=SQLITE_OK ) goto balance_cleanup;
put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
-#ifndef SQLITE_OMIT_AUTOVACUUM
+
/* If this is an auto-vacuum database, and not a leaf-data tree,
** then update the pointer map with an entry for the overflow page
** that the cell just inserted points to (if any).
*/
- if( pBt->autoVacuum && !leafData ){
+ if( ISAUTOVACUUM && !leafData ){
rc = ptrmapPutOvfl(pParent, nxDiv);
if( rc!=SQLITE_OK ){
goto balance_cleanup;
}
}
-#endif
j++;
nxDiv++;
}
+
+ /* Set the pointer-map entry for the new sibling page. */
+ if( ISAUTOVACUUM ){
+ rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
+ }
}
assert( j==nCell );
assert( nOld>0 );
assert( nNew>0 );
if( (pageFlags & PTF_LEAF)==0 ){
- memcpy(&apNew[nNew-1]->aData[8], &apCopy[nOld-1]->aData[8], 4);
+ u8 *zChild = &apCopy[nOld-1]->aData[8];
+ memcpy(&apNew[nNew-1]->aData[8], zChild, 4);
+ if( ISAUTOVACUUM ){
+ rc = ptrmapPut(pBt, get4byte(zChild), PTRMAP_BTREE, apNew[nNew-1]->pgno);
+ if( rc!=SQLITE_OK ){
+ goto balance_cleanup;
+ }
+ }
}
if( nxDiv==pParent->nCell+pParent->nOverflow ){
/* Right-most sibling is the right-most child of pParent */
@@ -36875,10 +37965,10 @@
** Reparent children of all cells.
*/
for(i=0; i<nNew; i++){
- rc = reparentChildPages(apNew[i]);
+ rc = reparentChildPages(apNew[i], 0);
if( rc!=SQLITE_OK ) goto balance_cleanup;
}
- rc = reparentChildPages(pParent);
+ rc = reparentChildPages(pParent, 0);
if( rc!=SQLITE_OK ) goto balance_cleanup;
/*
@@ -36986,10 +38076,9 @@
TRACE(("BALANCE: transfer child %d into root %d\n",
pChild->pgno, pPage->pgno));
}
- rc = reparentChildPages(pPage);
+ rc = reparentChildPages(pPage, 1);
assert( pPage->nOverflow==0 );
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
int i;
for(i=0; i<pPage->nCell; i++){
rc = ptrmapPutOvfl(pPage, i);
@@ -36998,7 +38087,6 @@
}
}
}
-#endif
releasePage(pChild);
}
end_shallow_balance:
@@ -37053,8 +38141,7 @@
zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
+ if( ISAUTOVACUUM ){
int i;
rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
if( rc ) goto balancedeeper_out;
@@ -37064,9 +38151,11 @@
goto balancedeeper_out;
}
}
+ rc = reparentChildPages(pChild, 1);
+ }
+ if( rc==SQLITE_OK ){
+ rc = balance_nonroot(pChild);
}
-#endif
- rc = balance_nonroot(pChild);
balancedeeper_out:
releasePage(pChild);
@@ -37219,7 +38308,7 @@
pPage = pCur->pPage;
assert( pPage->intKey || nKey>=0 );
- assert( pPage->leaf || !pPage->leafData );
+ assert( pPage->leaf || !pPage->intKey );
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
pCur->pgnoRoot, nKey, nData, pPage->pgno,
loc==0 ? "overwrite" : "new entry"));
@@ -37335,7 +38424,7 @@
unsigned char *pNext;
int notUsed;
unsigned char *tempCell = 0;
- assert( !pPage->leafData );
+ assert( !pPage->intKey );
sqlite3BtreeGetTempCursor(pCur, &leafCur);
rc = sqlite3BtreeNext(&leafCur, ¬Used);
if( rc==SQLITE_OK ){
@@ -37478,7 +38567,7 @@
releasePage(pRoot);
return rc;
}
- rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove);
+ rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
releasePage(pRoot);
/* Obtain the page at pgnoRoot */
@@ -37686,7 +38775,7 @@
if( rc!=SQLITE_OK ){
return rc;
}
- rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable);
+ rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
releasePage(pMove);
if( rc!=SQLITE_OK ){
return rc;
@@ -37873,6 +38962,9 @@
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
+ if( pCheck->errMsg.mallocFailed ){
+ pCheck->mallocFailed = 1;
+ }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -38116,7 +39208,9 @@
data = pPage->aData;
hdr = pPage->hdrOffset;
hit = sqlite3PageMalloc( pBt->pageSize );
- if( hit ){
+ if( hit==0 ){
+ pCheck->mallocFailed = 1;
+ }else{
memset(hit, 0, usableSize );
memset(hit, 1, get2byte(&data[hdr+5]));
nCell = get2byte(&data[hdr+3]);
@@ -38172,10 +39266,10 @@
** an array of pages numbers were each page number is the root page of
** a table. nRoot is the number of entries in aRoot.
**
-** If everything checks out, this routine returns NULL. If something is
-** amiss, an error message is written into memory obtained from malloc()
-** and a pointer to that error message is returned. The calling function
-** is responsible for freeing the error message when it is done.
+** Write the number of error seen in *pnErr. Except for some memory
+** allocation errors, nn error message is held in memory obtained from
+** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
+** returned.
*/
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
Btree *p, /* The btree to be checked */
@@ -38194,14 +39288,16 @@
pBt->db = p->db;
nRef = sqlite3PagerRefcount(pBt->pPager);
if( lockBtreeWithRetry(p)!=SQLITE_OK ){
+ *pnErr = 1;
sqlite3BtreeLeave(p);
- return sqlite3StrDup("Unable to acquire a read lock on the database");
+ return sqlite3DbStrDup(0, "cannot acquire a read lock on the database");
}
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
sCheck.nPage = pagerPagecount(sCheck.pPager);
sCheck.mxErr = mxErr;
sCheck.nErr = 0;
+ sCheck.mallocFailed = 0;
*pnErr = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->nTrunc!=0 ){
@@ -38218,8 +39314,7 @@
unlockBtreeIfUnused(pBt);
*pnErr = 1;
sqlite3BtreeLeave(p);
- return sqlite3MPrintf(p->db, "Unable to malloc %d bytes",
- (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
+ return 0;
}
for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
i = PENDING_BYTE_PAGE(pBt);
@@ -38281,6 +39376,11 @@
*/
sqlite3BtreeLeave(p);
sqlite3_free(sCheck.anRef);
+ if( sCheck.mallocFailed ){
+ sqlite3StrAccumReset(&sCheck.errMsg);
+ *pnErr = sCheck.nErr+1;
+ return 0;
+ }
*pnErr = sCheck.nErr;
if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
return sqlite3StrAccumFinish(&sCheck.errMsg);
@@ -38706,7 +39806,7 @@
** This file implements a FIFO queue of rowids used for processing
** UPDATE and DELETE statements.
**
-** $Id: vdbefifo.c,v 1.7 2008/06/15 02:51:48 drh Exp $
+** $Id: vdbefifo.c,v 1.8 2008/07/28 19:34:54 drh Exp $
*/
/*
@@ -38725,12 +39825,12 @@
** Allocate a new FifoPage and return a pointer to it. Return NULL if
** we run out of memory. Leave space on the page for nEntry entries.
*/
-static FifoPage *allocateFifoPage(int nEntry){
+static FifoPage *allocateFifoPage(sqlite3 *db, int nEntry){
FifoPage *pPage;
if( nEntry>FIFOSIZE_MAX ){
nEntry = FIFOSIZE_MAX;
}
- pPage = sqlite3Malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
+ pPage = sqlite3DbMallocRaw(db, sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
if( pPage ){
pPage->nSlot = nEntry;
pPage->iWrite = 0;
@@ -38743,8 +39843,9 @@
/*
** Initialize a Fifo structure.
*/
-SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo *pFifo){
+SQLITE_PRIVATE void sqlite3VdbeFifoInit(Fifo *pFifo, sqlite3 *db){
memset(pFifo, 0, sizeof(*pFifo));
+ pFifo->db = db;
}
/*
@@ -38756,12 +39857,13 @@
FifoPage *pPage;
pPage = pFifo->pLast;
if( pPage==0 ){
- pPage = pFifo->pLast = pFifo->pFirst = allocateFifoPage(FIFOSIZE_FIRST);
+ pPage = pFifo->pLast = pFifo->pFirst =
+ allocateFifoPage(pFifo->db, FIFOSIZE_FIRST);
if( pPage==0 ){
return SQLITE_NOMEM;
}
}else if( pPage->iWrite>=pPage->nSlot ){
- pPage->pNext = allocateFifoPage(pFifo->nEntry);
+ pPage->pNext = allocateFifoPage(pFifo->db, pFifo->nEntry);
if( pPage->pNext==0 ){
return SQLITE_NOMEM;
}
@@ -38793,7 +39895,7 @@
pFifo->nEntry--;
if( pPage->iRead>=pPage->iWrite ){
pFifo->pFirst = pPage->pNext;
- sqlite3_free(pPage);
+ sqlite3DbFree(pFifo->db, pPage);
if( pFifo->nEntry==0 ){
assert( pFifo->pLast==pPage );
pFifo->pLast = 0;
@@ -38814,9 +39916,9 @@
FifoPage *pPage, *pNextPage;
for(pPage=pFifo->pFirst; pPage; pPage=pNextPage){
pNextPage = pPage->pNext;
- sqlite3_free(pPage);
+ sqlite3DbFree(pFifo->db, pPage);
}
- sqlite3VdbeFifoInit(pFifo);
+ sqlite3VdbeFifoInit(pFifo, pFifo->db);
}
/************** End of vdbefifo.c ********************************************/
@@ -38838,7 +39940,7 @@
** only within the VDBE. Interface routines refer to a Mem using the
** name sqlite_value
**
-** $Id: vdbemem.c,v 1.118 2008/07/09 16:51:51 drh Exp $
+** $Id: vdbemem.c,v 1.121 2008/08/01 20:10:09 drh Exp $
*/
/*
@@ -38903,7 +40005,7 @@
);
if( n<32 ) n = 32;
- if( sqlite3MallocSize(pMem->zMalloc)<n ){
+ if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
if( preserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
if( !pMem->z ){
@@ -38911,7 +40013,7 @@
}
preserve = 0;
}else{
- sqlite3_free(pMem->zMalloc);
+ sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
}
@@ -38930,11 +40032,14 @@
}
/*
-** Make the given Mem object MEM_Dyn.
+** Make the given Mem object MEM_Dyn. In other words, make it so
+** that any TEXT or BLOB content is stored in memory obtained from
+** malloc(). In this way, we know that the memory is safe to be
+** overwritten or altered.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
-SQLITE_PRIVATE int sqlite3VdbeMemDynamicify(Mem *pMem){
+SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
int f;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
expandBlob(pMem);
@@ -38981,16 +40086,6 @@
/*
-** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes
-** of the Mem.z[] array can be modified.
-**
-** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
- return sqlite3VdbeMemDynamicify(pMem);
-}
-
-/*
** Make sure the given Mem is \u0000 terminated.
*/
SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
@@ -39075,7 +40170,7 @@
ctx.isError = 0;
pFunc->xFinalize(&ctx);
assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
- sqlite3_free(pMem->zMalloc);
+ sqlite3DbFree(pMem->db, pMem->zMalloc);
*pMem = ctx.s;
rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
}
@@ -39106,7 +40201,7 @@
*/
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
sqlite3VdbeMemReleaseExternal(p);
- sqlite3_free(p->zMalloc);
+ sqlite3DbFree(p->db, p->zMalloc);
p->z = 0;
p->zMalloc = 0;
p->xDel = 0;
@@ -39451,6 +40546,10 @@
return SQLITE_NOMEM;
}
memcpy(pMem->z, z, nAlloc);
+ }else if( xDel==SQLITE_DYNAMIC ){
+ sqlite3VdbeMemRelease(pMem);
+ pMem->zMalloc = pMem->z = (char *)z;
+ pMem->xDel = 0;
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
@@ -39786,11 +40885,11 @@
op = pExpr->op;
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- zVal = sqlite3StrNDup((char*)pExpr->token.z, pExpr->token.n);
+ zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);
pVal = sqlite3ValueNew(db);
if( !zVal || !pVal ) goto no_mem;
sqlite3Dequote(zVal);
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3_free);
+ sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
}else{
@@ -39813,7 +40912,7 @@
nVal = pExpr->token.n - 3;
zVal = (char*)pExpr->token.z + 2;
sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
- 0, sqlite3_free);
+ 0, SQLITE_DYNAMIC);
}
#endif
@@ -39822,7 +40921,7 @@
no_mem:
db->mallocFailed = 1;
- sqlite3_free(zVal);
+ sqlite3DbFree(db, zVal);
sqlite3ValueFree(pVal);
*ppVal = 0;
return SQLITE_NOMEM;
@@ -39847,7 +40946,7 @@
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return;
sqlite3VdbeMemRelease((Mem *)v);
- sqlite3_free(v);
+ sqlite3DbFree(((Mem*)v)->db, v);
}
/*
@@ -39884,7 +40983,7 @@
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
-** $Id: vdbeaux.c,v 1.397 2008/07/11 21:02:54 drh Exp $
+** $Id: vdbeaux.c,v 1.405 2008/08/02 03:50:39 drh Exp $
*/
@@ -40169,7 +41268,7 @@
pOp->p2 = aLabel[-1-pOp->p2];
}
}
- sqlite3_free(p->aLabel);
+ sqlite3DbFree(p->db, p->aLabel);
p->aLabel = 0;
*pMaxFuncArgs = nMaxArgs;
@@ -40299,16 +41398,16 @@
** If the input FuncDef structure is ephemeral, then free it. If
** the FuncDef is not ephermal, then do nothing.
*/
-static void freeEphemeralFunction(FuncDef *pDef){
+static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3_free(pDef);
+ sqlite3DbFree(db, pDef);
}
}
/*
** Delete a P4 value if necessary.
*/
-static void freeP4(int p4type, void *p4){
+static void freeP4(sqlite3 *db, int p4type, void *p4){
if( p4 ){
switch( p4type ){
case P4_REAL:
@@ -40318,18 +41417,18 @@
case P4_KEYINFO:
case P4_INTARRAY:
case P4_KEYINFO_HANDOFF: {
- sqlite3_free(p4);
+ sqlite3DbFree(db, p4);
break;
}
case P4_VDBEFUNC: {
VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
- freeEphemeralFunction(pVdbeFunc->pFunc);
+ freeEphemeralFunction(db, pVdbeFunc->pFunc);
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqlite3_free(pVdbeFunc);
+ sqlite3DbFree(db, pVdbeFunc);
break;
}
case P4_FUNCDEF: {
- freeEphemeralFunction((FuncDef*)p4);
+ freeEphemeralFunction(db, (FuncDef*)p4);
break;
}
case P4_MEM: {
@@ -40347,8 +41446,9 @@
SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){
if( p && p->aOp ){
VdbeOp *pOp = &p->aOp[addr];
+ sqlite3 *db = p->db;
while( N-- ){
- freeP4(pOp->p4type, pOp->p4.p);
+ freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
pOp++;
@@ -40383,11 +41483,13 @@
*/
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
Op *pOp;
+ sqlite3 *db;
assert( p!=0 );
+ db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->aOp==0 || p->db->mallocFailed ){
+ if( p->aOp==0 || db->mallocFailed ){
if (n != P4_KEYINFO) {
- freeP4(n, (void*)*(char**)&zP4);
+ freeP4(db, n, (void*)*(char**)&zP4);
}
return;
}
@@ -40397,7 +41499,7 @@
if( addr<0 ) return;
}
pOp = &p->aOp[addr];
- freeP4(pOp->p4type, pOp->p4.p);
+ freeP4(db, pOp->p4type, pOp->p4.p);
pOp->p4.p = 0;
if( n==P4_INT32 ){
/* Note: this cast is safe, because the origin data point was an int
@@ -40455,7 +41557,7 @@
if( p->nOp ){
char **pz = &p->aOp[p->nOp-1].zComment;
va_start(ap, zFormat);
- sqlite3_free(*pz);
+ sqlite3DbFree(p->db, *pz);
*pz = sqlite3VMPrintf(p->db, zFormat, ap);
va_end(ap);
}
@@ -40468,7 +41570,7 @@
if( p->nOp ){
char **pz = &p->aOp[p->nOp-1].zComment;
va_start(ap, zFormat);
- sqlite3_free(*pz);
+ sqlite3DbFree(p->db, *pz);
*pz = sqlite3VMPrintf(p->db, zFormat, ap);
va_end(ap);
}
@@ -40623,17 +41725,13 @@
/*
** Release an array of N Mem elements
*/
-static void releaseMemArray(Mem *p, int N, int freebuffers){
+static void releaseMemArray(Mem *p, int N){
if( p && N ){
sqlite3 *db = p->db;
int malloc_failed = db->mallocFailed;
while( N-->0 ){
assert( N<2 || p[0].db==p[1].db );
- if( freebuffers ){
- sqlite3VdbeMemRelease(p);
- }else{
- sqlite3VdbeMemReleaseExternal(p);
- }
+ sqlite3VdbeMemRelease(p);
p->flags = MEM_Null;
p++;
}
@@ -40650,7 +41748,7 @@
Mem *pMem = &p->aMem[ii];
if( pMem->z && pMem->flags&MEM_Dyn ){
assert( !pMem->xDel );
- nFree += sqlite3MallocSize(pMem->z);
+ nFree += sqlite3DbMallocSize(pMem->db, pMem->z);
sqlite3VdbeMemRelease(pMem);
}
}
@@ -40688,7 +41786,7 @@
** the result, result columns may become dynamic if the user calls
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/
- releaseMemArray(pMem, p->nMem, 1);
+ releaseMemArray(pMem, p->nMem);
do{
i = p->pc++;
@@ -40969,11 +42067,8 @@
}
#endif
if( !pCx->ephemPseudoTable ){
- sqlite3_free(pCx->pData);
+ sqlite3DbFree(p->db, pCx->pData);
}
- /* memset(pCx, 0, sizeof(Cursor)); */
- /* sqlite3_free(pCx->aType); */
- /* sqlite3_free(pCx); */
}
/*
@@ -40999,24 +42094,25 @@
** sorters that were left open. It also deletes the values of
** variables in the aVar[] array.
*/
-static void Cleanup(Vdbe *p, int freebuffers){
+static void Cleanup(Vdbe *p){
int i;
+ sqlite3 *db = p->db;
closeAllCursorsExceptActiveVtabs(p);
for(i=1; i<=p->nMem; i++){
MemSetTypeFlag(&p->aMem[i], MEM_Null);
}
- releaseMemArray(&p->aMem[1], p->nMem, freebuffers);
+ releaseMemArray(&p->aMem[1], p->nMem);
sqlite3VdbeFifoClear(&p->sFifo);
if( p->contextStack ){
for(i=0; i<p->contextStackTop; i++){
sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
}
- sqlite3_free(p->contextStack);
+ sqlite3DbFree(db, p->contextStack);
}
p->contextStack = 0;
p->contextStackDepth = 0;
p->contextStackTop = 0;
- sqlite3_free(p->zErrMsg);
+ sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
p->pResultSet = 0;
}
@@ -41030,12 +42126,13 @@
SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
Mem *pColName;
int n;
+ sqlite3 *db = p->db;
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
- sqlite3_free(p->aColName);
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+ sqlite3DbFree(db, p->aColName);
n = nResColumn*COLNAME_N;
p->nResColumn = nResColumn;
- p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
+ p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
if( p->aColName==0 ) return;
while( n-- > 0 ){
pColName->flags = MEM_Null;
@@ -41052,7 +42149,7 @@
**
** If N==P4_STATIC it means that zName is a pointer to a constant static
** string and we can just copy the pointer. If it is P4_DYNAMIC, then
-** the string is freed using sqlite3_free() when the vdbe is finished with
+** the string is freed using sqlite3DbFree(db, ) when the vdbe is finished with
** it. Otherwise, N bytes of zName are copied.
*/
SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
@@ -41081,7 +42178,7 @@
** write-transaction spanning more than one database file, this routine
** takes care of the master journal trickery.
*/
-static int vdbeCommit(sqlite3 *db){
+static int vdbeCommit(sqlite3 *db, Vdbe *p){
int i;
int nTrans = 0; /* Number of databases with an active write-transaction */
int rc = SQLITE_OK;
@@ -41093,7 +42190,7 @@
** required, as an xSync() callback may add an attached database
** to the transaction.
*/
- rc = sqlite3VtabSync(db, rc);
+ rc = sqlite3VtabSync(db, &p->zErrMsg);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -41172,7 +42269,7 @@
/* Select a master journal file name */
do {
u32 random;
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
sqlite3_randomness(sizeof(random), &random);
zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);
if( !zMaster ){
@@ -41188,7 +42285,7 @@
);
}
if( rc!=SQLITE_OK ){
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
return rc;
}
@@ -41212,7 +42309,7 @@
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
return rc;
}
}
@@ -41227,7 +42324,7 @@
&& (rc=sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))!=SQLITE_OK) ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
return rc;
}
@@ -41249,7 +42346,7 @@
}
sqlite3OsCloseFree(pMaster);
if( rc!=SQLITE_OK ){
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
return rc;
}
@@ -41258,7 +42355,7 @@
** transaction files are deleted.
*/
rc = sqlite3OsDelete(pVfs, zMaster, 1);
- sqlite3_free(zMaster);
+ sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
return rc;
@@ -41457,7 +42554,7 @@
** successful or hit an 'OR FAIL' constraint. This means a commit
** is required.
*/
- int rc = vdbeCommit(db);
+ int rc = vdbeCommit(db, p);
if( rc==SQLITE_BUSY ){
sqlite3BtreeMutexArrayLeave(&p->aMutex);
return SQLITE_BUSY;
@@ -41500,7 +42597,7 @@
rc = xFunc(pBt);
if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
p->rc = rc;
- sqlite3_free(p->zErrMsg);
+ sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
}
@@ -41561,7 +42658,7 @@
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
** VDBE_MAGIC_INIT.
*/
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p, int freebuffers){
+SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
sqlite3 *db;
db = p->db;
@@ -41580,8 +42677,9 @@
*/
if( p->pc>=0 ){
if( p->zErrMsg ){
- sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,sqlite3_free);
+ sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,SQLITE_TRANSIENT);
db->errCode = p->rc;
+ sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}else if( p->rc ){
sqlite3Error(db, p->rc, 0);
@@ -41594,13 +42692,14 @@
** called), set the database error in this case as well.
*/
sqlite3Error(db, p->rc, 0);
- sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free);
+ sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
+ sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
/* Reclaim all memory used by the VDBE
*/
- Cleanup(p, freebuffers);
+ Cleanup(p);
/* Save profiling information from this VDBE run.
*/
@@ -41627,7 +42726,6 @@
}
#endif
p->magic = VDBE_MAGIC_INIT;
- p->aborted = 0;
return p->rc & db->errMask;
}
@@ -41638,12 +42736,11 @@
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
int rc = SQLITE_OK;
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
- rc = sqlite3VdbeReset(p, 1);
+ rc = sqlite3VdbeReset(p);
assert( (rc & p->db->errMask)==rc );
}else if( p->magic!=VDBE_MAGIC_INIT ){
return SQLITE_MISUSE;
}
- releaseMemArray(&p->aMem[1], p->nMem, 1);
sqlite3VdbeDelete(p);
return rc;
}
@@ -41672,13 +42769,15 @@
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
int i;
+ sqlite3 *db;
+
if( p==0 ) return;
- Cleanup(p, 1);
+ db = p->db;
if( p->pPrev ){
p->pPrev->pNext = p->pNext;
}else{
- assert( p->db->pVdbe==p );
- p->db->pVdbe = p->pNext;
+ assert( db->pVdbe==p );
+ db->pVdbe = p->pNext;
}
if( p->pNext ){
p->pNext->pPrev = p->pPrev;
@@ -41686,23 +42785,23 @@
if( p->aOp ){
Op *pOp = p->aOp;
for(i=0; i<p->nOp; i++, pOp++){
- freeP4(pOp->p4type, pOp->p4.p);
+ freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
- sqlite3_free(pOp->zComment);
+ sqlite3DbFree(db, pOp->zComment);
#endif
}
- sqlite3_free(p->aOp);
+ sqlite3DbFree(db, p->aOp);
}
- releaseMemArray(p->aVar, p->nVar, 1);
- sqlite3_free(p->aLabel);
+ releaseMemArray(p->aVar, p->nVar);
+ sqlite3DbFree(db, p->aLabel);
if( p->aMem ){
- sqlite3_free(&p->aMem[1]);
+ sqlite3DbFree(db, &p->aMem[1]);
}
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
- sqlite3_free(p->aColName);
- sqlite3_free(p->zSql);
+ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+ sqlite3DbFree(db, p->aColName);
+ sqlite3DbFree(db, p->zSql);
p->magic = VDBE_MAGIC_DEAD;
- sqlite3_free(p);
+ sqlite3DbFree(db, p);
}
/*
@@ -41748,9 +42847,9 @@
**
** sqlite3VdbeSerialType()
** sqlite3VdbeSerialTypeLen()
-** sqlite3VdbeSerialRead()
** sqlite3VdbeSerialLen()
-** sqlite3VdbeSerialWrite()
+** sqlite3VdbeSerialPut()
+** sqlite3VdbeSerialGet()
**
** encapsulate the code that serializes values for storage in SQLite
** data and index records. Each serialized value consists of a
@@ -42072,7 +43171,8 @@
const unsigned char *aKey = (const unsigned char *)pKey;
UnpackedRecord *p;
int nByte;
- int i, idx, d;
+ int idx, d;
+ u16 u; /* Unsigned loop counter */
u32 szHdr;
Mem *pMem;
@@ -42092,8 +43192,8 @@
p->aMem = pMem = &((Mem*)p)[1];
idx = getVarint32(aKey, szHdr);
d = szHdr;
- i = 0;
- while( idx<szHdr && i<p->nField ){
+ u = 0;
+ while( idx<szHdr && u<p->nField ){
u32 serial_type;
idx += getVarint32( aKey+idx, serial_type);
@@ -42104,9 +43204,9 @@
pMem->zMalloc = 0;
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
pMem++;
- i++;
+ u++;
}
- p->nField = i;
+ p->nField = u;
return (void*)p;
}
@@ -42125,7 +43225,7 @@
}
}
if( p->needFree ){
- sqlite3_free(p);
+ sqlite3DbFree(p->pKeyInfo->db, p);
}
}
}
@@ -42220,13 +43320,17 @@
** an integer rowid). This routine returns the number of bytes in
** that integer.
*/
-SQLITE_PRIVATE int sqlite3VdbeIdxRowidLen(const u8 *aKey){
+SQLITE_PRIVATE int sqlite3VdbeIdxRowidLen(const u8 *aKey, int nKey, int *pRowidLen){
u32 szHdr; /* Size of the header */
u32 typeRowid; /* Serial type of the rowid */
(void)getVarint32(aKey, szHdr);
+ if( szHdr>nKey ){
+ return SQLITE_CORRUPT_BKPT;
+ }
(void)getVarint32(&aKey[szHdr-1], typeRowid);
- return sqlite3VdbeSerialTypeLen(typeRowid);
+ *pRowidLen = sqlite3VdbeSerialTypeLen(typeRowid);
+ return SQLITE_OK;
}
@@ -42295,11 +43399,11 @@
m.db = 0;
m.flags = 0;
m.zMalloc = 0;
- rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
- if( rc ){
+ if( (rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m))
+ || (rc = sqlite3VdbeIdxRowidLen((u8*)m.z, m.n, &lenRowid))
+ ){
return rc;
}
- lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
if( !pUnpacked ){
pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey,
zSpace, sizeof(zSpace));
@@ -42376,7 +43480,7 @@
** This file contains code use to implement APIs that are part of the
** VDBE.
**
-** $Id: vdbeapi.c,v 1.134 2008/06/19 02:52:25 drh Exp $
+** $Id: vdbeapi.c,v 1.138 2008/08/02 03:50:39 drh Exp $
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -42589,7 +43693,7 @@
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
- rc = sqlite3VdbeReset(v, 1);
+ rc = sqlite3VdbeReset(v);
stmtLruAdd(v);
sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
assert( (rc & (v->db->errMask))==rc );
@@ -42796,9 +43900,6 @@
db = p->db;
assert( !db->mallocFailed );
- if( p->aborted ){
- return SQLITE_ABORT;
- }
if( p->pc<=0 && p->expired ){
if( p->rc==SQLITE_OK ){
p->rc = SQLITE_SCHEMA;
@@ -42858,14 +43959,16 @@
}
#endif
- sqlite3Error(p->db, rc, 0);
+ db->errCode = rc;
+ /*sqlite3Error(p->db, rc, 0);*/
p->rc = sqlite3ApiExit(p->db, p->rc);
end_of_step:
assert( (rc&0xff)==rc );
if( p->zSql && (rc&0xff)<SQLITE_ROW ){
/* This behavior occurs if sqlite3_prepare_v2() was used to build
** the prepared statement. Return error codes directly */
- sqlite3Error(p->db, p->rc, 0);
+ p->db->errCode = p->rc;
+ /* sqlite3Error(p->db, p->rc, 0); */
return p->rc;
}else{
/* This is for legacy sqlite3_prepare() builds and when the code
@@ -42915,7 +44018,7 @@
** sqlite3_errmsg() and sqlite3_errcode().
*/
const char *zErr = (const char *)sqlite3_value_text(db->pErr);
- sqlite3_free(v->zErrMsg);
+ sqlite3DbFree(db, v->zErrMsg);
if( !db->mallocFailed ){
v->zErrMsg = sqlite3DbStrDup(db, zErr);
} else {
@@ -43683,7 +44786,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.761 2008/07/11 21:02:54 drh Exp $
+** $Id: vdbe.c,v 1.772 2008/08/02 15:10:09 danielk1977 Exp $
*/
/*
@@ -44124,7 +45227,7 @@
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 class CPUs.
**
-** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+** $Id: hwtime.h,v 1.3 2008/08/01 14:33:15 shane Exp $
*/
#ifndef _HWTIME_H_
#define _HWTIME_H_
@@ -44165,6 +45268,21 @@
return val;
}
+#elif (defined(__GNUC__) && defined(__ppc__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned long long retval;
+ unsigned long junk;
+ __asm__ __volatile__ ("\n\
+ 1: mftbu %1\n\
+ mftb %L0\n\
+ mftbu %0\n\
+ cmpw %0,%1\n\
+ bne 1b"
+ : "=r" (retval), "=r" (junk));
+ return retval;
+ }
+
#else
#error Need implementation of sqlite3Hwtime() for your platform.
@@ -44603,12 +45721,12 @@
if( encoding!=SQLITE_UTF8 ){
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
- if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
+ if( SQLITE_OK!=sqlite3VdbeMemMakeWriteable(pOut) ) goto no_mem;
pOut->zMalloc = 0;
pOut->flags |= MEM_Static;
pOut->flags &= ~MEM_Dyn;
if( pOp->p4type==P4_DYNAMIC ){
- sqlite3_free(pOp->p4.z);
+ sqlite3DbFree(db, pOp->p4.z);
}
pOp->p4type = P4_DYNAMIC;
pOp->p4.z = pOut->z;
@@ -44892,6 +46010,8 @@
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
int flags;
+ applyNumericAffinity(pIn1);
+ applyNumericAffinity(pIn2);
flags = pIn1->flags | pIn2->flags;
if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
@@ -45868,17 +46988,8 @@
if( aOffset[p2] ){
assert( rc==SQLITE_OK );
if( zRec ){
- if( pDest->flags&MEM_Dyn ){
- sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
- sMem.db = db;
- rc = sqlite3VdbeMemCopy(pDest, &sMem);
- assert( !(sMem.flags&MEM_Dyn) );
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- }else{
- sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
- }
+ sqlite3VdbeMemReleaseExternal(pDest);
+ sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
}else{
len = sqlite3VdbeSerialTypeLen(aType[p2]);
sqlite3VdbeMemMove(&sMem, pDest);
@@ -46318,7 +47429,7 @@
iMeta = 0;
}
if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
- sqlite3_free(p->zErrMsg);
+ sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
** stored with the in-memory representation of the schema, do
@@ -46849,7 +47960,14 @@
zKey = pK->z;
nKey = pK->n;
- szRowid = sqlite3VdbeIdxRowidLen((u8*)zKey);
+ /* sqlite3VdbeIdxRowidLen() only returns other than SQLITE_OK when the
+ ** record passed as an argument corrupt. Since the record in this case
+ ** has just been created by an OP_MakeRecord instruction, and not loaded
+ ** from the database file, it is not possible for it to be corrupt.
+ ** Therefore, assert(rc==SQLITE_OK).
+ */
+ rc = sqlite3VdbeIdxRowidLen((u8*)zKey, nKey, &szRowid);
+ assert(rc==SQLITE_OK);
len = nKey-szRowid;
/* Search for an entry in P1 where all but the last four bytes match K.
@@ -47176,7 +48294,7 @@
}
if( pC->pseudoTable ){
if( !pC->ephemPseudoTable ){
- sqlite3_free(pC->pData);
+ sqlite3DbFree(db, pC->pData);
}
pC->iKey = iKey;
pC->nData = pData->n;
@@ -47855,7 +48973,7 @@
assert( !db->mallocFailed );
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_ABORT ) rc = initData.rc;
- sqlite3_free(zSql);
+ sqlite3DbFree(db, zSql);
db->init.busy = 0;
(void)sqlite3SafetyOn(db);
if( rc==SQLITE_NOMEM ){
@@ -47947,7 +49065,7 @@
nRoot = pOp->p2;
assert( nRoot>0 );
- aRoot = sqlite3Malloc( sizeof(int)*(nRoot+1) );
+ aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
if( aRoot==0 ) goto no_mem;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
pnErr = &p->aMem[pOp->p3];
@@ -47962,16 +49080,18 @@
assert( (p->btreeMask & (1<<pOp->p5))!=0 );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
pnErr->u.i, &nErr);
+ sqlite3DbFree(db, aRoot);
pnErr->u.i -= nErr;
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
+ }else if( z==0 ){
+ goto no_mem;
}else{
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
- sqlite3_free(aRoot);
break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -47981,6 +49101,7 @@
** Write the integer from register P1 into the Fifo.
*/
case OP_FifoWrite: { /* in1 */
+ p->sFifo.db = db;
if( sqlite3VdbeFifoPush(&p->sFifo, sqlite3VdbeIntValue(pIn1))==SQLITE_NOMEM ){
goto no_mem;
}
@@ -48028,7 +49149,7 @@
pContext->lastRowid = db->lastRowid;
pContext->nChange = p->nChange;
pContext->sFifo = p->sFifo;
- sqlite3VdbeFifoInit(&p->sFifo);
+ sqlite3VdbeFifoInit(&p->sFifo, db);
break;
}
@@ -48282,11 +49403,21 @@
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VBegin * * * P4 *
**
-** P4 a pointer to an sqlite3_vtab structure. Call the xBegin method
-** for that table.
+** P4 may be a pointer to an sqlite3_vtab structure. If so, call the
+** xBegin method for that table.
+**
+** Also, whether or not P4 is set, check that this is not being called from
+** within a callback to a virtual table xSync() method. If it is, set the
+** error code to SQLITE_LOCKED.
*/
case OP_VBegin: {
- rc = sqlite3VtabBegin(db, pOp->p4.pVtab);
+ sqlite3_vtab *pVtab = pOp->p4.pVtab;
+ rc = sqlite3VtabBegin(db, pVtab);
+ if( pVtab ){
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
+ }
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -48334,6 +49465,9 @@
assert(pVtab && pModule);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
rc = pModule->xOpen(pVtab, &pVtabCursor);
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
@@ -48378,12 +49512,16 @@
const sqlite3_module *pModule;
Mem *pQuery = &p->aMem[pOp->p3];
Mem *pArgc = &pQuery[1];
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
Cursor *pCur = p->apCsr[pOp->p1];
REGISTER_TRACE(pOp->p3, pQuery);
assert( pCur->pVtabCursor );
- pModule = pCur->pVtabCursor->pVtab->pModule;
+ pVtabCursor = pCur->pVtabCursor;
+ pVtab = pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
/* Grab the index number and argc parameters */
assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
@@ -48401,11 +49539,16 @@
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+ sqlite3VtabLock(pVtab);
p->inVtabMethod = 1;
- rc = pModule->xFilter(pCur->pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
p->inVtabMethod = 0;
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, pVtab);
if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->pVtabCursor);
+ res = pModule->xEof(pVtabCursor);
}
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
@@ -48426,6 +49569,7 @@
** the virtual-table that the P1 cursor is pointing to.
*/
case OP_VRowid: { /* out2-prerelease */
+ sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
sqlite_int64 iRow;
Cursor *pCur = p->apCsr[pOp->p1];
@@ -48434,10 +49578,14 @@
if( pCur->nullRow ){
break;
}
- pModule = pCur->pVtabCursor->pVtab->pModule;
+ pVtab = pCur->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
assert( pModule->xRowid );
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
rc = pModule->xRowid(pCur->pVtabCursor, &iRow);
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = iRow;
@@ -48453,6 +49601,7 @@
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
+ sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
Mem *pDest;
sqlite3_context sContext;
@@ -48465,7 +49614,8 @@
sqlite3VdbeMemSetNull(pDest);
break;
}
- pModule = pCur->pVtabCursor->pVtab->pModule;
+ pVtab = pCur->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
@@ -48479,6 +49629,9 @@
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
/* Copy the result of the function to the P3 register. We
** do this regardless of whether or not an error occured to ensure any
@@ -48507,6 +49660,7 @@
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: { /* jump */
+ sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
int res = 0;
@@ -48515,7 +49669,8 @@
if( pCur->nullRow ){
break;
}
- pModule = pCur->pVtabCursor->pVtab->pModule;
+ pVtab = pCur->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
assert( pModule->xNext );
/* Invoke the xNext() method of the module. There is no way for the
@@ -48525,9 +49680,14 @@
** some other method is next invoked on the save virtual table cursor.
*/
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
+ sqlite3VtabLock(pVtab);
p->inVtabMethod = 1;
rc = pModule->xNext(pCur->pVtabCursor);
p->inVtabMethod = 0;
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->pVtabCursor);
}
@@ -48559,6 +49719,9 @@
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
sqlite3VtabLock(pVtab);
rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
sqlite3VtabUnlock(db, pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
@@ -48611,6 +49774,9 @@
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
sqlite3VtabLock(pVtab);
rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
sqlite3VtabUnlock(db, pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( pOp->p1 && rc==SQLITE_OK ){
@@ -48798,7 +49964,7 @@
**
** This file contains code used to implement incremental BLOB I/O.
**
-** $Id: vdbeblob.c,v 1.24 2008/07/10 00:32:42 drh Exp $
+** $Id: vdbeblob.c,v 1.25 2008/07/28 19:34:54 drh Exp $
*/
@@ -48901,7 +50067,7 @@
if( sParse.zErrMsg ){
sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
}
- sqlite3_free(sParse.zErrMsg);
+ sqlite3DbFree(db, sParse.zErrMsg);
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
@@ -49013,7 +50179,7 @@
}
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
if( db->mallocFailed ){
- sqlite3_free(pBlob);
+ sqlite3DbFree(db, pBlob);
goto blob_open_out;
}
pBlob->flags = flags;
@@ -49052,7 +50218,7 @@
int rc;
rc = sqlite3_finalize(p->pStmt);
- sqlite3_free(p);
+ sqlite3DbFree(p->db, p);
return rc;
}
@@ -49388,7 +50554,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.385 2008/07/09 01:39:44 drh Exp $
+** $Id: expr.c,v 1.387 2008/07/28 19:34:53 drh Exp $
*/
/*
@@ -49430,7 +50596,8 @@
SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){
char *zColl = 0; /* Dequoted name of collation sequence */
CollSeq *pColl;
- zColl = sqlite3NameFromToken(pParse->db, pName);
+ sqlite3 *db = pParse->db;
+ zColl = sqlite3NameFromToken(db, pName);
if( pExpr && zColl ){
pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
if( pColl ){
@@ -49438,7 +50605,7 @@
pExpr->flags |= EP_ExpCollate;
}
}
- sqlite3_free(zColl);
+ sqlite3DbFree(db, zColl);
return pExpr;
}
@@ -49741,8 +50908,8 @@
** this function must always be allocated with sqlite3Expr() for this
** reason.
*/
- sqlite3ExprDelete(pLeft);
- sqlite3ExprDelete(pRight);
+ sqlite3ExprDelete(db, pLeft);
+ sqlite3ExprDelete(db, pRight);
return 0;
}
pNew->op = op;
@@ -49839,7 +51006,7 @@
SQLITE_PRIVATE void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
assert( pRight!=0 );
assert( pLeft!=0 );
- if( pExpr && pRight->z && pLeft->z ){
+ if( pExpr ){
pExpr->span.z = pLeft->z;
pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
}
@@ -49851,10 +51018,11 @@
*/
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
Expr *pNew;
+ sqlite3 *db = pParse->db;
assert( pToken );
- pNew = sqlite3DbMallocZero(pParse->db, sizeof(Expr) );
+ pNew = sqlite3DbMallocZero(db, sizeof(Expr) );
if( pNew==0 ){
- sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */
+ sqlite3ExprListDelete(db, pList); /* Avoid leaking memory when malloc fails */
return 0;
}
pNew->op = TK_FUNCTION;
@@ -49952,15 +51120,15 @@
/*
** Recursively delete an expression tree.
*/
-SQLITE_PRIVATE void sqlite3ExprDelete(Expr *p){
+SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
- if( p->span.dyn ) sqlite3_free((char*)p->span.z);
- if( p->token.dyn ) sqlite3_free((char*)p->token.z);
- sqlite3ExprDelete(p->pLeft);
- sqlite3ExprDelete(p->pRight);
- sqlite3ExprListDelete(p->pList);
- sqlite3SelectDelete(p->pSelect);
- sqlite3_free(p);
+ if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
+ if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
+ sqlite3ExprDelete(db, p->pLeft);
+ sqlite3ExprDelete(db, p->pRight);
+ sqlite3ExprListDelete(db, p->pList);
+ sqlite3SelectDelete(db, p->pSelect);
+ sqlite3DbFree(db, p);
}
/*
@@ -50011,7 +51179,7 @@
return pNew;
}
SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3 *db, Token *pTo, Token *pFrom){
- if( pTo->dyn ) sqlite3_free((char*)pTo->z);
+ if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);
if( pFrom->z ){
pTo->n = pFrom->n;
pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
@@ -50031,7 +51199,7 @@
pNew->nExpr = pNew->nAlloc = p->nExpr;
pNew->a = pItem = sqlite3DbMallocRaw(db, p->nExpr*sizeof(p->a[0]) );
if( pItem==0 ){
- sqlite3_free(pNew);
+ sqlite3DbFree(db, pNew);
return 0;
}
pOldItem = p->a;
@@ -50102,7 +51270,7 @@
pNew->nId = pNew->nAlloc = p->nId;
pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
if( pNew->a==0 ){
- sqlite3_free(pNew);
+ sqlite3DbFree(db, pNew);
return 0;
}
for(i=0; i<p->nId; i++){
@@ -50188,8 +51356,8 @@
no_mem:
/* Avoid leaking memory if malloc has failed. */
- sqlite3ExprDelete(pExpr);
- sqlite3ExprListDelete(pList);
+ sqlite3ExprDelete(db, pExpr);
+ sqlite3ExprListDelete(db, pList);
return 0;
}
@@ -50213,18 +51381,18 @@
/*
** Delete an entire expression list.
*/
-SQLITE_PRIVATE void sqlite3ExprListDelete(ExprList *pList){
+SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
int i;
struct ExprList_item *pItem;
if( pList==0 ) return;
assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
assert( pList->nExpr<=pList->nAlloc );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
- sqlite3ExprDelete(pItem->pExpr);
- sqlite3_free(pItem->zName);
+ sqlite3ExprDelete(db, pItem->pExpr);
+ sqlite3DbFree(db, pItem->zName);
}
- sqlite3_free(pList->a);
- sqlite3_free(pList);
+ sqlite3DbFree(db, pList->a);
+ sqlite3DbFree(db, pList);
}
/*
@@ -50638,7 +51806,7 @@
pOrig = pEList->a[j].pExpr;
if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
return 2;
}
pDup = sqlite3ExprDup(db, pOrig);
@@ -50646,10 +51814,10 @@
pDup->pColl = pExpr->pColl;
pDup->flags |= EP_ExpCollate;
}
- if( pExpr->span.dyn ) sqlite3_free((char*)pExpr->span.z);
- if( pExpr->token.dyn ) sqlite3_free((char*)pExpr->token.z);
+ if( pExpr->span.dyn ) sqlite3DbFree(db, (char*)pExpr->span.z);
+ if( pExpr->token.dyn ) sqlite3DbFree(db, (char*)pExpr->token.z);
memcpy(pExpr, pDup, sizeof(*pExpr));
- sqlite3_free(pDup);
+ sqlite3DbFree(db, pDup);
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
@@ -50677,7 +51845,7 @@
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
return 0;
}
@@ -50717,15 +51885,15 @@
lookupname_end:
/* Clean up and return
*/
- sqlite3_free(zDb);
- sqlite3_free(zTab);
- sqlite3ExprDelete(pExpr->pLeft);
+ sqlite3DbFree(db, zDb);
+ sqlite3DbFree(db, zTab);
+ sqlite3ExprDelete(db, pExpr->pLeft);
pExpr->pLeft = 0;
- sqlite3ExprDelete(pExpr->pRight);
+ sqlite3ExprDelete(db, pExpr->pRight);
pExpr->pRight = 0;
pExpr->op = TK_COLUMN;
lookupname_end_2:
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
if( cnt==1 ){
assert( pNC!=0 );
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
@@ -51340,7 +52508,7 @@
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
VdbeComment((v, "Init EXISTS result"));
}
- sqlite3ExprDelete(pSel->pLimit);
+ sqlite3ExprDelete(pParse->db, pSel->pLimit);
pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
if( sqlite3Select(pParse, pSel, &dest, 0, 0, 0) ){
return;
@@ -52973,7 +54141,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.46 2008/07/15 14:47:19 drh Exp $
+** $Id: alter.c,v 1.47 2008/07/28 19:34:53 drh Exp $
*/
/*
@@ -53039,7 +54207,7 @@
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -53114,7 +54282,7 @@
*/
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
#endif /* !SQLITE_OMIT_TRIGGER */
@@ -53157,7 +54325,7 @@
}else{
tmp = zWhere;
zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name);
- sqlite3_free(tmp);
+ sqlite3DbFree(db, tmp);
}
}
}
@@ -53368,7 +54536,7 @@
"sql = sqlite_rename_trigger(sql, %Q), "
"tbl_name = %Q "
"WHERE %s;", zName, zName, zWhere);
- sqlite3_free(zWhere);
+ sqlite3DbFree(db, zWhere);
}
#endif
@@ -53376,8 +54544,8 @@
reloadTableSchema(pParse, pTab, zName);
exit_rename_table:
- sqlite3SrcListDelete(pSrc);
- sqlite3_free(zName);
+ sqlite3SrcListDelete(db, pSrc);
+ sqlite3DbFree(db, zName);
}
@@ -53477,7 +54645,7 @@
zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
zTab
);
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
}
/* If the default value of the new column is NULL, then set the file
@@ -53544,6 +54712,7 @@
if( !pNew ) goto exit_begin_add_column;
pParse->pNewTable = pNew;
pNew->nRef = 1;
+ pNew->db = db;
pNew->nCol = pTab->nCol;
assert( pNew->nCol>0 );
nAlloc = (((pNew->nCol-1)/8)*8)+8;
@@ -53573,7 +54742,7 @@
sqlite3ChangeCookie(pParse, iDb);
exit_begin_add_column:
- sqlite3SrcListDelete(pSrc);
+ sqlite3SrcListDelete(db, pSrc);
return;
}
#endif /* SQLITE_ALTER_TABLE */
@@ -53593,7 +54762,7 @@
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
-** @(#) $Id: analyze.c,v 1.42 2008/03/25 09:47:35 danielk1977 Exp $
+** @(#) $Id: analyze.c,v 1.43 2008/07/28 19:34:53 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
@@ -53897,7 +55066,7 @@
z = sqlite3NameFromToken(db, pName1);
if( z ){
pTab = sqlite3LocateTable(pParse, 0, z, 0);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
if( pTab ){
analyzeTable(pParse, pTab);
}
@@ -53911,7 +55080,7 @@
z = sqlite3NameFromToken(db, pTableName);
if( z ){
pTab = sqlite3LocateTable(pParse, 0, z, zDb);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
if( pTab ){
analyzeTable(pParse, pTab);
}
@@ -53998,7 +55167,7 @@
(void)sqlite3SafetyOff(db);
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
(void)sqlite3SafetyOn(db);
- sqlite3_free(zSql);
+ sqlite3DbFree(db, zSql);
return rc;
}
@@ -54020,7 +55189,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
-** $Id: attach.c,v 1.76 2008/06/15 02:51:47 drh Exp $
+** $Id: attach.c,v 1.77 2008/07/28 19:34:53 drh Exp $
*/
#ifndef SQLITE_OMIT_ATTACH
@@ -54222,7 +55391,7 @@
/* Return an error if we get here */
if( zErrDyn ){
sqlite3_result_error(context, zErrDyn, -1);
- sqlite3_free(zErrDyn);
+ sqlite3DbFree(db, zErrDyn);
}else{
zErr[sizeof(zErr)-1] = 0;
sqlite3_result_error(context, zErr, -1);
@@ -54313,7 +55482,7 @@
goto attach_end;
}
rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- sqlite3_free(zAuthArg);
+ sqlite3DbFree(db, zAuthArg);
if(rc!=SQLITE_OK ){
goto attach_end;
}
@@ -54353,9 +55522,9 @@
}
attach_end:
- sqlite3ExprDelete(pFilename);
- sqlite3ExprDelete(pDbname);
- sqlite3ExprDelete(pKey);
+ sqlite3ExprDelete(db, pFilename);
+ sqlite3ExprDelete(db, pDbname);
+ sqlite3ExprDelete(db, pKey);
}
/*
@@ -54793,7 +55962,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.490 2008/07/08 23:40:20 drh Exp $
+** $Id: build.c,v 1.493 2008/08/04 04:39:49 danielk1977 Exp $
*/
/*
@@ -54906,12 +56075,6 @@
if( db->mallocFailed ) return;
if( pParse->nested ) return;
if( pParse->nErr ) return;
- if( !pParse->pVdbe ){
- if( pParse->rc==SQLITE_OK && pParse->nErr ){
- pParse->rc = SQLITE_ERROR;
- return;
- }
- }
/* Begin by generating some termination code at the end of the
** vdbe program
@@ -55008,24 +56171,24 @@
va_list ap;
char *zSql;
char *zErrMsg = 0;
+ sqlite3 *db = pParse->db;
# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
char saveBuf[SAVE_SZ];
if( pParse->nErr ) return;
assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
va_start(ap, zFormat);
- zSql = sqlite3VMPrintf(pParse->db, zFormat, ap);
+ zSql = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
if( zSql==0 ){
- pParse->db->mallocFailed = 1;
return; /* A malloc must have failed */
}
pParse->nested++;
memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
memset(&pParse->nVar, 0, SAVE_SZ);
sqlite3RunParser(pParse, zSql, &zErrMsg);
- sqlite3_free(zErrMsg);
- sqlite3_free(zSql);
+ sqlite3DbFree(db, zErrMsg);
+ sqlite3DbFree(db, zSql);
memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
pParse->nested--;
}
@@ -55127,8 +56290,9 @@
** Reclaim the memory used by an index
*/
static void freeIndex(Index *p){
- sqlite3_free(p->zColAff);
- sqlite3_free(p);
+ sqlite3 *db = p->pTable->db;
+ sqlite3DbFree(db, p->zColAff);
+ sqlite3DbFree(db, p);
}
/*
@@ -55222,7 +56386,7 @@
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
- sqlite3_free(pDb->zName);
+ sqlite3DbFree(db, pDb->zName);
pDb->zName = 0;
continue;
}
@@ -55235,7 +56399,7 @@
db->nDb = j;
if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
- sqlite3_free(db->aDb);
+ sqlite3DbFree(db, db->aDb);
db->aDb = db->aDbStatic;
}
}
@@ -55253,15 +56417,16 @@
static void sqliteResetColumnNames(Table *pTable){
int i;
Column *pCol;
+ sqlite3 *db = pTable->db;
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
- sqlite3_free(pCol->zName);
- sqlite3ExprDelete(pCol->pDflt);
- sqlite3_free(pCol->zType);
- sqlite3_free(pCol->zColl);
+ sqlite3DbFree(db, pCol->zName);
+ sqlite3ExprDelete(db, pCol->pDflt);
+ sqlite3DbFree(db, pCol->zType);
+ sqlite3DbFree(db, pCol->zColl);
}
- sqlite3_free(pTable->aCol);
+ sqlite3DbFree(db, pTable->aCol);
}
pTable->aCol = 0;
pTable->nCol = 0;
@@ -55280,8 +56445,10 @@
SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){
Index *pIndex, *pNext;
FKey *pFKey, *pNextFKey;
+ sqlite3 *db;
if( pTable==0 ) return;
+ db = pTable->db;
/* Do not delete the table until the reference count reaches zero. */
pTable->nRef--;
@@ -55306,21 +56473,21 @@
pNextFKey = pFKey->pNextFrom;
assert( sqlite3HashFind(&pTable->pSchema->aFKey,
pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
- sqlite3_free(pFKey);
+ sqlite3DbFree(db, pFKey);
}
#endif
/* Delete the Table structure itself.
*/
sqliteResetColumnNames(pTable);
- sqlite3_free(pTable->zName);
- sqlite3_free(pTable->zColAff);
- sqlite3SelectDelete(pTable->pSelect);
+ sqlite3DbFree(db, pTable->zName);
+ sqlite3DbFree(db, pTable->zColAff);
+ sqlite3SelectDelete(db, pTable->pSelect);
#ifndef SQLITE_OMIT_CHECK
- sqlite3ExprDelete(pTable->pCheck);
+ sqlite3ExprDelete(db, pTable->pCheck);
#endif
sqlite3VtabClear(pTable);
- sqlite3_free(pTable);
+ sqlite3DbFree(db, pTable);
}
/*
@@ -55410,7 +56577,7 @@
break;
}
}
- sqlite3_free(zName);
+ sqlite3DbFree(db, zName);
}
return i;
}
@@ -55601,6 +56768,7 @@
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
+ pTable->db = db;
if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
pParse->pNewTable = pTable;
@@ -55680,7 +56848,7 @@
/* If an error occurs, we jump here */
begin_table_error:
- sqlite3_free(zName);
+ sqlite3DbFree(db, zName);
return;
}
@@ -55723,7 +56891,7 @@
for(i=0; i<p->nCol; i++){
if( STRICMP(z, p->aCol[i].zName) ){
sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
return;
}
}
@@ -55731,7 +56899,7 @@
Column *aNew;
aNew = sqlite3DbRealloc(pParse->db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
if( aNew==0 ){
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
return;
}
p->aCol = aNew;
@@ -55838,13 +57006,15 @@
Table *p;
int i;
Column *pCol;
+ sqlite3 *db;
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
if( i<0 ) return;
pCol = &p->aCol[i];
- sqlite3_free(pCol->zType);
- pCol->zType = sqlite3NameFromToken(pParse->db, pType);
+ db = pParse->db;
+ sqlite3DbFree(db, pCol->zType);
+ pCol->zType = sqlite3NameFromToken(db, pType);
pCol->affinity = sqlite3AffinityType(pType);
}
@@ -55861,6 +57031,7 @@
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
Table *p;
Column *pCol;
+ sqlite3 *db = pParse->db;
if( (p = pParse->pNewTable)!=0 ){
pCol = &(p->aCol[p->nCol-1]);
if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
@@ -55868,15 +57039,14 @@
pCol->zName);
}else{
Expr *pCopy;
- sqlite3 *db = pParse->db;
- sqlite3ExprDelete(pCol->pDflt);
+ sqlite3ExprDelete(db, pCol->pDflt);
pCol->pDflt = pCopy = sqlite3ExprDup(db, pExpr);
if( pCopy ){
sqlite3TokenCopy(db, &pCopy->span, &pExpr->span);
}
}
}
- sqlite3ExprDelete(pExpr);
+ sqlite3ExprDelete(db, pExpr);
}
/*
@@ -55949,7 +57119,7 @@
}
primary_key_exit:
- sqlite3ExprListDelete(pList);
+ sqlite3ExprListDelete(pParse->db, pList);
return;
}
@@ -55960,9 +57130,9 @@
Parse *pParse, /* Parsing context */
Expr *pCheckExpr /* The check expression */
){
+ sqlite3 *db = pParse->db;
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
- sqlite3 *db = pParse->db;
if( pTab && !IN_DECLARE_VTAB ){
/* The CHECK expression must be duplicated so that tokens refer
** to malloced space and not the (ephemeral) text of the CREATE TABLE
@@ -55971,7 +57141,7 @@
sqlite3ExprDup(db, pCheckExpr));
}
#endif
- sqlite3ExprDelete(pCheckExpr);
+ sqlite3ExprDelete(db, pCheckExpr);
}
/*
@@ -55982,11 +57152,12 @@
Table *p;
int i;
char *zColl; /* Dequoted name of collation sequence */
+ sqlite3 *db;
if( (p = pParse->pNewTable)==0 ) return;
i = p->nCol-1;
-
- zColl = sqlite3NameFromToken(pParse->db, pToken);
+ db = pParse->db;
+ zColl = sqlite3NameFromToken(db, pToken);
if( !zColl ) return;
if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
@@ -56004,7 +57175,7 @@
}
}
}else{
- sqlite3_free(zColl);
+ sqlite3DbFree(db, zColl);
}
}
@@ -56291,6 +57462,7 @@
SelectDest dest;
Table *pSelTab;
+ assert(pParse->nTab==0);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, 1);
pParse->nTab = 2;
@@ -56337,7 +57509,7 @@
zStmt,
pParse->regRowid
);
- sqlite3_free(zStmt);
+ sqlite3DbFree(db, zStmt);
sqlite3ChangeCookie(pParse, iDb);
#ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -56427,13 +57599,13 @@
if( pParse->nVar>0 ){
sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
return;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
if( p==0 || pParse->nErr ){
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
return;
}
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
@@ -56441,7 +57613,7 @@
if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
&& sqlite3FixSelect(&sFix, pSelect)
){
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
return;
}
@@ -56451,7 +57623,7 @@
** they will persist after the current sqlite3_exec() call returns.
*/
p->pSelect = sqlite3SelectDup(db, pSelect);
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
if( db->mallocFailed ){
return;
}
@@ -56558,7 +57730,7 @@
pTable->nCol = 0;
nErr++;
}
- sqlite3SelectDelete(pSel);
+ sqlite3SelectDelete(db, pSel);
} else {
nErr++;
}
@@ -56874,7 +58046,7 @@
sqliteViewResetAll(db, iDb);
exit_drop_table:
- sqlite3SrcListDelete(pName);
+ sqlite3SrcListDelete(db, pName);
}
/*
@@ -56909,8 +58081,10 @@
int i;
int nCol;
char *z;
+ sqlite3 *db;
assert( pTo!=0 );
+ db = pParse->db;
if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end;
if( pFromCol==0 ){
int iCol = p->nCol-1;
@@ -56936,7 +58110,7 @@
nByte += strlen(pToCol->a[i].zName) + 1;
}
}
- pFKey = sqlite3DbMallocZero(pParse->db, nByte );
+ pFKey = sqlite3DbMallocZero(db, nByte );
if( pFKey==0 ){
goto fk_end;
}
@@ -56990,10 +58164,10 @@
pFKey = 0;
fk_end:
- sqlite3_free(pFKey);
+ sqlite3DbFree(db, pFKey);
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
- sqlite3ExprListDelete(pFromCol);
- sqlite3ExprListDelete(pToCol);
+ sqlite3ExprListDelete(db, pFromCol);
+ sqlite3ExprListDelete(db, pToCol);
}
/*
@@ -57480,7 +58654,7 @@
iMem,
zStmt
);
- sqlite3_free(zStmt);
+ sqlite3DbFree(db, zStmt);
/* Fill the index with data and reparse the schema. Code an OP_Expire
** to invalidate all pre-compiled statements.
@@ -57520,9 +58694,9 @@
if( pIndex ){
freeIndex(pIndex);
}
- sqlite3ExprListDelete(pList);
- sqlite3SrcListDelete(pTblName);
- sqlite3_free(zName);
+ sqlite3ExprListDelete(db, pList);
+ sqlite3SrcListDelete(db, pTblName);
+ sqlite3DbFree(db, zName);
return;
}
@@ -57651,7 +58825,7 @@
}
exit_drop_index:
- sqlite3SrcListDelete(pName);
+ sqlite3SrcListDelete(db, pName);
}
/*
@@ -57721,7 +58895,7 @@
&i
);
if( i<0 ){
- sqlite3IdListDelete(pList);
+ sqlite3IdListDelete(db, pList);
return 0;
}
pList->a[i].zName = sqlite3NameFromToken(db, pToken);
@@ -57731,14 +58905,14 @@
/*
** Delete an IdList.
*/
-SQLITE_PRIVATE void sqlite3IdListDelete(IdList *pList){
+SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
int i;
if( pList==0 ) return;
for(i=0; i<pList->nId; i++){
- sqlite3_free(pList->a[i].zName);
+ sqlite3DbFree(db, pList->a[i].zName);
}
- sqlite3_free(pList->a);
- sqlite3_free(pList);
+ sqlite3DbFree(db, pList->a);
+ sqlite3DbFree(db, pList);
}
/*
@@ -57797,7 +58971,7 @@
pNew = sqlite3DbRealloc(db, pList,
sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
if( pNew==0 ){
- sqlite3SrcListDelete(pList);
+ sqlite3SrcListDelete(db, pList);
return 0;
}
pList = pNew;
@@ -57841,20 +59015,20 @@
/*
** Delete an entire SrcList including all its substructure.
*/
-SQLITE_PRIVATE void sqlite3SrcListDelete(SrcList *pList){
+SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
int i;
struct SrcList_item *pItem;
if( pList==0 ) return;
for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
- sqlite3_free(pItem->zDatabase);
- sqlite3_free(pItem->zName);
- sqlite3_free(pItem->zAlias);
+ sqlite3DbFree(db, pItem->zDatabase);
+ sqlite3DbFree(db, pItem->zName);
+ sqlite3DbFree(db, pItem->zAlias);
sqlite3DeleteTable(pItem->pTab);
- sqlite3SelectDelete(pItem->pSelect);
- sqlite3ExprDelete(pItem->pOn);
- sqlite3IdListDelete(pItem->pUsing);
+ sqlite3SelectDelete(db, pItem->pSelect);
+ sqlite3ExprDelete(db, pItem->pOn);
+ sqlite3IdListDelete(db, pItem->pUsing);
}
- sqlite3_free(pList);
+ sqlite3DbFree(db, pList);
}
/*
@@ -57887,9 +59061,9 @@
sqlite3 *db = pParse->db;
p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
if( p==0 || p->nSrc==0 ){
- sqlite3ExprDelete(pOn);
- sqlite3IdListDelete(pUsing);
- sqlite3SelectDelete(pSubquery);
+ sqlite3ExprDelete(db, pOn);
+ sqlite3IdListDelete(db, pUsing);
+ sqlite3SelectDelete(db, pSubquery);
return p;
}
pItem = &p->a[p->nSrc-1];
@@ -58194,11 +59368,11 @@
if( pColl ){
if( zColl ){
reindexDatabases(pParse, zColl);
- sqlite3_free(zColl);
+ sqlite3DbFree(db, zColl);
}
return;
}
- sqlite3_free(zColl);
+ sqlite3DbFree(db, zColl);
}
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
@@ -58208,11 +59382,11 @@
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
return;
}
pIndex = sqlite3FindIndex(db, z, zDb);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
if( pIndex ){
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3RefillIndex(pParse, pIndex, -1);
@@ -58227,7 +59401,7 @@
** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
**
** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3_free() on the returned
+** the caller is responsible for calling sqlite3DbFree(db, ) on the returned
** pointer. If an error occurs (out of memory or missing collation
** sequence), NULL is returned and the state of pParse updated to reflect
** the error.
@@ -58236,7 +59410,8 @@
int i;
int nCol = pIdx->nColumn;
int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
- KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes);
+ sqlite3 *db = pParse->db;
+ KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
if( pKey ){
pKey->db = pParse->db;
@@ -58252,7 +59427,7 @@
}
if( pParse->nErr ){
- sqlite3_free(pKey);
+ sqlite3DbFree(db, pKey);
pKey = 0;
}
return pKey;
@@ -58275,7 +59450,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
-** $Id: callback.c,v 1.25 2008/07/08 14:52:10 drh Exp $
+** $Id: callback.c,v 1.26 2008/07/28 19:34:53 drh Exp $
*/
@@ -58291,7 +59466,7 @@
char *zExternal = sqlite3DbStrNDup(db, zName, nName);
if( !zExternal ) return;
db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
- sqlite3_free(zExternal);
+ sqlite3DbFree(db, zExternal);
}
#ifndef SQLITE_OMIT_UTF16
if( db->xCollNeeded16 ){
@@ -58443,7 +59618,7 @@
assert( pDel==0 || pDel==pColl );
if( pDel!=0 ){
db->mallocFailed = 1;
- sqlite3_free(pDel);
+ sqlite3DbFree(db, pDel);
pColl = 0;
}
}
@@ -58573,7 +59748,7 @@
pBest->zName[nName] = 0;
if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
db->mallocFailed = 1;
- sqlite3_free(pBest);
+ sqlite3DbFree(db, pBest);
return 0;
}
}
@@ -58586,7 +59761,7 @@
/*
** Free all resources held by the schema structure. The void* argument points
-** at a Schema struct. This function does not call sqlite3_free() on the
+** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
** pointer itself, it just cleans up subsiduary resources (i.e. the contents
** of the schema hash tables).
**
@@ -58604,7 +59779,7 @@
sqlite3HashClear(&pSchema->aFKey);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
- sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem));
+ sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash, SQLITE_HASH_STRING, 0);
@@ -58656,7 +59831,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
-** $Id: delete.c,v 1.170 2008/07/08 23:40:20 drh Exp $
+** $Id: delete.c,v 1.171 2008/07/28 19:34:53 drh Exp $
*/
/*
@@ -58750,7 +59925,7 @@
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pDup, &dest, 0, 0, 0);
- sqlite3SelectDelete(pDup);
+ sqlite3SelectDelete(db, pDup);
}
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
@@ -59058,8 +60233,8 @@
delete_from_cleanup:
sqlite3AuthContextPop(&sContext);
- sqlite3SrcListDelete(pTabList);
- sqlite3ExprDelete(pWhere);
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprDelete(db, pWhere);
return;
}
@@ -59206,7 +60381,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.195 2008/07/08 22:28:49 shane Exp $
+** $Id: func.c,v 1.196 2008/07/28 19:34:53 drh Exp $
*/
@@ -60017,14 +61192,14 @@
nOut += nRep - nPattern;
if( nOut>=db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
- sqlite3_free(zOut);
+ sqlite3DbFree(db, zOut);
return;
}
zOld = zOut;
zOut = sqlite3_realloc(zOut, (int)nOut);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
- sqlite3_free(zOld);
+ sqlite3DbFree(db, zOld);
return;
}
memcpy(&zOut[j], zRep, nRep);
@@ -60599,7 +61774,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.247 2008/07/08 23:40:20 drh Exp $
+** $Id: insert.c,v 1.248 2008/07/28 19:34:53 drh Exp $
*/
/*
@@ -60631,8 +61806,9 @@
int n;
Table *pTab = pIdx->pTable;
sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3DbMallocRaw(db, pIdx->nColumn+2);
+ pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2);
if( !pIdx->zColAff ){
+ db->mallocFailed = 1;
return;
}
for(n=0; n<pIdx->nColumn; n++){
@@ -60672,8 +61848,9 @@
int i;
sqlite3 *db = sqlite3VdbeDb(v);
- zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1);
+ zColAff = (char *)sqlite3Malloc(pTab->nCol+1);
if( !zColAff ){
+ db->mallocFailed = 1;
return;
}
@@ -61580,11 +62757,11 @@
}
insert_cleanup:
- sqlite3SrcListDelete(pTabList);
- sqlite3ExprListDelete(pList);
- sqlite3SelectDelete(pSelect);
- sqlite3IdListDelete(pColumn);
- sqlite3_free(aRegIdx);
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprListDelete(db, pList);
+ sqlite3SelectDelete(db, pSelect);
+ sqlite3IdListDelete(db, pColumn);
+ sqlite3DbFree(db, aRegIdx);
}
/*
@@ -62339,7 +63516,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: legacy.c,v 1.27 2008/06/15 02:51:47 drh Exp $
+** $Id: legacy.c,v 1.29 2008/08/02 03:50:39 drh Exp $
*/
@@ -62407,10 +63584,9 @@
}
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
- if( !azCols[i] ){
- db->mallocFailed = 1;
- goto exec_out;
- }
+ /* sqlite3VdbeSetColName() installs column names as UTF8
+ ** strings so there is no way for sqlite3_column_name() to fail. */
+ assert( azCols[i]!=0 );
}
nCallback++;
}
@@ -62445,13 +63621,13 @@
}
}
- sqlite3_free(azCols);
+ sqlite3DbFree(db, azCols);
azCols = 0;
}
exec_out:
if( pStmt ) sqlite3_finalize(pStmt);
- if( azCols ) sqlite3_free(azCols);
+ sqlite3DbFree(db, azCols);
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
@@ -62485,7 +63661,7 @@
** This file contains code used to dynamically load extensions into
** the SQLite library.
**
-** $Id: loadext.c,v 1.51 2008/07/08 14:17:35 danielk1977 Exp $
+** $Id: loadext.c,v 1.53 2008/08/02 03:50:39 drh Exp $
*/
#ifndef SQLITE_CORE
@@ -63171,7 +64347,7 @@
**
** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with
** error message text. The calling function should free this memory
-** by calling sqlite3_free().
+** by calling sqlite3DbFree(db, ).
*/
static int sqlite3LoadExtension(
sqlite3 *db, /* Load the extension into this database connection */
@@ -63210,7 +64386,7 @@
sqlite3_snprintf(sizeof(zErr)-1, zErr,
"unable to open shared library [%s]", zFile);
sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(db, zErr);
+ *pzErrMsg = sqlite3DbStrDup(0, zErr);
}
return SQLITE_ERROR;
}
@@ -63223,7 +64399,7 @@
sqlite3_snprintf(sizeof(zErr)-1, zErr,
"no entry point [%s] in shared library [%s]", zProc,zFile);
sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(db, zErr);
+ *pzErrMsg = sqlite3DbStrDup(0, zErr);
sqlite3OsDlClose(pVfs, handle);
}
return SQLITE_ERROR;
@@ -63237,18 +64413,17 @@
}
/* Append the new shared library handle to the db->aExtension array. */
- db->nExtension++;
- aHandle = sqlite3DbMallocZero(db, sizeof(handle)*db->nExtension);
+ aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
if( aHandle==0 ){
return SQLITE_NOMEM;
}
if( db->nExtension>0 ){
- memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1));
+ memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
}
- sqlite3_free(db->aExtension);
+ sqlite3DbFree(db, db->aExtension);
db->aExtension = aHandle;
- db->aExtension[db->nExtension-1] = handle;
+ db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
SQLITE_API int sqlite3_load_extension(
@@ -63274,7 +64449,7 @@
for(i=0; i<db->nExtension; i++){
sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
}
- sqlite3_free(db->aExtension);
+ sqlite3DbFree(db, db->aExtension);
}
/*
@@ -63429,7 +64604,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.182 2008/07/08 07:35:52 danielk1977 Exp $
+** $Id: pragma.c,v 1.183 2008/07/28 19:34:53 drh Exp $
*/
/* Ignore this whole file if pragmas are disabled
@@ -64098,8 +65273,7 @@
}
sqlite3_free(sqlite3_temp_directory);
if( zRight[0] ){
- sqlite3_temp_directory = zRight;
- zRight = 0;
+ sqlite3_temp_directory = sqlite3DbStrDup(0, zRight);
}else{
sqlite3_temp_directory = 0;
}
@@ -64165,9 +65339,12 @@
for (func_elem = sqliteHashFirst (func_hash); func_elem ; func_elem = sqliteHashNext (func_elem)) {
FuncDef *func;
char *sname;
+ int size;
func = sqliteHashData (func_elem);
- sname = sqlite3_mprintf ("%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
+ size = strlen (func->zName) + 25;
+ sname = sqlite3_malloc (sizeof (char) * size);
+ snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
@@ -64778,8 +65955,8 @@
#endif
}
pragma_out:
- sqlite3_free(zLeft);
- sqlite3_free(zRight);
+ sqlite3DbFree(db, zLeft);
+ sqlite3DbFree(db, zRight);
}
#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */
@@ -64801,7 +65978,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.89 2008/07/08 19:34:07 drh Exp $
+** $Id: prepare.c,v 1.91 2008/08/02 03:50:39 drh Exp $
*/
/*
@@ -64818,7 +65995,7 @@
sqlite3SetString(pData->pzErrMsg, pData->db,
"malformed database schema (%s)", zObj);
if( zExtra && zExtra[0] ){
- *pData->pzErrMsg = sqlite3MPrintf(pData->db, "%z - %s",
+ *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s",
*pData->pzErrMsg, zExtra);
}
}
@@ -64865,11 +66042,15 @@
*/
char *zErr;
int rc;
+ u8 lookasideEnabled;
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = atoi(argv[1]);
+ lookasideEnabled = db->lookaside.bEnabled;
+ db->lookaside.bEnabled = 0;
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
db->init.iDb = 0;
+ db->lookaside.bEnabled = lookasideEnabled;
assert( rc!=SQLITE_OK || zErr==0 );
if( SQLITE_OK!=rc ){
pData->rc = rc;
@@ -64878,7 +66059,7 @@
}else if( rc!=SQLITE_INTERRUPT ){
corruptSchema(pData, argv[0], zErr);
}
- sqlite3_free(zErr);
+ sqlite3DbFree(db, zErr);
return 1;
}
}else if( argv[0]==0 ){
@@ -65006,7 +66187,7 @@
rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto leave_error_out;
+ goto initone_error_out;
}
/* Get the database meta information.
@@ -65028,12 +66209,12 @@
*/
if( rc==SQLITE_OK ){
int i;
- for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
+ for(i=0; i<sizeof(meta)/sizeof(meta[0]); i++){
rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
- }
- if( rc ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto leave_error_out;
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
+ goto initone_error_out;
+ }
}
}else{
memset(meta, 0, sizeof(meta));
@@ -65056,7 +66237,7 @@
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
- goto leave_error_out;
+ goto initone_error_out;
}
}
}else{
@@ -65085,7 +66266,7 @@
if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
sqlite3SetString(pzErrMsg, db, "unsupported file format");
rc = SQLITE_ERROR;
- goto leave_error_out;
+ goto initone_error_out;
}
/* Ticket #2804: When we open a database in the newer file format,
@@ -65122,7 +66303,7 @@
#endif
if( rc==SQLITE_ABORT ) rc = initData.rc;
(void)sqlite3SafetyOn(db);
- sqlite3_free(zSql);
+ sqlite3DbFree(db, zSql);
#ifndef SQLITE_OMIT_ANALYZE
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
@@ -65150,7 +66331,7 @@
** curMain and calling sqlite3BtreeEnter(). For an error that occurs
** before that point, jump to error_out.
*/
-leave_error_out:
+initone_error_out:
sqlite3BtreeCloseCursor(curMain);
sqlite3_free(curMain);
sqlite3BtreeLeave(pDb->pBt);
@@ -65354,7 +66535,7 @@
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
- sqlite3_free(zSqlCopy);
+ sqlite3DbFree(db, zSqlCopy);
sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
}else{
sParse.zTail = &zSql[nBytes];
@@ -65418,7 +66599,7 @@
if( zErrMsg ){
sqlite3Error(db, rc, "%s", zErrMsg);
- sqlite3_free(zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
}else{
sqlite3Error(db, rc, 0);
}
@@ -65553,7 +66734,7 @@
int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8);
*pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
}
- sqlite3_free(zSql8);
+ sqlite3DbFree(db, zSql8);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -65610,7 +66791,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.457 2008/07/15 20:56:17 drh Exp $
+** $Id: select.c,v 1.463 2008/08/04 03:51:24 danielk1977 Exp $
*/
@@ -65618,16 +66799,16 @@
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
*/
-static void clearSelect(Select *p){
- sqlite3ExprListDelete(p->pEList);
- sqlite3SrcListDelete(p->pSrc);
- sqlite3ExprDelete(p->pWhere);
- sqlite3ExprListDelete(p->pGroupBy);
- sqlite3ExprDelete(p->pHaving);
- sqlite3ExprListDelete(p->pOrderBy);
- sqlite3SelectDelete(p->pPrior);
- sqlite3ExprDelete(p->pLimit);
- sqlite3ExprDelete(p->pOffset);
+static void clearSelect(sqlite3 *db, Select *p){
+ sqlite3ExprListDelete(db, p->pEList);
+ sqlite3SrcListDelete(db, p->pSrc);
+ sqlite3ExprDelete(db, p->pWhere);
+ sqlite3ExprListDelete(db, p->pGroupBy);
+ sqlite3ExprDelete(db, p->pHaving);
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ sqlite3SelectDelete(db, p->pPrior);
+ sqlite3ExprDelete(db, p->pLimit);
+ sqlite3ExprDelete(db, p->pOffset);
}
/*
@@ -65685,7 +66866,7 @@
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
if( pNew==&standin) {
- clearSelect(pNew);
+ clearSelect(db, pNew);
pNew = 0;
}
return pNew;
@@ -65694,10 +66875,10 @@
/*
** Delete the given Select structure and all of its substructures.
*/
-SQLITE_PRIVATE void sqlite3SelectDelete(Select *p){
+SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
if( p ){
- clearSelect(p);
- sqlite3_free(p);
+ clearSelect(db, p);
+ sqlite3DbFree(db, p);
}
}
@@ -66760,12 +67941,14 @@
if( pTab==0 ){
return 0;
}
+ pTab->db = db;
pTab->nRef = 1;
pTab->zName = zTabName ? sqlite3DbStrDup(db, zTabName) : 0;
pEList = pSelect->pEList;
pTab->nCol = pEList->nExpr;
assert( pTab->nCol>0 );
pTab->aCol = aCol = sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol);
+ testcase( aCol==0 );
for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
Expr *p;
char *zType;
@@ -66791,11 +67974,9 @@
/* Use the original text of the column expression as its name */
zName = sqlite3MPrintf(db, "%T", &p->span);
}
- if( !zName || db->mallocFailed ){
- db->mallocFailed = 1;
- sqlite3_free(zName);
- sqlite3DeleteTable(pTab);
- return 0;
+ if( db->mallocFailed ){
+ sqlite3DbFree(db, zName);
+ break;
}
sqlite3Dequote(zName);
@@ -66805,8 +67986,11 @@
nName = strlen(zName);
for(j=cnt=0; j<i; j++){
if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
+ char *zNewName;
zName[nName] = 0;
- zName = sqlite3MPrintf(db, "%z:%d", zName, ++cnt);
+ zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
+ sqlite3DbFree(db, zName);
+ zName = zNewName;
j = -1;
if( zName==0 ) break;
}
@@ -66827,6 +68011,10 @@
}
}
pTab->iPKey = -1;
+ if( db->mallocFailed ){
+ sqlite3DeleteTable(pTab);
+ return 0;
+ }
return pTab;
}
@@ -67068,10 +68256,10 @@
}
rc = 1;
}
- sqlite3_free(zTName);
+ sqlite3DbFree(db, zTName);
}
}
- sqlite3ExprListDelete(pEList);
+ sqlite3ExprListDelete(db, pEList);
p->pEList = pNew;
}
#if SQLITE_MAX_COLUMN
@@ -67132,11 +68320,11 @@
for(i=0; i<pEList->nExpr; i++){
char *zAs = pEList->a[i].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
return i+1;
}
}
- sqlite3_free(zCol);
+ sqlite3DbFree(db, zCol);
}
/* Resolve all names in the ORDER BY term expression
@@ -67225,7 +68413,7 @@
if( iCol>0 ){
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
- sqlite3ExprDelete(pE);
+ sqlite3ExprDelete(db, pE);
pE = sqlite3ExprDup(db, pEList->a[iCol-1].pExpr);
pOrderBy->a[i].pExpr = pE;
if( pE && pColl && flags ){
@@ -67296,7 +68484,7 @@
assert(pDup);
iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
}
- sqlite3ExprDelete(pDup);
+ sqlite3ExprDelete(db, pDup);
if( iCol<0 ){
return 1;
}
@@ -67476,14 +68664,13 @@
Vdbe *v; /* Generate code to this VDBE */
SelectDest dest; /* Alternative data destination */
Select *pDelete = 0; /* Chain of simple selects to delete */
+ sqlite3 *db; /* Database connection */
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
*/
- if( p==0 || p->pPrior==0 ){
- rc = 1;
- goto multi_select_end;
- }
+ assert( p && p->pPrior ); /* Calling function guarantees this much */
+ db = pParse->db;
pPrior = p->pPrior;
assert( pPrior->pRightmost!=pPrior );
assert( pPrior->pRightmost==p->pRightmost );
@@ -67500,13 +68687,8 @@
goto multi_select_end;
}
- /* Make sure we have a valid query engine. If not, create a new one.
- */
v = sqlite3GetVdbe(pParse);
- if( v==0 ){
- rc = 1;
- goto multi_select_end;
- }
+ assert( v!=0 ); /* The VDBE already created by calling function */
/* Create the destination temporary table if necessary
*/
@@ -67605,10 +68787,11 @@
/* Code the current SELECT statement
*/
- switch( p->op ){
- case TK_EXCEPT: op = SRT_Except; break;
- case TK_UNION: op = SRT_Union; break;
- case TK_ALL: op = SRT_Table; break;
+ if( p->op==TK_EXCEPT ){
+ op = SRT_Except;
+ }else{
+ assert( p->op==TK_UNION );
+ op = SRT_Union;
}
p->pPrior = 0;
p->disallowOrderBy = 0;
@@ -67620,11 +68803,11 @@
rc = sqlite3Select(pParse, p, &uniondest, 0, 0, 0);
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
- sqlite3ExprListDelete(p->pOrderBy);
+ sqlite3ExprListDelete(db, p->pOrderBy);
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
- sqlite3ExprDelete(p->pLimit);
+ sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
p->iLimit = 0;
@@ -67703,7 +68886,7 @@
rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0);
pDelete = p->pPrior;
p->pPrior = pPrior;
- sqlite3ExprDelete(p->pLimit);
+ sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
if( rc ){
@@ -67756,20 +68939,20 @@
assert( p->pRightmost==p );
nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3DbMallocZero(pParse->db,
+ pKeyInfo = sqlite3DbMallocZero(db,
sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
if( !pKeyInfo ){
rc = SQLITE_NOMEM;
goto multi_select_end;
}
- pKeyInfo->enc = ENC(pParse->db);
+ pKeyInfo->enc = ENC(db);
pKeyInfo->nField = nCol;
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
*apColl = multiSelectCollSeq(pParse, p, i);
if( 0==*apColl ){
- *apColl = pParse->db->pDfltColl;
+ *apColl = db->pDfltColl;
}
}
@@ -67787,13 +68970,13 @@
pLoop->addrOpenEphm[i] = -1;
}
}
- sqlite3_free(pKeyInfo);
+ sqlite3DbFree(db, pKeyInfo);
}
multi_select_end:
pDest->iMem = dest.iMem;
pDest->nMem = dest.nMem;
- sqlite3SelectDelete(pDelete);
+ sqlite3SelectDelete(db, pDelete);
return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
@@ -68042,6 +69225,7 @@
** until all data is exhausted then jump to the "end" labe. AltB, AeqB,
** and AgtB jump to either L2 or to one of EofA or EofB.
*/
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
static int multiSelectOrderBy(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
@@ -68216,9 +69400,9 @@
}else{
regLimitA = regLimitB = 0;
}
- sqlite3ExprDelete(p->pLimit);
+ sqlite3ExprDelete(db, p->pLimit);
p->pLimit = 0;
- sqlite3ExprDelete(p->pOffset);
+ sqlite3ExprDelete(db, p->pOffset);
p->pOffset = 0;
regAddrA = ++pParse->nMem;
@@ -68380,7 +69564,7 @@
/* Reassembly the compound query so that it will be freed correctly
** by the calling function */
if( p->pPrior ){
- sqlite3SelectDelete(p->pPrior);
+ sqlite3SelectDelete(db, p->pPrior);
}
p->pPrior = pPrior;
@@ -68388,8 +69572,9 @@
**** subqueries ****/
return SQLITE_OK;
}
+#endif
-#ifndef SQLITE_OMIT_VIEW
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Forward Declarations */
static void substExprList(sqlite3*, ExprList*, int, ExprList*);
static void substSelect(sqlite3*, Select *, int, ExprList *);
@@ -68472,9 +69657,9 @@
substExpr(db, p->pWhere, iTable, pEList);
substSelect(db, p->pPrior, iTable, pEList);
}
-#endif /* !defined(SQLITE_OMIT_VIEW) */
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-#ifndef SQLITE_OMIT_VIEW
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries in order to speed
** execution. It returns 1 if it makes changes and 0 if no flattening
@@ -68749,9 +69934,9 @@
nSubSrc = pSubSrc->nSrc;
jointype = pSubitem->jointype;
sqlite3DeleteTable(pSubitem->pTab);
- sqlite3_free(pSubitem->zDatabase);
- sqlite3_free(pSubitem->zName);
- sqlite3_free(pSubitem->zAlias);
+ sqlite3DbFree(db, pSubitem->zDatabase);
+ sqlite3DbFree(db, pSubitem->zName);
+ sqlite3DbFree(db, pSubitem->zAlias);
pSubitem->pTab = 0;
pSubitem->zDatabase = 0;
pSubitem->zName = 0;
@@ -68848,11 +70033,11 @@
/* Finially, delete what is left of the subquery and return
** success.
*/
- sqlite3SelectDelete(pSub1);
+ sqlite3SelectDelete(db, pSub1);
return 1;
}
-#endif /* SQLITE_OMIT_VIEW */
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
** Analyze the SELECT statement passed as an argument to see if it
@@ -69119,33 +70304,6 @@
pAggInfo->directMode = 0;
}
-#if 0
-/*
-** This function is used when a SELECT statement is used to create a
-** temporary table for iterating through when running an INSTEAD OF
-** UPDATE or INSTEAD OF DELETE trigger.
-**
-** If possible, the SELECT statement is modified so that NULL values
-** are stored in the temporary table for all columns for which the
-** corresponding bit in argument mask is not set. If mask takes the
-** special value 0xffffffff, then all columns are populated.
-*/
-SQLITE_PRIVATE void sqlite3SelectMask(Parse *pParse, Select *p, u32 mask){
- if( p && !p->pPrior && !p->isDistinct && mask!=0xffffffff ){
- ExprList *pEList;
- int i;
- sqlite3SelectResolve(pParse, p, 0);
- pEList = p->pEList;
- for(i=0; pEList && i<pEList->nExpr && i<32; i++){
- if( !(mask&((u32)1<<i)) ){
- sqlite3ExprDelete(pEList->a[i].pExpr);
- pEList->a[i].pExpr = sqlite3Expr(pParse->db, TK_NULL, 0, 0, 0);
- }
- }
- }
-}
-#endif
-
/*
** Generate code for the given SELECT statement.
**
@@ -69614,12 +70772,20 @@
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
int r1 = j + regBase;
- int r2 = sqlite3ExprCodeGetColumn(pParse,
+#ifndef NDEBUG
+ int r2 =
+#endif
+ sqlite3ExprCodeGetColumn(pParse,
pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
- if( r1!=r2 ){
- sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
- }
j++;
+
+ /* sAggInfo.aCol[] only contains one entry per column. So
+ ** The reference to pCol->iColumn,pCol->iTable must have been
+ ** the first reference to that column. Hence,
+ ** sqliteExprCodeGetColumn is guaranteed to put the result in
+ ** the column requested.
+ */
+ assert( r1==r2 );
}
}
regRecord = sqlite3GetTempReg(pParse);
@@ -69738,7 +70904,7 @@
resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, flag);
if( pWInfo==0 ){
- sqlite3ExprListDelete(pDel);
+ sqlite3ExprListDelete(db, pDel);
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
@@ -69755,7 +70921,7 @@
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd);
- sqlite3ExprListDelete(pDel);
+ sqlite3ExprListDelete(db, pDel);
}
sqlite3VdbeResolveLabel(v, addrEnd);
@@ -69802,8 +70968,8 @@
generateColumnNames(pParse, pTabList, pEList);
}
- sqlite3_free(sAggInfo.aCol);
- sqlite3_free(sAggInfo.aFunc);
+ sqlite3DbFree(db, sAggInfo.aCol);
+ sqlite3DbFree(db, sAggInfo.aFunc);
return rc;
}
@@ -70118,25 +71284,25 @@
*************************************************************************
**
**
-** $Id: trigger.c,v 1.127 2008/07/08 23:40:20 drh Exp $
+** $Id: trigger.c,v 1.128 2008/07/28 19:34:54 drh Exp $
*/
#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
+SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
while( pTriggerStep ){
TriggerStep * pTmp = pTriggerStep;
pTriggerStep = pTriggerStep->pNext;
- if( pTmp->target.dyn ) sqlite3_free((char*)pTmp->target.z);
- sqlite3ExprDelete(pTmp->pWhere);
- sqlite3ExprListDelete(pTmp->pExprList);
- sqlite3SelectDelete(pTmp->pSelect);
- sqlite3IdListDelete(pTmp->pIdList);
+ if( pTmp->target.dyn ) sqlite3DbFree(db, (char*)pTmp->target.z);
+ sqlite3ExprDelete(db, pTmp->pWhere);
+ sqlite3ExprListDelete(db, pTmp->pExprList);
+ sqlite3SelectDelete(db, pTmp->pSelect);
+ sqlite3IdListDelete(db, pTmp->pIdList);
- sqlite3_free(pTmp);
+ sqlite3DbFree(db, pTmp);
}
}
@@ -70293,12 +71459,12 @@
pParse->pNewTrigger = pTrigger;
trigger_cleanup:
- sqlite3_free(zName);
- sqlite3SrcListDelete(pTableName);
- sqlite3IdListDelete(pColumns);
- sqlite3ExprDelete(pWhen);
+ sqlite3DbFree(db, zName);
+ sqlite3SrcListDelete(db, pTableName);
+ sqlite3IdListDelete(db, pColumns);
+ sqlite3ExprDelete(db, pWhen);
if( !pParse->pNewTrigger ){
- sqlite3DeleteTrigger(pTrigger);
+ sqlite3DeleteTrigger(db, pTrigger);
}else{
assert( pParse->pNewTrigger==pTrigger );
}
@@ -70348,7 +71514,7 @@
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrig->name,
pTrig->table, z);
- sqlite3_free(z);
+ sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
@@ -70375,9 +71541,9 @@
}
triggerfinish_cleanup:
- sqlite3DeleteTrigger(pTrig);
+ sqlite3DeleteTrigger(db, pTrig);
assert( !pParse->pNewTrigger );
- sqlite3DeleteTriggerStep(pStepList);
+ sqlite3DeleteTriggerStep(db, pStepList);
}
/*
@@ -70397,22 +71563,22 @@
}
if( p->pSelect ){
Select *pNew = sqlite3SelectDup(db, p->pSelect);
- sqlite3SelectDelete(p->pSelect);
+ sqlite3SelectDelete(db, p->pSelect);
p->pSelect = pNew;
}
if( p->pWhere ){
Expr *pNew = sqlite3ExprDup(db, p->pWhere);
- sqlite3ExprDelete(p->pWhere);
+ sqlite3ExprDelete(db, p->pWhere);
p->pWhere = pNew;
}
if( p->pExprList ){
ExprList *pNew = sqlite3ExprListDup(db, p->pExprList);
- sqlite3ExprListDelete(p->pExprList);
+ sqlite3ExprListDelete(db, p->pExprList);
p->pExprList = pNew;
}
if( p->pIdList ){
IdList *pNew = sqlite3IdListDup(db, p->pIdList);
- sqlite3IdListDelete(p->pIdList);
+ sqlite3IdListDelete(db, p->pIdList);
p->pIdList = pNew;
}
}
@@ -70427,7 +71593,7 @@
SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ) {
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
return 0;
}
@@ -70469,9 +71635,9 @@
pTriggerStep->orconf = orconf;
sqlitePersistTriggerStep(db, pTriggerStep);
}else{
- sqlite3IdListDelete(pColumn);
- sqlite3ExprListDelete(pEList);
- sqlite3SelectDelete(pSelect);
+ sqlite3IdListDelete(db, pColumn);
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3SelectDelete(db, pSelect);
}
return pTriggerStep;
@@ -70491,8 +71657,8 @@
){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ){
- sqlite3ExprListDelete(pEList);
- sqlite3ExprDelete(pWhere);
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3ExprDelete(db, pWhere);
return 0;
}
@@ -70518,7 +71684,7 @@
){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ){
- sqlite3ExprDelete(pWhere);
+ sqlite3ExprDelete(db, pWhere);
return 0;
}
@@ -70534,15 +71700,15 @@
/*
** Recursively delete a Trigger structure
*/
-SQLITE_PRIVATE void sqlite3DeleteTrigger(Trigger *pTrigger){
+SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
if( pTrigger==0 ) return;
- sqlite3DeleteTriggerStep(pTrigger->step_list);
- sqlite3_free(pTrigger->name);
- sqlite3_free(pTrigger->table);
- sqlite3ExprDelete(pTrigger->pWhen);
- sqlite3IdListDelete(pTrigger->pColumns);
- if( pTrigger->nameToken.dyn ) sqlite3_free((char*)pTrigger->nameToken.z);
- sqlite3_free(pTrigger);
+ sqlite3DeleteTriggerStep(db, pTrigger->step_list);
+ sqlite3DbFree(db, pTrigger->name);
+ sqlite3DbFree(db, pTrigger->table);
+ sqlite3ExprDelete(db, pTrigger->pWhen);
+ sqlite3IdListDelete(db, pTrigger->pColumns);
+ if( pTrigger->nameToken.dyn ) sqlite3DbFree(db, (char*)pTrigger->nameToken.z);
+ sqlite3DbFree(db, pTrigger);
}
/*
@@ -70585,7 +71751,7 @@
sqlite3DropTriggerPtr(pParse, pTrigger);
drop_trigger_cleanup:
- sqlite3SrcListDelete(pName);
+ sqlite3SrcListDelete(db, pName);
}
/*
@@ -70677,7 +71843,7 @@
}
assert(cc);
}
- sqlite3DeleteTrigger(pTrigger);
+ sqlite3DeleteTrigger(db, pTrigger);
db->flags |= SQLITE_InternChanges;
}
}
@@ -70788,7 +71954,7 @@
sqlite3SelectDestInit(&dest, SRT_Discard, 0);
sqlite3SelectResolve(pParse, ss, 0);
sqlite3Select(pParse, ss, &dest, 0, 0, 0);
- sqlite3SelectDelete(ss);
+ sqlite3SelectDelete(db, ss);
}
break;
}
@@ -70938,11 +72104,11 @@
whenExpr = sqlite3ExprDup(db, p->pWhen);
if( db->mallocFailed || sqlite3ExprResolveNames(&sNC, whenExpr) ){
pParse->trigStack = trigStackEntry.pNext;
- sqlite3ExprDelete(whenExpr);
+ sqlite3ExprDelete(db, whenExpr);
return 1;
}
sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);
- sqlite3ExprDelete(whenExpr);
+ sqlite3ExprDelete(db, whenExpr);
codeTriggerProgram(pParse, p->step_list, orconf);
@@ -70975,7 +72141,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.180 2008/07/09 16:51:51 drh Exp $
+** $Id: update.c,v 1.181 2008/07/28 19:34:54 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -71532,11 +72698,11 @@
update_cleanup:
sqlite3AuthContextPop(&sContext);
- sqlite3_free(aRegIdx);
- sqlite3_free(aXRef);
- sqlite3SrcListDelete(pTabList);
- sqlite3ExprListDelete(pChanges);
- sqlite3ExprDelete(pWhere);
+ sqlite3DbFree(db, aRegIdx);
+ sqlite3DbFree(db, aXRef);
+ sqlite3SrcListDelete(db, pTabList);
+ sqlite3ExprListDelete(db, pChanges);
+ sqlite3ExprDelete(db, pWhere);
return;
}
@@ -71630,7 +72796,7 @@
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
/* Cleanup */
- sqlite3SelectDelete(pSelect);
+ sqlite3SelectDelete(db, pSelect);
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -71948,7 +73114,7 @@
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.70 2008/06/23 17:44:19 danielk1977 Exp $
+** $Id: vtab.c,v 1.74 2008/08/02 03:50:39 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -71977,7 +73143,7 @@
if( pDel && pDel->xDestroy ){
pDel->xDestroy(pDel->pAux);
}
- sqlite3_free(pDel);
+ sqlite3DbFree(db, pDel);
if( pDel==pMod ){
db->mallocFailed = 1;
}
@@ -72052,17 +73218,18 @@
*/
SQLITE_PRIVATE void sqlite3VtabClear(Table *p){
sqlite3_vtab *pVtab = p->pVtab;
+ sqlite3 *db = p->db;
if( pVtab ){
assert( p->pMod && p->pMod->pModule );
- sqlite3VtabUnlock(p->pSchema->db, pVtab);
+ sqlite3VtabUnlock(db, pVtab);
p->pVtab = 0;
}
if( p->azModuleArg ){
int i;
for(i=0; i<p->nModuleArg; i++){
- sqlite3_free(p->azModuleArg[i]);
+ sqlite3DbFree(db, p->azModuleArg[i]);
}
- sqlite3_free(p->azModuleArg);
+ sqlite3DbFree(db, p->azModuleArg);
}
}
@@ -72080,10 +73247,10 @@
if( azModuleArg==0 ){
int j;
for(j=0; j<i; j++){
- sqlite3_free(pTable->azModuleArg[j]);
+ sqlite3DbFree(db, pTable->azModuleArg[j]);
}
- sqlite3_free(zArg);
- sqlite3_free(pTable->azModuleArg);
+ sqlite3DbFree(db, zArg);
+ sqlite3DbFree(db, pTable->azModuleArg);
pTable->nModuleArg = 0;
}else{
azModuleArg[i] = zArg;
@@ -72214,7 +73381,7 @@
zStmt,
pParse->regRowid
);
- sqlite3_free(zStmt);
+ sqlite3DbFree(db, zStmt);
v = sqlite3GetVdbe(pParse);
sqlite3ChangeCookie(pParse, iDb);
@@ -72313,7 +73480,7 @@
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
}else {
*pzErr = sqlite3MPrintf(db, "%s", zErr);
- sqlite3_free(zErr);
+ sqlite3DbFree(db, zErr);
}
}else if( db->pVTab ){
const char *zFormat = "vtable constructor did not declare schema: %s";
@@ -72324,7 +73491,7 @@
rc = rc2;
}
db->pVTab = 0;
- sqlite3_free(zModuleName);
+ sqlite3DbFree(db, zModuleName);
/* If everything went according to plan, loop through the columns
** of the table to see if any of them contain the token "hidden".
@@ -72393,7 +73560,7 @@
if( rc!=SQLITE_OK ){
sqlite3ErrorMsg(pParse, "%s", zErr);
}
- sqlite3_free(zErr);
+ sqlite3DbFree(db, zErr);
}
return rc;
@@ -72429,7 +73596,7 @@
**
** If an error occurs, *pzErr is set to point an an English language
** description of the error and an SQLITE_XXX error code is returned.
-** In this case the caller must call sqlite3_free() on *pzErr.
+** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
*/
SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
int rc = SQLITE_OK;
@@ -72498,7 +73665,7 @@
db->pVTab = 0;
} else {
sqlite3Error(db, SQLITE_ERROR, zErr);
- sqlite3_free(zErr);
+ sqlite3DbFree(db, zErr);
rc = SQLITE_ERROR;
}
sParse.declareVtab = 0;
@@ -72568,24 +73735,25 @@
if( x ) x(pVtab);
sqlite3VtabUnlock(db, pVtab);
}
- sqlite3_free(db->aVTrans);
+ sqlite3DbFree(db, db->aVTrans);
db->nVTrans = 0;
db->aVTrans = 0;
}
}
/*
-** If argument rc2 is not SQLITE_OK, then return it and do nothing.
-** Otherwise, invoke the xSync method of all virtual tables in the
-** sqlite3.aVTrans array. Return the error code for the first error
-** that occurs, or SQLITE_OK if all xSync operations are successful.
+** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
+** array. Return the error code for the first error that occurs, or
+** SQLITE_OK if all xSync operations are successful.
+**
+** Set *pzErrmsg to point to a buffer that should be released using
+** sqlite3DbFree() containing an error message, if one is available.
*/
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, int rc2){
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
int i;
int rc = SQLITE_OK;
int rcsafety;
sqlite3_vtab **aVTrans = db->aVTrans;
- if( rc2!=SQLITE_OK ) return rc2;
rc = sqlite3SafetyOff(db);
db->aVTrans = 0;
@@ -72595,6 +73763,9 @@
x = pVtab->pModule->xSync;
if( x ){
rc = x(pVtab);
+ sqlite3DbFree(db, *pzErrmsg);
+ *pzErrmsg = pVtab->zErrMsg;
+ pVtab->zErrMsg = 0;
}
}
db->aVTrans = aVTrans;
@@ -72662,11 +73833,9 @@
/* Invoke the xBegin method */
rc = pModule->xBegin(pVtab);
- if( rc!=SQLITE_OK ){
- return rc;
+ if( rc==SQLITE_OK ){
+ rc = addToVTrans(db, pVtab);
}
-
- rc = addToVTrans(db, pVtab);
}
return rc;
}
@@ -72722,7 +73891,12 @@
*z = sqlite3UpperToLower[*z];
}
rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
- sqlite3_free(zLowerName);
+ sqlite3DbFree(db, zLowerName);
+ if( pVtab->zErrMsg ){
+ sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
+ sqlite3DbFree(db, pVtab->zErrMsg);
+ pVtab->zErrMsg = 0;
+ }
}
if( rc==0 ){
return pDef;
@@ -72785,7 +73959,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.317 2008/07/12 14:52:20 drh Exp $
+** $Id: where.c,v 1.319 2008/08/01 17:37:41 danielk1977 Exp $
*/
/*
@@ -72860,7 +74034,7 @@
/*
** Allowed values of WhereTerm.flags
*/
-#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(pExpr) */
+#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */
#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */
#define TERM_CODED 0x04 /* This term is already coded */
#define TERM_COPIED 0x08 /* Has a child */
@@ -72971,13 +74145,14 @@
static void whereClauseClear(WhereClause *pWC){
int i;
WhereTerm *a;
+ sqlite3 *db = pWC->pParse->db;
for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
if( a->flags & TERM_DYNAMIC ){
- sqlite3ExprDelete(a->pExpr);
+ sqlite3ExprDelete(db, a->pExpr);
}
}
if( pWC->a!=pWC->aStatic ){
- sqlite3_free(pWC->a);
+ sqlite3DbFree(db, pWC->a);
}
}
@@ -72998,18 +74173,18 @@
int idx;
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
- pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
+ sqlite3 *db = pWC->pParse->db;
+ pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
- pWC->pParse->db->mallocFailed = 1;
if( flags & TERM_DYNAMIC ){
- sqlite3ExprDelete(p);
+ sqlite3ExprDelete(db, p);
}
pWC->a = pOld;
return 0;
}
memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
if( pOld!=pWC->aStatic ){
- sqlite3_free(pOld);
+ sqlite3DbFree(db, pOld);
}
pWC->nSlot *= 2;
}
@@ -73541,7 +74716,7 @@
int idxNew;
pDup = sqlite3ExprDup(db, pExpr);
if( db->mallocFailed ){
- sqlite3ExprDelete(pDup);
+ sqlite3ExprDelete(db, pDup);
return;
}
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
@@ -73657,7 +74832,7 @@
pWC->a[idxNew].iParent = idxTerm;
pTerm->nChild = 1;
}else{
- sqlite3ExprListDelete(pList);
+ sqlite3ExprListDelete(db, pList);
}
}
or_not_possible:
@@ -74026,6 +75201,7 @@
sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */
){
Table *pTab = pSrc->pTab;
+ sqlite3_vtab *pVtab = pTab->pVtab;
sqlite3_index_info *pIdxInfo;
struct sqlite3_index_constraint *pIdxCons;
struct sqlite3_index_orderby *pIdxOrderBy;
@@ -74137,7 +75313,7 @@
** sqlite3ViewGetColumnNames() would have picked up the error.
*/
assert( pTab->azModuleArg && pTab->azModuleArg[0] );
- assert( pTab->pVtab );
+ assert( pVtab );
#if 0
if( pTab->pVtab==0 ){
sqlite3ErrorMsg(pParse, "undefined module %s for table %s",
@@ -74190,10 +75366,22 @@
(void)sqlite3SafetyOff(pParse->db);
WHERETRACE(("xBestIndex for %s\n", pTab->zName));
TRACE_IDX_INPUTS(pIdxInfo);
- rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo);
+ rc = pVtab->pModule->xBestIndex(pVtab, pIdxInfo);
TRACE_IDX_OUTPUTS(pIdxInfo);
(void)sqlite3SafetyOn(pParse->db);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_NOMEM ){
+ pParse->db->mallocFailed = 1;
+ }else if( !pVtab->zErrMsg ){
+ sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
+ }else{
+ sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
+ }
+ }
+ sqlite3DbFree(pParse->db, pVtab->zErrMsg);
+ pVtab->zErrMsg = 0;
+
for(i=0; i<pIdxInfo->nConstraint; i++){
if( !pIdxInfo->aConstraint[i].usable && pUsage[i].argvIndex>0 ){
sqlite3ErrorMsg(pParse,
@@ -74202,15 +75390,7 @@
}
}
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ){
- pParse->db->mallocFailed = 1;
- }else {
- sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
- }
- }
*(int*)&pIdxInfo->nOrderBy = nOrderBy;
-
return pIdxInfo->estimatedCost;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -74676,14 +75856,15 @@
static void whereInfoFree(WhereInfo *pWInfo){
if( pWInfo ){
int i;
+ sqlite3 *db = pWInfo->pParse->db;
for(i=0; i<pWInfo->nLevel; i++){
sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
if( pInfo ){
assert( pInfo->needToFreeIdxStr==0 );
- sqlite3_free(pInfo);
+ sqlite3DbFree(db, pInfo);
}
}
- sqlite3_free(pWInfo);
+ sqlite3DbFree(db, pWInfo);
}
}
@@ -75016,22 +76197,22 @@
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
zMsg = sqlite3MPrintf(db, "TABLE %s", pItem->zName);
if( pItem->zAlias ){
- zMsg = sqlite3MPrintf(db, "%z AS %s", zMsg, pItem->zAlias);
+ zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
}
if( (pIx = pLevel->pIdx)!=0 ){
- zMsg = sqlite3MPrintf(db, "%z WITH INDEX %s", zMsg, pIx->zName);
+ zMsg = sqlite3MAppendf(db, zMsg, "%s WITH INDEX %s", zMsg, pIx->zName);
}else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- zMsg = sqlite3MPrintf(db, "%z USING PRIMARY KEY", zMsg);
+ zMsg = sqlite3MAppendf(db, zMsg, "%s USING PRIMARY KEY", zMsg);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( pLevel->pBestIdx ){
sqlite3_index_info *pBestIdx = pLevel->pBestIdx;
- zMsg = sqlite3MPrintf(db, "%z VIRTUAL TABLE INDEX %d:%s", zMsg,
+ zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
pBestIdx->idxNum, pBestIdx->idxStr);
}
#endif
if( pLevel->flags & WHERE_ORDERBY ){
- zMsg = sqlite3MPrintf(db, "%z ORDER BY", zMsg);
+ zMsg = sqlite3MAppendf(db, zMsg, "%s ORDER BY", zMsg);
}
sqlite3VdbeAddOp4(v, OP_Explain, i, pLevel->iFrom, 0, zMsg, P4_DYNAMIC);
}
@@ -75547,14 +76728,16 @@
** sqlite3WhereBegin() for additional information.
*/
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
- Vdbe *v = pWInfo->pParse->pVdbe;
+ Parse *pParse = pWInfo->pParse;
+ Vdbe *v = pParse->pVdbe;
int i;
WhereLevel *pLevel;
SrcList *pTabList = pWInfo->pTabList;
+ sqlite3 *db = pParse->db;
/* Generate loop termination code.
*/
- sqlite3ExprClearColumnCache(pWInfo->pParse, -1);
+ sqlite3ExprClearColumnCache(pParse, -1);
for(i=pTabList->nSrc-1; i>=0; i--){
pLevel = &pWInfo->a[i];
sqlite3VdbeResolveLabel(v, pLevel->cont);
@@ -75570,7 +76753,7 @@
sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->topAddr);
sqlite3VdbeJumpHere(v, pIn->topAddr-1);
}
- sqlite3_free(pLevel->aInLoop);
+ sqlite3DbFree(db, pLevel->aInLoop);
}
sqlite3VdbeResolveLabel(v, pLevel->brk);
if( pLevel->iLeftJoin ){
@@ -76409,11 +77592,11 @@
** It is sometimes called the "minor" token.
*/
struct yyStackEntry {
- int stateno; /* The state-number */
- int major; /* The major token value. This is the code
- ** number for the token at this stack level */
- YYMINORTYPE minor; /* The user-supplied minor token value. This
- ** is the value of the token */
+ YYACTIONTYPE stateno; /* The state-number */
+ YYCODETYPE major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
};
typedef struct yyStackEntry yyStackEntry;
@@ -76421,6 +77604,9 @@
** the following structure */
struct yyParser {
int yyidx; /* Index of top element in stack */
+#ifdef YYTRACKMAXSTACKDEPTH
+ int yyidxMax; /* Maximum value of yyidx */
+#endif
int yyerrcnt; /* Shifts left before out of the error */
sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
@@ -76893,6 +78079,9 @@
pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
if( pParser ){
pParser->yyidx = -1;
+#ifdef YYTRACKMAXSTACKDEPTH
+ pParser->yyidxMax = 0;
+#endif
#if YYSTACKDEPTH<=0
yyGrowStack(pParser);
#endif
@@ -76905,7 +78094,12 @@
** "yymajor" is the symbol code, and "yypminor" is a pointer to
** the value.
*/
-static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+static void yy_destructor(
+ yyParser *yypParser, /* The parser */
+ YYCODETYPE yymajor, /* Type code for object to destroy */
+ YYMINORTYPE *yypminor /* The object to be destroyed */
+){
+ sqlite3ParserARG_FETCH;
switch( yymajor ){
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
@@ -76921,7 +78115,7 @@
case 189: /* oneselect */
case 206: /* seltablist_paren */
{
-sqlite3SelectDelete((yypminor->yy219));
+sqlite3SelectDelete(pParse->db, (yypminor->yy219));
}
break;
case 169: /* term */
@@ -76936,7 +78130,7 @@
case 235: /* when_clause */
case 238: /* key_opt */
{
-sqlite3ExprDelete((yypminor->yy172));
+sqlite3ExprDelete(pParse->db, (yypminor->yy172));
}
break;
case 174: /* idxlist_opt */
@@ -76952,7 +78146,7 @@
case 216: /* exprlist */
case 222: /* case_exprlist */
{
-sqlite3ExprListDelete((yypminor->yy174));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy174));
}
break;
case 188: /* fullname */
@@ -76960,25 +78154,25 @@
case 201: /* seltablist */
case 202: /* stl_prefix */
{
-sqlite3SrcListDelete((yypminor->yy373));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy373));
}
break;
case 205: /* using_opt */
case 208: /* inscollist */
case 214: /* inscollist_opt */
{
-sqlite3IdListDelete((yypminor->yy432));
+sqlite3IdListDelete(pParse->db, (yypminor->yy432));
}
break;
case 231: /* trigger_cmd_list */
case 236: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep((yypminor->yy243));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy243));
}
break;
case 233: /* trigger_event */
{
-sqlite3IdListDelete((yypminor->yy370).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy370).b);
}
break;
default: break; /* If no destructor action specified: do nothing */
@@ -77006,7 +78200,7 @@
}
#endif
yymajor = yytos->major;
- yy_destructor( yymajor, &yytos->minor);
+ yy_destructor(pParser, yymajor, &yytos->minor);
pParser->yyidx--;
return yymajor;
}
@@ -77037,6 +78231,16 @@
}
/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef YYTRACKMAXSTACKDEPTH
+SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
+ yyParser *pParser = (yyParser*)p;
+ return pParser->yyidxMax;
+}
+#endif
+
+/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
@@ -77158,6 +78362,11 @@
){
yyStackEntry *yytos;
yypParser->yyidx++;
+#ifdef YYTRACKMAXSTACKDEPTH
+ if( yypParser->yyidx>yypParser->yyidxMax ){
+ yypParser->yyidxMax = yypParser->yyidx;
+ }
+#endif
#if YYSTACKDEPTH>0
if( yypParser->yyidx>=YYSTACKDEPTH ){
yyStackOverflow(yypParser, yypMinor);
@@ -77668,7 +78877,7 @@
case 27: /* create_table_args ::= AS select */
{
sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy219);
- sqlite3SelectDelete(yymsp[0].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy219);
}
break;
case 30: /* column ::= columnid type carglist */
@@ -77850,7 +79059,7 @@
{
SelectDest dest = {SRT_Callback, 0, 0, 0, 0};
sqlite3Select(pParse, yymsp[0].minor.yy219, &dest, 0, 0, 0);
- sqlite3SelectDelete(yymsp[0].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy219);
}
break;
case 105: /* select ::= oneselect */
@@ -77863,7 +79072,7 @@
yymsp[0].minor.yy219->op = yymsp[-1].minor.yy46;
yymsp[0].minor.yy219->pPrior = yymsp[-2].minor.yy219;
}else{
- sqlite3SelectDelete(yymsp[-2].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy219);
}
yygotominor.yy219 = yymsp[0].minor.yy219;
}
@@ -77900,7 +79109,7 @@
break;
case 118: /* selcollist ::= sclp nm DOT STAR */
{
- Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
+ Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174, pDot, 0);
@@ -78222,7 +79431,7 @@
if( yygotominor.yy172 ){
yygotominor.yy172->pList = pList;
}else{
- sqlite3ExprListDelete(pList);
+ sqlite3ExprListDelete(pParse->db, pList);
}
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span);
@@ -78235,7 +79444,7 @@
yygotominor.yy172->pList = yymsp[-1].minor.yy174;
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3ExprListDelete(yymsp[-1].minor.yy174);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy174);
}
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
@@ -78248,7 +79457,7 @@
yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3SelectDelete(yymsp[-1].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
}
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
@@ -78260,7 +79469,7 @@
yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3SelectDelete(yymsp[-1].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
}
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
@@ -78274,7 +79483,7 @@
yygotominor.yy172->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3SrcListDelete(pSrc);
+ sqlite3SrcListDelete(pParse->db, pSrc);
}
if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
@@ -78288,7 +79497,7 @@
sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3SelectDelete(yymsp[-1].minor.yy219);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy219);
}
}
break;
@@ -78299,7 +79508,7 @@
yygotominor.yy172->pList = yymsp[-2].minor.yy174;
sqlite3ExprSetHeight(pParse, yygotominor.yy172);
}else{
- sqlite3ExprListDelete(yymsp[-2].minor.yy174);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy174);
}
sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
}
@@ -78724,7 +79933,7 @@
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser, yymajor,&yyminorunion);
yymajor = YYNOCODE;
}else{
while(
@@ -78737,7 +79946,7 @@
yy_pop_parser_stack(yypParser);
}
if( yypParser->yyidx < 0 || yymajor==0 ){
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser,yymajor,&yyminorunion);
yy_parse_failed(yypParser);
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
@@ -78762,7 +79971,7 @@
yy_syntax_error(yypParser,yymajor,yyminorunion);
}
yypParser->yyerrcnt = 3;
- yy_destructor(yymajor,&yyminorunion);
+ yy_destructor(yypParser,yymajor,&yyminorunion);
if( yyendofinput ){
yy_parse_failed(yypParser);
}
@@ -78792,7 +80001,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.146 2008/07/08 19:34:07 drh Exp $
+** $Id: tokenize.c,v 1.148 2008/07/28 19:34:54 drh Exp $
*/
/*
@@ -79317,7 +80526,7 @@
break;
}
case TK_ILLEGAL: {
- sqlite3_free(*pzErrMsg);
+ sqlite3DbFree(db, *pzErrMsg);
*pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
&pParse->sLastToken);
nErr++;
@@ -79345,6 +80554,11 @@
}
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
}
+#ifdef YYTRACKMAXSTACKDEPTH
+ sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
+ sqlite3ParserStackPeak(pEngine)
+ );
+#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
@@ -79356,7 +80570,7 @@
if( *pzErrMsg==0 ){
*pzErrMsg = pParse->zErrMsg;
}else{
- sqlite3_free(pParse->zErrMsg);
+ sqlite3DbFree(db, pParse->zErrMsg);
}
pParse->zErrMsg = 0;
nErr++;
@@ -79367,13 +80581,13 @@
}
#ifndef SQLITE_OMIT_SHARED_CACHE
if( pParse->nested==0 ){
- sqlite3_free(pParse->aTableLock);
+ sqlite3DbFree(db, pParse->aTableLock);
pParse->aTableLock = 0;
pParse->nTableLock = 0;
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3_free(pParse->apVtabLock);
+ sqlite3DbFree(db, pParse->apVtabLock);
#endif
if( !IN_DECLARE_VTAB ){
@@ -79384,8 +80598,8 @@
sqlite3DeleteTable(pParse->pNewTable);
}
- sqlite3DeleteTrigger(pParse->pNewTrigger);
- sqlite3_free(pParse->apVarExpr);
+ sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+ sqlite3DbFree(db, pParse->apVarExpr);
if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
pParse->rc = SQLITE_ERROR;
}
@@ -79689,7 +80903,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.479 2008/07/16 14:02:33 drh Exp $
+** $Id: main.c,v 1.486 2008/08/04 20:13:27 drh Exp $
*/
#ifdef SQLITE_ENABLE_FTS3
@@ -79848,6 +81062,20 @@
sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0);
sqlite3_mutex_leave(sqlite3Config.pInitMutex);
}
+
+ /* Check NaN support. */
+#ifndef NDEBUG
+ /* This section of code's only "output" is via assert() statements. */
+ if ( rc==SQLITE_OK ){
+ u64 x = (((u64)1)<<63)-1;
+ double y;
+ assert(sizeof(x)==8);
+ assert(sizeof(x)==sizeof(y));
+ memcpy(&y, &x, 8);
+ assert( sqlite3IsNaN(y) );
+ }
+#endif
+
return rc;
}
@@ -79984,6 +81212,95 @@
}
#endif
+#if defined(SQLITE_ENABLE_MEMSYS6)
+ case SQLITE_CONFIG_CHUNKALLOC: {
+ sqlite3Config.nSmall = va_arg(ap, int);
+ sqlite3Config.m = *sqlite3MemGetMemsys6();
+ break;
+ }
+#endif
+
+ case SQLITE_CONFIG_LOOKASIDE: {
+ sqlite3Config.szLookaside = va_arg(ap, int);
+ sqlite3Config.nLookaside = va_arg(ap, int);
+ break;
+ }
+
+ default: {
+ rc = SQLITE_ERROR;
+ break;
+ }
+ }
+ va_end(ap);
+ return rc;
+}
+
+/*
+** Set up the lookaside buffers for a database connection.
+** Return SQLITE_OK on success.
+** If lookaside is already active, return SQLITE_BUSY.
+**
+** The sz parameter is the number of bytes in each lookaside slot.
+** The cnt parameter is the number of slots. If pStart is NULL the
+** space for the lookaside memory is obtained from sqlite3_malloc().
+** If pStart is not NULL then it is sz*cnt bytes of memory to use for
+** the lookaside memory.
+*/
+static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
+ void *pStart;
+ if( db->lookaside.nOut ){
+ return SQLITE_BUSY;
+ }
+ if( sz<0 ) sz = 0;
+ if( cnt<0 ) cnt = 0;
+ sz = (sz+7)&~7;
+ if( pBuf==0 ){
+ sqlite3BeginBenignMalloc();
+ pStart = sqlite3Malloc( sz*cnt );
+ sqlite3EndBenignMalloc();
+ }else{
+ pStart = pBuf;
+ }
+ if( db->lookaside.bMalloced ){
+ sqlite3_free(db->lookaside.pStart);
+ }
+ db->lookaside.pStart = pStart;
+ db->lookaside.pFree = 0;
+ db->lookaside.sz = sz;
+ db->lookaside.bMalloced = pBuf==0;
+ if( pStart ){
+ int i;
+ LookasideSlot *p;
+ p = (LookasideSlot*)pStart;
+ for(i=cnt-1; i>=0; i--){
+ p->pNext = db->lookaside.pFree;
+ db->lookaside.pFree = p;
+ p = (LookasideSlot*)&((u8*)p)[sz];
+ }
+ db->lookaside.pEnd = p;
+ db->lookaside.bEnabled = 1;
+ }else{
+ db->lookaside.pEnd = 0;
+ db->lookaside.bEnabled = 0;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Configuration settings for an individual database connection
+*/
+SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
+ va_list ap;
+ int rc;
+ va_start(ap, op);
+ switch( op ){
+ case SQLITE_DBCONFIG_LOOKASIDE: {
+ void *pBuf = va_arg(ap, void*);
+ int sz = va_arg(ap, int);
+ int cnt = va_arg(ap, int);
+ rc = setupLookaside(db, pBuf, sz, cnt);
+ break;
+ }
default: {
rc = SQLITE_ERROR;
break;
@@ -80142,7 +81459,7 @@
FuncDef *pFunc, *pNext;
for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
pNext = pFunc->pNext;
- sqlite3_free(pFunc);
+ sqlite3DbFree(db, pFunc);
}
}
@@ -80154,7 +81471,7 @@
pColl[j].xDel(pColl[j].pUser);
}
}
- sqlite3_free(pColl);
+ sqlite3DbFree(db, pColl);
}
sqlite3HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -80163,7 +81480,7 @@
if( pMod->xDestroy ){
pMod->xDestroy(pMod->pAux);
}
- sqlite3_free(pMod);
+ sqlite3DbFree(db, pMod);
}
sqlite3HashClear(&db->aModule);
#endif
@@ -80183,10 +81500,13 @@
** the same sqliteMalloc() as the one that allocates the database
** structure?
*/
- sqlite3_free(db->aDb[1].pSchema);
+ sqlite3DbFree(db, db->aDb[1].pSchema);
sqlite3_mutex_leave(db->mutex);
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
+ if( db->lookaside.bMalloced ){
+ sqlite3_free(db->lookaside.pStart);
+ }
sqlite3_free(db);
return SQLITE_OK;
}
@@ -80516,7 +81836,7 @@
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
- sqlite3_free(zFunc8);
+ sqlite3DbFree(db, zFunc8);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -81021,6 +82341,7 @@
db->nDb = 2;
db->magic = SQLITE_MAGIC_BUSY;
db->aDb = db->aDbStatic;
+
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->autoCommit = 1;
@@ -81162,6 +82483,9 @@
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ /* Enable the lookaside-malloc subsystem */
+ setupLookaside(db, 0, sqlite3Config.szLookaside, sqlite3Config.nLookaside);
+
opendb_out:
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
@@ -81289,7 +82613,7 @@
zName8 = sqlite3Utf16to8(db, zName, -1);
if( zName8 ){
rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
- sqlite3_free(zName8);
+ sqlite3DbFree(db, zName8);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -81478,13 +82802,13 @@
if( pAutoinc ) *pAutoinc = autoinc;
if( SQLITE_OK==rc && !pTab ){
- sqlite3_free(zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
zColumnName);
rc = SQLITE_ERROR;
}
sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
- sqlite3_free(zErrMsg);
+ sqlite3DbFree(db, zErrMsg);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -85986,21 +87310,43 @@
fulltext_cursor *c = (fulltext_cursor *) pCursor;
fulltext_vtab *v = cursor_vtab(c);
int rc;
- StringBuffer sb;
FTSTRACE(("FTS3 Filter %p\n",pCursor));
- initStringBuffer(&sb);
- append(&sb, "SELECT docid, ");
- appendList(&sb, v->nColumn, v->azContentColumn);
- append(&sb, " FROM %_content");
- if( idxNum!=QUERY_GENERIC ) append(&sb, " WHERE docid = ?");
- sqlite3_finalize(c->pStmt);
- rc = sql_prepare(v->db, v->zDb, v->zName, &c->pStmt, stringBufferData(&sb));
- stringBufferDestroy(&sb);
- if( rc!=SQLITE_OK ) return rc;
+ /* If the cursor has a statement that was not prepared according to
+ ** idxNum, clear it. I believe all calls to fulltextFilter with a
+ ** given cursor will have the same idxNum , but in this case it's
+ ** easy to be safe.
+ */
+ if( c->pStmt && c->iCursorType!=idxNum ){
+ sqlite3_finalize(c->pStmt);
+ c->pStmt = NULL;
+ }
+
+ /* Get a fresh statement appropriate to idxNum. */
+ /* TODO(shess): Add a prepared-statement cache in the vt structure.
+ ** The cache must handle multiple open cursors. Easier to cache the
+ ** statement variants at the vt to reduce malloc/realloc/free here.
+ ** Or we could have a StringBuffer variant which allowed stack
+ ** construction for small values.
+ */
+ if( !c->pStmt ){
+ StringBuffer sb;
+ initStringBuffer(&sb);
+ append(&sb, "SELECT docid, ");
+ appendList(&sb, v->nColumn, v->azContentColumn);
+ append(&sb, " FROM %_content");
+ if( idxNum!=QUERY_GENERIC ) append(&sb, " WHERE docid = ?");
+ rc = sql_prepare(v->db, v->zDb, v->zName, &c->pStmt,
+ stringBufferData(&sb));
+ stringBufferDestroy(&sb);
+ if( rc!=SQLITE_OK ) return rc;
+ c->iCursorType = idxNum;
+ }else{
+ sqlite3_reset(c->pStmt);
+ assert( c->iCursorType==idxNum );
+ }
- c->iCursorType = idxNum;
switch( idxNum ){
case QUERY_GENERIC:
break;
@@ -93511,3 +94857,504 @@
#endif
/************** End of rtree.c ***********************************************/
+/************** Begin file icu.c *********************************************/
+/*
+** 2007 May 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $
+**
+** This file implements an integration between the ICU library
+** ("International Components for Unicode", an open-source library
+** for handling unicode data) and SQLite. The integration uses
+** ICU to provide the following to SQLite:
+**
+** * An implementation of the SQL regexp() function (and hence REGEXP
+** operator) using the ICU uregex_XX() APIs.
+**
+** * Implementations of the SQL scalar upper() and lower() functions
+** for case mapping.
+**
+** * Integration of ICU and SQLite collation seqences.
+**
+** * An implementation of the LIKE operator that uses ICU to
+** provide case-independent matching.
+*/
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+
+/* Include ICU headers */
+#include <unicode/utypes.h>
+#include <unicode/uregex.h>
+#include <unicode/ustring.h>
+#include <unicode/ucol.h>
+
+
+#ifndef SQLITE_CORE
+ #include "sqlite3ext.h"
+ SQLITE_EXTENSION_INIT1
+#else
+ #include "sqlite3.h"
+#endif
+
+/*
+** Maximum length (in bytes) of the pattern in a LIKE or GLOB
+** operator.
+*/
+#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
+# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
+#endif
+
+/*
+** Version of sqlite3_free() that is always a function, never a macro.
+*/
+static void xFree(void *p){
+ sqlite3_free(p);
+}
+
+/*
+** Compare two UTF-8 strings for equality where the first string is
+** a "LIKE" expression. Return true (1) if they are the same and
+** false (0) if they are different.
+*/
+static int icuLikeCompare(
+ const uint8_t *zPattern, /* LIKE pattern */
+ const uint8_t *zString, /* The UTF-8 string to compare against */
+ const UChar32 uEsc /* The escape character */
+){
+ static const int MATCH_ONE = (UChar32)'_';
+ static const int MATCH_ALL = (UChar32)'%';
+
+ int iPattern = 0; /* Current byte index in zPattern */
+ int iString = 0; /* Current byte index in zString */
+
+ int prevEscape = 0; /* True if the previous character was uEsc */
+
+ while( zPattern[iPattern]!=0 ){
+
+ /* Read (and consume) the next character from the input pattern. */
+ UChar32 uPattern;
+ U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
+ assert(uPattern!=0);
+
+ /* There are now 4 possibilities:
+ **
+ ** 1. uPattern is an unescaped match-all character "%",
+ ** 2. uPattern is an unescaped match-one character "_",
+ ** 3. uPattern is an unescaped escape character, or
+ ** 4. uPattern is to be handled as an ordinary character
+ */
+ if( !prevEscape && uPattern==MATCH_ALL ){
+ /* Case 1. */
+ uint8_t c;
+
+ /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
+ ** MATCH_ALL. For each MATCH_ONE, skip one character in the
+ ** test string.
+ */
+ while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
+ if( c==MATCH_ONE ){
+ if( zString[iString]==0 ) return 0;
+ U8_FWD_1_UNSAFE(zString, iString);
+ }
+ iPattern++;
+ }
+
+ if( zPattern[iPattern]==0 ) return 1;
+
+ while( zString[iString] ){
+ if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
+ return 1;
+ }
+ U8_FWD_1_UNSAFE(zString, iString);
+ }
+ return 0;
+
+ }else if( !prevEscape && uPattern==MATCH_ONE ){
+ /* Case 2. */
+ if( zString[iString]==0 ) return 0;
+ U8_FWD_1_UNSAFE(zString, iString);
+
+ }else if( !prevEscape && uPattern==uEsc){
+ /* Case 3. */
+ prevEscape = 1;
+
+ }else{
+ /* Case 4. */
+ UChar32 uString;
+ U8_NEXT_UNSAFE(zString, iString, uString);
+ uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
+ uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
+ if( uString!=uPattern ){
+ return 0;
+ }
+ prevEscape = 0;
+ }
+ }
+
+ return zString[iString]==0;
+}
+
+/*
+** Implementation of the like() SQL function. This function implements
+** the build-in LIKE operator. The first argument to the function is the
+** pattern and the second argument is the string. So, the SQL statements:
+**
+** A LIKE B
+**
+** is implemented as like(B, A). If there is an escape character E,
+**
+** A LIKE B ESCAPE E
+**
+** is mapped to like(B, A, E).
+*/
+static void icuLikeFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zA = sqlite3_value_text(argv[0]);
+ const unsigned char *zB = sqlite3_value_text(argv[1]);
+ UChar32 uEsc = 0;
+
+ /* Limit the length of the LIKE or GLOB pattern to avoid problems
+ ** of deep recursion and N*N behavior in patternCompare().
+ */
+ if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
+ sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
+ return;
+ }
+
+
+ if( argc==3 ){
+ /* The escape character string must consist of a single UTF-8 character.
+ ** Otherwise, return an error.
+ */
+ int nE= sqlite3_value_bytes(argv[2]);
+ const unsigned char *zE = sqlite3_value_text(argv[2]);
+ int i = 0;
+ if( zE==0 ) return;
+ U8_NEXT(zE, i, nE, uEsc);
+ if( i!=nE){
+ sqlite3_result_error(context,
+ "ESCAPE expression must be a single character", -1);
+ return;
+ }
+ }
+
+ if( zA && zB ){
+ sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc));
+ }
+}
+
+/*
+** This function is called when an ICU function called from within
+** the implementation of an SQL scalar function returns an error.
+**
+** The scalar function context passed as the first argument is
+** loaded with an error message based on the following two args.
+*/
+static void icuFunctionError(
+ sqlite3_context *pCtx, /* SQLite scalar function context */
+ const char *zName, /* Name of ICU function that failed */
+ UErrorCode e /* Error code returned by ICU function */
+){
+ char zBuf[128];
+ sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
+ zBuf[127] = '\0';
+ sqlite3_result_error(pCtx, zBuf, -1);
+}
+
+/*
+** Function to delete compiled regexp objects. Registered as
+** a destructor function with sqlite3_set_auxdata().
+*/
+static void icuRegexpDelete(void *p){
+ URegularExpression *pExpr = (URegularExpression *)p;
+ uregex_close(pExpr);
+}
+
+/*
+** Implementation of SQLite REGEXP operator. This scalar function takes
+** two arguments. The first is a regular expression pattern to compile
+** the second is a string to match against that pattern. If either
+** argument is an SQL NULL, then NULL Is returned. Otherwise, the result
+** is 1 if the string matches the pattern, or 0 otherwise.
+**
+** SQLite maps the regexp() function to the regexp() operator such
+** that the following two are equivalent:
+**
+** zString REGEXP zPattern
+** regexp(zPattern, zString)
+**
+** Uses the following ICU regexp APIs:
+**
+** uregex_open()
+** uregex_matches()
+** uregex_close()
+*/
+static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
+ UErrorCode status = U_ZERO_ERROR;
+ URegularExpression *pExpr;
+ UBool res;
+ const UChar *zString = sqlite3_value_text16(apArg[1]);
+
+ /* If the left hand side of the regexp operator is NULL,
+ ** then the result is also NULL.
+ */
+ if( !zString ){
+ return;
+ }
+
+ pExpr = sqlite3_get_auxdata(p, 0);
+ if( !pExpr ){
+ const UChar *zPattern = sqlite3_value_text16(apArg[0]);
+ if( !zPattern ){
+ return;
+ }
+ pExpr = uregex_open(zPattern, -1, 0, 0, &status);
+
+ if( U_SUCCESS(status) ){
+ sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
+ }else{
+ assert(!pExpr);
+ icuFunctionError(p, "uregex_open", status);
+ return;
+ }
+ }
+
+ /* Configure the text that the regular expression operates on. */
+ uregex_setText(pExpr, zString, -1, &status);
+ if( !U_SUCCESS(status) ){
+ icuFunctionError(p, "uregex_setText", status);
+ return;
+ }
+
+ /* Attempt the match */
+ res = uregex_matches(pExpr, 0, &status);
+ if( !U_SUCCESS(status) ){
+ icuFunctionError(p, "uregex_matches", status);
+ return;
+ }
+
+ /* Set the text that the regular expression operates on to a NULL
+ ** pointer. This is not really necessary, but it is tidier than
+ ** leaving the regular expression object configured with an invalid
+ ** pointer after this function returns.
+ */
+ uregex_setText(pExpr, 0, 0, &status);
+
+ /* Return 1 or 0. */
+ sqlite3_result_int(p, res ? 1 : 0);
+}
+
+/*
+** Implementations of scalar functions for case mapping - upper() and
+** lower(). Function upper() converts its input to upper-case (ABC).
+** Function lower() converts to lower-case (abc).
+**
+** ICU provides two types of case mapping, "general" case mapping and
+** "language specific". Refer to ICU documentation for the differences
+** between the two.
+**
+** To utilise "general" case mapping, the upper() or lower() scalar
+** functions are invoked with one argument:
+**
+** upper('ABC') -> 'abc'
+** lower('abc') -> 'ABC'
+**
+** To access ICU "language specific" case mapping, upper() or lower()
+** should be invoked with two arguments. The second argument is the name
+** of the locale to use. Passing an empty string ("") or SQL NULL value
+** as the second argument is the same as invoking the 1 argument version
+** of upper() or lower().
+**
+** lower('I', 'en_us') -> 'i'
+** lower('I', 'tr_tr') -> 'Ä' (small dotless i)
+**
+** http://www.icu-project.org/userguide/posix.html#case_mappings
+*/
+static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
+ const UChar *zInput;
+ UChar *zOutput;
+ int nInput;
+ int nOutput;
+
+ UErrorCode status = U_ZERO_ERROR;
+ const char *zLocale = 0;
+
+ assert(nArg==1 || nArg==2);
+ if( nArg==2 ){
+ zLocale = (const char *)sqlite3_value_text(apArg[1]);
+ }
+
+ zInput = sqlite3_value_text16(apArg[0]);
+ if( !zInput ){
+ return;
+ }
+ nInput = sqlite3_value_bytes16(apArg[0]);
+
+ nOutput = nInput * 2 + 2;
+ zOutput = sqlite3_malloc(nOutput);
+ if( !zOutput ){
+ return;
+ }
+
+ if( sqlite3_user_data(p) ){
+ u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
+ }else{
+ u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
+ }
+
+ if( !U_SUCCESS(status) ){
+ icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
+ return;
+ }
+
+ sqlite3_result_text16(p, zOutput, -1, xFree);
+}
+
+/*
+** Collation sequence destructor function. The pCtx argument points to
+** a UCollator structure previously allocated using ucol_open().
+*/
+static void icuCollationDel(void *pCtx){
+ UCollator *p = (UCollator *)pCtx;
+ ucol_close(p);
+}
+
+/*
+** Collation sequence comparison function. The pCtx argument points to
+** a UCollator structure previously allocated using ucol_open().
+*/
+static int icuCollationColl(
+ void *pCtx,
+ int nLeft,
+ const void *zLeft,
+ int nRight,
+ const void *zRight
+){
+ UCollationResult res;
+ UCollator *p = (UCollator *)pCtx;
+ res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2);
+ switch( res ){
+ case UCOL_LESS: return -1;
+ case UCOL_GREATER: return +1;
+ case UCOL_EQUAL: return 0;
+ }
+ assert(!"Unexpected return value from ucol_strcoll()");
+ return 0;
+}
+
+/*
+** Implementation of the scalar function icu_load_collation().
+**
+** This scalar function is used to add ICU collation based collation
+** types to an SQLite database connection. It is intended to be called
+** as follows:
+**
+** SELECT icu_load_collation(<locale>, <collation-name>);
+**
+** Where <locale> is a string containing an ICU locale identifier (i.e.
+** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the
+** collation sequence to create.
+*/
+static void icuLoadCollation(
+ sqlite3_context *p,
+ int nArg,
+ sqlite3_value **apArg
+){
+ sqlite3 *db = (sqlite3 *)sqlite3_user_data(p);
+ UErrorCode status = U_ZERO_ERROR;
+ const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
+ const char *zName; /* SQL Collation sequence name (eg. "japanese") */
+ UCollator *pUCollator; /* ICU library collation object */
+ int rc; /* Return code from sqlite3_create_collation_x() */
+
+ assert(nArg==2);
+ zLocale = (const char *)sqlite3_value_text(apArg[0]);
+ zName = (const char *)sqlite3_value_text(apArg[1]);
+
+ if( !zLocale || !zName ){
+ return;
+ }
+
+ pUCollator = ucol_open(zLocale, &status);
+ if( !U_SUCCESS(status) ){
+ icuFunctionError(p, "ucol_open", status);
+ return;
+ }
+ assert(p);
+
+ rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
+ icuCollationColl, icuCollationDel
+ );
+ if( rc!=SQLITE_OK ){
+ ucol_close(pUCollator);
+ sqlite3_result_error(p, "Error registering collation function", -1);
+ }
+}
+
+/*
+** Register the ICU extension functions with database db.
+*/
+SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
+ struct IcuScalar {
+ const char *zName; /* Function name */
+ int nArg; /* Number of arguments */
+ int enc; /* Optimal text encoding */
+ void *pContext; /* sqlite3_user_data() context */
+ void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+ } scalars[] = {
+ {"regexp",-1, SQLITE_ANY, 0, icuRegexpFunc},
+
+ {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
+
+ {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16},
+
+ {"like", 2, SQLITE_UTF8, 0, icuLikeFunc},
+ {"like", 3, SQLITE_UTF8, 0, icuLikeFunc},
+
+ {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation},
+ };
+
+ int rc = SQLITE_OK;
+ int i;
+
+ for(i=0; rc==SQLITE_OK && i<(sizeof(scalars)/sizeof(struct IcuScalar)); i++){
+ struct IcuScalar *p = &scalars[i];
+ rc = sqlite3_create_function(
+ db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
+ );
+ }
+
+ return rc;
+}
+
+#if !SQLITE_CORE
+SQLITE_API int sqlite3_extension_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi)
+ return sqlite3IcuInit(db);
+}
+#endif
+
+#endif
+
+/************** End of icu.c *************************************************/
Modified: trunk/libgda/sqlite/sqlite-src/sqlite3.h
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/sqlite3.h (original)
+++ trunk/libgda/sqlite/sqlite-src/sqlite3.h Thu Aug 28 19:38:33 2008
@@ -62,7 +62,7 @@
#endif
/*
-** CAPI3REF: Compile-Time Library Version Numbers {F10010}
+** CAPI3REF: Compile-Time Library Version Numbers {H10010} <S60100>
**
** The SQLITE_VERSION and SQLITE_VERSION_NUMBER #defines in
** the sqlite3.h file specify the version of SQLite with which
@@ -83,19 +83,19 @@
**
** INVARIANTS:
**
-** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
+** {H10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
** evaluate to a string literal that is the SQLite version
** with which the header file is associated.
**
-** {F10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
+** {H10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
** are the major version, minor version, and release number.
*/
-#define SQLITE_VERSION "3.6.0"
-#define SQLITE_VERSION_NUMBER 3006000
+#define SQLITE_VERSION "3.6.1"
+#define SQLITE_VERSION_NUMBER 3006001
/*
-** CAPI3REF: Run-Time Library Version Numbers {F10020}
+** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
** KEYWORDS: sqlite3_version
**
** These features provide the same information as the [SQLITE_VERSION]
@@ -112,13 +112,13 @@
**
** INVARIANTS:
**
-** {F10021} The [sqlite3_libversion_number()] interface shall return
+** {H10021} The [sqlite3_libversion_number()] interface shall return
** an integer equal to [SQLITE_VERSION_NUMBER].
**
-** {F10022} The [sqlite3_version] string constant shall contain
+** {H10022} The [sqlite3_version] string constant shall contain
** the text of the [SQLITE_VERSION] string.
**
-** {F10023} The [sqlite3_libversion()] function shall return
+** {H10023} The [sqlite3_libversion()] function shall return
** a pointer to the [sqlite3_version] string constant.
*/
SQLITE_EXTERN const char sqlite3_version[];
@@ -126,7 +126,7 @@
int sqlite3_libversion_number(void);
/*
-** CAPI3REF: Test To See If The Library Is Threadsafe {F10100}
+** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} <S60100>
**
** SQLite can be compiled with or without mutexes. When
** the [SQLITE_THREADSAFE] C preprocessor macro is true, mutexes
@@ -154,12 +154,12 @@
**
** INVARIANTS:
**
-** {F10101} The [sqlite3_threadsafe()] function shall return nonzero if
+** {H10101} The [sqlite3_threadsafe()] function shall return nonzero if
** SQLite was compiled with the its mutexes enabled by default
** or zero if SQLite was compiled such that mutexes are
** permanently disabled.
**
-** {F10102} The value returned by the [sqlite3_threadsafe()] function
+** {H10102} The value returned by the [sqlite3_threadsafe()] function
** shall not change when mutex setting are modified at
** runtime using the [sqlite3_config()] interface and
** especially the [SQLITE_CONFIG_SINGLETHREAD],
@@ -169,7 +169,7 @@
int sqlite3_threadsafe(void);
/*
-** CAPI3REF: Database Connection Handle {F12000}
+** CAPI3REF: Database Connection Handle {H12000} <S40200>
** KEYWORDS: {database connection} {database connections}
**
** Each open SQLite database is represented by a pointer to an instance of
@@ -184,7 +184,7 @@
typedef struct sqlite3 sqlite3;
/*
-** CAPI3REF: 64-Bit Integer Types {F10200}
+** CAPI3REF: 64-Bit Integer Types {H10200} <S10110>
** KEYWORDS: sqlite_int64 sqlite_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
@@ -196,10 +196,10 @@
**
** INVARIANTS:
**
-** {F10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
+** {H10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
** a 64-bit signed integer.
**
-** {F10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
+** {H10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
** a 64-bit unsigned integer.
*/
#ifdef SQLITE_INT64_TYPE
@@ -224,7 +224,7 @@
#endif
/*
-** CAPI3REF: Closing A Database Connection {F12010}
+** CAPI3REF: Closing A Database Connection {H12010} <S30100><S40200>
**
** This routine is the destructor for the [sqlite3] object.
**
@@ -247,30 +247,30 @@
**
** INVARIANTS:
**
-** {F12011} A successful call to [sqlite3_close(C)] shall destroy the
+** {H12011} A successful call to [sqlite3_close(C)] shall destroy the
** [database connection] object C.
**
-** {F12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
+** {H12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
**
-** {F12013} A successful call to [sqlite3_close(C)] shall release all
+** {H12013} A successful call to [sqlite3_close(C)] shall release all
** memory and system resources associated with [database connection]
** C.
**
-** {F12014} A call to [sqlite3_close(C)] on a [database connection] C that
+** {H12014} A call to [sqlite3_close(C)] on a [database connection] C that
** has one or more open [prepared statements] shall fail with
** an [SQLITE_BUSY] error code.
**
-** {F12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
+** {H12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
** return SQLITE_OK.
**
-** {F12019} When [sqlite3_close(C)] is invoked on a [database connection] C
+** {H12019} When [sqlite3_close(C)] is invoked on a [database connection] C
** that has a pending transaction, the transaction shall be
** rolled back.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12016} The C parameter to [sqlite3_close(C)] must be either a NULL
-** pointer or an [sqlite3] object pointer previously obtained
+** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
** [sqlite3_open_v2()], and not previously closed.
*/
@@ -284,7 +284,7 @@
typedef int (*sqlite3_callback)(void*,int,char**, char**);
/*
-** CAPI3REF: One-Step Query Execution Interface {F12100}
+** CAPI3REF: One-Step Query Execution Interface {H12100} <S10000>
**
** The sqlite3_exec() interface is a convenient way of running one or more
** SQL statements without having to write a lot of C code. The UTF-8 encoded
@@ -312,69 +312,69 @@
**
** INVARIANTS:
**
-** {F12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
+** {H12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
** shall sequentially evaluate all of the UTF-8 encoded,
** semicolon-separated SQL statements in the zero-terminated
** string S within the context of the [database connection] D.
**
-** {F12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
+** {H12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
** the actions of the interface shall be the same as if the
** S parameter were an empty string.
**
-** {F12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
+** {H12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
** SQL statements run successfully and to completion.
**
-** {F12105} The return value of [sqlite3_exec()] shall be an appropriate
+** {H12105} The return value of [sqlite3_exec()] shall be an appropriate
** non-zero [error code] if any SQL statement fails.
**
-** {F12107} If one or more of the SQL statements handed to [sqlite3_exec()]
+** {H12107} If one or more of the SQL statements handed to [sqlite3_exec()]
** return results and the 3rd parameter is not NULL, then
** the callback function specified by the 3rd parameter shall be
** invoked once for each row of result.
**
-** {F12110} If the callback returns a non-zero value then [sqlite3_exec()]
+** {H12110} If the callback returns a non-zero value then [sqlite3_exec()]
** shall abort the SQL statement it is currently evaluating,
** skip all subsequent SQL statements, and return [SQLITE_ABORT].
**
-** {F12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
+** {H12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
** as the 1st parameter of the callback.
**
-** {F12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
+** {H12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
** callback to be the number of columns in the current row of
** result.
**
-** {F12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
+** {H12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
** callback to be an array of pointers to strings holding the
** values for each column in the current result set row as
** obtained from [sqlite3_column_text()].
**
-** {F12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
+** {H12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
** callback to be an array of pointers to strings holding the
** names of result columns as obtained from [sqlite3_column_name()].
**
-** {F12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
+** {H12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
** [sqlite3_exec()] shall silently discard query results.
**
-** {F12131} If an error occurs while parsing or evaluating any of the SQL
+** {H12131} If an error occurs while parsing or evaluating any of the SQL
** statements in the S parameter of [sqlite3_exec(D,S,C,A,E)] and if
** the E parameter is not NULL, then [sqlite3_exec()] shall store
** in *E an appropriate error message written into memory obtained
** from [sqlite3_malloc()].
**
-** {F12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
+** {H12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
** *E to NULL if E is not NULL and there are no errors.
**
-** {F12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
+** {H12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
** and message accessible via [sqlite3_errcode()],
** [sqlite3_errmsg()], and [sqlite3_errmsg16()].
**
-** {F12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
+** {H12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
** empty string or contains nothing other than whitespace, comments,
** and/or semicolons, then results of [sqlite3_errcode()],
** [sqlite3_errmsg()], and [sqlite3_errmsg16()]
** shall reset to indicate no errors.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12141} The first parameter to [sqlite3_exec()] must be an valid and open
** [database connection].
@@ -398,7 +398,7 @@
);
/*
-** CAPI3REF: Result Codes {F10210}
+** CAPI3REF: Result Codes {H10210} <S10700>
** KEYWORDS: SQLITE_OK {error code} {error codes}
** KEYWORDS: {result code} {result codes}
**
@@ -442,7 +442,7 @@
/* end-of-error-codes */
/*
-** CAPI3REF: Extended Result Codes {F10220}
+** CAPI3REF: Extended Result Codes {H10220} <S10700>
** KEYWORDS: {extended error code} {extended error codes}
** KEYWORDS: {extended result code} {extended result codes}
**
@@ -466,14 +466,14 @@
**
** INVARIANTS:
**
-** {F10223} The symbolic name for an extended result code shall contains
+** {H10223} The symbolic name for an extended result code shall contains
** a related primary result code as a prefix.
**
-** {F10224} Primary result code names shall contain a single "_" character.
+** {H10224} Primary result code names shall contain a single "_" character.
**
-** {F10225} Extended result code names shall contain two or more "_" characters.
+** {H10225} Extended result code names shall contain two or more "_" characters.
**
-** {F10226} The numeric value of an extended result code shall contain the
+** {H10226} The numeric value of an extended result code shall contain the
** numeric value of its corresponding primary result code in
** its least significant 8 bits.
*/
@@ -493,7 +493,7 @@
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
/*
-** CAPI3REF: Flags For File Open Operations {F10230}
+** CAPI3REF: Flags For File Open Operations {H10230} <H11120> <H12700>
**
** These bit values are intended for use in the
** 3rd parameter to the [sqlite3_open_v2()] interface and
@@ -515,7 +515,7 @@
#define SQLITE_OPEN_NOMUTEX 0x00008000
/*
-** CAPI3REF: Device Characteristics {F10240}
+** CAPI3REF: Device Characteristics {H10240} <H11120>
**
** The xDeviceCapabilities method of the [sqlite3_io_methods]
** object returns an integer which is a vector of the these
@@ -547,7 +547,7 @@
#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
/*
-** CAPI3REF: File Locking Levels {F10250}
+** CAPI3REF: File Locking Levels {H10250} <H11120> <H11310>
**
** SQLite uses one of these integer values as the second
** argument to calls it makes to the xLock() and xUnlock() methods
@@ -560,7 +560,7 @@
#define SQLITE_LOCK_EXCLUSIVE 4
/*
-** CAPI3REF: Synchronization Type Flags {F10260}
+** CAPI3REF: Synchronization Type Flags {H10260} <H11120>
**
** When SQLite invokes the xSync() method of an
** [sqlite3_io_methods] object it uses a combination of
@@ -577,7 +577,7 @@
#define SQLITE_SYNC_DATAONLY 0x00010
/*
-** CAPI3REF: OS Interface Open File Handle {F11110}
+** CAPI3REF: OS Interface Open File Handle {H11110} <S20110>
**
** An [sqlite3_file] object represents an open file in the OS
** interface layer. Individual OS interface implementations will
@@ -592,7 +592,7 @@
};
/*
-** CAPI3REF: OS Interface File Virtual Methods Object {F11120}
+** CAPI3REF: OS Interface File Virtual Methods Object {H11120} <S20110>
**
** Every file opened by the [sqlite3_vfs] xOpen method populates an
** [sqlite3_file] object (or, more commonly, a subclass of the
@@ -685,7 +685,7 @@
};
/*
-** CAPI3REF: Standard File Control Opcodes {F11310}
+** CAPI3REF: Standard File Control Opcodes {H11310} <S30800>
**
** These integer constants are opcodes for the xFileControl method
** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
@@ -702,7 +702,7 @@
#define SQLITE_FCNTL_LOCKSTATE 1
/*
-** CAPI3REF: Mutex Handle {F17110}
+** CAPI3REF: Mutex Handle {H17110} <S20130>
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object. The SQLite core never looks
@@ -714,7 +714,7 @@
typedef struct sqlite3_mutex sqlite3_mutex;
/*
-** CAPI3REF: OS Interface Object {F11140}
+** CAPI3REF: OS Interface Object {H11140} <S20100>
**
** An instance of the sqlite3_vfs object defines the interface between
** the SQLite core and the underlying operating system. The "vfs"
@@ -747,11 +747,11 @@
** The zName field holds the name of the VFS module. The name must
** be unique across all VFS modules.
**
-** {F11141} SQLite will guarantee that the zFilename parameter to xOpen
+** {H11141} SQLite will guarantee that the zFilename parameter to xOpen
** is either a NULL pointer or string obtained
** from xFullPathname(). SQLite further guarantees that
** the string will be valid and unchanged until xClose() is
-** called. {END} Becasue of the previous sentense,
+** called. {END} Because of the previous sentense,
** the [sqlite3_file] can safely store a pointer to the
** filename if it needs to remember the filename for some reason.
** If the zFilename parameter is xOpen is a NULL pointer then xOpen
@@ -759,14 +759,14 @@
** xFilename parameter is NULL it will also be the case that the
** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
**
-** {F11142} The flags argument to xOpen() includes all bits set in
+** {H11142} The flags argument to xOpen() includes all bits set in
** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
** or [sqlite3_open16()] is used, then flags includes at least
** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. {END}
** If xOpen() opens a file read-only then it sets *pOutFlags to
** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
**
-** {F11143} SQLite will also add one of the following flags to the xOpen()
+** {H11143} SQLite will also add one of the following flags to the xOpen()
** call, depending on the object being opened:
**
** <ul>
@@ -795,27 +795,27 @@
** <li> [SQLITE_OPEN_EXCLUSIVE]
** </ul>
**
-** {F11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. {F11146} The [SQLITE_OPEN_DELETEONCLOSE]
+** {H11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
+** deleted when it is closed. {H11146} The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases, journals and for subjournals.
**
-** {F11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
+** {H11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
** for exclusive access. This flag is set for all files except
** for the main database file.
**
-** {F11148} At least szOsFile bytes of memory are allocated by SQLite
+** {H11148} At least szOsFile bytes of memory are allocated by SQLite
** to hold the [sqlite3_file] structure passed as the third
** argument to xOpen. {END} The xOpen method does not have to
** allocate the structure; it should just fill it in.
**
-** {F11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
+** {H11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
** to test whether a file is at least readable. {END} The file can be a
** directory.
**
-** {F11150} SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. {F11151} The exact size of the output buffer
+** {H11150} SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname. {H11151} The exact size of the output buffer
** is also passed as a parameter to both methods. {END} If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
@@ -857,16 +857,16 @@
};
/*
-** CAPI3REF: Flags for the xAccess VFS method {F11190}
+** CAPI3REF: Flags for the xAccess VFS method {H11190} <H11140>
**
-** {F11191} These integer constants can be used as the third parameter to
+** {H11191} These integer constants can be used as the third parameter to
** the xAccess method of an [sqlite3_vfs] object. {END} They determine
** what kind of permissions the xAccess method is looking for.
-** {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
+** {H11192} With SQLITE_ACCESS_EXISTS, the xAccess method
** simply checks whether the file exists.
-** {F11193} With SQLITE_ACCESS_READWRITE, the xAccess method
+** {H11193} With SQLITE_ACCESS_READWRITE, the xAccess method
** checks whether the file is both readable and writable.
-** {F11194} With SQLITE_ACCESS_READ, the xAccess method
+** {H11194} With SQLITE_ACCESS_READ, the xAccess method
** checks whether the file is readable.
*/
#define SQLITE_ACCESS_EXISTS 0
@@ -874,7 +874,7 @@
#define SQLITE_ACCESS_READ 2
/*
-** CAPI3REF: Initialize The SQLite Library {F10130}
+** CAPI3REF: Initialize The SQLite Library {H10130} <S20000><S30100>
**
** The sqlite3_initialize() routine initializes the
** SQLite library. The sqlite3_shutdown() routine
@@ -939,7 +939,8 @@
int sqlite3_os_end(void);
/*
-** CAPI3REF: Configuring The SQLite Library {F10145}
+** CAPI3REF: Configuring The SQLite Library {H10145} <S20000><S30200>
+** EXPERIMENTAL
**
** The sqlite3_config() interface is used to make global configuration
** changes to SQLite in order to tune SQLite to the specific needs of
@@ -964,15 +965,33 @@
** When a configuration option is set, sqlite3_config() returns SQLITE_OK.
** If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
-**
-** The sqlite3_config() interface is considered experimental in that
-** new configuration options may be added in future releases and existing
-** configuration options may be discontinued or modified.
*/
int sqlite3_config(int, ...);
/*
-** CAPI3REF: Memory Allocation Routines {F10155}
+** CAPI3REF: Configure database connections {H10180} <S20000>
+** EXPERIMENTAL
+**
+** The sqlite3_db_config() interface is used to make configuration
+** changes to a [database connection]. The interface is similar to
+** [sqlite3_config()] except that the changes apply to a single
+** [database connection] (specified in the first argument). The
+** sqlite3_db_config() interface can only be used immediately after
+** the database connection is created using [sqlite3_open()],
+** [sqlite3_open16()], or [sqlite3_open_v2()].
+**
+** The second argument to sqlite3_db_config(D,V,...) is the
+** configuration verb - an integer code that indicates what
+** aspect of the [database connection] is being configured.
+** The only choice for this value is [SQLITE_DBCONFIG_LOOKASIDE].
+** New verbs are likely to be added in future releases of SQLite.
+** Additional arguments depend on the verb.
+*/
+int sqlite3_db_config(sqlite3*, int op, ...);
+
+/*
+** CAPI3REF: Memory Allocation Routines {H10155} <S20120>
+** EXPERIMENTAL
**
** An instance of this object defines the interface between SQLite
** and low-level memory allocation routines.
@@ -1026,7 +1045,8 @@
};
/*
-** CAPI3REF: Configuration Options {F10160}
+** CAPI3REF: Configuration Options {H10160} <S20000>
+** EXPERIMENTAL
**
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
@@ -1082,14 +1102,15 @@
** tracks memory usage, for example.</dd>
**
** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd>This option takes single boolean argument which enables or disables
-** the collection of memory allocation statistics. When disabled, the
-** following SQLite interfaces become non-operational:
+** <dd>This option takes single argument of type int, interpreted as a
+** boolean, which enables or disables the collection of memory allocation
+** statistics. When disabled, the following SQLite interfaces become
+** non-operational:
** <ul>
** <li> [sqlite3_memory_used()]
** <li> [sqlite3_memory_highwater()]
** <li> [sqlite3_soft_heap_limit()]
-** <li> sqlite3_memory_status()
+** <li> [sqlite3_status()]
** </ul>
** </dd>
**
@@ -1097,8 +1118,10 @@
** <dd>This option specifies a static memory buffer that SQLite can use for
** scratch memory. There are three arguments: A pointer to the memory, the
** size of each scratch buffer (sz), and the number of buffers (N). The sz
-** argument must be a multiple of 16. The first
-** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** argument must be a multiple of 16. The sz parameter should be a few bytes
+** larger than the actual scratch space required due internal overhead.
+** The first
+** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use no more than one scratch buffer at once per thread, so
** N should be set to the expected maximum number of threads. The sz
** parameter should be 6 times the size of the largest database page size.
@@ -1112,11 +1135,13 @@
** the database page cache. There are three arguments: A pointer to the
** memory, the size of each page buffer (sz), and the number of pages (N).
** The sz argument must be a power of two between 512 and 32768. The first
-** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. If additional
** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.
+** The implementation might use one or more of the N buffers to hold
+** memory accounting information. </dd>
**
** <dt>SQLITE_CONFIG_HEAP</dt>
** <dd>This option specifies a static memory buffer that SQLite will use
@@ -1145,6 +1170,14 @@
** This option can be used to overload the default mutex allocation
** routines with a wrapper used to track mutex usage for performance
** profiling or testing, for example.</dd>
+**
+** <dt>SQLITE_CONFIG_LOOKASIDE</dt>
+** <dd>This option takes two arguments that determine the default
+** memory allcation lookaside optimization. The first argument is the
+** size of each lookaside buffer slot and the second is the number of
+** slots allocated to each database connection.</dd>
+**
+** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
@@ -1157,10 +1190,42 @@
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
+#define SQLITE_CONFIG_CHUNKALLOC 12 /* int threshold */
+#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
+
+/*
+** CAPI3REF: Configuration Options {H10170} <S20000>
+** EXPERIMENTAL
+**
+** These constants are the available integer configuration options that
+** can be passed as the second argument to the [sqlite3_db_config()] interface.
+**
+** New configuration options may be added in future releases of SQLite.
+** Existing configuration options might be discontinued. Applications
+** should check the return code from [sqlite3_db_config()] to make sure that
+** the call worked. The [sqlite3_db_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+** <dd>This option takes three additional arguments that determine the
+** [lookaside memory allocator] configuration for the [database connection].
+** The first argument (the third parameter to [sqlite3_db_config()] is a
+** pointer to a memory buffer to use for lookaside memory. The first
+** argument may be NULL in which case SQLite will allocate the lookaside
+** buffer itself using [sqlite3_malloc()]. The second argument is the
+** size of each lookaside buffer slot and the third argument is the number of
+** slots. The size of the buffer in the first argument must be greater than
+** or equal to the product of the second and third arguments.</dd>
+**
+** </dl>
+*/
+#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
/*
-** CAPI3REF: Enable Or Disable Extended Result Codes {F12200}
+** CAPI3REF: Enable Or Disable Extended Result Codes {H12200} <S10700>
**
** The sqlite3_extended_result_codes() routine enables or disables the
** [extended result codes] feature of SQLite. The extended result
@@ -1168,17 +1233,17 @@
**
** INVARIANTS:
**
-** {F12201} Each new [database connection] shall have the
+** {H12201} Each new [database connection] shall have the
** [extended result codes] feature disabled by default.
**
-** {F12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
+** {H12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
** [extended result codes] for the [database connection] D
** if the F parameter is true, or disable them if F is false.
*/
int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
-** CAPI3REF: Last Insert Rowid {F12220}
+** CAPI3REF: Last Insert Rowid {H12220} <S10700>
**
** Each entry in an SQLite table has a unique 64-bit signed
** integer key called the "rowid". The rowid is always available
@@ -1212,16 +1277,16 @@
**
** INVARIANTS:
**
-** {F12221} The [sqlite3_last_insert_rowid()] function returns the rowid
+** {H12221} The [sqlite3_last_insert_rowid()] function returns the rowid
** of the most recent successful INSERT performed on the same
** [database connection] and within the same or higher level
** trigger context, or zero if there have been no qualifying inserts.
**
-** {F12223} The [sqlite3_last_insert_rowid()] function returns the
+** {H12223} The [sqlite3_last_insert_rowid()] function returns the
** same value when called from the same trigger context
** immediately before and after a ROLLBACK.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12232} If a separate thread performs a new INSERT on the same
** database connection while the [sqlite3_last_insert_rowid()]
@@ -1233,7 +1298,7 @@
sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
/*
-** CAPI3REF: Count The Number Of Rows Modified {F12240}
+** CAPI3REF: Count The Number Of Rows Modified {H12240} <S10600>
**
** This function returns the number of database rows that were changed
** or inserted or deleted by the most recently completed SQL statement
@@ -1283,18 +1348,18 @@
**
** INVARIANTS:
**
-** {F12241} The [sqlite3_changes()] function shall return the number of
+** {H12241} The [sqlite3_changes()] function shall return the number of
** row changes caused by the most recent INSERT, UPDATE,
** or DELETE statement on the same database connection and
** within the same or higher trigger context, or zero if there have
** not been any qualifying row changes.
**
-** {F12243} Statements of the form "DELETE FROM tablename" with no
+** {H12243} Statements of the form "DELETE FROM tablename" with no
** WHERE clause shall cause subsequent calls to
** [sqlite3_changes()] to return zero, regardless of the
** number of rows originally in the table.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12252} If a separate thread makes changes on the same database connection
** while [sqlite3_changes()] is running then the value returned
@@ -1303,7 +1368,7 @@
int sqlite3_changes(sqlite3*);
/*
-** CAPI3REF: Total Number Of Rows Modified {F12260}
+** CAPI3REF: Total Number Of Rows Modified {H12260} <S10600>
**
** This function returns the number of row changes caused by INSERT,
** UPDATE or DELETE statements since the [database connection] was opened.
@@ -1327,16 +1392,16 @@
**
** INVARIANTS:
**
-** {F12261} The [sqlite3_total_changes()] returns the total number
+** {H12261} The [sqlite3_total_changes()] returns the total number
** of row changes caused by INSERT, UPDATE, and/or DELETE
** statements on the same [database connection], in any
** trigger context, since the database connection was created.
**
-** {F12263} Statements of the form "DELETE FROM tablename" with no
+** {H12263} Statements of the form "DELETE FROM tablename" with no
** WHERE clause shall not change the value returned
** by [sqlite3_total_changes()].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12264} If a separate thread makes changes on the same database connection
** while [sqlite3_total_changes()] is running then the value
@@ -1345,7 +1410,7 @@
int sqlite3_total_changes(sqlite3*);
/*
-** CAPI3REF: Interrupt A Long-Running Query {F12270}
+** CAPI3REF: Interrupt A Long-Running Query {H12270} <S30500>
**
** This function causes any pending database operation to abort and
** return at its earliest opportunity. This routine is typically
@@ -1372,14 +1437,14 @@
**
** INVARIANTS:
**
-** {F12271} The [sqlite3_interrupt()] interface will force all running
+** {H12271} The [sqlite3_interrupt()] interface will force all running
** SQL statements associated with the same database connection
** to halt after processing at most one additional row of data.
**
-** {F12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
+** {H12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
** will return [SQLITE_INTERRUPT].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12279} If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
@@ -1387,7 +1452,7 @@
void sqlite3_interrupt(sqlite3*);
/*
-** CAPI3REF: Determine If An SQL Statement Is Complete {F10510}
+** CAPI3REF: Determine If An SQL Statement Is Complete {H10510} <S70200>
**
** These routines are useful for command-line input to determine if the
** currently entered text seems to form complete a SQL statement or
@@ -1405,17 +1470,17 @@
**
** INVARIANTS:
**
-** {F10511} A successful evaluation of [sqlite3_complete()] or
+** {H10511} A successful evaluation of [sqlite3_complete()] or
** [sqlite3_complete16()] functions shall
** return a numeric 1 if and only if the last non-whitespace
** token in their input is a semicolon that is not in between
** the BEGIN and END of a CREATE TRIGGER statement.
**
-** {F10512} If a memory allocation error occurs during an invocation
+** {H10512} If a memory allocation error occurs during an invocation
** of [sqlite3_complete()] or [sqlite3_complete16()] then the
** routine shall return [SQLITE_NOMEM].
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A10512} The input to [sqlite3_complete()] must be a zero-terminated
** UTF-8 string.
@@ -1427,7 +1492,7 @@
int sqlite3_complete16(const void *sql);
/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {F12310}
+** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {H12310} <S40400>
**
** This routine sets a callback function that might be invoked whenever
** an attempt is made to open a database table that another thread
@@ -1485,27 +1550,27 @@
**
** INVARIANTS:
**
-** {F12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
+** {H12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
** busy callback in the [database connection] D with a new
** a new busy handler C and application data pointer A.
**
-** {F12312} Newly created [database connections] shall have a busy
+** {H12312} Newly created [database connections] shall have a busy
** handler of NULL.
**
-** {F12314} When two or more [database connections] share a
+** {H12314} When two or more [database connections] share a
** [sqlite3_enable_shared_cache | common cache],
** the busy handler for the database connection currently using
** the cache shall be invoked when the cache encounters a lock.
**
-** {F12316} If a busy handler callback returns zero, then the SQLite interface
+** {H12316} If a busy handler callback returns zero, then the SQLite interface
** that provoked the locking event shall return [SQLITE_BUSY].
**
-** {F12318} SQLite shall invokes the busy handler with two arguments which
+** {H12318} SQLite shall invokes the busy handler with two arguments which
** are a copy of the pointer supplied by the 3rd parameter to
** [sqlite3_busy_handler()] and a count of the number of prior
** invocations of the busy handler for the same locking event.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12319} A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
@@ -1513,12 +1578,12 @@
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
/*
-** CAPI3REF: Set A Busy Timeout {F12340}
+** CAPI3REF: Set A Busy Timeout {H12340} <S40410>
**
** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked. The handler
** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. {F12343} After "ms" milliseconds of sleeping,
+** have accumulated. {H12343} After "ms" milliseconds of sleeping,
** the handler returns 0 which causes [sqlite3_step()] to return
** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
**
@@ -1532,15 +1597,15 @@
**
** INVARIANTS:
**
-** {F12341} The [sqlite3_busy_timeout()] function shall override any prior
+** {H12341} The [sqlite3_busy_timeout()] function shall override any prior
** [sqlite3_busy_timeout()] or [sqlite3_busy_handler()] setting
** on the same [database connection].
**
-** {F12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
+** {H12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
** or equal to zero, then the busy handler shall be cleared so that
** all subsequent locking events immediately return [SQLITE_BUSY].
**
-** {F12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
+** {H12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
** number N, then a busy handler shall be set that repeatedly calls
** the xSleep() method in the [sqlite3_vfs | VFS interface] until
** either the lock clears or until the cumulative sleep time
@@ -1549,7 +1614,7 @@
int sqlite3_busy_timeout(sqlite3*, int ms);
/*
-** CAPI3REF: Convenience Routines For Running Queries {F12370}
+** CAPI3REF: Convenience Routines For Running Queries {H12370} <S10000>
**
** Definition: A <b>result table</b> is memory data structure created by the
** [sqlite3_get_table()] interface. A result table records the
@@ -1618,32 +1683,32 @@
**
** INVARIANTS:
**
-** {F12371} If a [sqlite3_get_table()] fails a memory allocation, then
+** {H12371} If a [sqlite3_get_table()] fails a memory allocation, then
** it shall free the result table under construction, abort the
** query in process, skip any subsequent queries, set the
** *pazResult output pointer to NULL and return [SQLITE_NOMEM].
**
-** {F12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
+** {H12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
** then a successful invocation of [sqlite3_get_table()] shall
** write the number of columns in the
** result set of the query into *pnColumn.
**
-** {F12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
+** {H12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
** then a successful invocation of [sqlite3_get_table()] shall
** writes the number of rows in the
** result set of the query into *pnRow.
**
-** {F12376} A successful invocation of [sqlite3_get_table()] that computes
+** {H12376} A successful invocation of [sqlite3_get_table()] that computes
** N rows of result with C columns per row shall make *pazResult
** point to an array of pointers to (N+1)*C strings where the first
** C strings are column names as obtained from
** [sqlite3_column_name()] and the rest are column result values
** obtained from [sqlite3_column_text()].
**
-** {F12379} The values in the pazResult array returned by [sqlite3_get_table()]
+** {H12379} The values in the pazResult array returned by [sqlite3_get_table()]
** shall remain valid until cleared by [sqlite3_free_table()].
**
-** {F12382} When an error occurs during evaluation of [sqlite3_get_table()]
+** {H12382} When an error occurs during evaluation of [sqlite3_get_table()]
** the function shall set *pazResult to NULL, write an error message
** into memory obtained from [sqlite3_malloc()], make
** **pzErrmsg point to that error message, and return a
@@ -1660,7 +1725,7 @@
void sqlite3_free_table(char **result);
/*
-** CAPI3REF: Formatted String Printing Functions {F17400}
+** CAPI3REF: Formatted String Printing Functions {H17400} <S70000><S20000>
**
** These routines are workalikes of the "printf()" family of functions
** from the standard C library.
@@ -1753,16 +1818,16 @@
**
** INVARIANTS:
**
-** {F17403} The [sqlite3_mprintf()] and [sqlite3_vmprintf()] interfaces
+** {H17403} The [sqlite3_mprintf()] and [sqlite3_vmprintf()] interfaces
** return either pointers to zero-terminated UTF-8 strings held in
** memory obtained from [sqlite3_malloc()] or NULL pointers if
** a call to [sqlite3_malloc()] fails.
**
-** {F17406} The [sqlite3_snprintf()] interface writes a zero-terminated
+** {H17406} The [sqlite3_snprintf()] interface writes a zero-terminated
** UTF-8 string into the buffer pointed to by the second parameter
** provided that the first parameter is greater than zero.
**
-** {F17407} The [sqlite3_snprintf()] interface does not write slots of
+** {H17407} The [sqlite3_snprintf()] interface does not write slots of
** its output buffer (the second parameter) outside the range
** of 0 through N-1 (where N is the first parameter)
** regardless of the length of the string
@@ -1773,7 +1838,7 @@
char *sqlite3_snprintf(int,char*,const char*, ...);
/*
-** CAPI3REF: Memory Allocation Subsystem {F17300}
+** CAPI3REF: Memory Allocation Subsystem {H17300} <S20000>
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence
@@ -1820,7 +1885,7 @@
**
** The default implementation of the memory allocation subsystem uses
** the malloc(), realloc() and free() provided by the standard C library.
-** {F17382} However, if SQLite is compiled with the
+** {H17382} However, if SQLite is compiled with the
** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
** is an integer), then SQLite create a static array of at least
** <i>NNN</i> bytes in size and uses that array for all of its dynamic
@@ -1842,46 +1907,46 @@
**
** INVARIANTS:
**
-** {F17303} The [sqlite3_malloc(N)] interface returns either a pointer to
+** {H17303} The [sqlite3_malloc(N)] interface returns either a pointer to
** a newly checked-out block of at least N bytes of memory
** that is 8-byte aligned, or it returns NULL if it is unable
** to fulfill the request.
**
-** {F17304} The [sqlite3_malloc(N)] interface returns a NULL pointer if
+** {H17304} The [sqlite3_malloc(N)] interface returns a NULL pointer if
** N is less than or equal to zero.
**
-** {F17305} The [sqlite3_free(P)] interface releases memory previously
+** {H17305} The [sqlite3_free(P)] interface releases memory previously
** returned from [sqlite3_malloc()] or [sqlite3_realloc()],
** making it available for reuse.
**
-** {F17306} A call to [sqlite3_free(NULL)] is a harmless no-op.
+** {H17306} A call to [sqlite3_free(NULL)] is a harmless no-op.
**
-** {F17310} A call to [sqlite3_realloc(0,N)] is equivalent to a call
+** {H17310} A call to [sqlite3_realloc(0,N)] is equivalent to a call
** to [sqlite3_malloc(N)].
**
-** {F17312} A call to [sqlite3_realloc(P,0)] is equivalent to a call
+** {H17312} A call to [sqlite3_realloc(P,0)] is equivalent to a call
** to [sqlite3_free(P)].
**
-** {F17315} The SQLite core uses [sqlite3_malloc()], [sqlite3_realloc()],
+** {H17315} The SQLite core uses [sqlite3_malloc()], [sqlite3_realloc()],
** and [sqlite3_free()] for all of its memory allocation and
** deallocation needs.
**
-** {F17318} The [sqlite3_realloc(P,N)] interface returns either a pointer
+** {H17318} The [sqlite3_realloc(P,N)] interface returns either a pointer
** to a block of checked-out memory of at least N bytes in size
** that is 8-byte aligned, or a NULL pointer.
**
-** {F17321} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
+** {H17321} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
** copies the first K bytes of content from P into the newly
** allocated block, where K is the lesser of N and the size of
** the buffer P.
**
-** {F17322} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
+** {H17322} When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
** releases the buffer P.
**
-** {F17323} When [sqlite3_realloc(P,N)] returns NULL, the buffer P is
+** {H17323} When [sqlite3_realloc(P,N)] returns NULL, the buffer P is
** not modified or released.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A17350} The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
** must be either NULL or else pointers obtained from a prior
@@ -1897,7 +1962,7 @@
void sqlite3_free(void*);
/*
-** CAPI3REF: Memory Allocator Statistics {F17370}
+** CAPI3REF: Memory Allocator Statistics {H17370} <S30210>
**
** SQLite provides these two interfaces for reporting on the status
** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
@@ -1905,20 +1970,20 @@
**
** INVARIANTS:
**
-** {F17371} The [sqlite3_memory_used()] routine returns the number of bytes
+** {H17371} The [sqlite3_memory_used()] routine returns the number of bytes
** of memory currently outstanding (malloced but not freed).
**
-** {F17373} The [sqlite3_memory_highwater()] routine returns the maximum
+** {H17373} The [sqlite3_memory_highwater()] routine returns the maximum
** value of [sqlite3_memory_used()] since the high-water mark
** was last reset.
**
-** {F17374} The values returned by [sqlite3_memory_used()] and
+** {H17374} The values returned by [sqlite3_memory_used()] and
** [sqlite3_memory_highwater()] include any overhead
** added by SQLite in its implementation of [sqlite3_malloc()],
** but not overhead added by the any underlying system library
** routines that [sqlite3_malloc()] may call.
**
-** {F17375} The memory high-water mark is reset to the current value of
+** {H17375} The memory high-water mark is reset to the current value of
** [sqlite3_memory_used()] if and only if the parameter to
** [sqlite3_memory_highwater()] is true. The value returned
** by [sqlite3_memory_highwater(1)] is the high-water mark
@@ -1928,7 +1993,7 @@
sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
-** CAPI3REF: Pseudo-Random Number Generator {F17390}
+** CAPI3REF: Pseudo-Random Number Generator {H17390} <S20000>
**
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random ROWIDs when inserting new records into a table that
@@ -1947,13 +2012,13 @@
**
** INVARIANTS:
**
-** {F17392} The [sqlite3_randomness(N,P)] interface writes N bytes of
+** {H17392} The [sqlite3_randomness(N,P)] interface writes N bytes of
** high-quality pseudo-randomness into buffer P.
*/
void sqlite3_randomness(int N, void *P);
/*
-** CAPI3REF: Compile-Time Authorization Callbacks {F12500}
+** CAPI3REF: Compile-Time Authorization Callbacks {H12500} <S70100>
**
** This routine registers a authorizer callback with a particular
** [database connection], supplied in the first argument.
@@ -2017,55 +2082,55 @@
**
** INVARIANTS:
**
-** {F12501} The [sqlite3_set_authorizer(D,...)] interface registers a
+** {H12501} The [sqlite3_set_authorizer(D,...)] interface registers a
** authorizer callback with database connection D.
**
-** {F12502} The authorizer callback is invoked as SQL statements are
+** {H12502} The authorizer callback is invoked as SQL statements are
** being compiled.
**
-** {F12503} If the authorizer callback returns any value other than
+** {H12503} If the authorizer callback returns any value other than
** [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY], then
** the [sqlite3_prepare_v2()] or equivalent call that caused
** the authorizer callback to run shall fail with an
** [SQLITE_ERROR] error code and an appropriate error message.
**
-** {F12504} When the authorizer callback returns [SQLITE_OK], the operation
+** {H12504} When the authorizer callback returns [SQLITE_OK], the operation
** described is processed normally.
**
-** {F12505} When the authorizer callback returns [SQLITE_DENY], the
+** {H12505} When the authorizer callback returns [SQLITE_DENY], the
** [sqlite3_prepare_v2()] or equivalent call that caused the
** authorizer callback to run shall fail
** with an [SQLITE_ERROR] error code and an error message
** explaining that access is denied.
**
-** {F12506} If the authorizer code (the 2nd parameter to the authorizer
+** {H12506} If the authorizer code (the 2nd parameter to the authorizer
** callback) is [SQLITE_READ] and the authorizer callback returns
** [SQLITE_IGNORE], then the prepared statement is constructed to
** insert a NULL value in place of the table column that would have
** been read if [SQLITE_OK] had been returned.
**
-** {F12507} If the authorizer code (the 2nd parameter to the authorizer
+** {H12507} If the authorizer code (the 2nd parameter to the authorizer
** callback) is anything other than [SQLITE_READ], then
** a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY].
**
-** {F12510} The first parameter to the authorizer callback is a copy of
+** {H12510} The first parameter to the authorizer callback is a copy of
** the third parameter to the [sqlite3_set_authorizer()] interface.
**
-** {F12511} The second parameter to the callback is an integer
+** {H12511} The second parameter to the callback is an integer
** [SQLITE_COPY | action code] that specifies the particular action
** to be authorized.
**
-** {F12512} The third through sixth parameters to the callback are
+** {H12512} The third through sixth parameters to the callback are
** zero-terminated strings that contain
** additional details about the action to be authorized.
**
-** {F12520} Each call to [sqlite3_set_authorizer()] overrides
+** {H12520} Each call to [sqlite3_set_authorizer()] overrides
** any previously installed authorizer.
**
-** {F12521} A NULL authorizer means that no authorization
+** {H12521} A NULL authorizer means that no authorization
** callback is invoked.
**
-** {F12522} The default authorizer is NULL.
+** {H12522} The default authorizer is NULL.
*/
int sqlite3_set_authorizer(
sqlite3*,
@@ -2074,7 +2139,7 @@
);
/*
-** CAPI3REF: Authorizer Return Codes {F12590}
+** CAPI3REF: Authorizer Return Codes {H12590} <H12500>
**
** The [sqlite3_set_authorizer | authorizer callback function] must
** return either [SQLITE_OK] or one of these two constants in order
@@ -2086,7 +2151,7 @@
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
/*
-** CAPI3REF: Authorizer Action Codes {F12550}
+** CAPI3REF: Authorizer Action Codes {H12550} <H12500>
**
** The [sqlite3_set_authorizer()] interface registers a callback function
** that is invoked to authorize certain SQL statement actions. The
@@ -2106,21 +2171,21 @@
**
** INVARIANTS:
**
-** {F12551} The second parameter to an
+** {H12551} The second parameter to an
** [sqlite3_set_authorizer | authorizer callback] is always an integer
** [SQLITE_COPY | authorizer code] that specifies what action
** is being authorized.
**
-** {F12552} The 3rd and 4th parameters to the
+** {H12552} The 3rd and 4th parameters to the
** [sqlite3_set_authorizer | authorization callback]
** will be parameters or NULL depending on which
** [SQLITE_COPY | authorizer code] is used as the second parameter.
**
-** {F12553} The 5th parameter to the
+** {H12553} The 5th parameter to the
** [sqlite3_set_authorizer | authorizer callback] is the name
** of the database (example: "main", "temp", etc.) if applicable.
**
-** {F12554} The 6th parameter to the
+** {H12554} The 6th parameter to the
** [sqlite3_set_authorizer | authorizer callback] is the name
** of the inner-most trigger or view that is responsible for
** the access attempt or NULL if this access attempt is directly from
@@ -2161,7 +2226,8 @@
#define SQLITE_COPY 0 /* No longer used */
/*
-** CAPI3REF: Tracing And Profiling Functions {F12280}
+** CAPI3REF: Tracing And Profiling Functions {H12280} <S60400>
+** EXPERIMENTAL
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
@@ -2178,46 +2244,38 @@
** the original statement text and an estimate of wall-clock time
** of how long that statement took to run.
**
-** The sqlite3_profile() API is currently considered experimental and
-** is subject to change or removal in a future release.
-**
-** The trigger reporting feature of the trace callback is considered
-** experimental and is subject to change or removal in future releases.
-** Future versions of SQLite might also add new trace callback
-** invocations.
-**
** INVARIANTS:
**
-** {F12281} The callback function registered by [sqlite3_trace()] is
+** {H12281} The callback function registered by [sqlite3_trace()] is
** whenever an SQL statement first begins to execute and
** whenever a trigger subprogram first begins to run.
**
-** {F12282} Each call to [sqlite3_trace()] overrides the previously
+** {H12282} Each call to [sqlite3_trace()] overrides the previously
** registered trace callback.
**
-** {F12283} A NULL trace callback disables tracing.
+** {H12283} A NULL trace callback disables tracing.
**
-** {F12284} The first argument to the trace callback is a copy of
+** {H12284} The first argument to the trace callback is a copy of
** the pointer which was the 3rd argument to [sqlite3_trace()].
**
-** {F12285} The second argument to the trace callback is a
+** {H12285} The second argument to the trace callback is a
** zero-terminated UTF-8 string containing the original text
** of the SQL statement as it was passed into [sqlite3_prepare_v2()]
** or the equivalent, or an SQL comment indicating the beginning
** of a trigger subprogram.
**
-** {F12287} The callback function registered by [sqlite3_profile()] is invoked
+** {H12287} The callback function registered by [sqlite3_profile()] is invoked
** as each SQL statement finishes.
**
-** {F12288} The first parameter to the profile callback is a copy of
+** {H12288} The first parameter to the profile callback is a copy of
** the 3rd parameter to [sqlite3_profile()].
**
-** {F12289} The second parameter to the profile callback is a
+** {H12289} The second parameter to the profile callback is a
** zero-terminated UTF-8 string that contains the complete text of
** the SQL statement as it was processed by [sqlite3_prepare_v2()]
** or the equivalent.
**
-** {F12290} The third parameter to the profile callback is an estimate
+** {H12290} The third parameter to the profile callback is an estimate
** of the number of nanoseconds of wall-clock time required to
** run the SQL statement from start to finish.
*/
@@ -2226,7 +2284,7 @@
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
-** CAPI3REF: Query Progress Callbacks {F12910}
+** CAPI3REF: Query Progress Callbacks {H12910} <S60400>
**
** This routine configures a callback function - the
** progress callback - that is invoked periodically during long
@@ -2240,39 +2298,40 @@
**
** INVARIANTS:
**
-** {F12911} The callback function registered by sqlite3_progress_handler()
+** {H12911} The callback function registered by sqlite3_progress_handler()
** is invoked periodically during long running calls to
** [sqlite3_step()].
**
-** {F12912} The progress callback is invoked once for every N virtual
+** {H12912} The progress callback is invoked once for every N virtual
** machine opcodes, where N is the second argument to
** the [sqlite3_progress_handler()] call that registered
** the callback. If N is less than 1, sqlite3_progress_handler()
** acts as if a NULL progress handler had been specified.
**
-** {F12913} The progress callback itself is identified by the third
+** {H12913} The progress callback itself is identified by the third
** argument to sqlite3_progress_handler().
**
-** {F12914} The fourth argument to sqlite3_progress_handler() is a
+** {H12914} The fourth argument to sqlite3_progress_handler() is a
** void pointer passed to the progress callback
** function each time it is invoked.
**
-** {F12915} If a call to [sqlite3_step()] results in fewer than N opcodes
+** {H12915} If a call to [sqlite3_step()] results in fewer than N opcodes
** being executed, then the progress callback is never invoked.
**
-** {F12916} Every call to [sqlite3_progress_handler()]
+** {H12916} Every call to [sqlite3_progress_handler()]
** overwrites any previously registered progress handler.
**
-** {F12917} If the progress handler callback is NULL then no progress
+** {H12917} If the progress handler callback is NULL then no progress
** handler is invoked.
**
-** {F12918} If the progress callback returns a result other than 0, then
+** {H12918} If the progress callback returns a result other than 0, then
** the behavior is a if [sqlite3_interrupt()] had been called.
+** <S30500>
*/
void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
-** CAPI3REF: Opening A New Database Connection {F12700}
+** CAPI3REF: Opening A New Database Connection {H12700} <S40200>
**
** These routines open an SQLite database file whose name is given by the
** filename argument. The filename argument is interpreted as UTF-8 for
@@ -2354,67 +2413,67 @@
**
** INVARIANTS:
**
-** {F12701} The [sqlite3_open()], [sqlite3_open16()], and
+** {H12701} The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces create a new
** [database connection] associated with
** the database file given in their first parameter.
**
-** {F12702} The filename argument is interpreted as UTF-8
+** {H12702} The filename argument is interpreted as UTF-8
** for [sqlite3_open()] and [sqlite3_open_v2()] and as UTF-16
** in the native byte order for [sqlite3_open16()].
**
-** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
+** {H12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()] writes a pointer to a new
** [database connection] into *ppDb.
**
-** {F12704} The [sqlite3_open()], [sqlite3_open16()], and
+** {H12704} The [sqlite3_open()], [sqlite3_open16()], and
** [sqlite3_open_v2()] interfaces return [SQLITE_OK] upon success,
** or an appropriate [error code] on failure.
**
-** {F12706} The default text encoding for a new database created using
+** {H12706} The default text encoding for a new database created using
** [sqlite3_open()] or [sqlite3_open_v2()] will be UTF-8.
**
-** {F12707} The default text encoding for a new database created using
+** {H12707} The default text encoding for a new database created using
** [sqlite3_open16()] will be UTF-16.
**
-** {F12709} The [sqlite3_open(F,D)] interface is equivalent to
+** {H12709} The [sqlite3_open(F,D)] interface is equivalent to
** [sqlite3_open_v2(F,D,G,0)] where the G parameter is
** [SQLITE_OPEN_READWRITE]|[SQLITE_OPEN_CREATE].
**
-** {F12711} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
+** {H12711} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_READONLY] then the database is opened
** for reading only.
**
-** {F12712} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
+** {H12712} If the G parameter to [sqlite3_open_v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_READWRITE] then the database is opened
** reading and writing if possible, or for reading only if the
** file is write protected by the operating system.
**
-** {F12713} If the G parameter to [sqlite3_open(v2(F,D,G,V)] omits the
+** {H12713} If the G parameter to [sqlite3_open(v2(F,D,G,V)] omits the
** bit value [SQLITE_OPEN_CREATE] and the database does not
** previously exist, an error is returned.
**
-** {F12714} If the G parameter to [sqlite3_open(v2(F,D,G,V)] contains the
+** {H12714} If the G parameter to [sqlite3_open(v2(F,D,G,V)] contains the
** bit value [SQLITE_OPEN_CREATE] and the database does not
** previously exist, then an attempt is made to create and
** initialize the database.
**
-** {F12717} If the filename argument to [sqlite3_open()], [sqlite3_open16()],
+** {H12717} If the filename argument to [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()] is ":memory:", then an private,
** ephemeral, in-memory database is created for the connection.
** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
** in sqlite3_open_v2()?</todo>
**
-** {F12719} If the filename is NULL or an empty string, then a private,
+** {H12719} If the filename is NULL or an empty string, then a private,
** ephemeral on-disk database will be created.
** <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
** in sqlite3_open_v2()?</todo>
**
-** {F12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
+** {H12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
** will use the [sqlite3_vfs] object identified by the V parameter,
** or the default [sqlite3_vfs] object if V is a NULL pointer.
**
-** {F12723} Two [database connections] will share a common cache if both were
+** {H12723} Two [database connections] will share a common cache if both were
** opened with the same VFS while [shared cache mode] was enabled and
** if both filenames compare equal using memcmp() after having been
** processed by the [sqlite3_vfs | xFullPathname] method of the VFS.
@@ -2435,7 +2494,7 @@
);
/*
-** CAPI3REF: Error Codes And Messages {F12800}
+** CAPI3REF: Error Codes And Messages {H12800} <S60200>
**
** The sqlite3_errcode() interface returns the numeric [result code] or
** [extended result code] for the most recent failed sqlite3_* API call
@@ -2456,24 +2515,24 @@
**
** INVARIANTS:
**
-** {F12801} The [sqlite3_errcode(D)] interface returns the numeric
+** {H12801} The [sqlite3_errcode(D)] interface returns the numeric
** [result code] or [extended result code] for the most recently
** failed interface call associated with the [database connection] D.
**
-** {F12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
+** {H12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
** interfaces return English-language text that describes
** the error in the mostly recently failed interface call,
** encoded as either UTF-8 or UTF-16 respectively.
**
-** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
+** {H12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
** are valid until the next SQLite interface call.
**
-** {F12808} Calls to API routines that do not return an error code
+** {H12808} Calls to API routines that do not return an error code
** (example: [sqlite3_data_count()]) do not
** change the error code or message returned by
** [sqlite3_errcode()], [sqlite3_errmsg()], or [sqlite3_errmsg16()].
**
-** {F12809} Interfaces that are not associated with a specific
+** {H12809} Interfaces that are not associated with a specific
** [database connection] (examples:
** [sqlite3_mprintf()] or [sqlite3_enable_shared_cache()]
** do not change the values returned by
@@ -2484,7 +2543,7 @@
const void *sqlite3_errmsg16(sqlite3*);
/*
-** CAPI3REF: SQL Statement Object {F13000}
+** CAPI3REF: SQL Statement Object {H13000} <H13010>
** KEYWORDS: {prepared statement} {prepared statements}
**
** An instance of this object represents a single SQL statement.
@@ -2510,7 +2569,7 @@
typedef struct sqlite3_stmt sqlite3_stmt;
/*
-** CAPI3REF: Run-time Limits {F12760}
+** CAPI3REF: Run-time Limits {H12760} <S20600>
**
** This interface allows the size of various constructs to be limited
** on a connection by connection basis. The first parameter is the
@@ -2543,22 +2602,22 @@
**
** INVARIANTS:
**
-** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is
+** {H12762} A successful call to [sqlite3_limit(D,C,V)] where V is
** positive changes the limit on the size of construct C in the
** [database connection] D to the lesser of V and the hard upper
** bound on the size of C that is set at compile-time.
**
-** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
+** {H12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
** leaves the state of the [database connection] D unchanged.
**
-** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the
+** {H12769} A successful call to [sqlite3_limit(D,C,V)] returns the
** value of the limit on the size of construct C in the
** [database connection] D as it was prior to the call.
*/
int sqlite3_limit(sqlite3*, int id, int newVal);
/*
-** CAPI3REF: Run-Time Limit Categories {F12790}
+** CAPI3REF: Run-Time Limit Categories {H12790} <H12760>
** KEYWORDS: {limit category} {limit categories}
**
** These constants define various aspects of a [database connection]
@@ -2614,7 +2673,7 @@
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
/*
-** CAPI3REF: Compiling An SQL Statement {F13010}
+** CAPI3REF: Compiling An SQL Statement {H13010} <S10000>
** KEYWORDS: {SQL statement compiler}
**
** To execute an SQL query, it must first be compiled into a byte-code
@@ -2684,37 +2743,37 @@
**
** INVARIANTS:
**
-** {F13011} The [sqlite3_prepare(db,zSql,...)] and
+** {H13011} The [sqlite3_prepare(db,zSql,...)] and
** [sqlite3_prepare_v2(db,zSql,...)] interfaces interpret the
** text in their zSql parameter as UTF-8.
**
-** {F13012} The [sqlite3_prepare16(db,zSql,...)] and
+** {H13012} The [sqlite3_prepare16(db,zSql,...)] and
** [sqlite3_prepare16_v2(db,zSql,...)] interfaces interpret the
** text in their zSql parameter as UTF-16 in the native byte order.
**
-** {F13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
+** {H13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
** and its variants is less than zero, the SQL text is
** read from zSql is read up to the first zero terminator.
**
-** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
+** {H13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
** and its variants is non-negative, then at most nBytes bytes of
** SQL text is read from zSql.
**
-** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
+** {H13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
** if the zSql input text contains more than one SQL statement
** and pzTail is not NULL, then *pzTail is made to point to the
** first byte past the end of the first SQL statement in zSql.
** <todo>What does *pzTail point to if there is one statement?</todo>
**
-** {F13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
+** {H13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
** or one of its variants writes into *ppStmt a pointer to a new
** [prepared statement] or a pointer to NULL if zSql contains
** nothing other than whitespace or comments.
**
-** {F13019} The [sqlite3_prepare_v2()] interface and its variants return
+** {H13019} The [sqlite3_prepare_v2()] interface and its variants return
** [SQLITE_OK] or an appropriate [error code] upon failure.
**
-** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
+** {H13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
** variants returns an error (any value other than [SQLITE_OK]),
** they first set *ppStmt to NULL.
*/
@@ -2748,7 +2807,7 @@
);
/*
-** CAPIREF: Retrieving Statement SQL {F13100}
+** CAPIREF: Retrieving Statement SQL {H13100} <H13000>
**
** This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
@@ -2756,23 +2815,23 @@
**
** INVARIANTS:
**
-** {F13101} If the [prepared statement] passed as the argument to
+** {H13101} If the [prepared statement] passed as the argument to
** [sqlite3_sql()] was compiled using either [sqlite3_prepare_v2()] or
** [sqlite3_prepare16_v2()], then [sqlite3_sql()] returns
** a pointer to a zero-terminated string containing a UTF-8 rendering
** of the original SQL statement.
**
-** {F13102} If the [prepared statement] passed as the argument to
+** {H13102} If the [prepared statement] passed as the argument to
** [sqlite3_sql()] was compiled using either [sqlite3_prepare()] or
** [sqlite3_prepare16()], then [sqlite3_sql()] returns a NULL pointer.
**
-** {F13103} The string returned by [sqlite3_sql(S)] is valid until the
+** {H13103} The string returned by [sqlite3_sql(S)] is valid until the
** [prepared statement] S is deleted using [sqlite3_finalize(S)].
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Dynamically Typed Value Object {F15000}
+** CAPI3REF: Dynamically Typed Value Object {H15000} <S20200>
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
@@ -2811,7 +2870,7 @@
typedef struct Mem sqlite3_value;
/*
-** CAPI3REF: SQL Function Context Object {F16001}
+** CAPI3REF: SQL Function Context Object {H16001} <S20200>
**
** The context in which an SQL function executes is stored in an
** sqlite3_context object. A pointer to an sqlite3_context object
@@ -2825,7 +2884,7 @@
typedef struct sqlite3_context sqlite3_context;
/*
-** CAPI3REF: Binding Values To Prepared Statements {F13500}
+** CAPI3REF: Binding Values To Prepared Statements {H13500} <S70300>
** KEYWORDS: {host parameter} {host parameters} {host parameter name}
** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
**
@@ -2905,75 +2964,75 @@
**
** INVARIANTS:
**
-** {F13506} The [SQL statement compiler] recognizes tokens of the forms
+** {H13506} The [SQL statement compiler] recognizes tokens of the forms
** "?", "?NNN", "$VVV", ":VVV", and "@VVV" as SQL parameters,
** where NNN is any sequence of one or more digits
** and where VVV is any sequence of one or more alphanumeric
** characters or "::" optionally followed by a string containing
** no spaces and contained within parentheses.
**
-** {F13509} The initial value of an SQL parameter is NULL.
+** {H13509} The initial value of an SQL parameter is NULL.
**
-** {F13512} The index of an "?" SQL parameter is one larger than the
+** {H13512} The index of an "?" SQL parameter is one larger than the
** largest index of SQL parameter to the left, or 1 if
** the "?" is the leftmost SQL parameter.
**
-** {F13515} The index of an "?NNN" SQL parameter is the integer NNN.
+** {H13515} The index of an "?NNN" SQL parameter is the integer NNN.
**
-** {F13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
+** {H13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
** the same as the index of leftmost occurrences of the same
** parameter, or one more than the largest index over all
** parameters to the left if this is the first occurrence
** of this parameter, or 1 if this is the leftmost parameter.
**
-** {F13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
+** {H13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
** error if the index of an SQL parameter is less than 1
** or greater than the compile-time SQLITE_MAX_VARIABLE_NUMBER
** parameter.
**
-** {F13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
+** {H13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
** associate the value V with all SQL parameters having an
** index of N in the [prepared statement] S.
**
-** {F13527} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,...)]
+** {H13527} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,...)]
** override prior calls with the same values of S and N.
**
-** {F13530} Bindings established by [sqlite3_bind_text | sqlite3_bind(S,...)]
+** {H13530} Bindings established by [sqlite3_bind_text | sqlite3_bind(S,...)]
** persist across calls to [sqlite3_reset(S)].
**
-** {F13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds the first L
** bytes of the BLOB or string pointed to by V, when L
** is non-negative.
**
-** {F13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
+** {H13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
** [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds characters
** from V through the first zero character when L is negative.
**
-** {F13539} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13539} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
** constant [SQLITE_STATIC], SQLite assumes that the value V
** is held in static unmanaged space that will not change
** during the lifetime of the binding.
**
-** {F13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
** constant [SQLITE_TRANSIENT], the routine makes a
** private copy of the value V before it returns.
**
-** {F13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
+** {H13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
** [sqlite3_bind_text(S,N,V,L,D)], or
** [sqlite3_bind_text16(S,N,V,L,D)] when D is a pointer to
** a function, SQLite invokes that function to destroy the
** value V after it has finished using the value V.
**
-** {F13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
+** {H13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
** is a BLOB of L bytes, or a zero-length BLOB if L is negative.
**
-** {F13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
+** {H13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
** be either a [protected sqlite3_value] object or an
** [unprotected sqlite3_value] object.
*/
@@ -2988,7 +3047,7 @@
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
/*
-** CAPI3REF: Number Of SQL Parameters {F13600}
+** CAPI3REF: Number Of SQL Parameters {H13600} <S70300>
**
** This routine can be used to find the number of [SQL parameters]
** in a [prepared statement]. SQL parameters are tokens of the
@@ -3007,14 +3066,14 @@
**
** INVARIANTS:
**
-** {F13601} The [sqlite3_bind_parameter_count(S)] interface returns
+** {H13601} The [sqlite3_bind_parameter_count(S)] interface returns
** the largest index of all SQL parameters in the
** [prepared statement] S, or 0 if S contains no SQL parameters.
*/
int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
-** CAPI3REF: Name Of A Host Parameter {F13620}
+** CAPI3REF: Name Of A Host Parameter {H13620} <S70300>
**
** This routine returns a pointer to the name of the n-th
** [SQL parameter] in a [prepared statement].
@@ -3040,7 +3099,7 @@
**
** INVARIANTS:
**
-** {F13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
+** {H13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
** a UTF-8 rendering of the name of the SQL parameter in
** the [prepared statement] S having index N, or
** NULL if there is no SQL parameter with index N or if the
@@ -3049,7 +3108,7 @@
const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
-** CAPI3REF: Index Of A Parameter With A Given Name {F13640}
+** CAPI3REF: Index Of A Parameter With A Given Name {H13640} <S70300>
**
** Return the index of an SQL parameter given its name. The
** index value returned is suitable for use as the second
@@ -3064,7 +3123,7 @@
**
** INVARIANTS:
**
-** {F13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
+** {H13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
** the index of SQL parameter in the [prepared statement]
** S whose name matches the UTF-8 string N, or 0 if there is
** no match.
@@ -3072,7 +3131,7 @@
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement {F13660}
+** CAPI3REF: Reset All Bindings On A Prepared Statement {H13660} <S70300>
**
** Contrary to the intuition of many, [sqlite3_reset()] does not reset
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
@@ -3080,13 +3139,13 @@
**
** INVARIANTS:
**
-** {F13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
+** {H13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
** parameter bindings in the [prepared statement] S back to NULL.
*/
int sqlite3_clear_bindings(sqlite3_stmt*);
/*
-** CAPI3REF: Number Of Columns In A Result Set {F13710}
+** CAPI3REF: Number Of Columns In A Result Set {H13710} <S10700>
**
** Return the number of columns in the result set returned by the
** [prepared statement]. This routine returns 0 if pStmt is an SQL
@@ -3094,14 +3153,14 @@
**
** INVARIANTS:
**
-** {F13711} The [sqlite3_column_count(S)] interface returns the number of
+** {H13711} The [sqlite3_column_count(S)] interface returns the number of
** columns in the result set generated by the [prepared statement] S,
** or 0 if S does not generate a result set.
*/
int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Column Names In A Result Set {F13720}
+** CAPI3REF: Column Names In A Result Set {H13720} <S10700>
**
** These routines return the name assigned to a particular column
** in the result set of a [SELECT] statement. The sqlite3_column_name()
@@ -3126,31 +3185,31 @@
**
** INVARIANTS:
**
-** {F13721} A successful invocation of the [sqlite3_column_name(S,N)]
+** {H13721} A successful invocation of the [sqlite3_column_name(S,N)]
** interface returns the name of the Nth column (where 0 is
** the leftmost column) for the result set of the
** [prepared statement] S as a zero-terminated UTF-8 string.
**
-** {F13723} A successful invocation of the [sqlite3_column_name16(S,N)]
+** {H13723} A successful invocation of the [sqlite3_column_name16(S,N)]
** interface returns the name of the Nth column (where 0 is
** the leftmost column) for the result set of the
** [prepared statement] S as a zero-terminated UTF-16 string
** in the native byte order.
**
-** {F13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
+** {H13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
** interfaces return a NULL pointer if they are unable to
** allocate memory to hold their normal return strings.
**
-** {F13725} If the N parameter to [sqlite3_column_name(S,N)] or
+** {H13725} If the N parameter to [sqlite3_column_name(S,N)] or
** [sqlite3_column_name16(S,N)] is out of range, then the
** interfaces return a NULL pointer.
**
-** {F13726} The strings returned by [sqlite3_column_name(S,N)] and
+** {H13726} The strings returned by [sqlite3_column_name(S,N)] and
** [sqlite3_column_name16(S,N)] are valid until the next
** call to either routine with the same S and N parameters
** or until [sqlite3_finalize(S)] is called.
**
-** {F13727} When a result column of a [SELECT] statement contains
+** {H13727} When a result column of a [SELECT] statement contains
** an AS clause, the name of that column is the identifier
** to the right of the AS keyword.
*/
@@ -3158,7 +3217,7 @@
const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
-** CAPI3REF: Source Of Data In A Query Result {F13740}
+** CAPI3REF: Source Of Data In A Query Result {H13740} <S10700>
**
** These routines provide a means to determine what column of what
** table in which database a result of a [SELECT] statement comes from.
@@ -3196,50 +3255,50 @@
**
** INVARIANTS:
**
-** {F13741} The [sqlite3_column_database_name(S,N)] interface returns either
+** {H13741} The [sqlite3_column_database_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the database from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13742} The [sqlite3_column_database_name16(S,N)] interface returns either
+** {H13742} The [sqlite3_column_database_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the database
** from which the Nth result column of the [prepared statement] S is
** extracted, or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13743} The [sqlite3_column_table_name(S,N)] interface returns either
+** {H13743} The [sqlite3_column_table_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the table from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13744} The [sqlite3_column_table_name16(S,N)] interface returns either
+** {H13744} The [sqlite3_column_table_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the table
** from which the Nth result column of the [prepared statement] S is
** extracted, or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13745} The [sqlite3_column_origin_name(S,N)] interface returns either
+** {H13745} The [sqlite3_column_origin_name(S,N)] interface returns either
** the UTF-8 zero-terminated name of the table column from which the
** Nth result column of the [prepared statement] S is extracted,
** or NULL if the Nth column of S is a general expression
** or if unable to allocate memory to store the name.
**
-** {F13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
+** {H13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
** the UTF-16 native byte order zero-terminated name of the table
** column from which the Nth result column of the
** [prepared statement] S is extracted, or NULL if the Nth column
** of S is a general expression or if unable to allocate memory
** to store the name.
**
-** {F13748} The return values from
+** {H13748} The return values from
** [sqlite3_column_database_name | column metadata interfaces]
** are valid for the lifetime of the [prepared statement]
** or until the encoding is changed by another metadata
** interface call for the same prepared statement and column.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A13751} If two or more threads call one or more
** [sqlite3_column_database_name | column metadata interfaces]
@@ -3254,7 +3313,7 @@
const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
-** CAPI3REF: Declared Datatype Of A Query Result {F13760}
+** CAPI3REF: Declared Datatype Of A Query Result {H13760} <S10700>
**
** The first parameter is a [prepared statement].
** If this statement is a [SELECT] statement and the Nth column of the
@@ -3284,18 +3343,18 @@
**
** INVARIANTS:
**
-** {F13761} A successful call to [sqlite3_column_decltype(S,N)] returns a
+** {H13761} A successful call to [sqlite3_column_decltype(S,N)] returns a
** zero-terminated UTF-8 string containing the declared datatype
** of the table column that appears as the Nth column (numbered
** from 0) of the result set to the [prepared statement] S.
**
-** {F13762} A successful call to [sqlite3_column_decltype16(S,N)]
+** {H13762} A successful call to [sqlite3_column_decltype16(S,N)]
** returns a zero-terminated UTF-16 native byte order string
** containing the declared datatype of the table column that appears
** as the Nth column (numbered from 0) of the result set to the
** [prepared statement] S.
**
-** {F13763} If N is less than 0 or N is greater than or equal to
+** {H13763} If N is less than 0 or N is greater than or equal to
** the number of columns in the [prepared statement] S,
** or if the Nth column of S is an expression or subquery rather
** than a table column, or if a memory allocation failure
@@ -3307,7 +3366,7 @@
const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
-** CAPI3REF: Evaluate An SQL Statement {F13200}
+** CAPI3REF: Evaluate An SQL Statement {H13200} <S10000>
**
** After a [prepared statement] has been prepared using either
** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3373,24 +3432,24 @@
**
** INVARIANTS:
**
-** {F13202} If the [prepared statement] S is ready to be run, then
+** {H13202} If the [prepared statement] S is ready to be run, then
** [sqlite3_step(S)] advances that prepared statement until
** completion or until it is ready to return another row of the
** result set, or until an [sqlite3_interrupt | interrupt]
** or a run-time error occurs.
**
-** {F15304} When a call to [sqlite3_step(S)] causes the [prepared statement]
+** {H15304} When a call to [sqlite3_step(S)] causes the [prepared statement]
** S to run to completion, the function returns [SQLITE_DONE].
**
-** {F15306} When a call to [sqlite3_step(S)] stops because it is ready to
+** {H15306} When a call to [sqlite3_step(S)] stops because it is ready to
** return another row of the result set, it returns [SQLITE_ROW].
**
-** {F15308} If a call to [sqlite3_step(S)] encounters an
+** {H15308} If a call to [sqlite3_step(S)] encounters an
** [sqlite3_interrupt | interrupt] or a run-time error,
** it returns an appropriate error code that is not one of
** [SQLITE_OK], [SQLITE_ROW], or [SQLITE_DONE].
**
-** {F15310} If an [sqlite3_interrupt | interrupt] or a run-time error
+** {H15310} If an [sqlite3_interrupt | interrupt] or a run-time error
** occurs during a call to [sqlite3_step(S)]
** for a [prepared statement] S created using
** legacy interfaces [sqlite3_prepare()] or
@@ -3400,17 +3459,17 @@
int sqlite3_step(sqlite3_stmt*);
/*
-** CAPI3REF: Number of columns in a result set {F13770}
+** CAPI3REF: Number of columns in a result set {H13770} <S10700>
**
** Returns the number of values in the current row of the result set.
**
** INVARIANTS:
**
-** {F13771} After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
+** {H13771} After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
** the [sqlite3_data_count(S)] routine will return the same value
** as the [sqlite3_column_count(S)] function.
**
-** {F13772} After [sqlite3_step(S)] has returned any value other than
+** {H13772} After [sqlite3_step(S)] has returned any value other than
** [SQLITE_ROW] or before [sqlite3_step(S)] has been called on the
** [prepared statement] for the first time since it was
** [sqlite3_prepare | prepared] or [sqlite3_reset | reset],
@@ -3419,10 +3478,10 @@
int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Fundamental Datatypes {F10265}
+** CAPI3REF: Fundamental Datatypes {H10265} <S10110><S10120>
** KEYWORDS: SQLITE_TEXT
**
-** {F10266} Every value in SQLite has one of five fundamental datatypes:
+** {H10266} Every value in SQLite has one of five fundamental datatypes:
**
** <ul>
** <li> 64-bit signed integer
@@ -3451,7 +3510,7 @@
#define SQLITE3_TEXT 3
/*
-** CAPI3REF: Result Values From A Query {F13800}
+** CAPI3REF: Result Values From A Query {H13800} <S10700>
** KEYWORDS: {column access functions}
**
** These routines form the "result set query" interface.
@@ -3604,55 +3663,55 @@
**
** INVARIANTS:
**
-** {F13803} The [sqlite3_column_blob(S,N)] interface converts the
+** {H13803} The [sqlite3_column_blob(S,N)] interface converts the
** Nth column in the current row of the result set for
** the [prepared statement] S into a BLOB and then returns a
** pointer to the converted value.
**
-** {F13806} The [sqlite3_column_bytes(S,N)] interface returns the
+** {H13806} The [sqlite3_column_bytes(S,N)] interface returns the
** number of bytes in the BLOB or string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_column_blob(S,N)] or
** [sqlite3_column_text(S,N)].
**
-** {F13809} The [sqlite3_column_bytes16(S,N)] interface returns the
+** {H13809} The [sqlite3_column_bytes16(S,N)] interface returns the
** number of bytes in the string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_column_text16(S,N)].
**
-** {F13812} The [sqlite3_column_double(S,N)] interface converts the
+** {H13812} The [sqlite3_column_double(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a floating point value and
** returns a copy of that value.
**
-** {F13815} The [sqlite3_column_int(S,N)] interface converts the
+** {H13815} The [sqlite3_column_int(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a 64-bit signed integer and
** returns the lower 32 bits of that integer.
**
-** {F13818} The [sqlite3_column_int64(S,N)] interface converts the
+** {H13818} The [sqlite3_column_int64(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a 64-bit signed integer and
** returns a copy of that integer.
**
-** {F13821} The [sqlite3_column_text(S,N)] interface converts the
+** {H13821} The [sqlite3_column_text(S,N)] interface converts the
** Nth column in the current row of the result set for
** the [prepared statement] S into a zero-terminated UTF-8
** string and returns a pointer to that string.
**
-** {F13824} The [sqlite3_column_text16(S,N)] interface converts the
+** {H13824} The [sqlite3_column_text16(S,N)] interface converts the
** Nth column in the current row of the result set for the
** [prepared statement] S into a zero-terminated 2-byte
** aligned UTF-16 native byte order string and returns
** a pointer to that string.
**
-** {F13827} The [sqlite3_column_type(S,N)] interface returns
+** {H13827} The [sqlite3_column_type(S,N)] interface returns
** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
** the Nth column in the current row of the result set for
** the [prepared statement] S.
**
-** {F13830} The [sqlite3_column_value(S,N)] interface returns a
+** {H13830} The [sqlite3_column_value(S,N)] interface returns a
** pointer to an [unprotected sqlite3_value] object for the
** Nth column in the current row of the result set for
** the [prepared statement] S.
@@ -3669,7 +3728,7 @@
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
-** CAPI3REF: Destroy A Prepared Statement Object {F13300}
+** CAPI3REF: Destroy A Prepared Statement Object {H13300} <S70300><S30100>
**
** The sqlite3_finalize() function is called to delete a [prepared statement].
** If the statement was executed successfully or not executed at all, then
@@ -3686,18 +3745,18 @@
**
** INVARIANTS:
**
-** {F11302} The [sqlite3_finalize(S)] interface destroys the
+** {H11302} The [sqlite3_finalize(S)] interface destroys the
** [prepared statement] S and releases all
** memory and file resources held by that object.
**
-** {F11304} If the most recent call to [sqlite3_step(S)] for the
+** {H11304} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned an error,
** then [sqlite3_finalize(S)] returns that same error.
*/
int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Reset A Prepared Statement Object {F13330}
+** CAPI3REF: Reset A Prepared Statement Object {H13330} <S70300>
**
** The sqlite3_reset() function is called to reset a [prepared statement]
** object back to its initial state, ready to be re-executed.
@@ -3705,25 +3764,25 @@
** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
** Use [sqlite3_clear_bindings()] to reset the bindings.
**
-** {F11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
+** {H11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
** back to the beginning of its program.
**
-** {F11334} If the most recent call to [sqlite3_step(S)] for the
+** {H11334} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
** or if [sqlite3_step(S)] has never before been called on S,
** then [sqlite3_reset(S)] returns [SQLITE_OK].
**
-** {F11336} If the most recent call to [sqlite3_step(S)] for the
+** {H11336} If the most recent call to [sqlite3_step(S)] for the
** [prepared statement] S indicated an error, then
** [sqlite3_reset(S)] returns an appropriate [error code].
**
-** {F11338} The [sqlite3_reset(S)] interface does not change the values
+** {H11338} The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
int sqlite3_reset(sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Create Or Redefine SQL Functions {F16100}
+** CAPI3REF: Create Or Redefine SQL Functions {H16100} <S20200>
** KEYWORDS: {function creation routines}
** KEYWORDS: {application-defined SQL function}
** KEYWORDS: {application-defined SQL functions}
@@ -3781,64 +3840,64 @@
**
** INVARIANTS:
**
-** {F16103} The [sqlite3_create_function16()] interface behaves exactly
+** {H16103} The [sqlite3_create_function16()] interface behaves exactly
** like [sqlite3_create_function()] in every way except that it
** interprets the zFunctionName argument as zero-terminated UTF-16
** native byte order instead of as zero-terminated UTF-8.
**
-** {F16106} A successful invocation of
+** {H16106} A successful invocation of
** the [sqlite3_create_function(D,X,N,E,...)] interface registers
** or replaces callback functions in the [database connection] D
** used to implement the SQL function named X with N parameters
** and having a preferred text encoding of E.
**
-** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
+** {H16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** replaces the P, F, S, and L values from any prior calls with
** the same D, X, N, and E values.
**
-** {F16112} The [sqlite3_create_function(D,X,...)] interface fails with
+** {H16112} The [sqlite3_create_function(D,X,...)] interface fails with
** a return code of [SQLITE_ERROR] if the SQL function name X is
** longer than 255 bytes exclusive of the zero terminator.
**
-** {F16118} Either F must be NULL and S and L are non-NULL or else F
+** {H16118} Either F must be NULL and S and L are non-NULL or else F
** is non-NULL and S and L are NULL, otherwise
** [sqlite3_create_function(D,X,N,E,P,F,S,L)] returns [SQLITE_ERROR].
**
-** {F16121} The [sqlite3_create_function(D,...)] interface fails with an
+** {H16121} The [sqlite3_create_function(D,...)] interface fails with an
** error code of [SQLITE_BUSY] if there exist [prepared statements]
** associated with the [database connection] D.
**
-** {F16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an
+** {H16124} The [sqlite3_create_function(D,X,N,...)] interface fails with an
** error code of [SQLITE_ERROR] if parameter N (specifying the number
** of arguments to the SQL function being registered) is less
** than -1 or greater than 127.
**
-** {F16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)]
+** {H16127} When N is non-negative, the [sqlite3_create_function(D,X,N,...)]
** interface causes callbacks to be invoked for the SQL function
** named X when the number of arguments to the SQL function is
** exactly N.
**
-** {F16130} When N is -1, the [sqlite3_create_function(D,X,N,...)]
+** {H16130} When N is -1, the [sqlite3_create_function(D,X,N,...)]
** interface causes callbacks to be invoked for the SQL function
** named X with any number of arguments.
**
-** {F16133} When calls to [sqlite3_create_function(D,X,N,...)]
+** {H16133} When calls to [sqlite3_create_function(D,X,N,...)]
** specify multiple implementations of the same function X
** and when one implementation has N>=0 and the other has N=(-1)
** the implementation with a non-zero N is preferred.
**
-** {F16136} When calls to [sqlite3_create_function(D,X,N,E,...)]
+** {H16136} When calls to [sqlite3_create_function(D,X,N,E,...)]
** specify multiple implementations of the same function X with
** the same number of arguments N but with different
** encodings E, then the implementation where E matches the
** database encoding is preferred.
**
-** {F16139} For an aggregate SQL function created using
+** {H16139} For an aggregate SQL function created using
** [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finalizer
** function L will always be invoked exactly once if the
** step function S is called one or more times.
**
-** {F16142} When SQLite invokes either the xFunc or xStep function of
+** {H16142} When SQLite invokes either the xFunc or xStep function of
** an application-defined SQL function or aggregate created
** by [sqlite3_create_function()] or [sqlite3_create_function16()],
** then the array of [sqlite3_value] objects passed as the
@@ -3866,7 +3925,7 @@
);
/*
-** CAPI3REF: Text Encodings {F10267}
+** CAPI3REF: Text Encodings {H10267} <S50200> <H16100>
**
** These constant define integer codes that represent the various
** text encodings supported by SQLite.
@@ -3879,11 +3938,12 @@
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
-** CAPI3REF: Obsolete Functions
+** CAPI3REF: Deprecated Functions
+** DEPRECATED
**
-** These functions are all now obsolete. In order to maintain
-** backwards compatibility with older code, we continue to support
-** these functions. However, new development projects should avoid
+** These functions are [deprecated]. In order to maintain
+** backwards compatibility with older code, these functions continue
+** to be supported. However, new applications should avoid
** the use of these functions. To help encourage people to avoid
** using these functions, we are not going to tell you want they do.
*/
@@ -3895,7 +3955,7 @@
int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
/*
-** CAPI3REF: Obtaining SQL Function Parameter Values {F15100}
+** CAPI3REF: Obtaining SQL Function Parameter Values {H15100} <S20200>
**
** The C-language implementation of SQL functions and aggregates uses
** this set of interface routines to access the parameter values on
@@ -3941,59 +4001,59 @@
**
** INVARIANTS:
**
-** {F15103} The [sqlite3_value_blob(V)] interface converts the
+** {H15103} The [sqlite3_value_blob(V)] interface converts the
** [protected sqlite3_value] object V into a BLOB and then
** returns a pointer to the converted value.
**
-** {F15106} The [sqlite3_value_bytes(V)] interface returns the
+** {H15106} The [sqlite3_value_bytes(V)] interface returns the
** number of bytes in the BLOB or string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_value_blob(V)] or
** [sqlite3_value_text(V)].
**
-** {F15109} The [sqlite3_value_bytes16(V)] interface returns the
+** {H15109} The [sqlite3_value_bytes16(V)] interface returns the
** number of bytes in the string (exclusive of the
** zero terminator on the string) that was returned by the
** most recent call to [sqlite3_value_text16(V)],
** [sqlite3_value_text16be(V)], or [sqlite3_value_text16le(V)].
**
-** {F15112} The [sqlite3_value_double(V)] interface converts the
+** {H15112} The [sqlite3_value_double(V)] interface converts the
** [protected sqlite3_value] object V into a floating point value and
** returns a copy of that value.
**
-** {F15115} The [sqlite3_value_int(V)] interface converts the
+** {H15115} The [sqlite3_value_int(V)] interface converts the
** [protected sqlite3_value] object V into a 64-bit signed integer and
** returns the lower 32 bits of that integer.
**
-** {F15118} The [sqlite3_value_int64(V)] interface converts the
+** {H15118} The [sqlite3_value_int64(V)] interface converts the
** [protected sqlite3_value] object V into a 64-bit signed integer and
** returns a copy of that integer.
**
-** {F15121} The [sqlite3_value_text(V)] interface converts the
+** {H15121} The [sqlite3_value_text(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated UTF-8
** string and returns a pointer to that string.
**
-** {F15124} The [sqlite3_value_text16(V)] interface converts the
+** {H15124} The [sqlite3_value_text16(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 native byte order
** string and returns a pointer to that string.
**
-** {F15127} The [sqlite3_value_text16be(V)] interface converts the
+** {H15127} The [sqlite3_value_text16be(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 big-endian
** string and returns a pointer to that string.
**
-** {F15130} The [sqlite3_value_text16le(V)] interface converts the
+** {H15130} The [sqlite3_value_text16le(V)] interface converts the
** [protected sqlite3_value] object V into a zero-terminated 2-byte
** aligned UTF-16 little-endian
** string and returns a pointer to that string.
**
-** {F15133} The [sqlite3_value_type(V)] interface returns
+** {H15133} The [sqlite3_value_type(V)] interface returns
** one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
** [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
** the [sqlite3_value] object V.
**
-** {F15136} The [sqlite3_value_numeric_type(V)] interface converts
+** {H15136} The [sqlite3_value_numeric_type(V)] interface converts
** the [protected sqlite3_value] object V into either an integer or
** a floating point value if it can do so without loss of
** information, and returns one of [SQLITE_NULL],
@@ -4015,7 +4075,7 @@
int sqlite3_value_numeric_type(sqlite3_value*);
/*
-** CAPI3REF: Obtain Aggregate Function Context {F16210}
+** CAPI3REF: Obtain Aggregate Function Context {H16210} <S20200>
**
** The implementation of aggregate SQL functions use this routine to allocate
** a structure for storing their state.
@@ -4039,20 +4099,20 @@
**
** INVARIANTS:
**
-** {F16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
+** {H16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
** a particular instance of an aggregate function (for a particular
** context C) causes SQLite to allocate N bytes of memory,
** zero that memory, and return a pointer to the allocated memory.
**
-** {F16213} If a memory allocation error occurs during
+** {H16213} If a memory allocation error occurs during
** [sqlite3_aggregate_context(C,N)] then the function returns 0.
**
-** {F16215} Second and subsequent invocations of
+** {H16215} Second and subsequent invocations of
** [sqlite3_aggregate_context(C,N)] for the same context pointer C
** ignore the N parameter and return a pointer to the same
** block of memory returned by the first invocation.
**
-** {F16217} The memory allocated by [sqlite3_aggregate_context(C,N)] is
+** {H16217} The memory allocated by [sqlite3_aggregate_context(C,N)] is
** automatically freed on the next call to [sqlite3_reset()]
** or [sqlite3_finalize()] for the [prepared statement] containing
** the aggregate function associated with context C.
@@ -4060,7 +4120,7 @@
void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
-** CAPI3REF: User Data For Functions {F16240}
+** CAPI3REF: User Data For Functions {H16240} <S20200>
**
** The sqlite3_user_data() interface returns a copy of
** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4073,7 +4133,7 @@
**
** INVARIANTS:
**
-** {F16243} The [sqlite3_user_data(C)] interface returns a copy of the
+** {H16243} The [sqlite3_user_data(C)] interface returns a copy of the
** P pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
** registered the SQL function associated with [sqlite3_context] C.
@@ -4081,7 +4141,7 @@
void *sqlite3_user_data(sqlite3_context*);
/*
-** CAPI3REF: Database Connection For Functions {F16250}
+** CAPI3REF: Database Connection For Functions {H16250} <S60600><S20200>
**
** The sqlite3_context_db_handle() interface returns a copy of
** the pointer to the [database connection] (the 1st parameter)
@@ -4091,7 +4151,7 @@
**
** INVARIANTS:
**
-** {F16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
+** {H16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
** D pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
** or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
** registered the SQL function associated with [sqlite3_context] C.
@@ -4099,7 +4159,7 @@
sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
-** CAPI3REF: Function Auxiliary Data {F16270}
+** CAPI3REF: Function Auxiliary Data {H16270} <S20200>
**
** The following two functions may be used by scalar SQL functions to
** associate metadata with argument values. If the same value is passed to
@@ -4142,27 +4202,27 @@
**
** INVARIANTS:
**
-** {F16272} The [sqlite3_get_auxdata(C,N)] interface returns a pointer
+** {H16272} The [sqlite3_get_auxdata(C,N)] interface returns a pointer
** to metadata associated with the Nth parameter of the SQL function
** whose context is C, or NULL if there is no metadata associated
** with that parameter.
**
-** {F16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
+** {H16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
** pointer P to the Nth parameter of the SQL function with context C.
**
-** {F16276} SQLite will invoke the destructor D with a single argument
+** {H16276} SQLite will invoke the destructor D with a single argument
** which is the metadata pointer P following a call to
** [sqlite3_set_auxdata(C,N,P,D)] when SQLite ceases to hold
** the metadata.
**
-** {F16277} SQLite ceases to hold metadata for an SQL function parameter
+** {H16277} SQLite ceases to hold metadata for an SQL function parameter
** when the value of that parameter changes.
**
-** {F16278} When [sqlite3_set_auxdata(C,N,P,D)] is invoked, the destructor
+** {H16278} When [sqlite3_set_auxdata(C,N,P,D)] is invoked, the destructor
** is called for any prior metadata associated with the same function
** context C and parameter N.
**
-** {F16279} SQLite will call destructors for any metadata it is holding
+** {H16279} SQLite will call destructors for any metadata it is holding
** in a particular [prepared statement] S when either
** [sqlite3_reset(S)] or [sqlite3_finalize(S)] is called.
*/
@@ -4171,7 +4231,7 @@
/*
-** CAPI3REF: Constants Defining Special Destructor Behavior {F10280}
+** CAPI3REF: Constants Defining Special Destructor Behavior {H10280} <S30100>
**
** These are special values for the destructor that is passed in as the
** final argument to routines like [sqlite3_result_blob()]. If the destructor
@@ -4189,7 +4249,7 @@
#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
/*
-** CAPI3REF: Setting The Result Of An SQL Function {F16400}
+** CAPI3REF: Setting The Result Of An SQL Function {H16400} <S20200>
**
** These routines are used by the xFunc or xFinal callbacks that
** implement SQL functions and aggregates. See
@@ -4294,93 +4354,93 @@
**
** INVARIANTS:
**
-** {F16403} The default return value from any SQL function is NULL.
+** {H16403} The default return value from any SQL function is NULL.
**
-** {F16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
+** {H16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
** return value of function C to be a BLOB that is N bytes
** in length and with content pointed to by V.
**
-** {F16409} The [sqlite3_result_double(C,V)] interface changes the
+** {H16409} The [sqlite3_result_double(C,V)] interface changes the
** return value of function C to be the floating point value V.
**
-** {F16412} The [sqlite3_result_error(C,V,N)] interface changes the return
+** {H16412} The [sqlite3_result_error(C,V,N)] interface changes the return
** value of function C to be an exception with error code
** [SQLITE_ERROR] and a UTF-8 error message copied from V up to the
** first zero byte or until N bytes are read if N is positive.
**
-** {F16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
+** {H16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
** value of function C to be an exception with error code
** [SQLITE_ERROR] and a UTF-16 native byte order error message
** copied from V up to the first zero terminator or until N bytes
** are read if N is positive.
**
-** {F16418} The [sqlite3_result_error_toobig(C)] interface changes the return
+** {H16418} The [sqlite3_result_error_toobig(C)] interface changes the return
** value of the function C to be an exception with error code
** [SQLITE_TOOBIG] and an appropriate error message.
**
-** {F16421} The [sqlite3_result_error_nomem(C)] interface changes the return
+** {H16421} The [sqlite3_result_error_nomem(C)] interface changes the return
** value of the function C to be an exception with error code
** [SQLITE_NOMEM] and an appropriate error message.
**
-** {F16424} The [sqlite3_result_error_code(C,E)] interface changes the return
+** {H16424} The [sqlite3_result_error_code(C,E)] interface changes the return
** value of the function C to be an exception with error code E.
** The error message text is unchanged.
**
-** {F16427} The [sqlite3_result_int(C,V)] interface changes the
+** {H16427} The [sqlite3_result_int(C,V)] interface changes the
** return value of function C to be the 32-bit integer value V.
**
-** {F16430} The [sqlite3_result_int64(C,V)] interface changes the
+** {H16430} The [sqlite3_result_int64(C,V)] interface changes the
** return value of function C to be the 64-bit integer value V.
**
-** {F16433} The [sqlite3_result_null(C)] interface changes the
+** {H16433} The [sqlite3_result_null(C)] interface changes the
** return value of function C to be NULL.
**
-** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
+** {H16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
** return value of function C to be the UTF-8 string
** V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
+** {H16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 native byte order
** string V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
+** {H16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 big-endian
** string V up to the first zero if N is negative
** or the first N bytes or V if N is non-negative.
**
-** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
+** {H16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
** return value of function C to be the UTF-16 little-endian
** string V up to the first zero if N is negative
** or the first N bytes of V if N is non-negative.
**
-** {F16448} The [sqlite3_result_value(C,V)] interface changes the
+** {H16448} The [sqlite3_result_value(C,V)] interface changes the
** return value of function C to be the [unprotected sqlite3_value]
** object V.
**
-** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
+** {H16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
** return value of function C to be an N-byte BLOB of all zeros.
**
-** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
+** {H16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
** interfaces make a copy of their error message strings before
** returning.
**
-** {F16457} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16457} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is the constant [SQLITE_STATIC]
** then no destructor is ever called on the pointer V and SQLite
** assumes that V is immutable.
**
-** {F16460} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16460} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is the constant
** [SQLITE_TRANSIENT] then the interfaces makes a copy of the
** content of V and retains the copy.
**
-** {F16463} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
+** {H16463} If the D destructor parameter to [sqlite3_result_blob(C,V,N,D)],
** [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
** [sqlite3_result_text16be(C,V,N,D)], or
** [sqlite3_result_text16le(C,V,N,D)] is some value other than
@@ -4406,7 +4466,7 @@
void sqlite3_result_zeroblob(sqlite3_context*, int n);
/*
-** CAPI3REF: Define New Collating Sequences {F16600}
+** CAPI3REF: Define New Collating Sequences {H16600} <S20300>
**
** These functions are used to add new collation sequences to the
** [database connection] specified as the first argument.
@@ -4449,49 +4509,49 @@
**
** INVARIANTS:
**
-** {F16603} A successful call to the
+** {H16603} A successful call to the
** [sqlite3_create_collation_v2(B,X,E,P,F,D)] interface
** registers function F as the comparison function used to
** implement collation X on the [database connection] B for
** databases having encoding E.
**
-** {F16604} SQLite understands the X parameter to
+** {H16604} SQLite understands the X parameter to
** [sqlite3_create_collation_v2(B,X,E,P,F,D)] as a zero-terminated
** UTF-8 string in which case is ignored for ASCII characters and
** is significant for non-ASCII characters.
**
-** {F16606} Successive calls to [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16606} Successive calls to [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** with the same values for B, X, and E, override prior values
** of P, F, and D.
**
-** {F16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** is not NULL then it is called with argument P when the
** collating function is dropped by SQLite.
**
-** {F16612} A collating function is dropped when it is overloaded.
+** {H16612} A collating function is dropped when it is overloaded.
**
-** {F16615} A collating function is dropped when the database connection
+** {H16615} A collating function is dropped when the database connection
** is closed using [sqlite3_close()].
**
-** {F16618} The pointer P in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {H16618} The pointer P in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
** is passed through as the first parameter to the comparison
** function F for all subsequent invocations of F.
**
-** {F16621} A call to [sqlite3_create_collation(B,X,E,P,F)] is exactly
+** {H16621} A call to [sqlite3_create_collation(B,X,E,P,F)] is exactly
** the same as a call to [sqlite3_create_collation_v2()] with
** the same parameters and a NULL destructor.
**
-** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
+** {H16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
** SQLite uses the comparison function F for all text comparison
** operations on the [database connection] B on text values that
** use the collating sequence named X.
**
-** {F16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
+** {H16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
** as [sqlite3_create_collation(B,X,E,P,F)] except that the
** collation name X is understood as UTF-16 in native byte order
** instead of UTF-8.
**
-** {F16630} When multiple comparison functions are available for the same
+** {H16630} When multiple comparison functions are available for the same
** collating sequence, SQLite chooses the one whose text encoding
** requires the least amount of conversion from the default
** text encoding of the database.
@@ -4520,7 +4580,7 @@
);
/*
-** CAPI3REF: Collation Needed Callbacks {F16700}
+** CAPI3REF: Collation Needed Callbacks {H16700} <S20300>
**
** To avoid having to register all collation sequences before a database
** can be used, a single callback function may be registered with the
@@ -4529,7 +4589,7 @@
**
** If the function is registered using the sqlite3_collation_needed() API,
** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used,
+** encoded in UTF-8. {H16703} If sqlite3_collation_needed16() is used,
** the names are passed as UTF-16 in machine native byte order.
** A call to either function replaces any existing callback.
**
@@ -4547,18 +4607,18 @@
**
** INVARIANTS:
**
-** {F16702} A successful call to [sqlite3_collation_needed(D,P,F)]
+** {H16702} A successful call to [sqlite3_collation_needed(D,P,F)]
** or [sqlite3_collation_needed16(D,P,F)] causes
** the [database connection] D to invoke callback F with first
** parameter P whenever it needs a comparison function for a
** collating sequence that it does not know about.
**
-** {F16704} Each successful call to [sqlite3_collation_needed()] or
+** {H16704} Each successful call to [sqlite3_collation_needed()] or
** [sqlite3_collation_needed16()] overrides the callback registered
** on the same [database connection] by prior calls to either
** interface.
**
-** {F16706} The name of the requested collating function passed in the
+** {H16706} The name of the requested collating function passed in the
** 4th parameter to the callback is in UTF-8 if the callback
** was registered using [sqlite3_collation_needed()] and
** is in UTF-16 native byte order if the callback was
@@ -4601,7 +4661,7 @@
);
/*
-** CAPI3REF: Suspend Execution For A Short Time {F10530}
+** CAPI3REF: Suspend Execution For A Short Time {H10530} <S40410>
**
** The sqlite3_sleep() function causes the current thread to suspend execution
** for at least a number of milliseconds specified in its parameter.
@@ -4616,19 +4676,19 @@
**
** INVARIANTS:
**
-** {F10533} The [sqlite3_sleep(M)] interface invokes the xSleep
+** {H10533} The [sqlite3_sleep(M)] interface invokes the xSleep
** method of the default [sqlite3_vfs|VFS] in order to
** suspend execution of the current thread for at least
** M milliseconds.
**
-** {F10536} The [sqlite3_sleep(M)] interface returns the number of
+** {H10536} The [sqlite3_sleep(M)] interface returns the number of
** milliseconds of sleep actually requested of the operating
** system, which might be larger than the parameter M.
*/
int sqlite3_sleep(int);
/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files {F10310}
+** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} <S20000>
**
** If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all temporary files
@@ -4644,7 +4704,7 @@
SQLITE_EXTERN char *sqlite3_temp_directory;
/*
-** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode {F12930}
+** CAPI3REF: Test For Auto-Commit Mode {H12930} <S60200>
** KEYWORDS: {autocommit mode}
**
** The sqlite3_get_autocommit() interface returns non-zero or
@@ -4662,18 +4722,18 @@
**
** INVARIANTS:
**
-** {F12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or
+** {H12931} The [sqlite3_get_autocommit(D)] interface returns non-zero or
** zero if the [database connection] D is or is not in autocommit
** mode, respectively.
**
-** {F12932} Autocommit mode is on by default.
+** {H12932} Autocommit mode is on by default.
**
-** {F12933} Autocommit mode is disabled by a successful [BEGIN] statement.
+** {H12933} Autocommit mode is disabled by a successful [BEGIN] statement.
**
-** {F12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
+** {H12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
** statement.
**
-** LIMITATIONS:
+** ASSUMPTIONS:
**
** {A12936} If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
@@ -4682,7 +4742,7 @@
int sqlite3_get_autocommit(sqlite3*);
/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120}
+** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} <S60600>
**
** The sqlite3_db_handle interface returns the [database connection] handle
** to which a [prepared statement] belongs. The database handle returned by
@@ -4692,14 +4752,14 @@
**
** INVARIANTS:
**
-** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
+** {H13123} The [sqlite3_db_handle(S)] interface returns a pointer
** to the [database connection] associated with the
** [prepared statement] S.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
-** CAPI3REF: Find the next prepared statement {F13140}
+** CAPI3REF: Find the next prepared statement {H13140} <S60600>
**
** This interface returns a pointer to the next [prepared statement] after
** pStmt associated with the [database connection] pDb. If pStmt is NULL
@@ -4709,28 +4769,34 @@
**
** INVARIANTS:
**
-** {F13143} If D is a [database connection] that holds one or more
+** {H13143} If D is a [database connection] that holds one or more
** unfinalized [prepared statements] and S is a NULL pointer,
** then [sqlite3_next_stmt(D, S)] routine shall return a pointer
** to one of the prepared statements associated with D.
**
-** {F13146} If D is a [database connection] that holds no unfinalized
+** {H13146} If D is a [database connection] that holds no unfinalized
** [prepared statements] and S is a NULL pointer, then
** [sqlite3_next_stmt(D, S)] routine shall return a NULL pointer.
**
-** {F13149} If S is a [prepared statement] in the [database connection] D
+** {H13149} If S is a [prepared statement] in the [database connection] D
** and S is not the last prepared statement in D, then
** [sqlite3_next_stmt(D, S)] routine shall return a pointer
** to the next prepared statement in D after S.
**
-** {F13152} If S is the last [prepared statement] in the
+** {H13152} If S is the last [prepared statement] in the
** [database connection] D then the [sqlite3_next_stmt(D, S)]
** routine shall return a NULL pointer.
+**
+** ASSUMPTIONS:
+**
+** {A13154} The [database connection] pointer D in a call to
+** [sqlite3_next_stmt(D,S)] must refer to an open database
+** connection and in particular must not be a NULL pointer.
*/
sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
-** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
+** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
**
** The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is committed.
@@ -4760,37 +4826,37 @@
**
** INVARIANTS:
**
-** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
+** {H12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
** callback function F to be invoked with argument P whenever
** a transaction commits on the [database connection] D.
**
-** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
+** {H12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
** from the previous call with the same [database connection] D,
** or NULL on the first call for a particular database connection D.
**
-** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback
+** {H12953} Each call to [sqlite3_commit_hook()] overwrites the callback
** registered by prior calls.
**
-** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
+** {H12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
** then the commit hook callback is canceled and no callback
** is invoked when a transaction commits.
**
-** {F12955} If the commit callback returns non-zero then the commit is
+** {H12955} If the commit callback returns non-zero then the commit is
** converted into a rollback.
**
-** {F12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
+** {H12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
** callback function F to be invoked with argument P whenever
** a transaction rolls back on the [database connection] D.
**
-** {F12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
+** {H12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
** argument from the previous call with the same
** [database connection] D, or NULL on the first call
** for a particular database connection D.
**
-** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
+** {H12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
** registered by prior calls.
**
-** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
+** {H12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
** then the rollback hook callback is canceled and no callback
** is invoked when a transaction rolls back.
*/
@@ -4798,7 +4864,7 @@
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
-** CAPI3REF: Data Change Notification Callbacks {F12970}
+** CAPI3REF: Data Change Notification Callbacks {H12970} <S60400>
**
** The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
@@ -4826,33 +4892,33 @@
**
** INVARIANTS:
**
-** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
+** {H12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
** function F to be invoked with first parameter P whenever
** a table row is modified, inserted, or deleted on
** the [database connection] D.
**
-** {F12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
+** {H12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
** of P for the previous call on the same [database connection] D,
** or NULL for the first call.
**
-** {F12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)]
+** {H12975} If the update hook callback F in [sqlite3_update_hook(D,F,P)]
** is NULL then the no update callbacks are made.
**
-** {F12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls
+** {H12977} Each call to [sqlite3_update_hook(D,F,P)] overrides prior calls
** to the same interface on the same [database connection] D.
**
-** {F12979} The update hook callback is not invoked when internal system
+** {H12979} The update hook callback is not invoked when internal system
** tables such as sqlite_master and sqlite_sequence are modified.
**
-** {F12981} The second parameter to the update callback
+** {H12981} The second parameter to the update callback
** is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
** depending on the operation that caused the callback to be invoked.
**
-** {F12983} The third and fourth arguments to the callback contain pointers
+** {H12983} The third and fourth arguments to the callback contain pointers
** to zero-terminated UTF-8 strings which are the names of the
** database and table that is being updated.
-** {F12985} The final callback parameter is the rowid of the row after
+** {H12985} The final callback parameter is the rowid of the row after
** the change occurs.
*/
void *sqlite3_update_hook(
@@ -4862,7 +4928,7 @@
);
/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330}
+** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} <S30900>
** KEYWORDS: {shared cache} {shared cache mode}
**
** This routine enables or disables the sharing of the database cache
@@ -4892,22 +4958,22 @@
**
** INVARIANTS:
**
-** {F10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
+** {H10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
** will enable or disable shared cache mode for any subsequently
** created [database connection] in the same process.
**
-** {F10336} When shared cache is enabled, the [sqlite3_create_module()]
+** {H10336} When shared cache is enabled, the [sqlite3_create_module()]
** interface will always return an error.
**
-** {F10337} The [sqlite3_enable_shared_cache(B)] interface returns
+** {H10337} The [sqlite3_enable_shared_cache(B)] interface returns
** [SQLITE_OK] if shared cache was enabled or disabled successfully.
**
-** {F10339} Shared cache is disabled by default.
+** {H10339} Shared cache is disabled by default.
*/
int sqlite3_enable_shared_cache(int);
/*
-** CAPI3REF: Attempt To Free Heap Memory {F17340}
+** CAPI3REF: Attempt To Free Heap Memory {H17340} <S30220>
**
** The sqlite3_release_memory() interface attempts to free N bytes
** of heap memory by deallocating non-essential memory allocations
@@ -4918,18 +4984,18 @@
**
** INVARIANTS:
**
-** {F17341} The [sqlite3_release_memory(N)] interface attempts to
+** {H17341} The [sqlite3_release_memory(N)] interface attempts to
** free N bytes of heap memory by deallocating non-essential
** memory allocations held by the database library.
**
-** {F16342} The [sqlite3_release_memory(N)] returns the number
+** {H16342} The [sqlite3_release_memory(N)] returns the number
** of bytes actually freed, which might be more or less
** than the amount requested.
*/
int sqlite3_release_memory(int);
/*
-** CAPI3REF: Impose A Limit On Heap Size {F17350}
+** CAPI3REF: Impose A Limit On Heap Size {H17350} <S30220>
**
** The sqlite3_soft_heap_limit() interface places a "soft" limit
** on the amount of heap memory that may be allocated by SQLite.
@@ -4960,36 +5026,36 @@
**
** INVARIANTS:
**
-** {F16351} The [sqlite3_soft_heap_limit(N)] interface places a soft limit
+** {H16351} The [sqlite3_soft_heap_limit(N)] interface places a soft limit
** of N bytes on the amount of heap memory that may be allocated
** using [sqlite3_malloc()] or [sqlite3_realloc()] at any point
** in time.
**
-** {F16352} If a call to [sqlite3_malloc()] or [sqlite3_realloc()] would
+** {H16352} If a call to [sqlite3_malloc()] or [sqlite3_realloc()] would
** cause the total amount of allocated memory to exceed the
** soft heap limit, then [sqlite3_release_memory()] is invoked
** in an attempt to reduce the memory usage prior to proceeding
** with the memory allocation attempt.
**
-** {F16353} Calls to [sqlite3_malloc()] or [sqlite3_realloc()] that trigger
+** {H16353} Calls to [sqlite3_malloc()] or [sqlite3_realloc()] that trigger
** attempts to reduce memory usage through the soft heap limit
** mechanism continue even if the attempt to reduce memory
** usage is unsuccessful.
**
-** {F16354} A negative or zero value for N in a call to
+** {H16354} A negative or zero value for N in a call to
** [sqlite3_soft_heap_limit(N)] means that there is no soft
** heap limit and [sqlite3_release_memory()] will only be
** called when memory is completely exhausted.
**
-** {F16355} The default value for the soft heap limit is zero.
+** {H16355} The default value for the soft heap limit is zero.
**
-** {F16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the
+** {H16358} Each call to [sqlite3_soft_heap_limit(N)] overrides the
** values set by all prior calls.
*/
void sqlite3_soft_heap_limit(int);
/*
-** CAPI3REF: Extract Metadata About A Column Of A Table {F12850}
+** CAPI3REF: Extract Metadata About A Column Of A Table {H12850} <S60300>
**
** This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
@@ -5063,28 +5129,28 @@
);
/*
-** CAPI3REF: Load An Extension {F12600}
+** CAPI3REF: Load An Extension {H12600} <S20500>
**
** This interface loads an SQLite extension library from the named file.
**
-** {F12601} The sqlite3_load_extension() interface attempts to load an
+** {H12601} The sqlite3_load_extension() interface attempts to load an
** SQLite extension library contained in the file zFile.
**
-** {F12602} The entry point is zProc.
+** {H12602} The entry point is zProc.
**
-** {F12603} zProc may be 0, in which case the name of the entry point
+** {H12603} zProc may be 0, in which case the name of the entry point
** defaults to "sqlite3_extension_init".
**
-** {F12604} The sqlite3_load_extension() interface shall return
+** {H12604} The sqlite3_load_extension() interface shall return
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
**
-** {F12605} If an error occurs and pzErrMsg is not 0, then the
+** {H12605} If an error occurs and pzErrMsg is not 0, then the
** [sqlite3_load_extension()] interface shall attempt to
** fill *pzErrMsg with error message text stored in memory
** obtained from [sqlite3_malloc()]. {END} The calling function
** should free this memory by calling [sqlite3_free()].
**
-** {F12606} Extension loading must be enabled using
+** {H12606} Extension loading must be enabled using
** [sqlite3_enable_load_extension()] prior to calling this API,
** otherwise an error will be returned.
*/
@@ -5096,7 +5162,7 @@
);
/*
-** CAPI3REF: Enable Or Disable Extension Loading {F12620}
+** CAPI3REF: Enable Or Disable Extension Loading {H12620} <S20500>
**
** So as not to open security holes in older applications that are
** unprepared to deal with extension loading, and as a means of disabling
@@ -5105,16 +5171,16 @@
**
** Extension loading is off by default. See ticket #1863.
**
-** {F12621} Call the sqlite3_enable_load_extension() routine with onoff==1
+** {H12621} Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
**
-** {F12622} Extension loading is off by default.
+** {H12622} Extension loading is off by default.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
-** CAPI3REF: Make Arrangements To Automatically Load An Extension {F12640}
+** CAPI3REF: Automatically Load An Extensions {H12640} <S20500>
**
** This API can be invoked at program startup in order to register
** one or more statically linked extensions that will be available
@@ -5125,32 +5191,32 @@
** on your program and it reports a leak because of this array, invoke
** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
**
-** {F12641} This function registers an extension entry point that is
+** {H12641} This function registers an extension entry point that is
** automatically invoked whenever a new [database connection]
** is opened using [sqlite3_open()], [sqlite3_open16()],
** or [sqlite3_open_v2()].
**
-** {F12642} Duplicate extensions are detected so calling this routine
+** {H12642} Duplicate extensions are detected so calling this routine
** multiple times with the same extension is harmless.
**
-** {F12643} This routine stores a pointer to the extension in an array
+** {H12643} This routine stores a pointer to the extension in an array
** that is obtained from [sqlite3_malloc()].
**
-** {F12644} Automatic extensions apply across all threads.
+** {H12644} Automatic extensions apply across all threads.
*/
int sqlite3_auto_extension(void *xEntryPoint);
/*
-** CAPI3REF: Reset Automatic Extension Loading {F12660}
+** CAPI3REF: Reset Automatic Extension Loading {H12660} <S20500>
**
** This function disables all previously registered automatic
** extensions. {END} It undoes the effect of all prior
** [sqlite3_auto_extension()] calls.
**
-** {F12661} This function disables all previously registered
+** {H12661} This function disables all previously registered
** automatic extensions.
**
-** {F12662} This function disables automatic extensions in all threads.
+** {H12662} This function disables automatic extensions in all threads.
*/
void sqlite3_reset_auto_extension(void);
@@ -5174,8 +5240,9 @@
typedef struct sqlite3_module sqlite3_module;
/*
-** CAPI3REF: Virtual Table Object {F18000}
+** CAPI3REF: Virtual Table Object {H18000} <S20400>
** KEYWORDS: sqlite3_module
+** EXPERIMENTAL
**
** A module is a class of virtual tables. Each module is defined
** by an instance of the following structure. This structure consists
@@ -5211,13 +5278,13 @@
int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
void **ppArg);
-
int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
};
/*
-** CAPI3REF: Virtual Table Indexing Information {F18100}
+** CAPI3REF: Virtual Table Indexing Information {H18100} <S20400>
** KEYWORDS: sqlite3_index_info
+** EXPERIMENTAL
**
** The sqlite3_index_info structure and its substructures is used to
** pass information into and receive the reply from the xBestIndex
@@ -5280,7 +5347,6 @@
int iColumn; /* Column number */
unsigned char desc; /* True for DESC. False for ASC. */
} *aOrderBy; /* The ORDER BY clause */
-
/* Outputs */
struct sqlite3_index_constraint_usage {
int argvIndex; /* if >0, constraint is part of argv to xFilter */
@@ -5300,7 +5366,8 @@
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
/*
-** CAPI3REF: Register A Virtual Table Implementation {F18200}
+** CAPI3REF: Register A Virtual Table Implementation {H18200} <S20400>
+** EXPERIMENTAL
**
** This routine is used to register a new module name with a
** [database connection]. Module names must be registered before
@@ -5318,7 +5385,8 @@
);
/*
-** CAPI3REF: Register A Virtual Table Implementation {F18210}
+** CAPI3REF: Register A Virtual Table Implementation {H18210} <S20400>
+** EXPERIMENTAL
**
** This routine is identical to the [sqlite3_create_module()] method above,
** except that it allows a destructor function to be specified. It is
@@ -5333,8 +5401,9 @@
);
/*
-** CAPI3REF: Virtual Table Instance Object {F18010}
+** CAPI3REF: Virtual Table Instance Object {H18010} <S20400>
** KEYWORDS: sqlite3_vtab
+** EXPERIMENTAL
**
** Every module implementation uses a subclass of the following structure
** to describe a particular instance of the module. Each subclass will
@@ -5363,8 +5432,9 @@
};
/*
-** CAPI3REF: Virtual Table Cursor Object {F18020}
+** CAPI3REF: Virtual Table Cursor Object {H18020} <S20400>
** KEYWORDS: sqlite3_vtab_cursor
+** EXPERIMENTAL
**
** Every module implementation uses a subclass of the following structure
** to describe cursors that point into the virtual table and are used
@@ -5384,7 +5454,8 @@
};
/*
-** CAPI3REF: Declare The Schema Of A Virtual Table {F18280}
+** CAPI3REF: Declare The Schema Of A Virtual Table {H18280} <S20400>
+** EXPERIMENTAL
**
** The xCreate and xConnect methods of a module use the following API
** to declare the format (the names and datatypes of the columns) of
@@ -5396,7 +5467,8 @@
int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
/*
-** CAPI3REF: Overload A Function For A Virtual Table {F18300}
+** CAPI3REF: Overload A Function For A Virtual Table {H18300} <S20400>
+** EXPERIMENTAL
**
** Virtual tables can provide alternative implementations of functions
** using the xFindFunction method. But global versions of those functions
@@ -5428,7 +5500,7 @@
*/
/*
-** CAPI3REF: A Handle To An Open BLOB {F17800}
+** CAPI3REF: A Handle To An Open BLOB {H17800} <S30230>
** KEYWORDS: {BLOB handle} {BLOB handles}
**
** An instance of this object represents an open BLOB on which
@@ -5442,7 +5514,7 @@
typedef struct sqlite3_blob sqlite3_blob;
/*
-** CAPI3REF: Open A BLOB For Incremental I/O {F17810}
+** CAPI3REF: Open A BLOB For Incremental I/O {H17810} <S30230>
**
** This interfaces opens a [BLOB handle | handle] to the BLOB located
** in row iRow, column zColumn, table zTable in database zDb;
@@ -5480,28 +5552,28 @@
**
** INVARIANTS:
**
-** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
+** {H17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
** interface shall open an [sqlite3_blob] object P on the BLOB
** in column C of the table T in the database B on
** the [database connection] D.
**
-** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
+** {H17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
** a new transaction on the [database connection] D if that
** connection is not already in a transaction.
**
-** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
+** {H17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
** the BLOB for read and write access if and only if the F
** parameter is non-zero.
**
-** {F17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
+** {H17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
** success and an appropriate [error code] on failure.
**
-** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
+** {H17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error.
**
-** {F17824} If any column in the row that a [sqlite3_blob] has open is
+** {H17824} If any column in the row that a [sqlite3_blob] has open is
** changed by a separate [UPDATE] or [DELETE] statement or by
** an [ON CONFLICT] side effect, then the [sqlite3_blob] shall
** be marked as invalid.
@@ -5517,7 +5589,7 @@
);
/*
-** CAPI3REF: Close A BLOB Handle {F17830}
+** CAPI3REF: Close A BLOB Handle {H17830} <S30230>
**
** Closes an open [BLOB handle].
**
@@ -5529,7 +5601,7 @@
**
** Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. {F17833} Any errors that occur during
+** at the time when the BLOB is closed. {H17833} Any errors that occur during
** closing are reported as a non-zero return value.
**
** The BLOB is closed unconditionally. Even if this routine returns
@@ -5537,37 +5609,37 @@
**
** INVARIANTS:
**
-** {F17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
+** {H17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
** object P previously opened using [sqlite3_blob_open()].
**
-** {F17836} Closing an [sqlite3_blob] object using
+** {H17836} Closing an [sqlite3_blob] object using
** [sqlite3_blob_close()] shall cause the current transaction to
** commit if there are no other open [sqlite3_blob] objects
** or [prepared statements] on the same [database connection] and
** the database connection is in [autocommit mode].
**
-** {F17839} The [sqlite3_blob_close(P)] interfaces shall close the
+** {H17839} The [sqlite3_blob_close(P)] interfaces shall close the
** [sqlite3_blob] object P unconditionally, even if
** [sqlite3_blob_close(P)] returns something other than [SQLITE_OK].
*/
int sqlite3_blob_close(sqlite3_blob *);
/*
-** CAPI3REF: Return The Size Of An Open BLOB {F17840}
+** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
**
** Returns the size in bytes of the BLOB accessible via the open
** []BLOB handle] in its only argument.
**
** INVARIANTS:
**
-** {F17843} The [sqlite3_blob_bytes(P)] interface returns the size
+** {H17843} The [sqlite3_blob_bytes(P)] interface returns the size
** in bytes of the BLOB that the [sqlite3_blob] object P
** refers to.
*/
int sqlite3_blob_bytes(sqlite3_blob *);
/*
-** CAPI3REF: Read Data From A BLOB Incrementally {F17850}
+** CAPI3REF: Read Data From A BLOB Incrementally {H17850} <S30230>
**
** This function is used to read data from an open [BLOB handle] into a
** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -5585,31 +5657,31 @@
**
** INVARIANTS:
**
-** {F17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)]
+** {H17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)]
** shall reads N bytes of data out of the BLOB referenced by
** [BLOB handle] P beginning at offset X and store those bytes
** into buffer Z.
**
-** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
+** {H17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
** is less than N+X bytes, then the function shall leave the
** Z buffer unchanged and return [SQLITE_ERROR].
**
-** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
+** {H17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
** then the function shall leave the Z buffer unchanged
** and return [SQLITE_ERROR].
**
-** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
+** {H17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
** if N bytes are successfully read into buffer Z.
**
-** {F17863} If the [BLOB handle] P is expired and X and N are within bounds
+** {H17863} If the [BLOB handle] P is expired and X and N are within bounds
** then [sqlite3_blob_read(P,Z,N,X)] shall leave the Z buffer
** unchanged and return [SQLITE_ABORT].
**
-** {F17865} If the requested read could not be completed,
+** {H17865} If the requested read could not be completed,
** the [sqlite3_blob_read(P,Z,N,X)] interface shall return an
** appropriate [error code] or [extended error code].
**
-** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
+** {H17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error, where D is the
@@ -5618,7 +5690,7 @@
int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
-** CAPI3REF: Write Data Into A BLOB Incrementally {F17870}
+** CAPI3REF: Write Data Into A BLOB Incrementally {H17870} <S30230>
**
** This function is used to write data into an open [BLOB handle] from a
** caller-supplied buffer. N bytes of data are copied from the buffer Z
@@ -5646,39 +5718,39 @@
**
** INVARIANTS:
**
-** {F17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
+** {H17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
** shall write N bytes of data from buffer Z into the BLOB
** referenced by [BLOB handle] P beginning at offset X into
** the BLOB.
**
-** {F17874} In the absence of other overridding changes, the changes
+** {H17874} In the absence of other overridding changes, the changes
** written to a BLOB by [sqlite3_blob_write()] shall
** remain in effect after the associated [BLOB handle] expires.
**
-** {F17875} If the [BLOB handle] P was opened for reading only then
+** {H17875} If the [BLOB handle] P was opened for reading only then
** an invocation of [sqlite3_blob_write(P,Z,N,X)] shall leave
** the referenced BLOB unchanged and return [SQLITE_READONLY].
**
-** {F17876} If the size of the BLOB referenced by [BLOB handle] P is
+** {H17876} If the size of the BLOB referenced by [BLOB handle] P is
** less than N+X bytes then [sqlite3_blob_write(P,Z,N,X)] shall
** leave the BLOB unchanged and return [SQLITE_ERROR].
**
-** {F17877} If the [BLOB handle] P is expired and X and N are within bounds
+** {H17877} If the [BLOB handle] P is expired and X and N are within bounds
** then [sqlite3_blob_read(P,Z,N,X)] shall leave the BLOB
** unchanged and return [SQLITE_ABORT].
**
-** {F17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
+** {H17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
** shall leave the BLOB referenced by [BLOB handle] P unchanged
** and return [SQLITE_ERROR].
**
-** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
+** {H17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
** [SQLITE_OK] if N bytes where successfully written into the BLOB.
**
-** {F17885} If the requested write could not be completed,
+** {H17885} If the requested write could not be completed,
** the [sqlite3_blob_write(P,Z,N,X)] interface shall return an
** appropriate [error code] or [extended error code].
**
-** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
+** {H17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
** then subsequent calls to [sqlite3_errcode(D)],
** [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
** information appropriate for that error.
@@ -5686,7 +5758,7 @@
int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
-** CAPI3REF: Virtual File System Objects {F11200}
+** CAPI3REF: Virtual File System Objects {H11200} <S20100>
**
** A virtual filesystem (VFS) is an [sqlite3_vfs] object
** that SQLite uses to interact
@@ -5716,27 +5788,27 @@
**
** INVARIANTS:
**
-** {F11203} The [sqlite3_vfs_find(N)] interface returns a pointer to the
+** {H11203} The [sqlite3_vfs_find(N)] interface returns a pointer to the
** registered [sqlite3_vfs] object whose name exactly matches
** the zero-terminated UTF-8 string N, or it returns NULL if
** there is no match.
**
-** {F11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
+** {H11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
** the function returns a pointer to the default [sqlite3_vfs]
** object if there is one, or NULL if there is no default
** [sqlite3_vfs] object.
**
-** {F11209} The [sqlite3_vfs_register(P,F)] interface registers the
+** {H11209} The [sqlite3_vfs_register(P,F)] interface registers the
** well-formed [sqlite3_vfs] object P using the name given
** by the zName field of the object.
**
-** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register
+** {H11212} Using the [sqlite3_vfs_register(P,F)] interface to register
** the same [sqlite3_vfs] object multiple times is a harmless no-op.
**
-** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
+** {H11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
** object P the default [sqlite3_vfs] object if F is non-zero.
**
-** {F11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
+** {H11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
** [sqlite3_vfs] object P so that it is no longer returned by
** subsequent calls to [sqlite3_vfs_find()].
*/
@@ -5745,7 +5817,7 @@
int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
-** CAPI3REF: Mutexes {F17000}
+** CAPI3REF: Mutexes {H17000} <S20000>
**
** The SQLite core uses these routines for thread
** synchronization. Though they are intended for internal
@@ -5778,10 +5850,10 @@
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
-** {F17011} The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. {F17012} If it returns NULL
-** that means that a mutex could not be allocated. {F17013} SQLite
-** will unwind its stack and return an error. {F17014} The argument
+** {H17011} The sqlite3_mutex_alloc() routine allocates a new
+** mutex and returns a pointer to it. {H17012} If it returns NULL
+** that means that a mutex could not be allocated. {H17013} SQLite
+** will unwind its stack and return an error. {H17014} The argument
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
@@ -5795,17 +5867,17 @@
** <li> SQLITE_MUTEX_STATIC_LRU2
** </ul>
**
-** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
+** {H17015} The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. {F17016} But SQLite will only request a recursive mutex in
+** not want to. {H17016} But SQLite will only request a recursive mutex in
** cases where it really needs one. {END} If a faster non-recursive mutex
** implementation is available on the host platform, the mutex subsystem
** might return such a mutex in response to SQLITE_MUTEX_FAST.
**
-** {F17017} The other allowed parameters to sqlite3_mutex_alloc() each return
+** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return
** a pointer to a static preexisting mutex. {END} Four static mutexes are
** used by the current version of SQLite. Future versions of SQLite
** may add additional static mutexes. Static mutexes are for internal
@@ -5813,41 +5885,41 @@
** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
** SQLITE_MUTEX_RECURSIVE.
**
-** {F17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
+** {H17018} Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. {F17034} But for the static
+** returns a different mutex on every call. {H17034} But for the static
** mutex types, the same mutex is returned on every call that has
** the same type number.
**
-** {F17019} The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. {F17020} SQLite is careful to deallocate every
+** {H17019} The sqlite3_mutex_free() routine deallocates a previously
+** allocated dynamic mutex. {H17020} SQLite is careful to deallocate every
** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
** use when they are deallocated. {A17022} Attempting to deallocate a static
-** mutex results in undefined behavior. {F17023} SQLite never deallocates
+** mutex results in undefined behavior. {H17023} SQLite never deallocates
** a static mutex. {END}
**
** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. {F17024} If another thread is already within the mutex,
+** to enter a mutex. {H17024} If another thread is already within the mutex,
** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {F17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. {F17026} Mutexes created using
+** SQLITE_BUSY. {H17025} The sqlite3_mutex_try() interface returns [SQLITE_OK]
+** upon successful entry. {H17026} Mutexes created using
** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** {F17027} In such cases the,
+** {H17027} In such cases the,
** mutex must be exited an equal number of times before another thread
** can enter. {A17028} If the same thread tries to enter any other
** kind of mutex more than once, the behavior is undefined.
-** {F17029} SQLite will never exhibit
+** {H17029} SQLite will never exhibit
** such behavior in its own use of mutexes.
**
** Some systems (for example, Windows 95) do not support the operation
** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. {F17030} The SQLite core only ever uses
+** will always return SQLITE_BUSY. {H17030} The SQLite core only ever uses
** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
**
-** {F17031} The sqlite3_mutex_leave() routine exits a mutex that was
+** {H17031} The sqlite3_mutex_leave() routine exits a mutex that was
** previously entered by the same thread. {A17032} The behavior
** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. {F17033} SQLite will
+** calling thread or is not currently allocated. {H17033} SQLite will
** never do either. {END}
**
** If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
@@ -5863,7 +5935,8 @@
void sqlite3_mutex_leave(sqlite3_mutex*);
/*
-** CAPI3REF: Mutex Methods Object {F17120}
+** CAPI3REF: Mutex Methods Object {H17120} <S20130>
+** EXPERIMENTAL
**
** An instance of this structure defines the low-level routines
** used to allocate and use mutexes.
@@ -5880,14 +5953,14 @@
**
** The xMutexInit method defined by this structure is invoked as
** part of system initialization by the sqlite3_initialize() function.
-** {F17001} The xMutexInit routine shall be called by SQLite once for each
+** {H17001} The xMutexInit routine shall be called by SQLite once for each
** effective call to [sqlite3_initialize()].
**
** The xMutexEnd method defined by this structure is invoked as
** part of system shutdown by the sqlite3_shutdown() function. The
** implementation of this method is expected to release all outstanding
** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. {F17003} The xMutexEnd()
+** those obtained by the xMutexInit method. {H17003} The xMutexEnd()
** interface shall be invoked once for each call to [sqlite3_shutdown()].
**
** The remaining seven methods defined by this structure (xMutexAlloc,
@@ -5926,18 +5999,18 @@
};
/*
-** CAPI3REF: Mutex Verification Routines {F17080}
+** CAPI3REF: Mutex Verification Routines {H17080} <S20130> <S30800>
**
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. {F17081} The SQLite core
+** are intended for use inside assert() statements. {H17081} The SQLite core
** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. {F17082} The core only
+** are advised to follow the lead of the core. {H17082} The core only
** provides implementations for these routines when it is compiled
** with the SQLITE_DEBUG flag. {A17087} External mutex implementations
** are only required to provide these routines if SQLITE_DEBUG is
** defined and if NDEBUG is not defined.
**
-** {F17083} These routines should return true if the mutex in their argument
+** {H17083} These routines should return true if the mutex in their argument
** is held or not held, respectively, by the calling thread.
**
** {X17084} The implementation is not required to provided versions of these
@@ -5945,23 +6018,27 @@
** versions of these routines, it should at least provide stubs that always
** return true so that one does not get spurious assertion failures.
**
-** {F17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
+** {H17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
** the routine should return 1. {END} This seems counter-intuitive since
** clearly the mutex cannot be held if it does not exist. But the
** the reason the mutex does not exist is because the build is not
** using mutexes. And we do not want the assert() containing the
** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. {F17086} The sqlite3_mutex_notheld()
+** the appropriate thing to do. {H17086} The sqlite3_mutex_notheld()
** interface should also return 1 when given a NULL pointer.
*/
int sqlite3_mutex_held(sqlite3_mutex*);
int sqlite3_mutex_notheld(sqlite3_mutex*);
/*
-** CAPI3REF: Mutex Types {F17001}
+** CAPI3REF: Mutex Types {H17001} <H17000>
**
-** {F17002} The [sqlite3_mutex_alloc()] interface takes a single argument
+** The [sqlite3_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
+**
+** The set of static mutexes may change from one SQLite release to the
+** next. Applications that override the built-in mutex logic must be
+** prepared to accommodate additional static mutexes.
*/
#define SQLITE_MUTEX_FAST 0
#define SQLITE_MUTEX_RECURSIVE 1
@@ -5973,21 +6050,21 @@
#define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */
/*
-** CAPI3REF: Low-Level Control Of Database Files {F11300}
+** CAPI3REF: Low-Level Control Of Database Files {H11300} <S30800>
**
-** {F11301} The [sqlite3_file_control()] interface makes a direct call to the
+** {H11301} The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. {F11302} The
+** with a particular database identified by the second argument. {H11302} The
** name of the database is the name assigned to the database by the
** <a href="lang_attach.html">ATTACH</a> SQL command that opened the
-** database. {F11303} To control the main database file, use the name "main"
-** or a NULL pointer. {F11304} The third and fourth parameters to this routine
+** database. {H11303} To control the main database file, use the name "main"
+** or a NULL pointer. {H11304} The third and fourth parameters to this routine
** are passed directly through to the second and third parameters of
-** the xFileControl method. {F11305} The return value of the xFileControl
+** the xFileControl method. {H11305} The return value of the xFileControl
** method becomes the return value of this routine.
**
-** {F11306} If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. {F11307} This error
+** {H11306} If the second parameter (zDbName) does not match the name of any
+** open database file, then SQLITE_ERROR is returned. {H11307} This error
** code is not remembered and will not be recalled by [sqlite3_errcode()]
** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
** also return SQLITE_ERROR. {A11309} There is no way to distinguish between
@@ -5999,7 +6076,7 @@
int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
-** CAPI3REF: Testing Interface {F11400}
+** CAPI3REF: Testing Interface {H11400} <S30800>
**
** The sqlite3_test_control() interface is used to read out internal
** state of SQLite and to inject faults into SQLite for testing
@@ -6018,7 +6095,7 @@
int sqlite3_test_control(int op, ...);
/*
-** CAPI3REF: Testing Interface Operation Codes {F11410}
+** CAPI3REF: Testing Interface Operation Codes {H11410} <H11400>
**
** These constants are the valid operation code parameters used
** as the first argument to [sqlite3_test_control()].
@@ -6036,7 +6113,8 @@
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
/*
-** CAPI3REF: SQLite Runtime Status {F17200}
+** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
+** EXPERIMENTAL
**
** This interface is used to retrieve runtime status information
** about the preformance of SQLite, and optionally to reset various
@@ -6062,13 +6140,33 @@
** and it is possible that another thread might change the parameter
** in between the times when *pCurrent and *pHighwater are written.
**
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** See also: [sqlite3_db_status()]
*/
int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
/*
-** CAPI3REF: Status Parameters {F17250}
+** CAPI3REF: Database Connection Status {H17201} <S60200>
+** EXPERIMENTAL
+**
+** This interface is used to retrieve runtime status information
+** about a single [database connection]. The first argument is the
+** database connection object to be interrogated. The second argument
+** is the parameter to interrogate. Currently, the only allowed value
+** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED].
+** Additional options will likely appear in future releases of SQLite.
+**
+** The current value of the request parameter is written into *pCur
+** and the highest instantaneous value is written into *pHiwtr. If
+** the resetFlg is true, then the highest instantaneous value is
+** reset back down to the current value.
+**
+** See also: [sqlite3_status()].
+*/
+int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+
+/*
+** CAPI3REF: Status Parameters {H17250} <H17200>
+** EXPERIMENTAL
**
** These integer constants designate various run-time status parameters
** that can be returned by [sqlite3_status()].
@@ -6084,35 +6182,61 @@
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>
**
+** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
+** internal equivalents). Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
+**
** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
** <dd>This parameter returns the number of pages used out of the
-** page cache buffer configured using [SQLITE_CONFIG_PAGECACHE]. The
+** [pagecache memory allocator] that was configured using
+** [SQLITE_CONFIG_PAGECACHE]. The
** value returned is in pages, not in bytes.</dd>
**
** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of page cache
** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+** buffer and where forced to overflow to [sqlite3_malloc()]. The
+** returned value includes allocations that overflowed because they
+** where too large (they were larger than the "sz" parameter to
+** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
+** no space was left in the page cache.</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [pagecache memory allocator]. Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
**
** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>This parameter returns the number of allocations used out of the
-** scratch allocation lookaside buffer configured using
+** [scratch memory allocator] configured using
** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one allocation
+** in bytes. Since a single thread may only have one scratch allocation
** outstanding at time, this parameter also reports the number of threads
** using scratch memory at the same time.</dd>
**
** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of scratch memory
** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+** buffer and where forced to overflow to [sqlite3_malloc()]. The values
+** returned include overflows because the requested allocation was too
+** larger (that is, because the requested allocation was larger than the
+** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
+** slots were available.
+** </dd>
**
-** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). The value of interest is return in the
-** *pHighwater parameter to [sqlite3_status()]. The value written
-** into the *pCurrent parameter is undefined.</dd>
+** handed to [scratch memory allocator]. Only the value returned in the
+** *pHighwater parameter to [sqlite3_status()] is of interest.
+** The value written into the *pCurrent parameter is undefined.</dd>
+**
+** <dt>SQLITE_STATUS_PARSER_STACK</dt>
+** <dd>This parameter records the deepest parser stack. It is only
+** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>
** </dl>
**
** New status parameters may be added from time to time.
@@ -6123,7 +6247,23 @@
#define SQLITE_STATUS_SCRATCH_USED 3
#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
#define SQLITE_STATUS_MALLOC_SIZE 5
+#define SQLITE_STATUS_PARSER_STACK 6
+#define SQLITE_STATUS_PAGECACHE_SIZE 7
+#define SQLITE_STATUS_SCRATCH_SIZE 8
+/*
+** CAPI3REF: Status Parameters for database connections {H17275} <H17200>
+** EXPERIMENTAL
+**
+** Status verbs for [sqlite3_db_status()].
+**
+** <dl>
+** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
+** <dd>This parameter returns the number of lookaside memory slots currently
+** checked out.</dd>
+** </dl>
+*/
+#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
/*
** Undo the hack that converts floating point types to integer for
Modified: trunk/providers/mysql/gda-mysql-provider.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-provider.c (original)
+++ trunk/providers/mysql/gda-mysql-provider.c Thu Aug 28 19:38:33 2008
@@ -1209,7 +1209,7 @@
} else {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_PREPARE_STMT_ERROR,
- _("Unnamed holder is not allowed in prepared statement."));
+ _("Unnamed statement parameter is not allowed in prepared statement."));
g_slist_foreach (param_ids, (GFunc) g_free, NULL);
g_slist_free (param_ids);
param_ids = NULL;
@@ -1311,6 +1311,8 @@
if (!cdata)
return FALSE;
+ if (last_inserted_row)
+ *last_inserted_row = NULL;
/* get/create new prepared statement */
ps = (GdaMysqlPStmt *) gda_connection_get_prepared_statement (cnc, stmt);
Modified: trunk/providers/mysql/gda-mysql-recordset.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-recordset.c (original)
+++ trunk/providers/mysql/gda-mysql-recordset.c Thu Aug 28 19:38:33 2008
@@ -33,6 +33,7 @@
#include <locale.h>
#endif
+extern gchar *gda_numeric_locale;
#define _GDA_PSTMT(x) ((GdaPStmt*)(x))
@@ -604,7 +605,7 @@
g_warning (_("Type %s not mapped for value %f"),
g_type_name (type), intvalue);
}
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
break;
case MYSQL_TYPE_STRING:
@@ -635,7 +636,7 @@
} else if (type == G_TYPE_DOUBLE) {
setlocale (LC_NUMERIC, "C");
g_value_set_double (value, atof (strvalue));
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
} else {
g_warning (_("Type %s not mapped for value %p"),
g_type_name (type), strvalue);
Modified: trunk/providers/postgres/gda-postgres-meta.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-meta.c (original)
+++ trunk/providers/postgres/gda-postgres-meta.c Thu Aug 28 19:38:33 2008
@@ -125,10 +125,10 @@
"SELECT current_database()::information_schema.sql_identifier AS table_catalog, nc.nspname::information_schema.sql_identifier AS table_schema, c.relname::information_schema.sql_identifier AS table_name, pg_catalog.pg_get_viewdef(c.oid, TRUE), NULL, CASE WHEN c.relkind = 'r'::\"char\" THEN TRUE ELSE FALSE END FROM pg_namespace nc, pg_class c WHERE current_database()::information_schema.sql_identifier = ##cat::string AND nc.nspname::information_schema.sql_identifier = ##schema::string AND c.relnamespace = nc.oid AND c.relkind = 'v' AND NOT pg_is_other_temp_schema(nc.oid) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'DELETE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text) OR has_table_privilege(c.oid, 'TRIGGER'::text)) AND c.relname::information_schema.sql_identifier = ##name::string",
/* I_STMT_COLUMNS_OF_TABLE */
- "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t
.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relname = ##name::string AND a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'
])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
+ "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t
.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN '" GDA_EXTRA_AUTO_INCREMENT "' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE current_database() = ##cat::string AND nc.nspname = ##schema::string AND c.relname = ##name::string AND a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (
ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
/* I_STMT_COLUMNS_ALL */
- "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t
.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_tab
le_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
+ "SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t
.*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN '" GDA_EXTRA_AUTO_INCREMENT "' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::te
xt) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
/* I_STMT_TABLES_CONSTRAINTS */
"SELECT current_database()::information_schema.sql_identifier AS constraint_catalog, nc.nspname::information_schema.sql_identifier AS constraint_schema, c.conname::information_schema.sql_identifier AS constraint_name, current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, CASE c.contype WHEN 'c'::\"char\" THEN 'CHECK'::text WHEN 'f'::\"char\" THEN 'FOREIGN KEY'::text WHEN 'p'::\"char\" THEN 'PRIMARY KEY'::text WHEN 'u'::\"char\" THEN 'UNIQUE'::text ELSE NULL::text END::information_schema.character_data AS constraint_type, CASE c.contype WHEN 'c'::\"char\" THEN c.consrc ELSE NULL END, CASE WHEN c.condeferrable THEN TRUE ELSE FALSE END AS is_deferrable, CASE WHEN c.condeferred THEN TRUE ELSE FALSE END AS initially_deferred FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r WHERE nc.oid = c.connamespace AND nr.oid = r.relna
mespace AND c.conrelid = r.oid AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string "
Modified: trunk/providers/postgres/gda-postgres-provider.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-provider.c (original)
+++ trunk/providers/postgres/gda-postgres-provider.c Thu Aug 28 19:38:33 2008
@@ -1860,7 +1860,8 @@
col = gda_data_model_describe_column (model, i);
h = gda_holder_new (gda_column_get_g_type (col));
id = g_strdup_printf ("+%d", i);
- g_object_set (G_OBJECT (h), "id", id, "not-null", FALSE, NULL);
+ g_object_set (G_OBJECT (h), "id", id, "not-null", FALSE,
+ "name", gda_column_get_name (col), NULL);
g_free (id);
gda_holder_set_value (h, gda_data_model_get_value_at (model, i, 0));
holders = g_slist_prepend (holders, h);
Modified: trunk/providers/postgres/gda-postgres-recordset.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-recordset.c (original)
+++ trunk/providers/postgres/gda-postgres-recordset.c Thu Aug 28 19:38:33 2008
@@ -34,6 +34,8 @@
#include <locale.h>
#endif
+extern gchar *gda_numeric_locale;
+
#define _GDA_PSTMT(x) ((GdaPStmt*)(x))
static void gda_postgres_recordset_class_init (GdaPostgresRecordsetClass *klass);
@@ -633,12 +635,12 @@
else if (type == G_TYPE_FLOAT) {
setlocale (LC_NUMERIC, "C");
g_value_set_float (value, atof (thevalue));
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
}
else if (type == G_TYPE_DOUBLE) {
setlocale (LC_NUMERIC, "C");
g_value_set_double (value, atof (thevalue));
- setlocale (LC_NUMERIC, "");
+ setlocale (LC_NUMERIC, gda_numeric_locale);
}
else if (type == GDA_TYPE_NUMERIC) {
GdaNumeric numeric;
Modified: trunk/tests/data-models/check_data_proxy.c
==============================================================================
--- trunk/tests/data-models/check_data_proxy.c (original)
+++ trunk/tests/data-models/check_data_proxy.c Thu Aug 28 19:38:33 2008
@@ -505,10 +505,10 @@
free_values_list (values);
clean_expected_signals (proxy);
if (!check_data_model_value (proxy, 1, 0, G_TYPE_STRING, "SmallCity2")) goto out;
- if (!check_data_model_value (proxy, 1, 1, G_TYPE_STRING, NULL)) goto out;
+ if (!check_data_model_value (proxy, 1, 1, G_TYPE_STRING, "ARG")) goto out;
if (!check_data_model_value (proxy, 1, 2, G_TYPE_STRING, "4907")) goto out;
if (!check_data_model_value (proxy, 1, 3, G_TYPE_STRING, "SmallCity2")) goto out;
- if (!check_data_model_value (proxy, 1, 4, G_TYPE_STRING, NULL)) goto out;
+ if (!check_data_model_value (proxy, 1, 4, G_TYPE_STRING, "ARG")) goto out;
if (!check_data_model_value (proxy, 1, 5, G_TYPE_STRING, "4907")) goto out;
/*
@@ -1444,7 +1444,7 @@
gint col;
for (col = 0, list = values; list; col++, list = list->next) {
const GValue *cvalue = gda_data_model_get_value_at (model, col, row);
- if (gda_value_compare_ext (cvalue, (GValue *) list->data)) {
+ if (list->data && gda_value_compare_ext (cvalue, (GValue *) list->data)) {
#ifdef CHECK_EXTRA_INFO
g_print ("ERROR: Read value is not equal to set value: got '%s' and expected '%s'\n",
gda_value_stringify (cvalue), gda_value_stringify ((GValue *) list->data));
Modified: trunk/tests/data-models/check_pmodel.c
==============================================================================
--- trunk/tests/data-models/check_pmodel.c (original)
+++ trunk/tests/data-models/check_pmodel.c Thu Aug 28 19:38:33 2008
@@ -15,19 +15,48 @@
#define CHECK_EXTRA_INFO
+/* signals checking */
+typedef struct {
+ GdaDataModel *model;
+ gchar type; /* U, I, D */
+ gint row;
+} SigEvent;
+static GSList *signals = NULL;
+static void monitor_model_signals (GdaDataModel *model);
+static void signal_callback (GdaDataModel *model, gint row, gchar *type);
+static void clear_signals (void);
+static gboolean check_expected_signal (GdaDataModel *model, gchar type, gint row);
+static gboolean check_no_expected_signal (GdaDataModel *model);
+
+/* utility functions */
static GdaConnection *setup_connection (void);
static GdaStatement *stmt_from_string (const gchar *sql);
static void load_data_from_file (GdaConnection *cnc, const gchar *table, const gchar *file);
+static gboolean check_set_value_at (GdaDataModel *model, gint col, gint row,
+ const GValue *set_value,
+ GdaConnection *cnc, GdaStatement *stmt, GdaSet *stmt_params);
+static gboolean check_set_values (GdaDataModel *model, gint row, GList *set_values,
+ GdaConnection *cnc, GdaStatement *stmt, GdaSet *stmt_params);
+static gint check_append_values (GdaDataModel *model, GList *set_values,
+ GdaConnection *cnc, GdaStatement *stmt, GdaSet *stmt_params);
typedef gboolean (*TestFunc) (GdaConnection *);
static gint test1 (GdaConnection *cnc);
static gint test2 (GdaConnection *cnc);
static gint test3 (GdaConnection *cnc);
+static gint test4 (GdaConnection *cnc);
+static gint test5 (GdaConnection *cnc);
+static gint test6 (GdaConnection *cnc);
+static gint test7 (GdaConnection *cnc);
TestFunc tests[] = {
test1,
test2,
- test3
+ test3,
+ test4,
+ test5,
+ test6,
+ test7
};
int
@@ -42,11 +71,11 @@
cnc = setup_connection ();
for (i = 0; i < sizeof (tests) / sizeof (TestFunc); i++) {
- g_print ("---------- test %d ----------\n", i);
+ g_print ("---------- test %d ----------\n", i+1);
gint n = tests[i] (cnc);
number_failed += n;
if (n > 0)
- g_print ("Test %d failed\n", i);
+ g_print ("Test %d failed\n", i+1);
ntests ++;
}
@@ -113,6 +142,13 @@
load_data_from_file (cnc, "locations", "pmodel_data_locations.xml");
load_data_from_file (cnc, "customers", "pmodel_data_customers.xml");
+ /* update meta store */
+ if (! gda_connection_update_meta_store (cnc, NULL, &error)) {
+ g_print ("Error updateing meta store: %s\n", error && error->message ? error->message : "No detail");
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
+
g_object_unref (ddl);
return cnc;
}
@@ -152,7 +188,11 @@
return stmt;
}
-/* Returns the number of failures */
+/*
+ * check modifications statements' setting
+ *
+ * Returns the number of failures
+ */
static gint
test1 (GdaConnection *cnc)
{
@@ -229,7 +269,11 @@
return nfailed;
}
-/* Returns the number of failures */
+/*
+ * check modifications statements' setting, with external parameter
+ *
+ * Returns the number of failures
+ */
static gint
test2 (GdaConnection *cnc)
{
@@ -239,6 +283,8 @@
gint nfailed = 0;
GdaSet *params;
+ clear_signals ();
+
/* create GdaPModel */
stmt = stmt_from_string ("SELECT * FROM customers WHERE country = ##country::string");
if (!gda_statement_get_parameters (stmt, ¶ms, &error)) {
@@ -298,7 +344,11 @@
return nfailed;
}
-/* Returns the number of failures */
+/*
+ * check gda_data_model_set_at()
+ *
+ * Returns the number of failures
+ */
static gint
test3 (GdaConnection *cnc)
{
@@ -306,6 +356,9 @@
GdaDataModel *model;
GdaStatement *stmt, *mod_stmt;
gint nfailed = 0;
+ GValue *value;
+
+ clear_signals ();
/* create GdaPModel */
stmt = stmt_from_string ("SELECT * FROM customers");
@@ -323,7 +376,7 @@
}
/* test INSERT with undefined params */
- mod_stmt = stmt_from_string ("UPDATE customers SET name = ##+1::string WHERE id = ##-0::gint");
+ mod_stmt = stmt_from_string ("UPDATE customers SET name = ##+1::string, last_update = ##+2::timestamp WHERE id = ##-0::gint");
if (!gda_pmodel_set_modification_statement (GDA_PMODEL (model), mod_stmt, &error)) {
nfailed++;
#ifdef CHECK_EXTRA_INFO
@@ -332,16 +385,39 @@
#endif
goto out;
}
- GValue *value;
+
+ /****/
+ monitor_model_signals (model);
g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), "Jack");
- if (! gda_data_model_set_value_at (model, 1, 0, value, &error)) {
+ if (! check_set_value_at (model, 1, 0, value, cnc, stmt, NULL)) {
+ nfailed ++;
+ goto out;
+ }
+ if (! check_expected_signal (model, 'U', 0)) {
nfailed++;
-#ifdef CHECK_EXTRA_INFO
- g_print ("gda_data_model_set_value_at failed: %s\n",
- error && error->message ? error->message : "No detail");
-#endif
goto out;
}
+ gda_value_free (value);
+ clear_signals ();
+
+ /****/
+ gda_value_set_from_string ((value = gda_value_new (GDA_TYPE_TIMESTAMP)),
+ "2009-11-30 11:22:33", GDA_TYPE_TIMESTAMP);
+ if (! check_set_value_at (model, 2, 1, value, cnc, stmt, NULL)) {
+ nfailed ++;
+ goto out;
+ }
+ gda_value_free (value);
+
+ /****/
+ g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), "Henry");
+ if (! check_set_value_at (model, 1, 0, value, cnc, stmt, NULL)) {
+ nfailed ++;
+ goto out;
+ }
+ gda_value_free (value);
+
+ /****/
if (gda_data_model_set_value_at (model, 0, 0, value, &error)) {
nfailed++;
#ifdef CHECK_EXTRA_INFO
@@ -353,11 +429,735 @@
g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
#endif
g_error_free (error);
- gda_value_free (value);
out:
g_object_unref (model);
g_object_unref (stmt);
+
+ return nfailed;
+}
+
+/*
+ * more check gda_data_model_remove_row()
+ *
+ * Returns the number of failures
+ */
+static gint
+test4 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model;
+ GdaStatement *stmt, *mod_stmt;
+ gint nfailed = 0;
+
+ clear_signals ();
+
+ /* create GdaPModel */
+ stmt = stmt_from_string ("SELECT * FROM customers");
+ model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
+ if (!model) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not execute SELECT!\n");
+#endif
+ goto out;
+ }
+ if (!GDA_IS_PMODEL (model)) {
+ g_print ("Data model should be a GdaPModel!\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* test INSERT with undefined params */
+ mod_stmt = stmt_from_string ("DELETE FROM customers WHERE id = ##-0::gint");
+ if (!gda_pmodel_set_modification_statement (GDA_PMODEL (model), mod_stmt, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_modification_statement() should have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ monitor_model_signals (model);
+ if (! gda_data_model_remove_row (model, 0, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_remove_row() should have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ g_error_free (error);
+ goto out;
+ }
+
+ if (! check_expected_signal (model, 'D', 0))
+ nfailed++;
+ clear_signals ();
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+
+ return nfailed;
+}
+
+/*
+ * check gda_data_model_set_values()
+ *
+ * Returns the number of failures
+ */
+static gint
+test5 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model;
+ GdaStatement *stmt, *mod_stmt;
+ gint nfailed = 0;
+ GValue *v1, *v2;
+ GList *values;
+
+ clear_signals ();
+
+ /* create GdaPModel */
+ stmt = stmt_from_string ("SELECT * FROM customers");
+ model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
+ if (!model) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not execute SELECT!\n");
+#endif
+ goto out;
+ }
+ if (!GDA_IS_PMODEL (model)) {
+ g_print ("Data model should be a GdaPModel!\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* test INSERT with undefined params */
+ mod_stmt = stmt_from_string ("UPDATE customers SET name = ##+1::string, last_update = ##+2::timestamp, default_served_by = ##+3::gint WHERE id = ##-0::gint");
+ if (!gda_pmodel_set_modification_statement (GDA_PMODEL (model), mod_stmt, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_modification_statement() should have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ /****/
+ monitor_model_signals (model);
+ g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), "Alf");
+ g_value_set_int ((v2 = gda_value_new (G_TYPE_INT)), 999);
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, v1);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, v2);
+ if (! check_set_values (model, 2, values, cnc, stmt, NULL)) {
+ nfailed ++;
+ goto out;
+ }
+ if (! check_expected_signal (model, 'U', 2)) {
+ nfailed++;
+ goto out;
+ }
+ gda_value_free (v1);
+ gda_value_free (v2);
+ g_list_free (values);
+ clear_signals ();
+
+ /****/
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, NULL);
+ if (! check_set_values (model, 2, values, cnc, stmt, NULL)) {
+ nfailed ++;
+ goto out;
+ }
+ if (! check_no_expected_signal (model)) {
+ nfailed++;
+ goto out;
+ }
+ g_list_free (values);
+
+ /****/
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ if (gda_data_model_set_values (model, 2, values, &error)) {
+ nfailed ++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_set_values should have failed\n");
+#endif
+ goto out;
+ }
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
+#endif
+ if (! check_no_expected_signal (model)) {
+ nfailed++;
+ goto out;
+ }
+ g_list_free (values);
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+
+ return nfailed;
+}
+
+/*
+ * check gda_data_model_append_values()
+ *
+ * Returns the number of failures
+ */
+static gint
+test6 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model;
+ GdaStatement *stmt, *mod_stmt;
+ gint nfailed = 0;
+ GValue *v1, *v2;
+ GList *values;
+ gint newrow;
+
+ clear_signals ();
+
+ /* create GdaPModel */
+ stmt = stmt_from_string ("SELECT * FROM customers");
+ model = gda_connection_statement_execute_select (cnc, stmt, NULL, &error);
+ if (!model) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not execute SELECT!\n");
+#endif
+ goto out;
+ }
+ if (!GDA_IS_PMODEL (model)) {
+ g_print ("Data model should be a GdaPModel!\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* set unique row select */
+ if (gda_pmodel_set_row_selection_condition_sql (GDA_PMODEL (model), "id > ##-0::gint", &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_row_selection_condition_sql() should have failed\n");
+#endif
+ goto out;
+ }
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
+#endif
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+
+ if (! gda_pmodel_set_row_selection_condition_sql (GDA_PMODEL (model), "id = ##-0::gint", &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_row_selection_condition_sql() have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ if (gda_pmodel_set_row_selection_condition_sql (GDA_PMODEL (model), "id = ##-0::gint", &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_row_selection_condition_sql() should have failed\n");
+#endif
+ goto out;
+ }
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
+#endif
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+
+ /* set INSERT statement */
+ mod_stmt = stmt_from_string ("INSERT INTO customers (name, last_update, default_served_by) VALUES (##+1::string, CURRENT_TIMESTAMP, ##+3::gint)");
+ if (!gda_pmodel_set_modification_statement (GDA_PMODEL (model), mod_stmt, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_set_modification_statement() should have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ /****/
+ monitor_model_signals (model);
+ g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), "George");
+ g_value_set_int ((v2 = gda_value_new (G_TYPE_INT)), 21);
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, v1);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, v2);
+ newrow = check_append_values (model, values, cnc, stmt, NULL);
+ if (newrow < 0) {
+ nfailed ++;
+ goto out;
+ }
+ if (! check_expected_signal (model, 'I', newrow)) {
+ nfailed++;
+ goto out;
+ }
+ gda_value_free (v1);
+ gda_value_free (v2);
+ g_list_free (values);
+ clear_signals ();
+
+ /****/
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, NULL);
+ if (gda_data_model_append_values (model, values, &error) >= 0) {
+ nfailed ++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_set_values should have failed\n");
+#endif
+ goto out;
+ }
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
+#endif
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+ if (! check_no_expected_signal (model)) {
+ nfailed++;
+ goto out;
+ }
+ g_list_free (values);
+
+ /****/
+ values = g_list_append (NULL, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ values = g_list_append (values, NULL);
+ if (gda_data_model_append_values (model, values, &error) >= 0) {
+ nfailed ++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_set_values should have failed\n");
+#endif
+ goto out;
+ }
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Got expected error: %s\n", error && error->message ? error->message : "No detail");
+#endif
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+ if (! check_no_expected_signal (model)) {
+ nfailed++;
+ goto out;
+ }
+ g_list_free (values);
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+
+ return nfailed;
+}
+
+/*
+ * check modifications statements' setting, with external parameter
+ *
+ * Returns the number of failures
+ */
+static gint
+test7 (GdaConnection *cnc)
+{
+ GError *error = NULL;
+ GdaDataModel *model;
+ GdaStatement *stmt;
+ gint nfailed = 0;
+ GdaSet *params;
+ GValue *value;
+
+ clear_signals ();
+
+ /* create GdaPModel */
+ stmt = stmt_from_string ("SELECT * FROM customers WHERE country = ##country::string");
+ if (!gda_statement_get_parameters (stmt, ¶ms, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not get SELECT's parameters!\n");
+#endif
+ goto out;
+ }
+ gda_set_set_holder_value (params, "country", "SP");
+ model = gda_connection_statement_execute_select (cnc, stmt, params, &error);
+ if (!model) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not execute SELECT!\n");
+#endif
+ goto out;
+ }
+ if (!GDA_IS_PMODEL (model)) {
+ g_print ("Data model should be a GdaPModel!\n");
+ exit (EXIT_FAILURE);
+ }
+
+
+ /* gda_pmodel_compute_modification_statements() */
+ if (!gda_pmodel_compute_modification_statements (GDA_PMODEL (model), TRUE, &error)) {
+ nfailed++;
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_pmodel_compute_modification_statements() should have succedded, error: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ goto out;
+ }
+
+ gda_value_set_from_string ((value = gda_value_new (GDA_TYPE_TIMESTAMP)),
+ "2004-03-22 11:22:44", GDA_TYPE_TIMESTAMP);
+ if (! check_set_value_at (model, 2, 1, value, cnc, stmt, params)) {
+ nfailed ++;
+ goto out;
+ }
+ gda_value_free (value);
+
+ out:
+ g_object_unref (model);
+ g_object_unref (stmt);
+ g_object_unref (params);
return nfailed;
}
+
+
+/*
+ * Checking value function:
+ * - reads the value of @model at the provided column and row and compares with the expected @set_value
+ * - if @stmt is not NULL, then re-run the statement and compares with @model
+ */
+static gboolean
+check_set_value_at (GdaDataModel *model, gint col, gint row, const GValue *set_value,
+ GdaConnection *cnc, GdaStatement *stmt, GdaSet *stmt_params)
+{
+ const GValue *get_value;
+ GError *error = NULL;
+
+ if (! gda_data_model_set_value_at (model, col, row, set_value, &error)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_set_value_at(%d,%d) failed: %s\n",
+ col, row,
+ error && error->message ? error->message : "No detail");
+#endif
+ return FALSE;
+ }
+ get_value = gda_data_model_get_value_at (model, col, row);
+ if (gda_value_compare_ext (get_value, set_value)) {
+#ifdef CHECK_EXTRA_INFO
+ gchar *s1, *s2;
+ s1 = gda_value_stringify (get_value);
+ s2 = gda_value_stringify (set_value);
+ g_print ("gda_data_model_get_value_at(%d,%d) returned '%s' when it should have returned '%s'\n", col, row, s1, s2);
+ g_free (s1);
+ g_free (s2);
+#endif
+ return FALSE;
+ }
+
+ if (stmt) {
+ /* run the statement and compare it with @model */
+ GdaDataModel *rerun;
+ GdaDataComparator *cmp;
+ GError *error = NULL;
+ gboolean cmpres = TRUE;
+ rerun = gda_connection_statement_execute_select (cnc, stmt, stmt_params, &error);
+ if (!rerun) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not re-run the SELECT statement: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ return FALSE;
+ }
+
+ cmp = (GdaDataComparator*) gda_data_comparator_new (model, rerun);
+ if (! gda_data_comparator_compute_diff (cmp, &error)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not compute the data model differences: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ cmpres = FALSE;
+ }
+ if (gda_data_comparator_get_n_diffs (cmp) != 0) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("There are some differences when re-running the SELECT statement...\n");
+#endif
+ cmpres = FALSE;
+ }
+ g_object_unref (cmp);
+ g_object_unref (rerun);
+ return cmpres;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Checking value function:
+ * - reads the value of @model at the provided column and row and compares with the expected @set_value
+ * - if @stmt is not NULL, then re-run the statement and compares with @model
+ */
+static gboolean
+check_set_values (GdaDataModel *model, gint row, GList *set_values, GdaConnection *cnc, GdaStatement *stmt, GdaSet *stmt_params)
+{
+ GError *error = NULL;
+ GList *list;
+ gint i;
+
+ if (! gda_data_model_set_values (model, row, set_values, &error)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_set_values (%d) failed: %s\n",
+ row,
+ error && error->message ? error->message : "No detail");
+#endif
+ return FALSE;
+ }
+
+ for (i = 0, list = set_values; list; i++, list = list->next) {
+ const GValue *get_value;
+
+ if (!list->data)
+ continue;
+
+ get_value = gda_data_model_get_value_at (model, i, row);
+ if (gda_value_compare_ext (get_value, (GValue*) list->data)) {
+#ifdef CHECK_EXTRA_INFO
+ gchar *s1, *s2;
+ s1 = gda_value_stringify (get_value);
+ s2 = gda_value_stringify ((GValue*) list->data);
+ g_print ("gda_data_model_get_value_at(%d,%d) returned '%s' when it should have returned '%s'\n", i, row, s1, s2);
+ g_free (s1);
+ g_free (s2);
+#endif
+ return FALSE;
+ }
+ }
+
+ if (stmt) {
+ /* run the statement and compare it with @model */
+ GdaDataModel *rerun;
+ GdaDataComparator *cmp;
+ GError *error = NULL;
+ gboolean cmpres = TRUE;
+ rerun = gda_connection_statement_execute_select (cnc, stmt, stmt_params, &error);
+ if (!rerun) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not re-run the SELECT statement: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ return FALSE;
+ }
+
+ cmp = (GdaDataComparator*) gda_data_comparator_new (model, rerun);
+ if (! gda_data_comparator_compute_diff (cmp, &error)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not compute the data model differences: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ cmpres = FALSE;
+ }
+ if (gda_data_comparator_get_n_diffs (cmp) != 0) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("There are some differences when re-running the SELECT statement...\n");
+#endif
+ cmpres = FALSE;
+ }
+
+ g_object_unref (cmp);
+ g_object_unref (rerun);
+ return cmpres;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Checking value function:
+ * - reads the value of @model at the provided column and row and compares with the expected @set_value
+ * - if @stmt is not NULL, then re-run the statement and compares with @model
+ *
+ * Returns: -1 if an error occurred, or the new row number
+ */
+static gint
+check_append_values (GdaDataModel *model, GList *set_values, GdaConnection *cnc,
+ GdaStatement *stmt, GdaSet *stmt_params)
+{
+ GError *error = NULL;
+ GList *list;
+ gint i, newrow;
+
+ newrow = gda_data_model_append_values (model, set_values, &error);
+ if (newrow < 0) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("gda_data_model_append_values () failed: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ return -1;
+ }
+
+ for (i = 0, list = set_values; list; i++, list = list->next) {
+ const GValue *get_value;
+
+ if (!list->data)
+ continue;
+
+ get_value = gda_data_model_get_value_at (model, i, newrow);
+ if (gda_value_compare_ext (get_value, (GValue*) list->data)) {
+#ifdef CHECK_EXTRA_INFO
+ gchar *s1, *s2;
+ s1 = gda_value_stringify (get_value);
+ s2 = gda_value_stringify ((GValue*) list->data);
+ g_print ("gda_data_model_get_value_at(%d,%d) returned '%s' when it should have returned '%s'\n", i,
+ newrow, s1, s2);
+ g_free (s1);
+ g_free (s2);
+#endif
+ return -1;
+ }
+ }
+
+ if (stmt) {
+ /* run the statement and compare it with @model */
+ GdaDataModel *rerun;
+ GdaDataComparator *cmp;
+ GError *error = NULL;
+ rerun = gda_connection_statement_execute_select (cnc, stmt, stmt_params, &error);
+ if (!rerun) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not re-run the SELECT statement: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ return -1;
+ }
+
+ cmp = (GdaDataComparator*) gda_data_comparator_new (model, rerun);
+ if (! gda_data_comparator_compute_diff (cmp, &error)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Could not compute the data model differences: %s\n",
+ error && error->message ? error->message : "No detail");
+#endif
+ newrow = -1;
+ }
+ if (gda_data_comparator_get_n_diffs (cmp) != 0) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("There are some differences when re-running the SELECT statement...\n");
+#endif
+ newrow = -1;
+ }
+
+ g_object_unref (cmp);
+ g_object_unref (rerun);
+ return newrow;
+ }
+
+ return newrow;
+}
+
+/*
+ * signals checking
+ */
+static void
+monitor_model_signals (GdaDataModel *model)
+{
+ g_signal_connect (model, "row-updated", G_CALLBACK (signal_callback), "U");
+ g_signal_connect (model, "row-removed", G_CALLBACK (signal_callback), "D");
+ g_signal_connect (model, "row-inserted", G_CALLBACK (signal_callback), "I");
+}
+
+static void
+signal_callback (GdaDataModel *model, gint row, gchar *type)
+{
+ SigEvent *se;
+ se = g_new0 (SigEvent, 1);
+ se->model = model;
+ se->type = *type;
+ se->row = row;
+ signals = g_slist_append (signals, se);
+#ifdef CHECK_EXTRA_INFO
+ g_print ("Received '%s' signal for row %d from model %p\n",
+ (*type == 'I') ? "row-inserted" : ((*type == 'D') ? "row-removed" : "row-updated"),
+ row, model);
+#endif
+}
+
+static void
+clear_signals (void)
+{
+ if (signals) {
+ GSList *list;
+ for (list = signals; list; list = list->next) {
+ SigEvent *se = (SigEvent*) list->data;
+ g_free (se);
+ }
+ g_slist_free (signals);
+ signals = NULL;
+ }
+}
+
+static gboolean
+check_expected_signal (GdaDataModel *model, gchar type, gint row)
+{
+ SigEvent *se = NULL;
+ if (signals)
+ se = (SigEvent*) signals->data;
+ if (se && (se->model == model) && (se->row == row) && (se->type == type)) {
+ g_free (se);
+ signals = g_slist_remove (signals, se);
+ return TRUE;
+ }
+#ifdef CHECK_EXTRA_INFO
+ else {
+ g_print ("Expected signal '%s' for row %d from model %p and got ",
+ (type == 'I') ? "row-inserted" : ((type == 'D') ? "row-removed" : "row-updated"),
+ row, model);
+ if (se)
+ g_print ("signal '%s' for row %d from model %p\n",
+ (se->type == 'I') ? "row-inserted" : ((se->type == 'D') ? "row-removed" : "row-updated"),
+ se->row, se->model);
+ else
+ g_print ("no signal\n");
+ }
+#endif
+
+ return FALSE;
+}
+
+static gboolean
+check_no_expected_signal (GdaDataModel *model)
+{
+ SigEvent *se = NULL;
+ if (signals)
+ se = (SigEvent*) signals->data;
+ if (se && (se->model == model)) {
+#ifdef CHECK_EXTRA_INFO
+ g_print ("No signal expected and got ");
+ if (se)
+ g_print ("signal '%s' for row %d from model %p\n",
+ (se->type == 'I') ? "row-inserted" : ((se->type == 'D') ? "row-removed" : "row-updated"),
+ se->row, se->model);
+ else
+ g_print ("no signal\n");
+#endif
+ return FALSE;
+ }
+
+ return TRUE;
+}
Modified: trunk/tests/data-models/pmodel_data_customers.xml
==============================================================================
--- trunk/tests/data-models/pmodel_data_customers.xml (original)
+++ trunk/tests/data-models/pmodel_data_customers.xml Thu Aug 28 19:38:33 2008
@@ -2,13 +2,15 @@
<gda_array id="EXPORT" name="Exported Data">
<gda_array_field id="FI0" name="id" title="id" gdatype="gint" size="-1" scale="-1" pkey="TRUE" unique="TRUE"/>
<gda_array_field id="FI1" name="name" title="name" gdatype="gchararray" size="-1" scale="-1"/>
- <gda_array_field id="FI2" name="default_served_by" title="default_served_by" gdatype="gint" size="-1" scale="-1" nullok="TRUE"/>
- <gda_array_field id="FI3" name="country" title="country" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
- <gda_array_field id="FI4" name="city" title="city" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
+ <gda_array_field id="FI2" name="last_update" title="last_update" gdatype="GdaTimestamp" size="-1" scale="-1"/>
+ <gda_array_field id="FI3" name="default_served_by" title="default_served_by" gdatype="gint" size="-1" scale="-1" nullok="TRUE"/>
+ <gda_array_field id="FI4" name="country" title="country" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
+ <gda_array_field id="FI5" name="city" title="city" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
<gda_array_data>
<gda_array_row>
<gda_value>2</gda_value>
<gda_value>Ed Lamton</gda_value>
+ <gda_value>2008-08-12 00:00:00+0</gda_value>
<gda_value>4</gda_value>
<gda_value>SP</gda_value>
<gda_value>MDR</gda_value>
@@ -16,6 +18,7 @@
<gda_array_row>
<gda_value>3</gda_value>
<gda_value>Lew Bonito</gda_value>
+ <gda_value>2008-08-13 00:00:00+0</gda_value>
<gda_value>1</gda_value>
<gda_value>FR</gda_value>
<gda_value>TLS</gda_value>
@@ -23,6 +26,7 @@
<gda_array_row>
<gda_value>4</gda_value>
<gda_value>Mark Lawrencep</gda_value>
+ <gda_value>2007-12-25 00:00:00+0</gda_value>
<gda_value isnull="t"/>
<gda_value>SP</gda_value>
<gda_value>MDR</gda_value>
@@ -30,6 +34,7 @@
<gda_array_row>
<gda_value>9</gda_value>
<gda_value>Greg Popoff</gda_value>
+ <gda_value>2007-12-25 00:00:00+0</gda_value>
<gda_value>2</gda_value>
<gda_value>SP</gda_value>
<gda_value>MDR</gda_value>
@@ -37,6 +42,7 @@
<gda_array_row>
<gda_value>10</gda_value>
<gda_value>Vladimir Zirkov</gda_value>
+ <gda_value>2001-01-31 00:00:00+0</gda_value>
<gda_value>4</gda_value>
<gda_value isnull="t"/>
<gda_value isnull="t"/>
Modified: trunk/tests/data-models/pmodel_dbstruct.xml
==============================================================================
--- trunk/tests/data-models/pmodel_dbstruct.xml (original)
+++ trunk/tests/data-models/pmodel_dbstruct.xml Thu Aug 28 19:38:33 2008
@@ -26,7 +26,7 @@
</provider>
<provider name="SQLite">
- <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="int"/>
+ <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="integer"/>
<symbol name="now">CURRENT_TIMESTAMP</symbol>
</provider>
</specifics>
@@ -35,6 +35,7 @@
<table name="customers">
<column name="id" type="gint" pkey="TRUE" autoinc="TRUE"/>
<column name="name"/>
+ <column name="last_update" type="timestamp"/>
<column name="default_served_by" type="gint" nullok="TRUE"/>
<column name="country" nullok="TRUE"/>
<column name="city" nullok="TRUE"/>
Modified: trunk/tests/gda-ddl-creator.c
==============================================================================
--- trunk/tests/gda-ddl-creator.c (original)
+++ trunk/tests/gda-ddl-creator.c Thu Aug 28 19:38:33 2008
@@ -548,6 +548,25 @@
if (! gda_server_operation_set_value_at (op, "FALSE", error,
"/FIELDS_A/@COLUMN_UNIQUE/%d", index))
goto onerror;
+ if (tcol->extra) {
+ gint i;
+ for (i = 0; i < tcol->extra->len; i++) {
+ const gchar *tmp;
+ tmp = g_array_index (tcol->extra, gchar *, i);
+ if (!strcmp (tmp, GDA_EXTRA_AUTO_INCREMENT)) {
+ if (! gda_server_operation_set_value_at (op, "TRUE", error,
+ "/FIELDS_A/@COLUMN_AUTOINC/%d", index))
+ goto onerror;
+ }
+ else {
+ g_warning ("Unknown extra keyword '%s'", tmp);
+ TO_IMPLEMENT;
+ g_set_error (error, 0, 0,
+ "Unknown extra keyword '%s'", tmp);
+ goto onerror;
+ }
+ }
+ }
repl = provider_specific_match (ddlc->priv->provider_specifics, prov, "dummy", "/FIELDS_A/@COLUMN_PKEY");
if (repl) {
if (! gda_server_operation_set_value_at (op, tcol->pkey ? "TRUE" : "FALSE", error,
Modified: trunk/tools/command-exec.c
==============================================================================
--- trunk/tools/command-exec.c (original)
+++ trunk/tools/command-exec.c Thu Aug 28 19:38:33 2008
@@ -782,11 +782,12 @@
GdaMetaTable *mt = GDA_META_TABLE (dbo);
GSList *list;
- model = gda_data_model_array_new (4);
+ model = gda_data_model_array_new (5);
gda_data_model_set_column_title (model, 0, _("Column"));
gda_data_model_set_column_title (model, 1, _("Type"));
gda_data_model_set_column_title (model, 2, _("Nullable"));
gda_data_model_set_column_title (model, 3, _("Default"));
+ gda_data_model_set_column_title (model, 4, _("Extra"));
if (dbo->obj_type == GDA_META_DB_VIEW)
g_object_set_data_full (G_OBJECT (model), "name",
g_strdup_printf (_("List of columns for view '%s'"),
@@ -808,6 +809,35 @@
values = g_list_append (values, val);
g_value_set_string ((val = gda_value_new (G_TYPE_STRING)), tcol->default_value);
values = g_list_append (values, val);
+ if (tcol->extra) {
+ GString *string;
+ gint i;
+ gboolean first = TRUE;
+ string = g_string_new ("");
+ for (i = 0; i < tcol->extra->len; i++) {
+ const gchar *tmp = g_array_index (tcol->extra, gchar *, i);
+ const gchar *astmp = NULL;
+ if (!strcmp (tmp, GDA_EXTRA_AUTO_INCREMENT))
+ astmp = _("Auto increment");
+ else {
+ g_warning ("Unknown extra keyword '%s'", tmp);
+ TO_IMPLEMENT;
+ }
+ if (astmp) {
+ if (first)
+ first = FALSE;
+ else
+ g_string_append (string, ", ");
+ g_string_append (string, astmp);
+ }
+ }
+ g_value_take_string ((val = gda_value_new (G_TYPE_STRING)), string->str);
+ g_string_free (string, FALSE);
+ }
+ else
+ val = gda_value_new_null ();
+ values = g_list_append (values, val);
+
gda_data_model_append_values (model, values, NULL);
g_list_foreach (values, (GFunc) gda_value_free, NULL);
g_list_free (values);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]