Update of /cvsroot/monetdb/MonetDB5/src/modules/mal
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv8323/src/modules/mal
Modified Files:
Tag: GDK-2
Makefile.ag remote.mx
Added Files:
Tag: GDK-2
batxml.mx
Log Message:
propagated changes of Tuesday Aug 21 2007 - Thursday Aug 23 2007
from the development trunk to the GDK-2 branch
Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/modules/mal/Makefile.ag,v
retrieving revision 1.102.2.1
retrieving revision 1.102.2.2
diff -u -d -r1.102.2.1 -r1.102.2.2
--- Makefile.ag 10 Aug 2007 14:54:51 -0000 1.102.2.1
+++ Makefile.ag 23 Aug 2007 13:32:48 -0000 1.102.2.2
@@ -30,7 +30,7 @@
profiler.mx const.mx algebraExtensions.mx \
inspect.mx manual.mx \
factory.mx mdb.mx \
- urlbox.mx mat.mx \
+ urlbox.mx mat.mx batxml.mx \
sabaoth.mx remote.mx
#datacell.mx radix.mx
@@ -159,7 +159,7 @@
factory.mx mdb.mx pcre.mx tablet.mx mat.mx \
urlbox.mx statistics.mx transaction.mx \
mserver.mx sabaoth.mx remote.mx \
- radix.mx bpm.mx
+ radix.mx bpm.mx batxml.mx
#datacell.mx
}
--- NEW FILE: batxml.mx ---
@' The contents of this file are subject to the MonetDB Public License
@' Version 1.1 (the "License"); you may not use this file except in
@' compliance with the License. You may obtain a copy of the License at
@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
@'
@' Software distributed under the License is distributed on an "AS IS"
@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
@' License for the specific language governing rights and limitations
@' under the License.
@'
@' The Original Code is the MonetDB Database System.
@'
@' The Initial Developer of the Original Code is CWI.
@' Portions created by CWI are Copyright (C) 1997-2007 CWI.
@' All Rights Reserved.
@f batxml
@a M.L. Kersten
@+ XML multiplexes
SQL/XML requires a handful of instructions.
The collection of routines provided here are map operations
for the atom xml primitives.
In line with the batcalc module, we assume that
if two bat operands are provided that they are already
aligned on the head. Moreover, the head of the BATs
are limited to :oid.
The implementation is focussed on functionality. At a later stage
we may postpone string contstruction until it is really needed.
@{
@mal
command xml.xml(src:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLstr2xml
comment "Cast the string to an xml compliant string";
pattern xml.str(src:bat[:oid,:xml]):bat[:oid,:str]
address BATXMLxml2str
comment "Cast the string to an xml compliant string";
command xml.tag(nme:str,val:bat[:oid,:xml]):bat[:oid,:xml]
address BATXMLtag
comment "Routine to put element brackets around an XML value";
command xml.comment(val:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLcomment
comment "Construct an comment struction ";
command xml.parse(val:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLparse
comment "Parse the XML document or element string values ";
command xml.serialize(val:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLxml2str
comment "Serialize the XML object to a string";
command xml.text(val:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLxml2str
comment "Serialize the XQuery object to a string";
command xml.query(val:bat[:oid,:str],expr:str):bat[:oid,:xml]
address BATXMLxquery
comment "Execute the XQuery against the elements";
#todo
#command xml.table(val:bat[:oid,:str],expr:str):bat[:oid,:xml]
#address BATXMLquery
#comment "Execute the XQuery against the elements";
command xml.pi(operator:str, ret:bat[:oid,:xml]):bat[:oid,:xml]
address XMLpi
comment "Call the processing instruction";
command xml.attribute(name:str, val:bat[:oid,:str]):bat[:oid,:xml]
address BATXMLattribute
comment "Construct an attribute value pair";
command xml.element(name:str, s:bat[:oid,:xml]) :bat[:oid,:xml]
address BATXMLelementSmall
comment "The basic building block for XML elements are namespaces,
attributes and a sequence of xml elements. The name space and
the attributes may be left unspecified.";
command xml.element(name:str, ns:bat[:oid,:str], attr:bat[:oid,:xml],
s:bat[:oid,:xml]):bat[:oid,:xml]
address BATXMLelement
comment "The basic building block for XML elements are namespaces,
attributes and a sequence of xml elements. The name space and the
attributes may be left unspecified(=nil:bat).";
command xml.concat(left:bat[:oid,:xml],right:bat[:oid,:xml] ):bat[:oid,:xml]
address BATXMLconcat
comment "Concatenate the xml values";
pattern xml.forest(val:bat[:oid,:xml]...):bat[:oid,:xml]
address BATXMLforest
comment "Construct an element list");
pattern xml.agg(val:bat[:oid,:xml], order:str...):bat[:oid,:xml]
address BATXMLagg
comment "Aggregate the XML values over grouping specified@;
command xml.root(val:bat[:oid,:xml], version:str, standalone:str):bat[:oid,:xml]
address BATXMLroot
comment "Contruct the root nodes";
command xml.isdocument(val:bat[:oid,:str]):bat[:oid,:bit]
address BATXMLisdocument
comment "Validate the string as a document"
@{
@include ../kernel/kprelude.mx
@+ Implementation
@h
#ifndef _BATXML_H_
#define _BATXML_H_
#include "mal_config.h"
#include <gdk.h>
#include "ctype.h"
#include <string.h>
#include "mal_interpreter.h"
#include "mal_function.h"
#include "xml.h"
#ifdef HAVE_LIBXML2
#include <libxml2.h>
#endif
#ifdef WIN32
#ifndef LIBBATXML
#define batxml_export extern __declspec(dllimport)
#else
#define batxml_export extern __declspec(dllexport)
#endif
#else
#define batxml_export extern
#endif
batxml_export str BATXMLxml2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr p);
batxml_export str BATXMLstr2xml(int *x, int *s);
batxml_export str BATXMLisdocument(int *x, int *s);
batxml_export str BATXMLtag(int *x, str *name, int *s);
batxml_export str BATXMLcomment(int *x, int *s);
batxml_export str BATXMLparse(int *x, int *s);
batxml_export str BATXMLxquery(int *x, int *s, str *expr);
batxml_export str BATXMLpi(int *x, str *oper, int *s);
batxml_export str BATXMLroot(int *ret, int *bid, str *version, str *standalone);
batxml_export str BATXMLattribute(int *ret, str *name, int *bid);
batxml_export str BATXMLelementSmall(int *ret, str *name, int *bid);
batxml_export str BATXMLelement(int *ret, str *name, int *ns, int *attr, int
*bid);
batxml_export str BATXMLconcat(int *ret, int *bid, int *rid);
batxml_export str BATXMLforest(MalBlkPtr mb, MalStkPtr stk, InstrPtr p);
batxml_export str BATXMLagg(MalBlkPtr mb, MalStkPtr stk, InstrPtr p);
#endif /* _BATXML_H_ */
@c
#include "batxml.h"
#define prepareOperand(X,Y,Z) \
if( (X= BATdescriptor(*Y)) == NULL ) \
throw(MAL, "batxml." Z, "Cannot access descriptor");
#define prepareResult(X,Y,T,Z) \
X= BATnew(Y->htype,T,BATcount(Y)); \
if( Y->htype== TYPE_void) \
BATseqbase(X, Y->hseqbase); \
if( X == NULL){ \
BBPreleaseref(Y->batCacheid); \
throw(MAL, "batxml." Z, "no space available "); \
} \
X->hsorted=Y->hsorted; \
X->tsorted=0;
#define finalizeResult(X,Y,Z) \
if (!((Y)->batDirty&2)) (Y) = BATsetaccess((Y), BAT_READ); \
*X = (Y)->batCacheid; \
BBPkeepref(*(X));\
BBPreleaseref(Z->batCacheid);
str
BATXMLstr2xml(int *ret, int *bid)
{
*ret= BBPincref(*bid,TRUE);
return MAL_SUCCEED;
}
@-
The core of the activity is xml2str, where the actual strings
are constructed.
To avoid repeatitive copying we make sure that the garbage
collector does not remove the xml intermediates.
This way, we know that as long as the xml-variables are not
reused, the complete structure of the xml document(s) are available.
We merely have to collect the pieces.
[FOR LATER, FIRST GO FOR THE EASY IMPLEMENTATION
static str
BATtreeWalker(MalBlkPtr mb, InstrPtr p, str base, int size, int offset){
(void)mb;
(void) p;
snprintf(base+offset,size-offset,"dummy");
return MAL_SUCCEED;
}
str
BATXMLxml2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
int *ret= (int*) getArgReference(stk,pci,0);
int *bid= (int*) getArgReference(stk,pci,1);
BAT *b,*bn;
ptr p,q;
str buf,msg= MAL_SUCCEED;
@:getBATdescriptor(bid,b,"batxml.str")@
bn= BATnew(TYPE_oid,TYPE_str,BATTINY);
if( bn == NULL){
BBPunfix(b->batCacheid);
throw(MAL,"batxml.str","Can not create BAT");
}
buf= GDKmalloc(BUFSIZ);
BATloop(b,p,q){
if( (msg= BATtreeWalker(mb,pci,buf,BUFSIZ,0)))
break;
}
BBPkeepref(*ret= bn->batCacheid);
(void)mb;
return msg;
}
@-
XML values are represented by strings already.
@c
str
BATXMLxml2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
int *ret= (int*) getArgReference(stk,pci,0);
int *bid= (int*) getArgReference(stk,pci,1);
(void) mb;
BBPincref(*ret= *bid,TRUE);
return MAL_SUCCEED;
}
str
BATXMLisdocument(int *x, int *s){
(void) x;
(void) s;
throw(MAL,"xml.isdocument","Not yet implemented");
}
str
BATXMLtag(int *ret, str *name, int *bid)
{
BAT *b,*bn;
BUN p,q;
int xx;
str buf= GDKmalloc(BUFSIZ);
int tlen= strlen(*name)+2, len, size= BUFSIZ;
prepareOperand(b,bid,"tag");
prepareResult(bn,b,TYPE_str,"tag");
snprintf(buf,size,"<%s>",*name);
BATloopFast(b,p,q,xx){
ptr h= BUNhead(b,p);
str t= (str) BUNtail(b,p);
if( (len=strlen(t) + 2*tlen+10) >= size){
if(buf) GDKfree(buf);
buf= GDKmalloc(len);
snprintf(buf,size,"<%s>",*name);
size= len;
}
snprintf(buf+tlen,size,"%s</%s>",t,*name);
bunfastins(bn,h,buf);
}
GDKfree(buf);
finalizeResult(ret,bn,b);
return MAL_SUCCEED;
bunins_failed:
BBPreleaseref(b->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "batstr.comment", "bunins failed");
}
str
BATXMLcomment(int *ret, int *bid)
{
BAT *b,*bn;
BUN p,q;
int xx;
str buf= GDKmalloc(BUFSIZ);
int len,size= BUFSIZ;
prepareOperand(b,bid,"comment");
prepareResult(bn,b,TYPE_str,"comment");
BATloopFast(b,p,q,xx){
ptr h= BUNhead(b,p);
str t= (str) BUNtail(b,p);
if( (len=strlen(t)) >= size){
if(buf) GDKfree(buf);
buf= GDKmalloc(size+20);
size= len+20;
}
snprintf(buf,size,"<!-- %s -->",t);
bunfastins(bn,h,buf);
}
GDKfree(buf);
finalizeResult(ret,bn,b);
return MAL_SUCCEED;
bunins_failed:
BBPreleaseref(b->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "batstr.comment", "bunins failed");
}
str
BATXMLparse(int *ret, int *bid)
{
BAT *b,*bn;
BUN p,q;
int xx;
prepareOperand(b,bid,"parse");
prepareResult(bn,b,TYPE_str,"parse");
BATloopFast(b,p,q,xx){
}
finalizeResult(ret,bn,b);
throw(MAL,"xml.parse","Not yet implemented");
}
str
BATXMLpi(int *ret, str *operator, int *bid)
{
BAT *b,*bn;
BUN p,q;
int xx;
(void) operator;
prepareOperand(b,bid,"pi");
prepareResult(bn,b,TYPE_str,"pi");
BATloopFast(b,p,q,xx){
}
finalizeResult(ret,bn,b);
throw(MAL,"xml.pi","Not yet implemented");
}
str
BATXMLroot(int *ret, int *bid, str *version, str *standalone)
{
BAT *b,*bn;
BUN p,q;
int xx;
prepareOperand(b,bid,"root");
prepareResult(bn,b,TYPE_str,"root");
BATloopFast(b,p,q,xx){
}
finalizeResult(ret,bn,b);
(void) version;
(void) standalone;
throw(MAL,"xml.root","Not yet implemented");
}
str
BATXMLattribute(int *ret, str *name, int *bid)
{
BAT *b,*bn;
BUN p,q;
int xx;
str buf= GDKmalloc(BUFSIZ);
int len,size= BUFSIZ;
prepareOperand(b,bid,"attribute");
prepareResult(bn,b,TYPE_str,"attribute");
BATloopFast(b,p,q,xx){
ptr h= BUNhead(b,p);
str t= (str) BUNtail(b,p);
if( (len=strlen(t)) >= size){
if(buf) GDKfree(buf);
buf= GDKmalloc(size+20);
size= len+20;
}
snprintf(buf,size," %s=\"%s\"",*name,t);
bunfastins(bn,h,buf);
}
GDKfree(buf);
finalizeResult(ret,bn,b);
return MAL_SUCCEED;
bunins_failed:
BBPreleaseref(b->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "xml.attribute", "bunins failed");
}
str
BATXMLelementSmall(int *ret, str *name, int *bid)
{
return BATXMLtag(ret,name,bid);
}
str
BATXMLelement(int *ret, str *name, int *namespace, int *attributes, int *bid)
{
BAT *b,*a=0, *n=0, *bn;
BUN p,q, ap, aq, np, nq;
int xx, axx, nxx;
str buf= GDKmalloc(BUFSIZ);
int offset,len,size= BUFSIZ;
/* check the namespaces */
if( *namespace && (n= BATdescriptor( *namespace)) ){
np = BUNfirst(n);
nq = BUNlast(n);
nxx= BUNsize(n);
}
/* check for attributes */
if( *attributes && (a= BATdescriptor( *attributes)) ){
ap= BUNfirst(a);
aq= BUNlast(a);
axx= BUNsize(a);
}
/* collect the admin for the xml elements */
if ( (b= BATdescriptor( *bid)) ){
p= BUNfirst(b);
q= BUNlast(b);
xx= BUNsize(b);
}
/* check for errors */
if( b== NULL){
if(a) BBPunfix(a->batCacheid);
if(n) BBPunfix(n->batCacheid);
throw(MAL,"batxml.element","Can not access BAT");
}
prepareResult(bn,b,TYPE_str,"element");
while(p < q){
str t;
oid *h;
int elm;
/* include attributes */
if( a) {
t= (str) BUNtail(a,ap);
if( (len=strlen(t)) >= size){
if(buf) GDKfree(buf);
buf= GDKmalloc(len+strlen(*name)+BUFSIZ);
size= len+strlen(*name)+BUFSIZ;
}
snprintf(buf,size,"<%s %s>",*name,t);
} else
snprintf(buf,size,"<%s>",*name);
elm= offset= strlen(buf);
/* fetch the elements */
h= (oid*) BUNhead(b,p);
t= (str) BUNtail(b,p);
if( (len=strlen(t)) >= size-offset){
if(buf) GDKfree(buf);
buf= GDKmalloc(size+2*elm);
size= len+2*elm;
}
snprintf(buf+offset,size-offset,"%s",t);
offset+= strlen(buf+offset);
snprintf(buf + offset,size-offset, "</%s>\n",*name);
bunfastins(bn,h,buf);
if(a)
ap= (ptr) ( ((char*)ap)+ axx);
if(n)
np= (ptr) ( ((char*)np)+ nxx);
if(b)
p= (ptr) ( ((char*)p)+ nxx);
}
GDKfree(buf);
finalizeResult(ret,bn,b);
return MAL_SUCCEED;
bunins_failed:
if(a)
BBPreleaseref(a->batCacheid);
if(n)
BBPreleaseref(n->batCacheid);
BBPreleaseref(b->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "xml.element", "bunins failed");
}
str
BATXMLforest(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
int *ret= (int*) getArgReference(stk,pci,0);
BAT **b,*bn;
BUN *p,*q;
int *xx;
str buf= GDKmalloc(BUFSIZ);
int i,offset,len,size= BUFSIZ;
(void)mb;
b= alloca(sizeof(BAT*) * pci->argc);
p= alloca(sizeof(BUN) * pci->argc);
q= alloca(sizeof(BUN) * pci->argc);
xx= alloca(sizeof(int) * pci->argc);
/* collect the admin for the xml elements */
for(i=pci->retc; i<pci->argc; i++){
if ( (b[i]= BATdescriptor(
*(int*)getArgReference(stk,pci,i)))==NULL)
break;
p[i]= BUNfirst(b[i]);
q[i]= BUNlast(b[i]);
xx[i]= BUNsize(b[i]);
}
/* check for errors */
if( i!= pci->argc) {
for( i--; i>=pci->retc; i--)
BBPunfix(b[i]->batCacheid);
throw(MAL,"batxml.element","Can not access BAT");
}
prepareResult(bn,b[pci->retc],TYPE_str,"attribute");
while(p[pci->retc] < q[pci->retc]){
str t;
oid *h;
int elm;
/* fetch the elements */
h= (oid*) BUNhead(b[4],p[4]);
for(i= pci->retc; i< pci->argc; i++)
{
t= (str) BUNtail(b[i],p[i]);
if( (len=strlen(t)) >= size-offset){
if(buf) GDKfree(buf);
buf= GDKmalloc(size+2*elm);
size= len+2*elm;
}
snprintf(buf+offset,size-offset,"%s",t);
offset+= strlen(buf+offset);
}
bunfastins(bn,h,buf);
for(i= pci->retc; i< pci->argc; i++)
if(b[i])
p[i]= (ptr) ( ((char*)p[i])+ xx[i]);
}
GDKfree(buf);
finalizeResult(ret,bn,b[pci->retc]);
return MAL_SUCCEED;
bunins_failed:
for(i= pci->retc; i< pci->argc; i++)
if(b[i])
BBPreleaseref(b[i]->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "xml.forest", "bunins failed");
}
str
BATXMLconcat(int *ret, int *bid, int *rid)
{
BAT *b,*r=0, *bn;
BUN p,q, rp;
int xx, rxx;
str buf= GDKmalloc(BUFSIZ);
int len,size= BUFSIZ;
if( *rid && (r= BATdescriptor( *rid)) ){
rp= BUNfirst(r);
rxx= BUNsize(r);
}
if(r==0)
throw(MAL,"batxml.concat","Can not access BAT");
/* collect the admin for the xml elements */
if ( (b= BATdescriptor( *bid)) ){
p= BUNfirst(b);
q= BUNlast(b);
xx= BUNsize(b);
}
if( b== NULL){
if(r) BBPunfix(r->batCacheid);
throw(MAL,"batxml.concat","Can not access BAT");
}
prepareResult(bn,b,TYPE_str,"concat");
while(p < q){
str t= (str) BUNtail(b,p);
oid *h= (oid*) BUNhead(b,p);
str v= (str) BUNtail(r,rp);
len= strlen(t)+strlen(v)+2;
if( len >= size){
if(buf) GDKfree(buf);
buf= GDKmalloc(len);
size= len;
}
snprintf(buf,size,"%s%s",t,v);
bunfastins(bn,h,buf);
rp= (ptr) ( ((char*)rp)+ rxx);
p= (ptr) ( ((char*)p)+ xx);
}
GDKfree(buf);
finalizeResult(ret,bn,b);
return MAL_SUCCEED;
bunins_failed:
BBPreleaseref(r->batCacheid);
BBPreleaseref(b->batCacheid);
BBPunfix(bn->batCacheid);
GDKfree(buf);
throw(MAL, "xml.element", "bunins failed");
}
str
BATXMLagg(MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
{
(void) mb;
(void) stk;
(void) p;
throw(MAL,"xml.agg","Not yet implemented");
}
str
BATXMLxquery(int *ret, int *bid, str *expr)
{
(void) ret;
(void) bid;
(void) expr;
/* use external library to solve this */
throw(MAL,"xml.xquery","Not yet implemented");
}
@}
Index: remote.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/modules/mal/remote.mx,v
retrieving revision 1.27.2.1
retrieving revision 1.27.2.2
diff -u -d -r1.27.2.1 -r1.27.2.2
--- remote.mx 10 Aug 2007 14:54:52 -0000 1.27.2.1
+++ remote.mx 23 Aug 2007 13:32:50 -0000 1.27.2.2
@@ -637,7 +637,7 @@
*/
str RMTexec(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
str conn, mod, func, ident, arg, tmp;
- int argc, i, len;
+ int i, len;
connection c;
char qbuf[512]; /* FIXME: make this dynamic */
MapiHdl mhdl;
@@ -673,8 +673,7 @@
mapi_close_handle(mhdl);
/* handle the arguments to the function */
- argc = pci->argc - 3 /* ret, conn, func */;
- assert(argc >= 0);
+ assert(pci->argc >= 3); /* ret, conn, func, ... */
/* put the arguments one by one, and dynamically build the
* invocation string */
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Monetdb-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-checkins