summaryrefslogtreecommitdiff
path: root/Docs
diff options
context:
space:
mode:
Diffstat (limited to 'Docs')
-rw-r--r--Docs/gis.txt874
-rw-r--r--Docs/internals.texi7
-rwxr-xr-xDocs/prepare.texi1736
3 files changed, 2617 insertions, 0 deletions
diff --git a/Docs/gis.txt b/Docs/gis.txt
new file mode 100644
index 00000000000..3556949d516
--- /dev/null
+++ b/Docs/gis.txt
@@ -0,0 +1,874 @@
+
+ OpenGIS <http://www.opengis.org> support in MySQL
+
+------------------------------------------------------------------------
+Note: Blue colored lines among the text is features not implemented yet.
+They are:
+
+ * Spatial Reference Systems and their IDs (SRIDs) related things:
+ o Functions like Length() and Area() assume planar coordinate
+ system.
+ o All objects are currently considered to be in the same
+ planar coordinate system.
+ * Function Length() on LineString and MultiLineString currently
+ should be called as GLength().
+* No binary constructors like GeomFromWKB().
+
+We also have to add "PostGIS compatibility" sections.
+
+
+ 1 Introduction
+
+MySQL implements a subset of *SQL2 with Geometry Types* environment
+proposed by OpenGIS consortium's *Simple Features Specification For
+SQL*. In this environment a geometry-valued column is implemented as a
+column whose SQL type is drawn from the set of Geometry Types. SQL
+server supports both textual and binary access to geometry.
+
+
+ 2 OpenGIS Geometry Model in MySQL
+
+MySQL supports the Open GIS Geometry Model based hierarcy of spatial
+objects classes, which consists of:
+
+ * Geometry
+ o *Point*
+ o Curve
+ + *LineString*
+ o Surface
+ + *Polygon*
+ o *GeometryCollection*
+ + *MultiPoint*
+ + MultiCurve
+ # *MultiLineString*
+ + MultiSurface
+ # *MultiPolygon*
+
+The base *Geometry* class has subclasses for Point, Curve, Surface and
+GeometryCollection.
+
+Geometry, Curve, Surface, MultiCurve and MultiSurface are defined to be
+non-instantiable classes, it is not possible to create an object of
+these classes.
+
+Point, LineString, Polygon, GeometryCollection, MultiPoint,
+MultiLineString, MultiPolygon are instantiable classes (bolded on the
+hierarcy tree). MySQL provides a number of functions to construct
+instances of these classes.
+
+TODO: Each spatial object is associated with a Spatial Reference System,
+which describes the coordinate space in which the geometric object is
+defined.
+
+
+ 2.1 Geometry
+
+Geometry is the root class of the hierarchy. Geometry is an abstract
+(non-instantiable) class. The instantiable subclasses of Geometry
+defined in this specification are restricted to 0, 1 and two-dimensional
+geometric objects that exist in two-dimensional coordinate space. All
+instantiable geometry classes are defined so that valid instances of a
+geometry class are topologically closed (i.e. all defined geometries
+include their boundary).
+
+
+ 2.2 Point
+
+A *Point* is a 0-dimensional geometry and represents a single location
+in coordinate space. A Point in the case of 2D has a x-coordinate value
+and a y-coordinate value. In the case of more dimensions, a Point has a
+coordinate value for each dimension. The boundary of a Point is the
+empty set.
+
+
+ 2.3 Curve
+
+A *Curve* is a one-dimensional geometric object usually stored as a
+sequence of points, with the subclass of Curve specifying the form of
+the interpolation between points. MySQL implementation defines only one
+subclass of Curve, LineString, which uses linear interpolation between
+points.
+
+A Curve is simple if it does not pass through the same point twice. A
+Curve is closed if its start point is equal to its end point. The
+boundary of a closed Curve is empty. A Curve that is simple and closed
+is a Ring. The boundary of a non-closed Curve consists of its two end
+points. A Curve is defined as topologically closed.
+
+
+ 2.4 LineString, Line, LinearRing
+
+A LineString is a Curve with linear interpolation between points. Each
+consecutive pair of points defines a line segment. A Line is a
+LineString with exactly 2 points. A LinearRing is a LineString that is
+both closed and simple.
+
+
+ 2.5 Surface
+
+A *Surface* is a two-dimensional geometric object. The OpenGIS Abstract
+Specification defines a simple Surface as consisting of a single 'patch'
+that is associated with one 'exterior boundary' and 0 or more 'interior'
+boundaries. Simple surfaces in three-dimensional space are isomorphic to
+planar surfaces. Polyhedral surfaces are formed by 'stitching' together
+simple surfaces along their boundaries, polyhedral surfaces in
+three-dimensional space may not be planar as a whole.
+
+The boundary of a simple Surface is the set of closed curves
+corresponding to its exterior and interior boundaries.
+
+The only instantiable subclass of Surface defined in this specification,
+Polygon, is a simple Surface that is planar.
+
+
+ 2.6 Polygon
+
+A Polygon is a planar Surface, defined by 1 exterior boundary and 0 or
+more interior boundaries. Each interior boundary defines a hole in the
+Polygon. The assertions for polygons (the rules that define valid
+polygons) are:
+
+ * Polygons are topologically closed.
+ * The boundary of a Polygon consists of a set of LinearRings (i.e.
+ LineStrings which are both simple and closed) that make up its
+ exterior and interior boundaries.
+ * No two rings in the boundary cross, the rings in the boundary of a
+ Polygon may intersect at a Point but only as a tangent.
+ * A Polygon may not have cut lines, spikes or punctures.
+ * The Interior of every Polygon is a connected point set.
+ * The Exterior of a Polygon with 1 or more holes is not connected.
+Each hole defines a connected component of the Exterior.
+
+In the above assertions, Interior, Closure and Exterior have the
+standard topological definitions. The combination of 1 and 3 make a
+Polygon a Regular Closed point set. Polygons are simple geometries.
+
+
+ 2.6 GeometryCollection
+
+A *GeometryCollection* is a geometry that is a collection of 1 or more
+geometries of any class. All the elements in a GeometryCollection must
+be in the same Spatial Reference (i.e. in the same coordinate system).
+GeometryCollection places no other constraints on its elements. However
+subclasses of GeometryCollection described below may restrict membership
+based on dimension and may also place other constraints on the degree of
+spatial overlap between elements.
+
+
+ 2.7 MultiPoint
+
+A *MultiPoint* is a 0 dimensional geometric collection. The elements of
+a MultiPoint are restricted to Points. The points are not connected or
+ordered. A MultiPoint is simple if no two Points in the MultiPoint are
+equal (have identical coordinate values). The boundary of a MultiPoint
+is the empty set.
+
+
+ 2.8 MultiCurve
+
+A MultiCurve is a one-dimensional geometry collection whose elements are
+Curves. MultiCurve is a non-instantiable class, it defines a set of
+methods for its subclasses and is included for reasons of extensibility.
+
+A MultiCurve is simple if and only if all of its elements are simple,
+the only intersections between any two elements occur at points that are
+on the boundaries of both elements.
+
+The boundary of a MultiCurve is obtained by applying the "mod 2 union
+rule": A point is in the boundary of a MultiCurve if it is in the
+boundaries of an odd number of elements of the MultiCurve.
+
+A MultiCurve is closed if all of its elements are closed. The boundary
+of a closed MultiCurve is always empty. A MultiCurve is defined as
+topologically closed.
+
+
+ 2.9 MultiLineString
+
+A *MultiLineString* is a MultiCurve whose elements are LineStrings.
+
+
+ 2.10 MultiSurface
+
+A MultiSurface is a two-dimensional geometric collection whose elements
+are surfaces. The interiors of any two surfaces in a MultiSurface may
+not intersect. The boundaries of any two elements in a MultiSurface may
+intersect at most at a finite number of points.
+
+MultiSurface is a non-instantiable class in this specification, it
+defines a set of methods for its subclasses and is included for reasons
+of extensibility. The instantiable subclass of MultiSurface is
+MultiPolygon, corresponding to a collection of Polygons.
+
+
+ 2.11 MultiPolygon
+
+A MultiPolygon is a MultiSurface whose elements are Polygons.
+
+The assertions for MultiPolygons are :
+
+ * The interiors of 2 Polygons that are elements of a MultiPolygon
+ may not intersect.
+ * The Boundaries of any 2 Polygons that are elements of a
+ MultiPolygon may not cross and may touch at only a finite number
+ of points. (Note that crossing is prevented by assertion 1 above).
+ * A MultiPolygon is defined as topologically closed.
+ * A MultiPolygon may not have cut lines, spikes or punctures, a
+ MultiPolygon is a Regular, Closed point set.
+ * The interior of a MultiPolygon with more than 1 Polygon is not
+ connected, the number of connected components of the interior of a
+MultiPolygon is equal to the number of Polygons in the MultiPolygon.
+
+The boundary of a MultiPolygon is a set of closed curves (LineStrings)
+corresponding to the boundaries of its element Polygons. Each Curve in
+the boundary of the MultiPolygon is in the boundary of exactly 1 element
+Polygon, and every Curve in the boundary of an element Polygon is in the
+boundary of the MultiPolygon.
+
+
+ 3 Exchange of spatial data
+
+MySQL provides binary and textual mechanismes to exchange spatial data.
+Exchange is provided via so called Well Known Binary (WKB) and Well
+Known Textual (WKT) representations of spatial data proposed by OpenGIS
+specifications.
+
+
+ 3.1 Well-known Text representation (WKT)
+
+The Well-known Text (WKT) representation of Geometry is designed to
+exchange geometry data in textual format.
+
+WKT is defined below in Bechus-Naur forms:
+
+ * the notation {}* denotes 0 or more repetitions of the tokens
+ within the braces;
+* the braces do not appear in the output token list.
+
+The text representation of the implemented instantiable geometric types
+conforms to this grammar:
+
+<Geometry Tagged Text> :=
+ <Point Tagged Text>
+ | <LineString Tagged Text>
+ | <Polygon Tagged Text>
+ | <MultiPoint Tagged Text>
+ | <MultiLineString Tagged Text>
+ | <MultiPolygon Tagged Text>
+ | <GeometryCollection Tagged Text>
+
+<Point Tagged Text> :=
+
+ POINT <Point Text>
+
+<LineString Tagged Text> :=
+
+ LINESTRING <LineString Text>
+
+<Polygon Tagged Text> :=
+
+ POLYGON <Polygon Text>
+
+<MultiPoint Tagged Text> :=
+
+ MULTIPOINT <Multipoint Text>
+
+<MultiLineString Tagged Text> :=
+
+ MULTILINESTRING <MultiLineString Text>
+
+<MultiPolygon Tagged Text> :=
+
+ MULTIPOLYGON <MultiPolygon Text>
+
+<GeometryCollection Tagged Text> :=
+
+ GEOMETRYCOLLECTION <GeometryCollection Text>
+
+<Point Text> := EMPTY | ( <Point> )
+
+<Point> := <x> <y>
+
+<x> := double precision literal
+
+<y> := double precision literal
+
+<LineString Text> := EMPTY
+
+ | ( <Point > {, <Point > }* )
+
+<Polygon Text> := EMPTY
+
+ | ( <LineString Text > {, < LineString Text > }*)
+
+<Multipoint Text> := EMPTY
+
+ | ( <Point Text > {, <Point Text > }* )
+
+<MultiLineString Text> := EMPTY
+
+ | ( <LineString Text > {, < LineString Text > }* )
+
+<MultiPolygon Text> := EMPTY
+
+ | ( < Polygon Text > {, < Polygon Text > }* )
+
+<GeometryCollection Text> := EMPTY
+
+ | ( <Geometry Tagged Text> {, <Geometry Tagged Text> }* )
+
+
+ WKT examples
+
+Examples of textual representations of Geometry objects are shown below:
+
+ * |POINT(10 10)| - a Point
+ * |LINESTRING( 10 10, 20 20, 30 40)| - a LineString with three points
+ * |POLYGON((10 10, 10 20, 20 20,20 15, 10 10))| - a Polygon with one
+ exterior ring and 0 interior rings
+ * |MULTIPOINT(10 10, 20 20)| - a MultiPoint with two Points
+ * |MULTILINESTRING((10 10, 20 20), (15 15, 30 15))| - a
+ MultiLineString with two LineStrings
+ * |MULTIPOLYGON(((10 10, 10 20, 20 20, 20 15, 10 10)), ((60 60, 70
+ 70, 80 60, 60 60 ) ))| - a MultiPolygon with two Polygons
+ * |GEOMETRYCOLLECTION( POINT (10 10),POINT (30 30), LINESTRING (15
+ 15, 20 20))| - a GeometryCollection consisting of two Points and
+one LineString
+
+
+ 3.2 Well-known Binary representation (WKB)
+
+Well Known Binary Representations is proposed by OpenGIS specifications
+to exchange geometry data in binary format. This is WKB description:
+
+// Basic Type definitions
+// byte : 1 byte
+// uint32 : 32 bit unsigned integer (4 bytes)
+// double : double precision number (8 bytes)
+// Building Blocks : Point, LinearRing
+
+Point {
+ double [numDimentions];
+};
+
+LinearRing {
+ uint32 numPoints;
+ Point points[numPoints];
+}
+
+enum wkbGeometryType {
+ wkbPoint = 1,
+ wkbLineString = 2,
+ wkbPolygon = 3,
+ wkbMultiPoint = 4,
+ wkbMultiLineString = 5,
+ wkbMultiPolygon = 6,
+ wkbGeometryCollection = 7
+};
+
+enum wkbByteOrder {
+ wkbXDR = 0, // Big Endian
+ wkbNDR = 1 // Little Endian
+};
+
+WKBPoint {
+ byte byteOrder;
+ uint32 wkbType; // 1
+ Point point;
+}
+
+WKBLineString {
+ byte byteOrder;
+ uint32 wkbType; // 2
+ uint32 numPoints;
+ Point points[numPoints];
+}
+
+WKBPolygon {
+ byte byteOrder;
+ uint32 wkbType; // 3
+ uint32 numRings;
+ LinearRing rings[numRings];
+}
+
+WKBMultiPoint {
+ byte byteOrder;
+ uint32 wkbType; // 4
+ uint32 num_wkbPoints;
+ WKBPoint WKBPoints[num_wkbPoints];
+}
+
+WKBMultiLineString {
+ byte byteOrder;
+ uint32 wkbType; // 5
+ uint32 num_wkbLineStrings;
+ WKBLineString WKBLineStrings[num_wkbLineStrings];
+}
+
+wkbMultiPolygon {
+ byte byteOrder;
+ uint32 wkbType; // 6
+ uint32 num_wkbPolygons;
+ WKBPolygon wkbPolygons[num_wkbPolygons];
+}
+
+WKBGeometry {
+ union {
+ WKBPoint point;
+ WKBLineString linestring;
+ WKBPolygon polygon;
+ WKBGeometryCollection collection;
+ WKBMultiPoint mpoint;
+ WKBMultiLineString mlinestring;
+ WKBMultiPolygon mpolygon;
+ }
+
+};
+
+WKBGeometryCollection {
+ byte byte_order;
+ uint32 wkbType; // 7
+ uint32 num_wkbGeometries;
+ WKBGeometry wkbGeometries[num_wkbGeometries];
+}
+
+
+ 3.3 MySQL data types for spatial objects
+
+MySQL implementation of OpenGIS provides the *GEOMETRY* data type to be
+used in CREATE TABLE statements. For example, this statement creates a
+table *geom* with spatial field *g*:
+
+CREATE TABLE geom (
+ g Geometry;
+);
+
+A field of *GEOMETRY* type can store a spatial objects of any OpenGIS
+geometry class described above.
+
+
+ 3.4 Internal spatial data representation
+
+Internally (in *.MYD* files) spatial objects are stored in *WKB*,
+combined with object's *SRID* (a numeric ID of Spatial Reference System
+object associated with). During spatial analysis, for example,
+calculating the fact that one object crosses another one, only those
+with the same *SRID* are accepted.
+
+*SRID* may affect a way in which various spatial characteristics are
+calculated. For example, in different coordinate systems distance
+between two objects may differ even objects have the same coordinates,
+like distance on plane coordinate system and distance on geocentric
+(coordinates on Earth surface) systems are different things.
+
+There is a plan to provide a number of commonly used coordinate systems
+in MySQL OpenGIS implementation.
+
+
+ 3.5 INSERTing spatial objects
+
+Spatial data can be INSERTed using a spatial constructor. The term
+*spatial constructor* is used in this manual to refer to any function
+which can construct a value of GEOMETRY type, i.e. an internal MySQL
+representation of spatial data.
+
+
+ 3.5.1 Textual spatial constructors
+
+Textual spatial constructors take a gemometry description in WKT and
+built GEOMETRY value.
+
+ * |*GeomFromText(geometryTaggedText String [, SRID
+ Integer]):Geometry *| - constructs a Geometry value from its
+ well-known textual representation.
+
+ |*GeomFromText()*| function accepts a WKT of any Geometry class as
+ it's first argument.
+
+ For construction of Geometry values restricted to a particular
+ subclass, an implementation also provides a class-specific
+ construction function for each instantiable subtype as described
+ in the list below:
+
+ * |*PointFromText(pointTaggedText String [,SRID Integer]):Point *| -
+ constructs a Point
+
+ * |*LineFromText(lineStringTaggedText String [,SRID
+ Integer]):LineString *| - constructs a LineString
+
+ . |*LineStringFromText()*| - synonym for LineFromText().
+
+ * |*PolyFromText(polygonTaggedText String [,SRID Integer]):Polygon
+ *|- constructs a Polygon
+
+ |*PolygonFromText()*| - synonym for PolyFromText().
+
+ * |*MPointFromText(multiPointTaggedText String [,SRID
+ Integer]):MultiPoint *| - constructs a MultiPoint
+
+ |*MultiPointFromText()*| - synonym for MPointFromText().
+
+ * |*MLineFromText(multiLineStringTaggedText String [,SRID
+ Integer]):MultiLineString *| - constructs a MultiLineString
+
+ |*MultiLineStringFromText()*| - synonym for MLineFromText().
+
+ * |*MPolyFromText(multiPolygonTaggedText String [,SRID
+ Integer]):MultiPolygon *| - constructs a MultiPolygon
+
+ |*MultiPolygonFromText()*| - synonym for MPolyFromText().
+
+ * |*GeomCollFromText(geometryCollectionTaggedText String [,SRID
+ Integer]):GeomCollection *| - constructs a GeometryCollection
+
+Usage examples:
+
+INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'))
+INSERT INTO geom VALUES (GeomFromText('LINESTRING(0 0,1 1,2 2)'))
+INSERT INTO geom VALUES (GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))'))
+INSERT INTO geom VALUES (GeomFromText('GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))'))
+
+The second argument of spatial constructirs, described above, is
+currently ignored, It will be used to specify SRID in the future.
+Nowdays, it is added for reasons of compatibility with OpenGIS
+specifications and PostGIS implementation.
+
+As an optional feature, an implementation may also support building of
+Polygon or MultiPolygon values given an arbitrary collection of possibly
+intersecting rings or closed LineString values. Implementations that
+support this feature should include the following functions:
+
+ * |*BdPolyFromText(multiLineStringTaggedText String, SRID
+ Integer):Polygon *| - constructs a Polygon given an arbitrary
+ collection of closed linestrings as a MultiLineString text
+ representation.
+ * |*BdMPolyFromText(multiLineStringTaggedText String, SRID
+ Integer):MultiPolygon *| - constructs a MultiPolygon given an
+ arbitrary collection of closed linestrings as a MultiLineString
+text representation.
+
+
+ 3.5.2 Binary spatial constructors
+
+ * |*GeomFromWKB(WKBGeometry Binary, SRID Integer):Geometry *| -
+ constructs a Geometry value given its well-known binary
+ representation.
+
+ |*GeomFromWKB()*| function can accept in it's first argument a WKB
+ of Geometry of any class. For construction of Geometry values
+ restricted to a particular subclass, an implementation also
+ provides a class-specific construction function for each
+ instantiable subclass as described in the list below:
+
+ * |*PointFromWKB(WKBPoint Binary, SRID Integer):Point - *|constructs
+ a Point
+ * |* LineFromWKB(WKBLineString Binary, SRID Integer):LineString *| -
+ constructs a LineString
+ * |* PolyFromWKB(WKBPolygon Binary, SRID Integer):Polygon *| -
+ constructs a Polygon
+ * |* MPointFromWKB(WKBMultiPoint Binary, SRID Integer):MultiPoint *|
+ - constructs a MultiPoint
+ * |* MLineFromWKB(WKBMultiLineString Binary, SRID
+ Integer):MultiLineString *| - constructs a MultiLineString
+ * |* MPolyFromWKB(WKBMultiPolygon Binary, SRID Integer):
+ MultiPolygon *| - constructs a MultiPolygon
+ * |* GeomCollFromWKB(WKBGeometryCollection Binary, SRID Integer):
+GeomCollection *| - constructs a GeometryCollection
+
+As an optional feature, an implementation may also support the uilding'
+of Polygon or MultiPolygon values given an arbitrary collection of
+possibly intersecting rings or closed LineString values. Implementations
+that support this feature should include the following functions:
+
+ * |* BdPolyFromWKB (WKBMultiLineString Binary,SRID Integer): Polygon
+ *| - constructs a Polygon given an arbitrary collection of closed
+ linestrings as a MultiLineString binary representation.
+ * |*BdMPolyFromWKB(WKBMultiLineString Binary, SRID
+ Integer):MultiPolygon *| - constructs a MultiPolygon given an
+ arbitrary collection of closed linestrings as a MultiLineString
+binary representation.
+
+Inserting in *WKB* assumes that |GeomFromWKB()| function argument
+contains a buffer with a correctly formed spatial object in WKB. In ODBC
+applications it can be done using binding of argument. One also can
+insert object in *WKB* using |mysql_escape_string()| in |libmysqlclient|
+applications.
+
+For example:
+
+INSERT INTO geom VALUES (GeomFromWKB(buf,SRID));
+
+where |buf| is a binary buffer with a spatial object in *WKB*
+representation.
+
+
+ 3.5 SELECTing spatial objects
+
+Spatial objects are selected either in *WKT* or *WKB* representation by
+use of AsText() and AsBinary() functions correspondently.
+
+
+mysql> select AsText(g) as g from geom;
++-------------------------+
+| g |
++-------------------------+
+| POINT(1 1) |
+| LINESTRING(0 0,1 1,2 2) |
++-------------------------+
+2 rows in set (0.00 sec)
+
+mysql>
+
+The query:
+
+SELECT AsBinary(g) FROM geom
+
+returns a BLOB which contains *WKB* representation of object.
+
+
+ 4 Functions for spatial analysis
+
+
+ 4.1 Basic functions on Geometry
+
+ * |*AsText(g:Geometry):String*| - Exports this Geometry to a
+ specific well-known text representation of Geometry.
+ * |*AsBinary(g:Geometry):Binary*| - Exports this Geometry to a
+ specific well-known binary representation of Geometry.
+ * |*GeometryType(g:Geometry):String*| - Returns the name of the
+ instantiable subtype of Geometry of which this Geometry instance
+ is a member. The name of the instantiable subtype of Geometry is
+ returned as a string.
+ * |*Dimension(g:Geometry):Integer*| - The inherent dimension of this
+ Geometry object, which must be less than or equal to the
+ coordinate dimension. This specification is restricted to
+ geometries in two-dimensional coordinate space.
+ * |*IsEmpty(g:Geometry):Integer*| - Returns 1 (TRUE) if this
+ Geometry is the empty geometry . If true, then this Geometry
+ represents the empty point set, , for the coordinate space.
+ * |*IsSimple(g:Geometry):Integer *| - Returns 1 (TRUE) if this
+ Geometry has no anomalous geometric points, such as self
+ intersection or self tangency. The description of each
+ instantiable geometric class includes the specific conditions that
+ cause an instance of that class to be classified as not simple.
+ * |*SRID(g:Geometry):Integer*| - Returns the Spatial Reference
+ System ID for this Geometry.
+ * |*Distance(g1:Geometry,g2:Geometry):Double*| - the shortest
+distance between any two points in the two geometries.
+
+
+ 4.2 Functions for specific geometry type
+
+
+ GeometryCollection functions
+
+ * *NumGeometries(g:GeometryCollection ):Integer * -Returns the
+ number of geometries in this GeometryCollection.
+ * *GeometryN(g:GeometryCollection,N:integer):Geometry * -Returns the
+Nth geometry in this GeometryCollection.
+
+
+ Point functions
+
+ * *X(p:Point):Double* -The x-coordinate value for this Point.
+* *Y(p:Point):Double* -The y-coordinate value for this Point.
+
+
+ LineString functions
+
+ * *StartPoint(l:LineString):Point* The start point of this LineString.
+ * *EndPoint(l:LineString):Point* The end point of this LineString.
+ * *PointN(l:LineString,N:Integer):Point* Returns the specified point
+ N in this Linestring.
+ * *Length(l:LineString):Double* The length of this LineString in its
+ associated spatial reference.
+ * *IsRing(l:LineString):Integer* Returns 1 (TRUE) if this LineString
+ is closed (StartPoint ( ) = EndPoint ( )) and this LineString is
+ simple (does not pass through the same point more than once).
+ * *IsClosed(l:LineString):Integer* Returns 1 (TRUE) if this
+ LineString is closed (StartPoint ( ) = EndPoint ( )).
+ * *NumPoints(l:LineString):Integer* The number of points in this
+LineString.
+
+
+ MultiLineString functions
+
+ * *Length(m:MultiLineString):Double* The Length of this
+ MultiLineString which is equal to the sum of the lengths of the
+ elements.
+ * *IsClosed(m:MultiLineString):Integer* Returns 1 (TRUE) if this
+ MultiLineString is closed (StartPoint() = EndPoint() for each
+LineString in this MultiLineString)
+
+
+ Polygon functions
+
+ * *Area(p:Polygon):Double* The area of this Polygon, as measured in
+ the spatial reference system of this Polygon.
+ * *Centroid(p:Polygon):Point* The mathematical centroid for this
+ Polygon as a Point. The result is not guaranteed to be on this
+ Polygon.
+ * *PointOnSurface(p:Polygon):Point* A point guaranteed to be on this
+ Polygon.
+ * *NumInteriorRing(p:Polygon):Integer* Returns the number of
+ interior rings in this Polygon.
+ * *ExteriorRing(p:Polygon):LineString* Returns the exterior ring of
+ this Polygon as a LineString.
+ * *InteriorRingN(p:Polygon,N:Integer):LineString* Returns the Nth
+interior ring for this Polygon as a LineString.
+
+
+ MultiPolygon functions
+
+ * *Area(m:MultuSurface):Double* The area of this MultiPolygon, as
+ measured in the spatial reference system of this MultiPolygon.
+ * *Centroid(m:MultyPolygon):Point* The mathematical centroid for
+ this MultiPolygon as a Point. The result is not guaranteed to be
+ on this MultiPolygon.
+ * *PointOnSurface(m:MultuPolygon):Point* A Point guaranteed to be on
+this MultiPolygon.
+
+Notes: /functions for specific geometry type retrun NULL if passed
+object type is incorrect. For example Area() returns NULL if object type
+is neither Polygon nor MultiPolygon/
+
+
+ 4.3 Spatial operations (compound spatial constructors)
+
+ * |*Envelope(g:Geometry):Geometry*|The minimum bounding box for this
+ Geometry, returned as a Geometry. The polygon is defined by the
+ corner points of the bounding box
+ |POLYGON((MINX,MINY),(MAXX,MINY),(MAXX,MAXY),(MINX,MAXY),(MINX,MINY))|.
+
+ * |*Boundary(g:Geometry):Geometry*| - returns the closure of the
+ combinatorial boundary of this Geometry.
+ * |*Intersection(g1,g2:Geometry):Geometry*| - a geometry that
+ represents the point set intersection of g1 with g2.
+ * |*Union(g1,g2:Geometry):Geometry*| - a geometry that represents
+ the point set union of g1 with g2.
+ * |*Difference(g1,g2:Geometry):Geometry*| - a geometry that
+ represents the point set difference of g1 with g2.
+ * |*SymDifference(g1,g2:Geometry):Geometry*| - a geometry that
+ represents the point set symmetric difference of g1 with g2.
+ * |*Buffer(g:Geometry,distance:Double):Geometry*| - a geometry that
+ represents all points whose distance from g is less than or equal
+ to distance.
+ * |*ConvexHull(g:Geometry):Geometry*| - a geometry that represents
+the convex hull of g.
+
+
+ 4.4 Functions for testing Spatial Relations between geometric objects
+
+ * |*Equals(g1,g2)*| - Returns 1 if g1 is spatially equal to g2.
+ * |*Disjoint(g1,g2)*| - Returns 1 if g1 is spatially disjoint from g2.
+ * |*Intersects(g1,g2)*| - Returns 1 if g1 spatially intersects g2.
+ * |*Touches(g1,g2)*| - Returns 1 if g1 spatially touches g2.
+ * |*Crosses(g1,g2)*| - Returns 1 if g1 spatially crosses g2.
+ * |*Within(g1,g2)*| - Returns 1 if g1 is spatially within g2.
+ * |*Contains(g1,g2)*| - Returns 1 if g1 spatially contains g2.
+* |*Overlaps(g1,g2)*| - Returns 1 if g1 spatially overlaps g2.
+
+
+ 5 Optimizing spatial analysis
+
+
+ 5.1 MBR
+
+MBR is a minimal bounding rectangle (box) for spatial object. It can be
+represented as a set of min and max values of each dimension.
+
+For example:
+
+(Xmin,Xmax,Ymin,Ymax)
+
+
+ 5.2 Using SPATIAL indexes
+
+To optimize spatial object relationships analysis it is possible to
+create a spatial index on geometry field using R-tree algorythm. R-tree
+based spatial indexes store MBRs of spatial objects as a key values.
+
+CREATE SPATIAL INDEX gind ON geom (g);
+
+Or together with table definition:
+
+CREATE TABLE geom (
+ g GEOMETRY,
+ SPATIAL INDEX(g)
+);
+
+Optimizer attaches R-tree based SPATIAL index when a query with spatial
+objects relationship functions is executed in WHERE clause.
+
+For example:
+
+SELECT geom.name FROM geom
+ WHERE Within(geom.g,GeomFromText('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))',SRID));
+
+
+ 8 OpenGIS extensions implemented in MySQL
+
+MySQL provides it's own constructors to build geometry objects:
+
+ * |*Point(double,double,SRID)*| - constructs a geometry of Point
+ class using it's coordinates and SRID.
+ * |*MultiPoint(Point,Point,...,Point)*| - constructs a MultiPoint
+ using Points. When any argument is not a geometry of Point class
+ the return value is NULL.
+ * |*LineString(Point,Point,...,Point)*| - constructs a LineString
+ from a number of Points. When any argument is not a geometry of
+ Point class the return value is NULL. When the number of Points is
+ less than two the return value is NULL.
+ * |*MultiLineString(LineString,LineString,...,LineString)*| -
+ constructs a MultiLineString using using LineStrings. When any
+ argument is not a geometry of LineStringClass return value is NULL.
+ * |*Polygon(LineString,LineString,...,LineString)*| - constructs a
+ Polygon from a number of LineStrings. When any argument is not a
+ LinearRing (i.e. not closed and simple geometry of class
+ LineString) the return value is NULL.
+ * |*MultiPolygon(Polygon,Polygon,...,Polygon)*| - constructs a
+ MultiPolygon from a set of Polygons. When any argument is not a
+ Polygon, the rerurn value is NULL.
+ * |*GeometryCollection(Geometry,Geometry,..,Geometry)*| - constucts
+ a GeometryCollection. When any argument is not a valid geometry
+object of any instantiable class, the return value is NULL.
+
+The above functions (except Point()) return NULL if arguments are not in
+the same spatial reference system (i.e. have different SRIDs).
+
+
+ Examples:
+
+INSERT INTO geom SELECT Point(x,y,SRID) FROM coords;
+SELECT AsText(g) FROM geom WHERE
+ Contains(Polygon(LineString(Point(0,0),Point(0,1),Point(1,1),Point(1,0),Point(0,0)),SRID),geom.g);
+
+
+ 9 Things that differ in MySQL implemention and OpenGIS specifications
+
+
+ 9.1 Single GEOMETRY type
+
+Besides a GEOMETRY type, OpenGIS consortium specifications suggest the
+implementation of several spatial field types correspondent to every
+instansiable object subclass. For example a *Point* type is proposed to
+restrict data stored in a field of this type to only Point OpenGIS
+subclass. MySQL provides an implementation of single GEOMETRY type which
+doesn't restrict objects to certain OpenGIS subclass. Other proposed
+spatial field types are mapped into GEOMETRY type, so all these types
+can be used as a symonym for GEOMETRY: POINT, MULTIPOINT, LINESTRING,
+MULTILINESTRING, POLYGON, MULTIPOLYGON.
+
+
+ 9.2 No additional Metadata Views
+
+OpenGIS specifications propose several additional metadata views. For
+example, a system view named GEOMETRY_COLUMNS contains a description of
+geometry columns, one row for each geometry column in the database.
+
+
+ 9.3 No functions to add/drop spatial columns
+
+OpenGIS assumes that columns can be added/dropped using
+AddGeometryColumn() and DropGeometryColumn() functions correspondently.
+In MySQL implementation one should use ALTER TABLE instead.
diff --git a/Docs/internals.texi b/Docs/internals.texi
index a94158f84f8..eac0fd11a07 100644
--- a/Docs/internals.texi
+++ b/Docs/internals.texi
@@ -1719,9 +1719,16 @@ The field description result set contains the meta info for a result set.
@item string @tab Table name alias (or table name if no alias)
@item string @tab Real table name
@item string @tab Alias for column name (or column name if not used)
+
+@item 11 byte @tab Fixed length fields in one field part:
+@itemize
+@item 2 byte int @tab Character set number
@item 3 byte int @tab Length of column definition
@item 1 byte int @tab Enum value for field type
@item 3 byte int @tab 2 byte column flags (NOT_NULL_FLAG etc..) + 1 byte number of decimals.
+@item 2 byte int @tab zero (reserved for future use)
+@end itemize
+
@item string int @tab Default value, only set when using mysql_list_fields().
@end multitable
diff --git a/Docs/prepare.texi b/Docs/prepare.texi
new file mode 100755
index 00000000000..0b515012980
--- /dev/null
+++ b/Docs/prepare.texi
@@ -0,0 +1,1736 @@
+\input texinfo @c -*-texinfo-*-
+@c Copyright 1997-2002 TcX AB, Detron HB and MySQL Finland AB
+@c
+@c This manual is NOT distributed under a GPL style license.
+@c Use of the manual is subject to the following terms:
+@c - Conversion to other formats is allowed, but the actual
+@c content may not be altered or edited in any way.
+@c - You may create a printed copy for your own personal use.
+@c - For all other uses, such as selling printed copies or
+@c using (parts of) the manual in another publication,
+@c prior written agreement from MySQL AB is required.
+@c
+@c Please e-mail docs@mysql.com for more information or if
+@c you are interested in doing a translation.
+@c
+@c *********************************************************
+@c Note that @node names are used on our web site.
+@c So do not change node names without checking
+@c Makefile.am and SitePages first.
+@c *********************************************************
+@c
+@c %**start of header
+
+@c there's a better way to do this... i just don't know it yet
+@c sed will remove the "@c ifnusphere " to make this valid
+@c ifnusphere @set nusphere 1
+
+@setfilename prepare.info
+
+@c We want the types in the same index
+@c @syncodeindex tp fn
+
+@c Get version information. This file is generated by the Makefile!!
+@include include.texi
+
+@ifclear tex-debug
+@c This removes the black squares in the right margin
+@finalout
+@end ifclear
+
+@c Set background for HTML
+@set _body_tags BGCOLOR=#FFFFFF TEXT=#000000 LINK=#101090 VLINK=#7030B0
+@c Set some style elements for the manual in HTML form. 'suggested'
+@c natural language colors: aqua, black, blue, fuchsia, gray, green,
+@c lime, maroon, navy, olive, purple, red, silver, teal, white, and
+@c yellow. From Steeve Buehler <ahr@YogElements.com>
+@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
+
+@settitle MySQL Prepared Statements
+
+@c We want single-sided heading format, with chapters on new pages. To
+@c get double-sided format change 'on' below to 'odd'
+@ifclear nusphere
+@setchapternewpage on
+@end ifclear
+
+@ifset nusphere
+@setchapternewpage odd
+@end ifset
+
+@c @paragraphindent 0
+
+@ifset nusphere
+@smallbook
+@end ifset
+
+@c @titlepage
+@c @sp 10
+@c @center @titlefont{MySQL Prepared Statements}
+@c @sp 10
+@c @right Copyright @copyright{} 1995-2003 MySQL AB
+@c blank page after title page makes page 1 be a page front.
+@c also makes the back of the title page blank.
+@c @page
+@c @end titlepage
+
+@c Short contents, blank page, long contents.
+@c until i can figure out the blank page, no short contents.
+@c @shortcontents
+@c @page
+@c @page
+@contents
+
+@c This should be added. The HTML conversion also needs a MySQL version
+@c number somewhere.
+
+@iftex
+@c change this to double if you want formatting for double-sided
+@c printing
+@headings single
+@end iftex
+
+@c @node Top, MySQL C API, (dir), (dir)
+
+@c @menu
+@c * MySQL C API::
+@c @end menu
+
+@c @node MySQL C API, , Top, Top
+@c @chapter MySQL C API
+
+@c @menu
+@c * Prepared statements::
+@c @end menu
+
+@node Top, MySQL prepared statements, (dir), (dir)
+
+@menu
+* MySQL prepared statements::
+@end menu
+
+@node MySQL prepared statements, , Top, Top
+@chapter MySQL Prepared Statements
+
+@menu
+* C Prepared statements::
+* C Prepared statement datatypes::
+* C Prepared statements function overview::
+* C Prepared statement functions::
+* multiple queries::
+* date handling::
+@end menu
+
+@node C Prepared statements, C Prepared statement datatypes, MySQL prepared statements, MySQL prepared statements
+@subsection C Prepared Statements
+
+@sp 1
+
+From MySQL 4.1 and above, you can also make use of the prepared
+statements using the statement handler 'MYSQL_STMT', which supports
+simultanious query executions along with input and output binding.
+
+@sp 1
+
+Prepared execution is an efficient way to execute a statement more than
+once. The statement is first parsed, or prepared. This is executed one
+or more times at a later time using the statement handle that is
+returned during the prepare.
+
+@sp 1
+
+Another advantage of prepared statements is that, it uses a binary protocol
+which makes the data tranfer between client and server in a more efficient
+way than the old MySQL protocol.
+
+@sp 1
+
+Prepared execution is faster than direct execution for statements
+executed more than once, primarly becuase the query is parsed only
+once; In the case of direct execution, the query is parsed every
+time. Prepared execution also can provide a reduction in the network
+traffic becuase during the execute call, it only sends the data for the
+parameters.
+
+
+
+@node C Prepared statement datatypes, C Prepared statements function overview, C Prepared statements, MySQL prepared statements
+@subsection C Prepared Statements DataTypes
+
+Prepared statements mainly uses the following two @code{MYSQL_STMT} and
+@code{MYSQL_BIND} structures:
+@sp 1
+
+@table @code
+@tindex MYSQL_STMT C type
+
+@item MYSQL_STMT
+
+This structure represents a statement handle to prepared statements.It
+is used for all statement related functions.
+
+@sp 1
+
+The statement is initialized when the query is prepared using
+@code{mysql_prepare()}.
+
+@sp 1
+
+One connection can have 'n' statement handles, and the limit depends up on
+the system resources.
+
+@sp 1
+
+@tindex MYSQL_BIND C type
+
+@item MYSQL_BIND
+
+This structure is used in order to bind parameter
+buffers(@code{mysql_bind_param()}) inorder to the parameters data to
+@code{mysql_execute()} call; as well as to bind row
+buffers(@code{mysql_bind_result()}) to fetch the result set data using
+@code{mysql_fetch()}.
+
+@sp 1
+
+@noindent
+The @code{MYSQL_BIND} structure contains the members listed here:
+
+
+@table @code
+
+@item enum enum_field_types buffer_type [input]
+The type of the buffer. The @code{type} value must be one of the following:
+
+
+@itemize @bullet
+@item @code{MYSQL_TYPE_TINY}
+@item @code{MYSQL_TYPE_SHORT}
+@item @code{MYSQL_TYPE_LONG}
+@item @code{MYSQL_TYPE_LONGLONG}
+@item @code{MYSQL_TYPE_FLOAT}
+@item @code{MYSQL_TYPE_DOUBLE}
+@item @code{MYSQL_TYPE_TIME}
+@item @code{MYSQL_TYPE_DATE}
+@item @code{MYSQL_TYPE_DATETIME}
+@item @code{MYSQL_TYPE_TIMESTAMP}
+@item @code{MYSQL_TYPE_STRING}
+@item @code{MYSQL_TYPE_VAR_STRING}
+@item @code{MYSQL_TYPE_TINY_BLOB}
+@item @code{MYSQL_TYPE_MEDIUM_BLOB}
+@item @code{MYSQL_TYPE_LONG_BLOB}
+@item @code{MYSQL_TYPE_BLOB}
+@end itemize
+@sp 1
+
+@item void *buffer [input/output]
+A pointer to a buffer for the parameters data in case if it is used to
+supply parameters data or pointer to a buffer in which to return the
+data when the structure is used for result set bind.
+
+@sp 1
+
+@item unsigned long buffer_length [input]
+Length of the @code{*buffer} in bytes. For character and binary C data,
+the buffer_length specifies the length of the @code{*buffer} to be used
+as a parameter data in case if it is used with @code{mysql_bind_param()}
+or to return that many bytes when fetching results when this is used
+with @code{mysql_bind_result()}.
+
+
+@item long *length [input/output]
+Pointer to the buffer for the parameter's length. When the structure is
+used as a input parameter data binding, then this argument points to a
+buffer that, when @code{mysql_execute()} is called, contains the length
+of the parameter value stored in *buffer. This is ignored except for
+character or binary C data.
+
+If the length is a null pointer, then the protocol assumes that all
+character and binary data are null terminated.
+
+When this structure is used in output binding, then @code{mysql_fetch()}
+return the the length of the data that is returned.
+
+@sp 1
+
+@item bool *is_null [input/output]
+Indicates if the parameter data is NULL or fetched data is NULL.
+@end table
+
+@sp 1
+
+@tindex MySQL C type
+
+@item MYSQL_TIME
+
+This structure is used to send and receive DATE, TIME and
+TIMESTAMP data directly to/from server.
+
+@sp 1
+
+@noindent
+The @code{MYSQL_TIME} structure contains the members listed here:
+
+@multitable @columnfractions .20 .20 .68
+
+@item @strong{Member} @tab @strong{Type} @tab @strong{Description}
+
+@item @code{year} @tab unsigned int @tab Year.
+@item @code{month} @tab unsigned int @tab Month of the year.
+@item @code{day} @tab unsigned int @tab Day of the month.
+@item @code{hour} @tab unsigned int @tab Hour of the day(TIME).
+@item @code{minute} @tab unsigned int @tab Minute of the hour.
+@item @code{second} @tab unsigned int @tab Second of the minute.
+@item @code{neg} @tab my_bool @tab A boolean flag to
+indicate if the time is negative.
+@item @code{second_part} @tab unsigned long @tab Fraction part of the
+second(not yet used)
+@end multitable
+@end table
+
+
+@node C Prepared statements function overview, C Prepared statement functions, C Prepared statement datatypes, MySQL prepared statements
+@subsection C Prepared Statements Function Overview
+
+@cindex C Prepared statements API, functions
+@cindex functions, C Prepared statements API
+
+The functions available in the prepared statements are listed here and
+are described in greater detail in the later section.
+@xref{C Prepared statement functions}.
+
+@multitable @columnfractions .32 .68
+@item @strong{Function} @tab @strong{Description}
+
+@item @strong{mysql_prepare()} @tab Prepares an SQL string for execution.
+
+@item @strong{mysql_param_count()} @tab Returns the number of parameters in a prepared SQL statement.
+
+@item @strong{mysql_prepare_result()} @tab Returns prepared statement meta information in the form of resultset.
+
+@item @strong{mysql_bind_param()} @tab Binds a buffer to parameter markers in a prepared SQL statement.
+
+@item @strong{mysql_execute()} @tab Executes the prepared statement.
+
+@item @strong{mysql_stmt_affected_rows()} @tab Returns the number of rows changes/deleted/inserted by the last UPDATE,DELETE,or INSERT query
+
+@item @strong{mysql_bind_result()} @tab Binds application data buffers
+to columns in the resultset.
+
+@item @strong{mysql_stmt_store_result()} @tab Retrieves the complete result set to the client
+
+@item @strong{mysql_fetch()} @tab Fetches the next rowset of data from the result set and returns data for all bound columns.
+
+@item @strong{mysql_stmt_close()} @tab Frees memory used by prepared statement.
+
+@item @strong{mysql_stmt_errno()} @tab Returns the error number for the last statement execution.
+
+@item @strong{mysql_stmt_error()} @tab Returns the error message for the last statement execution.
+
+@item @strong{mysql_send_long_data()} @tab Sends long data in chunks to server.
+
+@c TO BE MOVED TO MAIN C API FUCTIONS
+@item @strong{mysql_commit()} @tab Commits the transaction.
+
+@item @strong{mysql_rollback()} @tab Rollbacks the transaction.
+
+@item @strong{mysql_autocommit()} @tab Toggles the autocommit mode to on/off.
+
+@item @strong{mysql_more_results()} @tab Returns if there are any more results exists
+
+@item @strong{mysql_next_result()} @tab Returns/Initiates the next result in the multi-query executions
+
+@end multitable
+
+@sp 1
+
+Call @code{mysql_prepare()} to prepare and initialize the statement
+handle, then call @code{mysql_bind_param()} to supply the parameters
+data, and then call @code{mysql_execute()} to execute the query. You can
+repeat the @code{mysql_execute()} by changing parameter values from the
+respective buffer supplied through @code{mysql_bind_param()}.
+
+@sp 1
+
+
+In case if the query is a SELECT statement or any other query which
+results in a resultset, then mysql_prepare() will also return the result
+set meta data information in the form of @code{MYSQL_RES } result set
+through @code{mysql_prepare_result()}.
+
+@sp 1
+
+You can supply the result buffers using @code{mysql_bind_result()}, so
+that the @code{mysql_fetch()} will automatically returns data to this
+buffers. This is row by row fetching.
+
+@sp 1
+
+You can also send the text or binary data in chunks to server using
+@code{mysql_send_long_data()}, by specifying the option is_long_data=1
+or length=MYSQL_LONG_DATA or -2 in the MYSQL_BIND structure supplied
+with @code{mysql_bind_param()}.
+
+@sp 1
+
+Once the statement execution is over, it must be freed using
+@code{mysql_stmt_close} so that it frees all the alloced resources for
+the statement handle.
+
+
+@subsubheading Execution Steps:
+
+To prepare and execute a statement, the application:
+
+@itemize @bullet
+@item
+Calls @strong{mysql_prepare()} and passes it a string containing the SQL
+statement. On a successful prepare, mysql_prepare returns the valid statement
+handle back to the application
+@item
+If the query results in a resultset, then @strong{mysql_prepare_result}
+returns the result set meta info..
+@item
+Sets the values of any parameters using @strong{mysql_bind_param}. All
+parameters must be set; else it will return an error or produce
+un-expected results
+@item
+Calls @strong{mysql_execute} to execute the statement.
+@item
+Repeat steps 2 and 3 as necessary, by changing the parameter values and
+re-executing the statement.
+@item
+Bind the data buffers to return the row values, if it is a result set
+query; using @strong{mysql_bind_result()}.
+@item
+Fetch the data to buffers row by row by calling @strong{mysql_fetch()}
+repetedely until no more rows found.
+@item
+When @strong{mysql_prepare()} is called, in the MySQL client/server protocol:
+@itemize @minus
+@item
+Server parses the query and sends the ok status back to client by
+assinging a statement id. It also sends total number of parameters,
+columns count and its meta information if it is a result set oriented
+query. All syntax and symantecs of the query is checked during this call
+by the server.
+@item
+Client uses this statement id for the further executions, so that server
+identifies the statement back from the pool of statements. Now, client
+allocates a statement handle with this id and returns back to
+application.
+@end itemize
+@item
+When @strong{mysql_execute()} is called, in the MySQL client/server protocol:
+@itemize @minus
+@item
+Client uses the statement handle and sends the parameters data to
+server.
+@item
+Server identifies the statement using the id provided by the client, and
+replaces the parameter markers with the newly supplied data and executes
+the query. If it results in a result set, then sends the data back to
+client, else sends an OK status with total number of rows
+changes/deleted/inserted.
+@end itemize
+@item
+When @strong{mysql_fetch()} is called, in the MySQL client/server protocol:
+@itemize @minus
+@item
+Client reads the data from the packet row by row and places it to
+application data buffers by doing the necessary conversions. If the
+application buffer type is same as that of field type, then the
+conversions are stright forward.
+@end itemize
+@end itemize
+
+
+
+You can get the statement error code and message using
+@code{mysql_stmt_errno()} and @code{mysql_stmt_error()} respectively.
+
+
+@node C Prepared statement functions, multiple queries, C Prepared statements function overview, MySQL prepared statements
+@subsection C Prepared Statement Function Descriptions
+
+You need to use the following functions when you want to prepare and
+execute the queries.
+
+
+@menu
+* mysql_prepare:: @code{mysql_prepare()}
+* mysql_param_count:: @code{mysql_param_count()}
+* mysql_prepare_result:: @code{mysql_prepare_result()}
+* mysql_bind_param:: @code{mysql_bind_param()}
+* mysql_execute:: @code{mysql_execute()}
+* mysql_stmt_affected_rows:: @code{mysql_stmt_affected_rows()}
+* mysql_bind_result:: @code{mysql_bind_result()}
+* mysql_stmt_store_result:: @code{mysql_stmt_store_result()}
+* mysql_fetch:: @code{mysql_fetch()}
+* mysql_send_long_data:: @code{mysql_send_long_data()}
+* mysql_stmt_close:: @code{mysql_stmt_close()}
+* mysql_stmt_errno:: @code{mysql_stmt_errno()}
+* mysql_stmt_error:: @code{mysql_stmt_error()}
+* mysql_commit:: @code{mysql_commit()}
+* mysql_rollback:: @code{mysql_rollback()}
+* mysql_autocommit:: @code{mysql_autocommit()}
+* mysql_more_results:: @code{mysql_more_results()}
+* mysql_next_result:: @code{mysql_next_result()}
+@end menu
+
+@node mysql_prepare, mysql_param_count, C Prepared statement functions, C Prepared statement functions
+@subsubsection @code{mysql_prepare()}
+
+@findex @code{mysql_prepare()}
+
+@code{MYSQL_STMT * mysql_prepare(MYSQL *mysql, const char *query, unsigned
+long length)}
+
+@subsubheading Description
+
+Prepares the SQL query pointed to by the null-terminated string
+'query'. The query must consist of a single SQL statement. You should
+not add a terminating semicolon (`;`) or \g to the statement.
+
+@sp 1
+The application can include one or more parameter markers in the SQL
+statement. To include a parameter marker, the appication embeds a
+question mark (@code{?}) into the SQL string at the appropriate
+position.
+
+@sp 1
+The markers are legal only in certain places in SQL statements. For
+example, they are not allowed in the select list(the list of columns to
+be returned by a SELECT statement), nor are they allowed as both
+operands of a binary operator such as the equal sign (=), becuase it
+would be impossible to determine the parameter type. In general,
+parameters are legal only in Data Manipulation Languange(DML)
+statements, and not in Data Defination Language(DDL) statements.
+
+@sp 1
+The parameter markers are then bound to application variables using
+@code{mysql_bind_param()}.
+
+
+
+@subsubheading Return Values
+
+@code{MYSQL_STMT} if the prepare was successful. NULL if an error
+occured.
+
+@subsubheading Errors
+
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order
+@item CR_OUT_OF_MEMORY
+Out of memory
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away
+@item CR_SERVER_LOST
+The connection to the server was lost during the query
+@item CR_UNKNOWN_ERROR
+An unkown error occured
+@end table
+
+If the prepare is not successful, i.e. when @code{mysql_prepare()} returned a
+NULL statement, errors can be obtained by calling @code{mysql_error()}.
+
+
+@subsubheading Example
+
+For the usage of @code{mysql_prepare()} refer to the Example from
+@ref{mysql_execute,mysql_execute()}.
+
+
+
+
+@node mysql_param_count, mysql_prepare_result, mysql_prepare, C Prepared statement functions
+@subsubsection @code{mysql_param_count()}
+
+@findex @code{mysql_param_count()}
+
+@code{unsigned int mysql_param_count(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+Returns the number of parameter markers present from the prepared query.
+
+@subsubheading Return Values
+
+An unsigned integer representing the number of parameters in a
+statement.
+
+@subsubheading Errors
+
+None
+
+@subsubheading Example
+
+For the usage of @code{mysql_param_count()} refer to the Example from
+@ref{mysql_execute,mysql_execute()}.
+
+
+
+@node mysql_prepare_result, mysql_bind_param, mysql_param_count, C Prepared statement functions
+@subsubsection @code{mysql_prepare_result()}
+
+
+@findex @code{mysql_prepare_result}.
+
+@code{MYSQL_RES *mysql_prepare_result(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+If the @code{mysql_prepare()} resulted in a result set query, then
+@code{mysql_prepare_result()} returns the result set meta data in the form of
+@code{MYSQL_RES} structure; which can further be used to process the
+meta information such as total number of fields and individual field
+information. This resulted result set can be passed as an argument to
+any of the field based APIs in order to process the result set meta data
+information such as:
+
+@itemize @minus
+@item
+mysql_num_fields()
+@item
+mysql_fetch_field()
+@item
+mysql_fetch_field_direct()
+@item
+mysql_fetch_fields()
+@item
+mysql_field_count()
+@item
+mysql_field_seek()
+@item
+mysql_field_tell() and
+@item
+mysql_free_result()
+@end itemize
+
+
+@subsubheading Return Values
+
+A @code{MYSQL_RES} result structure. NULL if no meta information exists from
+the prepared query.
+
+
+@subsubheading Errors
+
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
+
+None
+
+
+@subsubheading Example
+
+For the usage of @code{mysql_prepare_result()} refer to the Example from
+@ref{mysql_fetch,mysql_fetch()}
+
+
+
+@node mysql_bind_param, mysql_execute, mysql_prepare_result, C Prepared statement functions
+@subsubsection @code{mysql_bind_param()}
+
+@findex @code{mysql_bind_param()}
+
+@code{int mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)}
+
+@subsubheading Description
+
+@code{mysql_bind_param} is used to bind data for the parameter markers
+in the SQL statement from @code{mysql_prepare}. It uses the structure
+MYSQL_BIND to supply the data.
+
+The supported buffer types are:
+
+@itemize @bullet
+@item
+MYSQL_TYPE_TINY
+@item
+MYSQL_TYPE_SHORT
+@item
+MYSQL_TYPE_LONG
+@item
+MYSQL_TYPE_LONGLONG
+@item
+MYSQL_TYPE_FLOAT
+@item
+MYSQL_TYPE_DOUBLE
+@item
+MYSQL_TYPE_TIME
+@item
+MYSQL_TYPE_DATE
+@item
+MYSQL_TYPE_DATETIME
+@item
+MYSQL_TYPE_TIMESTAMP
+@item
+MYSQL_TYPE_STRING
+@item
+MYSQL_TYPE_VAR_STRING
+@item
+MYSQL_TYPE_TINY_BLOB
+@item
+MYSQL_TYPE_MEDIUM_BLOB
+@item
+MYSQL_TYPE_LONG_BLOB
+@end itemize
+
+@subsubheading Return Values
+
+Zero if the bind was successful. Non-zero if an error occured.
+
+@subsubheading Errors
+@table @code
+@item CR_NO_PREPARE_STMT
+No prepared statement exists
+@item CR_NO_PARAMETERS_EXISTS
+No parameters exists to bind
+@item CR_INVALID_BUFFER_USE
+Indicates if the bind is to supply the long data in chunks and if the
+buffer type is non string or binary
+@item CR_UNSUPPORTED_PARAM_TYPE
+The conversion is not supported, possibly the buffer_type is illegal or
+its not from the above list of supported types.
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
+@end table
+
+@subsubheading Example
+
+For the usage of @code{mysql_bind_param()} refer to the Example from
+@ref{mysql_execute,mysql_execute()}.
+
+
+
+@node mysql_execute, mysql_stmt_affected_rows, mysql_bind_param, C Prepared statement functions
+@subsubsection @code{mysql_execute()}
+
+@findex @code{mysql_execute()}
+
+@code{int mysql_execute(MYSQL_STMT *stmt}.
+
+@subsubheading Description
+
+@code{mysql_execute()} executes the prepared query associated with the
+statement handle. The parameter marker values will be sent to server
+during this call, so that server replaces markers with this newly
+supplied data.
+
+@sp 1
+
+If the statement is UPDATE,DELETE,or INSERT, the total number of
+changed/deletd/inserted values can be found by calling
+@code{mysql_stmt_affected_rows}. If this is a result set query, then one
+must call @code{mysql_fetch()} to fetch the data prior to calling any
+other calls which results in query processing. For more information on
+how to fetch the statement binary data, refer to @ref{mysql_fetch}.
+
+
+@subsubheading Return Values
+
+@code{mysql_execute()} returns the following return values:
+
+@multitable @columnfractions .30 .65
+@item @strong{Return Value} @tab @strong{Description}
+@item 0 @tab Successful
+@item 1 @tab Error occured. Error code and
+message can be obtained by calling @code{mysql_stmt_errno()} and @code{mysql_stmt_error()}.
+@end multitable
+
+
+@subsubheading Errors
+
+@table @code
+@item CR_NO_PREPARE_QUERY
+No query prepared prior to execution
+@item CR_ALL_PARAMS_NOT_BOUND
+Not all parameters data is supplied
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
+@end table
+
+
+@subsubheading Example
+
+The following example explains the uasage of @code{mysql_prepare},
+@code{mysql_param_count}, @code{mysql_bind_param}, @code{mysql_execute}
+and @code{mysql_stmt_affected_rows()}.
+
+@example
+
+MYSQL_BIND bind[3];
+MYSQL_STMT *stmt;
+ulonglong affected_rows;
+long length;
+unsigned int param_count;
+int int_data;
+short small_data;
+char str_data[50], query[255];
+my_bool is_null;
+
+ /* Set autocommit mode to true */
+ mysql_autocommit(mysql, 1);
+
+ if (mysql_query(mysql,"DROP TABLE IF EXISTS test_table"))
+ @{
+ fprintf(stderr, "\n drop table failed");
+ fprintf(stderr, "\n %s", mysql_error(mysql));
+ exit(0);
+ @}
+ if (mysql_query(mysql,"CREATE TABLE test_table(col1 int, col2 varchar(50), \
+ col3 smallint,\
+ col4 timestamp(14))"))
+ @{
+ fprintf(stderr, "\n create table failed");
+ fprintf(stderr, "\n %s", mysql_error(mysql));
+ exit(0);
+ @}
+
+ /* Prepare a insert query with 3 parameters */
+ strmov(query, "INSERT INTO test_table(col1,col2,col3) values(?,?,?)");
+ if(!(stmt = mysql_prepare(mysql, query, strlen(query))))
+ @{
+ fprintf(stderr, "\n prepare, insert failed");
+ fprintf(stderr, "\n %s", mysql_error(mysql));
+ exit(0);
+ @}
+ fprintf(stdout, "\n prepare, insert successful");
+
+ /* Get the parameter count from the statement */
+ param_count= mysql_param_count(stmt);
+
+ fprintf(stdout, "\n total parameters in insert: %d", param_count);
+ if (param_count != 3) /* validate parameter count */
+ @{
+ fprintf(stderr, "\n invalid parameter count returned by MySQL");
+ exit(0);
+ @}
+
+ /* Bind the data for the parameters */
+
+ /* INTEGER PART */
+ bind[0].buffer_type= MYSQL_TYPE_LONG;
+ bind[0].buffer= (char *)&int_data;
+ bind[0].is_null= 0;
+ bind[0].length= 0;
+
+ /* STRING PART */
+ bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
+ bind[1].buffer= (char *)str_data;
+ bind[1].buffer_length= sizeof(str_data);
+ bind[1].is_null= 0;
+ bind[1].length= 0;
+
+ /* SMALLINT PART */
+ bind[2].buffer_type= MYSQL_TYPE_SHORT;
+ bind[2].buffer= (char *)&small_data;
+ bind[2].is_null= &is_null;
+ bind[2].length= 0;
+ is_null= 0;
+
+
+ /* Bind the buffers */
+ if (mysql_bind_param(stmt, bind))
+ @{
+ fprintf(stderr, "\n param bind failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Specify the data */
+ int_data= 10; /* integer */
+ strcpy(str_data,"MySQL"); /* string */
+
+ /* INSERT SMALLINT data as NULL */
+ is_null= 1;
+
+ /* Execute the insert statement - 1*/
+ if (mysql_execute(stmt))
+ @{
+ fprintf(stderr, "\n execute 1 failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ fprintf(stderr, "\n send a bug report to bugs@@lists.mysql.com, by asking why this is not working ?");
+ exit(0);
+ @}
+
+ /* Get the total rows affected */
+ affected_rows= mysql_stmt_affected_rows(stmt);
+
+ fprintf(stdout, "\n total affected rows: %lld", affected_rows);
+ if (affected_rows != 1) /* validate affected rows */
+ @{
+ fprintf(stderr, "\n invalid affected rows by MySQL");
+ exit(0);
+ @}
+
+ /* Re-execute the insert, by changing the values */
+ int_data= 1000;
+ strcpy(str_data,"The most popular open source database");
+ small_data= 1000; /* smallint */
+ is_null= 0; /* reset NULL */
+
+ /* Execute the insert statement - 2*/
+ if (mysql_execute(stmt))
+ @{
+ fprintf(stderr, "\n execute 2 failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Get the total rows affected */
+ affected_rows= mysql_stmt_affected_rows(stmt);
+
+ fprintf(stdout, "\n total affected rows: %lld", affected_rows);
+ if (affected_rows != 1) /* validate affected rows */
+ @{
+ fprintf(stderr, "\n invalid affected rows by MySQL");
+ exit(0);
+ @}
+
+ /* Close the statement */
+ if (mysql_stmt_close(stmt))
+ @{
+ fprintf(stderr, "\n failed while closing the statement");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* DROP THE TABLE */
+ if (mysql_query(mysql,"DROP TABLE test_table"))
+ @{
+ fprintf(stderr, "\n drop table failed");
+ fprintf(stderr, "\n %s", mysql_error(mysql));
+ exit(0);
+ @}
+ fprintf(stdout, "Success, MySQL prepared statements are working!!!");
+@end example
+
+
+
+
+@node mysql_stmt_affected_rows, mysql_bind_result, mysql_execute, C Prepared statement functions
+@subsubsection @code{mysql_stmt_affected_rows()}
+
+@findex @code{mysql_stmt_affected_rows()}
+
+@code{ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+Returns total number of rows changed by the last execute statement. May
+be called immediatlely after mysql_execute() for UPDATE,DELETE,or INSERT
+statements.For SELECT statements, mysql_stmt_affected rows works like
+mysql_num_rows().
+
+@subsubheading Return Values
+
+An integer greater than zero indicates the number of rows affected or
+retrieved. Zero indicates that no records where updated for an UPDATE
+statement, no rows matched the WHERE clause in the query or that no
+query has yet been executed. -1 indicates that the query returned an
+error or that, for a SELECT query, mysql_stmt_affected_rows() was called
+prior to calling mysql_fetch().
+
+@subsubheading Errors
+
+None.
+
+@subsubheading Example
+
+For the usage of @code{mysql_stmt_affected_rows()} refer to the Example
+from @ref{mysql_execute,mysql_execute()}.
+
+
+
+
+
+@node mysql_bind_result, mysql_stmt_store_result, mysql_stmt_affected_rows, C Prepared statement functions
+@subsubsection @code{mysql_bind_result()}
+
+@findex @code{mysql_bind_result()}
+
+@code{my_bool mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)}
+
+@subsubheading Description
+
+@code{mysql_bind_result()} is used to associate, or bind, columns in the
+resultset to data buffers and length buffers. When @code{mysql_fetch()} is
+called to fetch data, the MySQL client protocol returns the data for the
+bound columns in the specified buffers.
+
+@sp 1
+
+Note that all columns must be bound prior to calling @code{mysql_fetch()}
+in case of fetching the data to buffers; else @code{mysql_fetch()} simply ignores
+the data fetch; also the buffers should be sufficient enough to hold the
+data as the ptotocol doesn't return the data in chunks.
+
+@sp 1
+
+A column can be bound or rebound at any time, even after data has been
+fetched from the result set. The new binding takes effect the next time
+@code{mysql_fetch()} is called. For example, suppose an application binds
+the columns in a result set and calls @code{mysql_fetch()}. The mysql
+protocol returns data in the bound buffers. Now suppose the application
+binds the columns to a different set of buffers, then the protocol does
+not place the data for the just fetched row in the newly bound
+buffers. Instead, it does when the next @code{mysql_fetch()} is called.
+
+@sp 1
+
+To bind a column, an application calls @code{mysql_bind_result()} and
+passes the type, address, and the address of the length buffer.
+
+The supported buffer types are:
+
+@itemize @bullet
+@item
+MYSQL_TYPE_TINY
+@item
+MYSQL_TYPE_SHORT
+@item
+MYSQL_TYPE_LONG
+@item
+MYSQL_TYPE_LONGLONG
+@item
+MYSQL_TYPE_FLOAT
+@item
+MYSQL_TYPE_DOUBLE
+@item
+MYSQL_TYPE_TIME
+@item
+MYSQL_TYPE_DATE
+@item
+MYSQL_TYPE_DATETIME
+@item
+MYSQL_TYPE_TIMESTAMP
+@item
+MYSQL_TYPE_STRING
+@item
+MYSQL_TYPE_VAR_STRING
+@item
+MYSQL_TYPE_BLOB
+@item
+MYSQL_TYPE_TINY_BLOB
+@item
+MYSQL_TYPE_MEDIUM_BLOB
+@item
+MYSQL_TYPE_LONG_BLOB
+@end itemize
+
+@subsubheading Return Values
+
+Zero if the bind was successful. Non-zero if an error occured.
+
+@subsubheading Errors
+
+@table @code
+@item CR_NO_PREPARE_STMT
+No prepared statement exists
+@item CR_UNSUPPORTED_PARAM_TYPE
+The conversion is not supported, possibly the buffer_type is illegal or
+its not from the list of supported types.
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
+@end table
+
+@subsubheading Example
+
+For the usage of @code{mysql_bind_result()} refer to the Example from
+@ref{mysql_fetch,mysql_fetch()}
+
+
+
+
+@node mysql_stmt_store_result, mysql_fetch, mysql_bind_result, C Prepared statement functions
+@subsubsection @code{mysql_stmt_store_result()}
+
+@findex code{mysql_stmt_store_result()}
+
+@code{int mysql_stmt_store_result(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+You must call @code{mysql_stmt_store_result()} for every query that
+successfully retrieves
+data(@code{SELECT},@code{SHOW},@code{DESCRIBE},@code{EXPLAIN}), and only
+if you want to buffer the complete result set by the client, so that the
+subsequent @code{mysql_fetch()} call returns buffered data.
+
+@sp 1
+
+You don't have to call @code{mysql_stmt_store_result()} for other
+queries, but it will not harm or cause any notable performance in all
+cases.You can detect if the query didn't have a result set by checking
+if @code{mysql_prepare_result()} returns 0. For more information refer
+to @ref{mysql_prepare_result}.
+
+@subsubheading Return Values
+
+@code{Zero} if the results are buffered successfully or @code{Non Zero} in case of an error.
+
+
+@subsubheading Errors
+
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
+@end table
+
+
+
+@node mysql_fetch, mysql_send_long_data, mysql_stmt_store_result, C Prepared statement functions
+@subsubsection @code{mysql_fetch()}
+
+@findex code{mysql_fetch()}
+
+@code{int mysql_fetch(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+@code{mysql_fetch()} returns the next rowset in the result set. It can
+be called only while the result set exists i.e. after a call to
+@code{mysql_execute()} that creates a result set or after
+@code{mysql_stmt_store_result()}, which is called after
+@code{mysql_execute()} to buffer the entire resultset.
+
+@sp 1
+
+If row buffers are bound using @code{mysql_bind_result()}, it returns
+the data in those buffers for all the columns in the current row
+set and the lengths are returned to the length pointer.
+
+@sp 1
+Note that, all columns must be bound by the application.
+
+@sp 1
+If the data fetched is a NULL data, then the @code{is_null} value from
+@code{MYSQL_BIND} contains TRUE, 1, else the data and its length is
+returned to @code{*buffer} and @code{*length} variables based on the
+buffer type specified by the application. All numeric, float and double
+types have the fixed length(in bytes) as listed below:
+
+
+@multitable @columnfractions .10 .30
+@item @strong{Type} @tab @strong{Length}
+@item MYSQL_TYPE_TINY @tab 1
+@item MYSQL_TYPE_SHORT @tab 2
+@item MYSQL_TYPE_LONG @tab 4
+@item MYSQL_TYPE_FLOAT @tab 4
+@item MYSQL_TYPE_LONGLONG @tab 8
+@item MYSQL_TYPE_DOUBLE @tab 8
+@item MYSQL_TYPE_TIME @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_DATE @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_DATETIME @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_TIMESTAMP @tab sizeof(MYSQL_TIME)
+@item MYSQL_TYPE_STRING @tab data length
+@item MYSQL_TYPE_VAR_STRING @tab data_length
+@item MYSQL_TYPE_BLOB @tab data_length
+@item MYSQL_TYPE_TINY_BLOB @tab data_length
+@item MYSQL_TYPE_MEDIUM_BLOB @tab data_length
+@item MYSQL_TYPE_LONG_BLOB @tab data_length
+@end multitable
+
+@*
+where @code{*data_length} is nothing but the 'Actual length of the data'.
+
+@subsubheading Return Values
+
+@multitable @columnfractions .30 .65
+@item @strong{Return Value} @tab @strong{Description}
+@item 0 @tab Successful, the data has been
+fetched to application data buffers.
+@item 1 @tab Error occured. Error code and
+message can be obtained by calling @code{mysql_stmt_errno()} and @code{mysql_stmt_error()}.
+@item 100, MYSQL_NO_DATA @tab No more rows/data exists
+@end multitable
+
+
+@subsubheading Errors
+@table @code
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_OUT_OF_MEMORY
+Out of memory.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away.
+@item CR_SERVER_LOST
+The connection to the server was lost during the query.
+@item CR_UNKNOWN_ERROR
+An unknown error occurred.
+@item CR_UNSUPPORTED_PARAM_TYPE
+If the buffer type is MYSQL_TYPE_DATE,DATETIME,TIME,or TIMESTAMP; and if
+the field type is not DATE, TIME, DATETIME or TIMESTAMP.
+@item
+All other unsupported conversion errors are returned from
+@code{mysql_bind_result()}.
+@end table
+
+@subsubheading Example
+
+The following example explains the usage of @code{mysql_prepare_result},
+@code{mysql_bind_result()}, and @code{mysql_fetch()}
+
+@example
+
+MYSQL_STMT *stmt;
+MYSQL_BIND bind[2];
+MYSQL_RES *result;
+int int_data;
+long int_length, str_length;
+char str_data[50];
+my_bool is_null[2];
+
+ query= "SELECT col1, col2 FROM test_table WHERE col1= 10)");
+ if (!(stmt= mysql_prepare(&mysql, query, strlen(query)))
+ @{
+ fprintf(stderr, "\n prepare failed");
+ fprintf(stderr, "\n %s", mysql_error(&stmt));
+ exit(0);
+ @}
+
+ /* Get the fields meta information */
+ if (!(result= mysql_prepare_result(stmt)))
+ @{
+ fprintf(stderr, "\n prepare_result failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ fprintf(stdout, "Total fields: %ld", mysql_num_fields(result));
+
+ if (mysql_num_fields(result) != 2)
+ @{
+ fprintf(stderr, "\n prepare returned invalid field count");
+ exit(0);
+ @}
+
+ /* Execute the SELECT query */
+ if (mysql_execute(stmt))
+ @{
+ fprintf(stderr, "\n execute failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Bind the result data buffers */
+ bind[0].buffer_type= MYSQL_TYPE_LONG;
+ bind[0].buffer= (char *)&int_data;
+ bind[0].is_null= &is_null[0];
+ bind[0].length= &int_length;
+
+ bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
+ bind[1].buffer= (void *)str_data;
+ bind[1].is_null= &is_null[1];
+ bind[1].length= &str_length;
+
+ if (mysql_bind_result(stmt, bind))
+ @{
+ fprintf(stderr, "\n bind_result failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Now fetch data to buffers */
+ if (mysql_fetch(stmt))
+ @{
+ fprintf(stderr, "\n fetch failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ if (is_null[0])
+ fprintf(stdout, "\n Col1 data is NULL");
+ else
+ fprintf(stdout, "\n Col1: %d, length: %ld", int_data, int_length);
+
+ if (is_null[1])
+ fprintf(stdout, "\n Col2 data is NULL");
+ else
+ fprintf(stdout, "\n Col2: %s, length: %ld", str_data, str_length);
+
+
+ /* call mysql_fetch again */
+ if (mysql_fetch(stmt) |= MYSQL_NO_DATA)
+ @{
+ fprintf(stderr, "\n fetch return more than one row);
+ exit(0);
+ @}
+
+ /* Free the prepare result meta information */
+ mysql_free_result(result);
+
+ /* Free the statement handle */
+ if (mysql_stmt_free(stmt))
+ @{
+ fprintf(stderr, "\n failed to free the statement handle);
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+@end example
+
+
+
+@node mysql_send_long_data, mysql_stmt_close, mysql_fetch, C Prepared statement functions
+@subsubsection @code{mysql_send_long_data()}
+
+
+@findex @code{mysql_send_long_data()}.
+
+@code{int mysql_send_long_data(MYSQL_STMT *stmt, unsigned int
+parameter_number, const char *data, ulong length)}
+
+@subsubheading Description
+
+Allows an application to send the data in pieces or chunks to
+server. This function can be used to send character or binary data
+values in parts to a column(it must be a text or blob) with a character or
+binary data type.
+
+@sp 1
+The @code{data} is a pointer to buffer containing the actual data for
+the parameter represendted by @code{parameter_number}. The @code{length}
+indicates the amount of data to be sent in bytes.
+
+
+@subsubheading Return Values
+
+Zero if the data is sent successfully to server. Non-zero if an error
+occured.
+
+
+@subsubheading Errors
+
+@table @code
+@item CR_INVALID_PARAMETER_NO
+Invalid parameter number
+@item CR_COMMANDS_OUT_OF_SYNC
+Commands were executed in an improper order.
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away
+@item CR_OUT_OF_MEMOR
+Out of memory
+@item CR_UNKNOWN_ERROR
+An unknown error occured
+@end table
+
+@subsubheading Example
+The following example explains how to send the data in chunks to text
+column:
+@example
+
+MYSQL_BIND bind[1];
+long length;
+
+ query= "INSERT INTO test_long_data(text_column) VALUES(?)");
+ if (!mysql_prepare(&mysql, query, strlen(query))
+ @{
+ fprintf(stderr, "\n prepare failed");
+ fprintf(stderr, "\n %s", mysql_error(&stmt));
+ exit(0);
+ @}
+ memset(bind, 0, sizeof(bind));
+ bind[0].buffer_type= MYSQL_TYPE_STRING;
+ bind[0].length= &length;
+ bind[0].is_null= 0;
+
+ /* Bind the buffers */
+ if (mysql_bind_param(stmt, bind))
+ @{
+ fprintf(stderr, "\n param bind failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Supply data in chunks to server */
+ if (!mysql_send_long_data(stmt,1,"MySQL",5))
+ @{
+ fprintf(stderr, "\n send_long_data failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Supply the next piece of data */
+ if (mysql_send_long_data(stmt,1," - The most popular open source database",40))
+ @{
+ fprintf(stderr, "\n send_long_data failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ /* Now, execute the query */
+ if (mysql_execute(stmt))
+ @{
+ fprintf(stderr, "\n mysql_execute failed");
+ fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
+ exit(0);
+ @}
+
+ This inserts the data, "MySQL - The most popular open source database"
+ to the field 'text_column'.
+@end example
+
+
+
+@node mysql_stmt_close, mysql_stmt_errno, mysql_send_long_data, C Prepared statement functions
+@subsubsection @code{mysql_stmt_close()}
+
+@findex @code{mysql_stmt_close()}
+
+@code{my_bool mysql_stmt_close(MYSQL_STMT *)}
+
+@subsubheading Description
+
+Closes the prepared statement. @code{mysql_stmt_close()} also
+deallocates the statement handle pointed to by @code{stmt}.
+
+If the current query results are pending or un-read; this cancels the
+query results; so that next call can be executed.
+
+@subsubheading Return Values
+
+Zero if the statement was freed successfully. Non-zero if an error occured.
+
+
+@subsubheading Errors
+
+@table @code
+@item CR_SERVER_GONE_ERROR
+The MySQL server has gone away
+@item CR_UNKNOWN_ERROR
+An unkown error occured
+@end table
+
+@subsubheading Example
+
+For the usage of @code{mysql_stmt_close()} refer to the Example from
+@ref{mysql_execute,mysql_execute()}.
+
+
+
+@node mysql_stmt_errno, mysql_stmt_error, mysql_stmt_close, C Prepared statement functions
+@subsubsection @code{mysql_stmt_errno()}
+
+
+@findex @code{mysql_stmt_errno()}
+
+@code{unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+For the statement specified by @code{stmt}, @code{mysql_stmt_errno()}
+returns the error code for the most recently invoked statement API
+function that can succeed or fail. A return value of zero means that no
+error occured. Client error message numbers are listed in the MySQL
+errmsg.h header file. Server error message numbers are listed in
+mysqld_error.h. In the MySQL source distribution you can find a complete
+list of error messages and error numbers in the file Docs/mysqld_error.txt
+
+@subsubheading Return Values
+
+An error code value. Zero if no error occured.
+
+@subsubheading Errors
+
+None
+
+
+@node mysql_stmt_error, mysql_commit, mysql_stmt_errno, C Prepared statement functions
+@subsubsection @code{mysql_stmt_error()}
+
+
+@findex @code{mysql_stmt_error()}.
+
+@code{char *mysql_stmt_error(MYSQL_STMT *stmt)}
+
+@subsubheading Description
+
+For the statement specified by @code{stmt}, @code{mysql_stmt_error()}
+returns the error message for the most recently invoked statement API
+that can succeed or fail. An empty string ("") is returned if no error
+occured. This means the following two sets are equivalent:
+
+@example
+
+if (mysql_stmt_errno(stmt))
+@{
+ // an error occured
+@}
+
+if (mysql_stmt_error(stmt))
+@{
+ // an error occured
+@}
+@end example
+
+The language of the client error messages many be changed by recompiling
+the MySQL client library. Currently you can choose error messages in
+several different languages.
+
+
+@subsubheading Return Values
+
+A character string that describes the error. An empry string if no error
+occured.
+
+@subsubheading Errors
+
+None
+
+
+
+@node mysql_commit, mysql_rollback, mysql_stmt_error, C Prepared statement functions
+@subsubsection @code{mysql_commit()}
+
+
+@findex @code{mysql_commit()}.
+
+@code{my_bool mysql_commit(MYSQL *mysql)}
+
+@subsubheading Description
+
+Commits the current transaction
+
+@subsubheading Return Values
+
+Zero if successful. Non-zero if an error occured.
+
+@subsubheading Errors
+
+None
+
+
+
+@node mysql_rollback, mysql_autocommit, mysql_commit, C Prepared statement functions
+@subsubsection @code{mysql_rollback()}
+
+
+@findex @code{mysql_rollback()}.
+
+@code{my_bool mysql_rollback(MYSQL *mysql)}
+
+@subsubheading Description
+
+Rollbacks the current transaction.
+
+
+@subsubheading Return Values
+
+Zero if successful. Non-zero if an error occured.
+
+@subsubheading Errors
+
+None.
+
+
+
+
+@node mysql_autocommit, mysql_more_results, mysql_rollback, C Prepared statement functions
+@subsubsection @code{mysql_autocommit()}
+
+
+@findex @code{mysql_autocommit()}.
+
+@code{my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)}
+
+@subsubheading Description
+
+Sets the autocommit mode to on or off. If the @code{mode} is '1', then it
+sets the autocommit mode to on, else to off in case of '0'.
+
+@subsubheading Return Values
+
+Zero if successful. Non-zero if an error occured
+
+@subsubheading Errors
+
+None.
+
+
+@node mysql_more_results, mysql_next_result, mysql_autocommit, C Prepared statement functions
+@subsubsection @code{mysql_more_results()}
+
+
+@findex @code{mysql_more_results()}.
+
+@code{my_bool mysql_more_results(MYSQL *mysql)}
+
+@subsubheading Description
+
+Returns true if more results exists from the currently executed query,
+and the application must call @code{mysql_next_result()} to fetch the
+results.
+
+
+@subsubheading Return Values
+
+@code{TRUE} if more results exists. @code{FALSE} if no more results exists.
+
+@subsubheading Errors
+
+None.
+
+
+@node mysql_next_result, , mysql_more_results, C Prepared statement functions
+@subsubsection @code{mysql_next_result()}
+
+
+@findex @code{mysql_next_result()}.
+
+@code{int mysql_next_result(MYSQL *mysql)}
+
+@subsubheading Description
+
+If more query results exists, then @code{mysql_next_result()} reads the
+next query results and returns the status back to application.
+
+@subsubheading Return Values
+
+Zero if successful. Non-zero if an error occured
+
+@subsubheading Errors
+
+None.
+
+
+
+@node multiple queries, date handling, C Prepared statement functions, MySQL prepared statements
+@subsection Handling multiple query executions
+
+
+From version 4.1 and above, MySQL supports the multi query execution
+using the single command. In order to do this, you must set the client flag
+@code{CLIENT_MULTI_QUERIES} option during the connection.
+
+@sp 1
+
+By default @code{mysql_query()} or @code{mysql_real_query()} returns
+only the first query status and the subsequent queries status can
+be processed using @code{mysql_more_results()} and
+@code{mysql_next_result()}.
+
+
+@example
+
+ /* Connect to server with option CLIENT_MULTI_QUERIES */
+ mysql_real_query(..., CLIENT_MULTI_QUERIES);
+
+ /* Now execute multiple queries */
+ mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
+ CREATE TABLE test_table(id int);\
+ INSERT INTO test_table VALUES(10);\
+ UPDATE test_table SET id=20 WHERE id=10;\
+ SELECT * FROM test_table;\
+ DROP TABLE test_table";
+ while (mysql_more_results(mysql))
+ {
+ /* Process all results */
+ mysql_next_result(mysql);
+ ...
+ printf("total affected rows: %lld", mysql_affected_rows(mysql));
+ ...
+ if ((result= mysql_store_result(mysql))
+ {
+ /* Returned a result set, process it */
+ }
+ }
+
+@end example
+
+
+
+@node date handling, , multiple queries, MySQL prepared statements
+@subsection Handling DATE, TIME and TIMESTAMP
+
+Using the new binary protocol from MySQL 4.1 and above, one can send and
+receive the DATE, TIME and TIMESTAMP data using the @code{MYSQL_TIME}
+structure.
+
+@code{MYSQL_TIME} structure consites of the following members:
+
+@itemize @bullet
+@item year
+@item month
+@item day
+@item hour
+@item minute
+@item second
+@item second_part
+@end itemize
+
+
+In order to send the data, one must use the prepared statements through
+@code{mysql_prepare()} and @code{mysql_execute()}; and must bind the
+parameter using type as @code{MYSQL_TYPE_DATE} inorder to process date
+value, @code{MYSQL_TYPE_TIME} for time and @code{MYSQL_TYPE_DATETIME} or
+@code{MYSQL_TYPE_TIMESTAMP} for datetime/timestamp using
+@code{mysql_bind_param()} when sending and @code{mysql_bind_results()}
+while receiving the data.
+
+@sp 1
+Here is a simple example; which inserts the DATE, TIME and TIMESTAMP data.
+
+@example
+
+MYSQL_TIME ts;
+MYSQL_BIND bind[3];
+MYSQL_STMT *stmt;
+
+ strmov(query, "INSERT INTO test_table(date_field, time_field,
+ timestamp_field) VALUES(?,?,?");
+
+ stmt= mysql_prepare(mysql, query, strlen(query)));
+
+ /* setup input buffers for all 3 parameters */
+ bind[0].buffer_type= MYSQL_TYPE_DATE;
+ bind[0].buffer= (char *)&ts;
+ bind[0].is_null= 0;
+ bind[0].length= 0;
+ ..
+ bind[1]= bind[2]= bind[0];
+ ..
+
+ mysql_bind_param(stmt, bind);
+
+ /* supply the data to be sent is the ts structure */
+ ts.year= 2002;
+ ts.month= 02;
+ ts.day= 03;
+
+ ts.hour= 10;
+ ts.minute= 45;
+ ts.second= 20;
+
+ mysql_execute(stmt);
+ ..
+
+@end example
+
+
+@bye