Commit a3a4ba93 authored by jimw@mysql.com's avatar jimw@mysql.com

Merge mysql.com:/home/jimw/my/mysql-5.1-ndb-cleanup

into  mysql.com:/home/jimw/my/mysql-5.1-clean
parents 64295d82 0302bb4f
......@@ -7,7 +7,6 @@ include $(top_srcdir)/storage/ndb/config/common.mk.am
dist-hook:
-rm -rf `find $(distdir) -type d -name SCCS`
-rm -rf `find $(distdir) -type d -name old_files`
-rm -rf `find $(distdir)/ndbapi-examples -name '*.o'`
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" != "." -a "$$subdir" != "include"; then \
......
CC=gcc
LD=$(CC)
SOURCES=memtest.c
OUTPUT=memtest
all:
$(CC) $(SOURCES) -o $(OUTPUT)
debug:
$(CC) -g $(SOURCES) -o $(OUTPUT)
clean: rm -rf *.o
rm -rf core*
include .defs.mk
TYPE := ndbapitest
BIN_TARGET := munmaptest
SOURCES = munmaptest.cpp
include $(NDB_TOP)/Epilogue.mk
include .defs.mk
TYPE :=
PIC_ARCHIVE := Y
ARCHIVE_TARGET := portlib
SOURCES = NdbOut.cpp
SOURCES.c = NdbCondition.c \
NdbMutex.c \
NdbSleep.c \
NdbTick.c \
NdbEnv.c \
NdbThread.c \
NdbHost.c \
NdbTCP.c
ifeq ($(NDB_OS), SOFTOSE)
SOURCES += NdbMem_SoftOse.cpp
else
SOURCES.c += NdbMem.c
endif
include $(NDB_TOP)/Epilogue.mk
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbCondition.h"
#include <pthread.h>
#include <sys/types.h>
#include <malloc.h>
#include <NdbMutex.h>
#include "NdbConditionOSE.h"
struct NdbCondition
{
PROCESS condserv_pid;
};
OS_PROCESS(ndbcond_serv){
union SIGNAL* sig;
union SIGNAL* sig2;
static const SIGSELECT sel_signal[] = {2, NDBCOND_SIGNAL, NDBCOND_BROADCAST};
static const SIGSELECT sel_cond[] = {2, NDBCOND_WAIT, NDBCOND_WAITTIMEOUT};
for(;;){
/* Receive condition wait signal */
sig = receive((SIGSELECT*)sel_cond);
if (sig != NIL){
switch (sig->sigNo){
case NDBCOND_WAIT:
/* Wait for a SIGNAL or BROADCAST from anyone */
sig2 = receive((SIGSELECT*)sel_signal);
if (sig2 != NIL){
switch(sig2->sigNo){
case NDBCOND_SIGNAL:
((struct NdbCondWait*)sig)->status = NDBCOND_SIGNALED;
/* Send signal back to the one waiting for this condition */
send(&sig, sender(&sig));
break;
case NDBCOND_BROADCAST:
/* Not handled yet */
assert(1==0);
break;
default:
assert(1==0);
break;
}
free_buf(&sig2);
}
break;
case NDBCOND_WAITTIMEOUT:
/* Wait for a SIGNAL or BROADCAST from anyone */
sig2 = receive_w_tmo(((struct NdbCondWaitTimeout*)sig)->timeout, (SIGSELECT*)sel_signal);
if (sig2 != NIL){
switch(sig2->sigNo){
case NDBCOND_SIGNAL:
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_SIGNALED;
/* Send signal back to the one waiting for this condition */
send(&sig, sender(&sig));
break;
case NDBCOND_BROADCAST:
/* Not handled yet */
assert(1==0);
break;
default:
assert(1==0);
break;
}
free_buf(&sig2);
}else{
((struct NdbCondWaitTimeout*)sig)->status = NDBCOND_TIMEOUT;
send(&sig, sender(&sig));
}
break;
default:
assert(1==0);
break;
}
}
}
}
struct NdbCondition*
NdbCondition_Create(void)
{
struct NdbCondition* tmpCond;
tmpCond = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
if (tmpCond == NULL)
return NULL;
/**
* Start this process with a quite high
* priority, we want it to be responsive
*/
tmpCond->condserv_pid = create_process(OS_PRI_PROC, /* Process type */
"ndbcond_serv", /* Name */
ndbcond_serv, /* Entry point */
2048, /* Stack size */
10, /* Priority */
0, /* Time slice */
get_bid(current_process()), /* Block */
NULL, /* Redir table */
0,
0);
start(tmpCond->condserv_pid);
return tmpCond;
}
int
NdbCondition_Wait(struct NdbCondition* p_cond,
NdbMutex* p_mutex)
{
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAIT};
union SIGNAL* sig;
int result;
if (p_cond == NULL || p_mutex == NULL)
return 0;
sig = alloc(sizeof(struct NdbCondWait), NDBCOND_WAIT);
send(&sig, p_cond->condserv_pid);
NdbMutex_Unlock(p_mutex);
result = 1;
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
if (sig != NIL){
if (sig->sigNo == NDBCOND_WAIT){
/* Condition is signaled */
result = 0;
}else{
assert(1==0);
}
free_buf(&sig);
}
NdbMutex_Lock(p_mutex);
return result;
}
int
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
NdbMutex* p_mutex,
int msecs){
static const SIGSELECT sel_cond[] = {1, NDBCOND_WAITTIMEOUT};
union SIGNAL* sig;
int result;
if (p_cond == NULL || p_mutex == NULL)
return 0;
sig = alloc(sizeof(struct NdbCondWaitTimeout), NDBCOND_WAITTIMEOUT);
((struct NdbCondWaitTimeout*)sig)->timeout = msecs;
send(&sig, p_cond->condserv_pid);
NdbMutex_Unlock(p_mutex);
result = 1;
while(NIL == (sig = receive_from((OSTIME)-1, (SIGSELECT*)sel_cond, p_cond->condserv_pid)));
if (sig != NIL){
if (sig->sigNo == NDBCOND_WAITTIMEOUT){
/* Condition is signaled */
result = 0;
}else{
assert(1==0);
}
free_buf(&sig);
}
NdbMutex_Lock(p_mutex);
return result;
}
int
NdbCondition_Signal(struct NdbCondition* p_cond){
union SIGNAL* sig;
if (p_cond == NULL)
return 1;
sig = alloc(sizeof(struct NdbCondSignal), NDBCOND_SIGNAL);
send(&sig, p_cond->condserv_pid);
return 0;
}
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
{
union SIGNAL* sig;
if (p_cond == NULL)
return 1;
sig = alloc(sizeof(struct NdbCondBroadcast), NDBCOND_BROADCAST);
send(&sig, p_cond->condserv_pid);
return 0;
}
int NdbCondition_Destroy(struct NdbCondition* p_cond)
{
if (p_cond == NULL)
return 1;
kill_proc(p_cond->condserv_pid);
free(p_cond);
return 0;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef NDB_CONDITIONOSE_H
#define NDB_CONDITIONOSE_H
#ifdef __cplusplus
extern "C" {
#endif
#define NDBCOND_SIGBASE 4000
#define NDBCOND_WAIT (NDBCOND_SIGBASE + 1) /* !-SIGNO(struct NdbCondWait)-! */
#define NDBCOND_WAITTIMEOUT (NDBCOND_SIGBASE + 2) /* !-SIGNO(struct NdbCondWaitTimeOut)-! */
#define NDBCOND_SIGNAL (NDBCOND_SIGBASE + 3) /* !-SIGNO(struct NdbCondSignal)-! */
#define NDBCOND_BROADCAST (NDBCOND_SIGBASE + 4) /* !-SIGNO(struct NdbCondBroadcast)-! */
const char *
sigNo2String(SIGSELECT sigNo){
switch(sigNo){
case NDBCOND_WAIT:
return "NDBCOND_WAIT";
break;
case NDBCOND_WAITTIMEOUT:
return "NDBCOND_WAITTIMEOUT";
break;
case NDBCOND_SIGNAL:
return "NDBCOND_SIGNAL";
break;
case NDBCOND_BROADCAST:
return "NDBCOND_BROADCAST";
break;
}
return "UNKNOWN";
}
struct NdbCondWait
{
SIGSELECT sigNo;
int status;
};
/**
* Signal received
*/
#define NDBCOND_SIGNALED 1
/**
* Timeout occured
*/
#define NDBCOND_TIMEOUT 2
struct NdbCondWaitTimeout
{
SIGSELECT sigNo;
int timeout;
int status;
};
struct NdbCondSignal
{
SIGSELECT sigNo;
};
struct NdbCondBroadcast
{
SIGSELECT sigNo;
};
union SIGNAL
{
SIGSELECT sigNo;
struct NdbCondWait condWait;
struct NdbCondWaitTimeout condWaitTimeout;
struct NdbCondSignal condSignal;
struct NdbCondBroadcast condBroadcast;
};
#ifdef __cplusplus
}
#endif
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbEnv.h"
#include <string.h>
#include <stdlib.h>
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
{
/**
* All environment variables are associated with a process
* it's important to read env from the correct process
* for now read from own process, own block and last the "ose_shell" process.
*
* TODO! What process should this be read from in the future?
*
*/
PROCESS proc_;
char* p = NULL;
/* Look in own process */
p = get_env(current_process(), (char*)name);
if (p == NULL){
/* Look in block process */
p = get_env(get_bid(current_process()), (char*)name);
if (p == NULL){
/* Look in ose_shell process */
if (hunt("ose_shell", 0, &proc_, NULL)){
p = get_env(proc_, (char*)name);
}
}
}
if (p != NULL){
strncpy(buf, p, buflen);
buf[buflen-1] = 0;
free_buf((union SIGNAL **)&p);
p = buf;
}
return p;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbHost.h"
#include <unistd.h>
#include <inet.sig>
#include <string.h>
union SIGNAL
{
SIGSELECT sigNo;
struct InetIfUp inetIfUp;
};
int NdbHost_GetHostName(char* buf)
{
#if 0
extern PROCESS ose_inet_;
union SIGNAL *signal;
static const SIGSELECT select_if_up_reply[] = { 1, INET_IF_UP_REPLY };
signal = alloc(sizeof(struct InetIfUp), INET_IF_UP_REQUEST);
strcpy(signal->inetIfUp.ifName, "*");
send((union SIGNAL **)&signal, ose_inet_);
signal = receive((SIGSELECT *)select_if_up_reply);
strcpy(buf, signal->inetIfUp.ifName);
free_buf(&signal);
return 0;
#else
return -1;
#endif
}
int NdbHost_GetProcessId(void)
{
return current_process();
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbMem.h"
#if defined NDB_OSE
#include <ose.h>
#include <mms.sig>
#include <mms_err.h>
#include <string.h>
#include <stdio.h>
#include <NdbOut.hpp>
// Page size for mp750 is 4096 bytes.
#define PAGE_SIZE 4096
/**
* NOTE: To use NdbMem from a OSE system ose_mms has to be defined
* as a "Required External Process"(see OSE Kernel User's Guide/R1.1(p. 148)),
* like this in osemain.con:
* EXT_PROC(ose_mms, ose_mms, 50000)
* This will create a global variable ose_mms_ that is used from here.
*/
union SIGNAL
{
SIGSELECT sigNo;
struct MmsAllocateRegionRequest mmsAllocateRegionRequest;
struct MmsAllocateRegionReply mmsAllocateRegionReply;
struct MmsFreeRegionRequest mmsFreeRegionRequest;
struct MmsFreeRegionReply mmsFreeRegionReply;
}; /* union SIGNAL */
extern PROCESS ose_mms_;
void NdbMem_Create(void)
{
/* Do nothing */
return;
}
void NdbMem_Destroy(void)
{
/* Do nothing */
return;
}
void* NdbMem_Allocate(size_t size)
{
static SIGSELECT allocate_sig[] = {1,MMS_ALLOCATE_REGION_REPLY};
union SIGNAL *sig;
U32 allocatedAdress;
assert(size > 0);
// Only allowed to allocate multiples of the page size.
if(size % PAGE_SIZE != 0) {
size += PAGE_SIZE - size%PAGE_SIZE;
}
/* Allocate a new region in the callers memory segment. */
sig = alloc(sizeof(struct MmsAllocateRegionRequest),
MMS_ALLOCATE_REGION_REQUEST);
/* -1: The callers domain is used */
sig->mmsAllocateRegionRequest.domain = (MemoryDomain)-1;
sig->mmsAllocateRegionRequest.useAddr = False;
sig->mmsAllocateRegionRequest.size = size;
sig->mmsAllocateRegionRequest.access = SuperRW_UserRW;
sig->mmsAllocateRegionRequest.resident = False;
sig->mmsAllocateRegionRequest.memory = CodeData;
sig->mmsAllocateRegionRequest.cache = CopyBack;
strcpy(sig->mmsAllocateRegionRequest.name, "NDB_DATA");
send(&sig, ose_mms_);
sig = receive(allocate_sig);
if (sig->mmsAllocateRegionReply.status != MMS_SUCCESS){
/* Memory allocation failed, make sure this function returns NULL */
allocatedAdress = NULL;
}
else{
allocatedAdress = sig->mmsAllocateRegionReply.address;
}
free_buf(&sig);
return (void*)allocatedAdress;
}
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
{
return NdbMem_Allocate(size);
}
void NdbMem_Free(void* ptr)
{
static SIGSELECT free_sig[] = {1,MMS_FREE_REGION_REPLY};
union SIGNAL *sig;
/* Free a region in the callers domain. */
sig = alloc(sizeof(struct MmsFreeRegionRequest),
MMS_FREE_REGION_REQUEST);
sig->mmsFreeRegionRequest.address = (U32)ptr;
send(&sig, ose_mms_);
sig = receive(free_sig);
if (sig->mmsFreeRegionReply.status != MMS_SUCCESS){
ndbout_c("The MMS Region could not be deallocated.\r\n");
error(sig->mmsFreeRegionReply.status);
};
free_buf(&sig);
}
int NdbMem_MemLockAll(){
return -1;
}
int NdbMem_MemUnlockAll(){
return -1;
}
#else
#include <stdlib.h>
void NdbMem_Create()
{
/* Do nothing */
return;
}
void NdbMem_Destroy()
{
/* Do nothing */
return;
}
void* NdbMem_Allocate(size_t size)
{
assert(size > 0);
return (void*)malloc(size);
}
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
{
/*
return (void*)memalign(alignment, size);
TEMP fix
*/
return (void*)malloc(size);
}
void NdbMem_Free(void* ptr)
{
free(ptr);
}
int NdbMem_MemLockAll(){
return -1;
}
int NdbMem_MemUnlockAll(){
return -1;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbMem.h"
extern "C"
void NdbMem_Create()
{
}
extern "C"
void NdbMem_Destroy()
{
}
extern "C"
void* NdbMem_Allocate(size_t size)
{
return new char[size];
}
extern "C"
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
{
return NdbMem_Allocate(size);
}
extern "C"
void NdbMem_Free(void* ptr)
{
delete [] (char *)(ptr);
}
int NdbMem_MemLockAll(){
return -1;
}
int NdbMem_MemUnlockAll(){
return -1;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbMutex.h"
#include <pthread.h>
#include <stdlib.h>
NdbMutex* NdbMutex_Create(void)
{
NdbMutex* pNdbMutex;
pNdbMutex = create_sem(1);
return pNdbMutex;
}
int NdbMutex_Destroy(NdbMutex* p_mutex)
{
if (p_mutex == NULL)
return -1;
kill_sem(p_mutex);
return 0;
}
int NdbMutex_Lock(NdbMutex* p_mutex)
{
if (p_mutex == NULL)
return -1;
wait_sem(p_mutex);
return 0;
}
int NdbMutex_Unlock(NdbMutex* p_mutex)
{
if (p_mutex == NULL)
return -1;
signal_sem(p_mutex);
return 0;
}
int NdbMutex_Trylock(NdbMutex* p_mutex)
{
int result = -1;
if (p_mutex != NULL) {
OSSEMVAL semvalue = get_sem(p_mutex);
if (semvalue > 0) {
wait_sem(p_mutex);
result = 0;
}
}
return result;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include "NdbOut.hpp"
#if defined NDB_SOFTOSE
#include <dbgprintf.h>
#define printfunc dbgprintf
#else
#define printfunc printf
#endif
static char const* const endlineString = "\r\n";
static int CtrlC = 0;
NdbOut ndbout;
NdbOut& NdbOut::operator<<(int aVal)
{
char* format;
char HexFormat[] = "0x%08x";
char DecFormat[] = "%d";
if (isHexFormat == 1)
format = HexFormat;
else
format = DecFormat;
printfunc(format, aVal);
return *this;
}
NdbOut& NdbOut::operator<<(char* pVal)
{
printfunc("%s", pVal);
return *this;
}
NdbOut& NdbOut::endline()
{
isHexFormat = 0; // Reset hex to normal, if user forgot this
printfunc(endlineString);
return *this;
}
NdbOut& NdbOut::flushline()
{
isHexFormat = 0; // Reset hex to normal, if user forgot this
return *this;
}
NdbOut& NdbOut::setHexFormat(int _format)
{
isHexFormat = _format;
return *this;
}
NdbOut::NdbOut()
{
CtrlC = 0;
isHexFormat = 0;
}
NdbOut::~NdbOut()
{
}
extern "C"
void
ndbout_c(const char * fmt, ...){
va_list ap;
char buf[1000];
va_start(ap, fmt);
if (fmt != 0)
vsnprintf(buf, sizeof(buf)-1, fmt, ap);
ndbout << buf << endl;
va_end(ap);
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbSleep.h"
#include <ose.h>
int
NdbSleep_MilliSleep(int milliseconds){
const OSTIME millisecond_delay = milliseconds;
delay(millisecond_delay);
return 0;
}
int
NdbSleep_SecSleep(int seconds){
const OSTIME millisecond_delay = seconds*1000;
delay(millisecond_delay);
return 0;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbTCP.h"
int
Ndb_getInAddr(struct in_addr * dst, const char *address) {
struct hostent * host;
host = gethostbyname_r(address);
if(host != 0){
dst->s_addr = ((struct in_addr *) *host->h_addr_list)->s_addr;
free_buf((union SIGNAL **)&host);
return 0;
}
/* Try it as aaa.bbb.ccc.ddd. */
dst->s_addr = inet_addr(address);
if (dst->s_addr != INADDR_NONE) {
return 0;
}
return -1;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbThread.h"
#include <pthread.h>
#include <malloc.h>
#include <string.h>
#include <NdbOut.hpp>
#define MAX_THREAD_NAME 16
struct NdbThread
{
PROCESS pid;
char thread_name[MAX_THREAD_NAME];
};
#define NDBTHREAD_SIGBASE 4010
#define NDBTHREAD_START (NDBTHREAD_SIGBASE + 1) /* !-SIGNO(struct NdbThreadStart)-! */
struct NdbThreadStart
{
SIGSELECT sigNo;
NDB_THREAD_FUNC* func;
NDB_THREAD_ARG arg;
};
struct NdbThreadStopped
{
SIGSELECT sigNo;
};
union SIGNAL
{
SIGSELECT sigNo;
struct NdbThreadStart threadStart;
struct NdbThreadStopped threadStopped;
};
OS_PROCESS(thread_starter){
static const SIGSELECT sel_start[] = {1, NDBTHREAD_START};
struct NdbThreadStart* sigstart;
union SIGNAL* sig;
/* Receive function adress and params */
sig = receive((SIGSELECT*)sel_start);
if (sig != NIL){
if (sig->sigNo == NDBTHREAD_START){
sigstart = ((struct NdbThreadStart*)sig);
/* Execute function with arg */
(*sigstart->func)(sigstart->arg);
}else{
assert(1==0);
}
free_buf(&sig);
}
}
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC* p_thread_func,
NDB_THREAD_ARG *p_thread_arg,
const NDB_THREAD_STACKSIZE thread_stack_size,
const char* p_thread_name,
NDB_THREAD_PRIO thread_prio)
{
struct NdbThread* tmpThread;
union SIGNAL* sig;
int ose_prio;
if (p_thread_func == NULL)
return 0;
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
if (tmpThread == NULL)
return NULL;
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
switch(thread_prio){
case NDB_THREAD_PRIO_HIGHEST:
ose_prio = 1;
break;
case NDB_THREAD_PRIO_HIGH:
ose_prio = 10;
break;
case NDB_THREAD_PRIO_MEAN:
ose_prio = 16;
break;
case NDB_THREAD_PRIO_LOW:
ose_prio = 23;
break;
case NDB_THREAD_PRIO_LOWEST:
ose_prio = 31;
break;
default:
return NULL;
break;
}
/* Create process */
tmpThread->pid = create_process(OS_PRI_PROC, /* Process type */
(char*)p_thread_name, /* Name */
thread_starter, /* Entry point */
thread_stack_size, /* Stack size */
ose_prio, /* Priority */
0, /* Time slice */
get_bid(current_process()), /* Block */
NULL, /* Redir table */
0,
0);
/* Send params to process */
sig = alloc(sizeof(struct NdbThreadStart), NDBTHREAD_START);
((struct NdbThreadStart*)sig)->func = p_thread_func;
((struct NdbThreadStart*)sig)->arg = p_thread_arg;
send(&sig, tmpThread->pid);
/* Enable NDB_HOME environment variable for the thread */
{
/* Hardcoded NDB_HOME...*/
char* ndb_home_env = get_env(current_process(), "NDB_HOME");
if (ndb_home_env != NULL)
{
/* Set NDB_HOME */
int rc = set_env(tmpThread->pid, "NDB_HOME", ndb_home_env);
if (rc != 0)
{
/* Not really a problem */
}
} /* Enable NDB_HOME */
}
/* Start process */
start(tmpThread->pid);
return tmpThread;
}
void NdbThread_Destroy(struct NdbThread** p_thread)
{
free(* p_thread); * p_thread = 0;
}
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
{
while(hunt(p_wait_thread->thread_name, 0, NULL, NULL) != 0)
delay(1000);
* status = 0;
return 0;
}
void NdbThread_Exit(int a)
{
kill_proc(current_process());
}
int NdbThread_SetConcurrencyLevel(int level)
{
return 0;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbTick.h"
#include <time.h>
#define NANOSEC_PER_SEC 1000000000
#define MICROSEC_PER_SEC 1000000
#define MILLISEC_PER_SEC 1000
#define MICROSEC_PER_MILLISEC 1000
#define MILLISEC_PER_NANOSEC 1000000
#ifdef NDB_OSE
NDB_TICKS NdbTick_CurrentMillisecond(void)
{
return get_ticks()*4;
}
#include <rtc.h>
int
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
struct TimePair tvp;
rtc_get_time(&tvp);
* secs = tvp.seconds;
* micros = tvp.micros;
return 0;
}
#endif
#if defined NDB_SOFTOSE
NDB_TICKS NdbTick_CurrentMillisecond(void)
{
/**
* Depends on the interval counter in solaris
* that means each "tick" in OSE is really 10 milliseconds
*/
return get_ticks()*10;
}
#include <rtc.h>
int
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros){
struct TimePair tvp;
rtc_get_time(&tvp);
* secs = tvp.seconds;
* micros = tvp.micros;
return 0;
}
#endif
include .defs.mk
TYPE := kernel
BIN_TARGET := PortLibTest
BIN_TARGET_ARCHIVES := portlib general
SOURCES = NdbPortLibTest.cpp
include $(NDB_TOP)/Epilogue.mk
include .defs.mk
TYPE := util
PIC_ARCHIVE := Y
ARCHIVE_TARGET := portlib
SOURCES.c = NdbCondition.c \
NdbMutex.c \
NdbSleep.c \
NdbTick.c \
NdbEnv.c \
NdbThread.c \
NdbHost.c \
NdbTCP.c \
NdbDaemon.c
ifeq ($(NDB_OS), SOFTOSE)
SOURCES += NdbMem_SoftOse.cpp
else
SOURCES.c += NdbMem.c
endif
include $(NDB_TOP)/Epilogue.mk
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <sys/types.h>
#include "NdbCondition.h"
#include <NdbMutex.h>
struct NdbCondition
{
long nWaiters;
NdbMutex* pNdbMutexWaitersLock;
HANDLE hSemaphore;
HANDLE hEventWaitersDone;
int bWasBroadcast;
};
struct NdbCondition*
NdbCondition_Create(void)
{
int result = 0;
struct NdbCondition* pNdbCondition = (struct NdbCondition*)malloc(sizeof(struct NdbCondition));
if(!pNdbCondition)
return 0;
pNdbCondition->nWaiters = 0;
pNdbCondition->bWasBroadcast = 0;
if(!(pNdbCondition->hSemaphore = CreateSemaphore(0, 0, MAXLONG, 0)))
result = -1;
else if(!(pNdbCondition->pNdbMutexWaitersLock = NdbMutex_Create()))
result = -1;
else if(!(pNdbCondition->hEventWaitersDone = CreateEvent(0, 0, 0, 0)))
result = -1;
assert(!result);
return pNdbCondition;
}
int
NdbCondition_Wait(struct NdbCondition* p_cond,
NdbMutex* p_mutex)
{
int result;
int bLastWaiter;
if(!p_cond || !p_mutex)
return 1;
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
p_cond->nWaiters++;
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(NdbMutex_Unlock(p_mutex))
return -1;
result = WaitForSingleObject (p_cond->hSemaphore, INFINITE);
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
p_cond->nWaiters--;
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(result==WAIT_OBJECT_0 && bLastWaiter)
SetEvent(p_cond->hEventWaitersDone);
NdbMutex_Lock(p_mutex);
return result;
}
int
NdbCondition_WaitTimeout(struct NdbCondition* p_cond,
NdbMutex* p_mutex,
int msecs)
{
int result;
int bLastWaiter;
if (!p_cond || !p_mutex)
return 1;
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
p_cond->nWaiters++;
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(msecs<0)
msecs = 0;
if(NdbMutex_Unlock(p_mutex))
return -1;
result = WaitForSingleObject(p_cond->hSemaphore, msecs);
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
p_cond->nWaiters--;
bLastWaiter = (p_cond->bWasBroadcast && p_cond->nWaiters==0);
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(result!=WAIT_OBJECT_0)
result = -1;
if(bLastWaiter)
SetEvent(p_cond->hEventWaitersDone);
NdbMutex_Lock(p_mutex);
return result;
}
int
NdbCondition_Signal(struct NdbCondition* p_cond)
{
int bHaveWaiters;
if(!p_cond)
return 1;
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
bHaveWaiters = (p_cond->nWaiters > 0);
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(bHaveWaiters)
return (ReleaseSemaphore(p_cond->hSemaphore, 1, 0) ? 0 : -1);
else
return 0;
}
int NdbCondition_Broadcast(struct NdbCondition* p_cond)
{
int bHaveWaiters;
int result = 0;
if(!p_cond)
return 1;
NdbMutex_Lock(p_cond->pNdbMutexWaitersLock);
bHaveWaiters = 0;
if(p_cond->nWaiters > 0)
{
p_cond->bWasBroadcast = !0;
bHaveWaiters = 1;
}
NdbMutex_Unlock(p_cond->pNdbMutexWaitersLock);
if(bHaveWaiters)
{
if(!ReleaseSemaphore(p_cond->hSemaphore, p_cond->nWaiters, 0))
result = -1;
else if(WaitForSingleObject (p_cond->hEventWaitersDone, INFINITE) != WAIT_OBJECT_0)
result = -1;
p_cond->bWasBroadcast = 0;
}
return result;
}
int NdbCondition_Destroy(struct NdbCondition* p_cond)
{
int result;
if(!p_cond)
return 1;
CloseHandle(p_cond->hEventWaitersDone);
NdbMutex_Destroy(p_cond->pNdbMutexWaitersLock);
result = (CloseHandle(p_cond->hSemaphore) ? 0 : -1);
free(p_cond);
return 0;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
#include "NdbDaemon.h"
#define NdbDaemon_ErrorSize 500
long NdbDaemon_DaemonPid;
int NdbDaemon_ErrorCode;
char NdbDaemon_ErrorText[NdbDaemon_ErrorSize];
int
NdbDaemon_Make(const char* lockfile, const char* logfile, unsigned flags)
{
/* Fail */
snprintf(NdbDaemon_ErrorText, NdbDaemon_ErrorSize,
"Daemon mode not implemented");
return -1;
}
#ifdef NDB_DAEMON_TEST
int
main()
{
if (NdbDaemon_Make("test.pid", "test.log", 0) == -1) {
fprintf(stderr, "NdbDaemon_Make: %s\n", NdbDaemon_ErrorText);
return 1;
}
sleep(10);
return 0;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbEnv.h"
#include <string.h>
#include <stdlib.h>
const char* NdbEnv_GetEnv(const char* name, char * buf, int buflen)
{
char* p = NULL;
p = getenv(name);
if (p != NULL && buf != NULL){
strncpy(buf, p, buflen);
buf[buflen-1] = 0;
}
return p;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbHost.h"
#include <windows.h>
#include <process.h>
int NdbHost_GetHostName(char* buf)
{
/* We must initialize TCP/IP if we want to call gethostname */
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/**
* Tell the user that we couldn't find a usable
* WinSock DLL.
*/
return -1;
}
/* Get host name */
if(gethostname(buf, MAXHOSTNAMELEN))
{
return -1;
}
return 0;
}
int NdbHost_GetProcessId(void)
{
return _getpid();
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <windows.h>
#include "NdbMem.h"
struct AWEINFO
{
SIZE_T dwSizeInBytesRequested;
ULONG_PTR nNumberOfPagesRequested;
ULONG_PTR nNumberOfPagesActual;
ULONG_PTR nNumberOfPagesFreed;
ULONG_PTR* pnPhysicalMemoryPageArray;
void* pRegionReserved;
};
const size_t cNdbMem_nMaxAWEinfo = 256;
size_t gNdbMem_nAWEinfo = 0;
struct AWEINFO* gNdbMem_pAWEinfo = 0;
void ShowLastError(const char* szContext, const char* szFunction)
{
DWORD dwError = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
printf("%s : %s failed : %lu : %s\n", szContext, szFunction, dwError, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
}
void NdbMem_Create()
{
// Address Windowing Extensions
struct PRIVINFO
{
DWORD Count;
LUID_AND_ATTRIBUTES Privilege[1];
} Info;
HANDLE hProcess = GetCurrentProcess();
HANDLE hToken;
if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
{
ShowLastError("NdbMem_Create", "OpenProcessToken");
}
Info.Count = 1;
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &(Info.Privilege[0].Luid)))
{
ShowLastError("NdbMem_Create", "LookupPrivilegeValue");
}
if(!AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&Info, 0, 0, 0))
{
ShowLastError("NdbMem_Create", "AdjustTokenPrivileges");
}
if(!CloseHandle(hToken))
{
ShowLastError("NdbMem_Create", "CloseHandle");
}
return;
}
void NdbMem_Destroy()
{
/* Do nothing */
return;
}
void* NdbMem_Allocate(size_t size)
{
// Address Windowing Extensions
struct AWEINFO* pAWEinfo;
HANDLE hProcess;
SYSTEM_INFO sysinfo;
if(!gNdbMem_pAWEinfo)
{
gNdbMem_pAWEinfo = VirtualAlloc(0,
sizeof(struct AWEINFO)*cNdbMem_nMaxAWEinfo,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
}
assert(gNdbMem_nAWEinfo < cNdbMem_nMaxAWEinfo);
pAWEinfo = gNdbMem_pAWEinfo+gNdbMem_nAWEinfo++;
hProcess = GetCurrentProcess();
GetSystemInfo(&sysinfo);
pAWEinfo->nNumberOfPagesRequested = (size+sysinfo.dwPageSize-1)/sysinfo.dwPageSize;
pAWEinfo->pnPhysicalMemoryPageArray = VirtualAlloc(0,
sizeof(ULONG_PTR)*pAWEinfo->nNumberOfPagesRequested,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
pAWEinfo->nNumberOfPagesActual = pAWEinfo->nNumberOfPagesRequested;
if(!AllocateUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesActual), pAWEinfo->pnPhysicalMemoryPageArray))
{
ShowLastError("NdbMem_Allocate", "AllocateUserPhysicalPages");
return 0;
}
if(pAWEinfo->nNumberOfPagesRequested != pAWEinfo->nNumberOfPagesActual)
{
ShowLastError("NdbMem_Allocate", "nNumberOfPagesRequested != nNumberOfPagesActual");
return 0;
}
pAWEinfo->dwSizeInBytesRequested = size;
pAWEinfo->pRegionReserved = VirtualAlloc(0, pAWEinfo->dwSizeInBytesRequested, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE);
if(!pAWEinfo->pRegionReserved)
{
ShowLastError("NdbMem_Allocate", "VirtualAlloc");
return 0;
}
if(!MapUserPhysicalPages(pAWEinfo->pRegionReserved, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pnPhysicalMemoryPageArray))
{
ShowLastError("NdbMem_Allocate", "MapUserPhysicalPages");
return 0;
}
/*
printf("allocate AWE memory: %lu bytes, %lu pages, address %lx\n",
pAWEinfo->dwSizeInBytesRequested,
pAWEinfo->nNumberOfPagesActual,
pAWEinfo->pRegionReserved);
*/
return pAWEinfo->pRegionReserved;
}
void* NdbMem_AllocateAlign(size_t size, size_t alignment)
{
/*
return (void*)memalign(alignment, size);
TEMP fix
*/
return NdbMem_Allocate(size);
}
void NdbMem_Free(void* ptr)
{
// VirtualFree(ptr, 0, MEM_DECOMMIT|MEM_RELEASE);
// Address Windowing Extensions
struct AWEINFO* pAWEinfo = 0;
size_t i;
HANDLE hProcess;
for(i=0; i<gNdbMem_nAWEinfo; ++i)
{
if(ptr==gNdbMem_pAWEinfo[i].pRegionReserved)
{
pAWEinfo = gNdbMem_pAWEinfo+i;
}
}
if(!pAWEinfo)
{
ShowLastError("NdbMem_Free", "ptr is not AWE memory");
}
hProcess = GetCurrentProcess();
if(!MapUserPhysicalPages(ptr, pAWEinfo->nNumberOfPagesActual, 0))
{
ShowLastError("NdbMem_Free", "MapUserPhysicalPages");
}
if(!VirtualFree(ptr, 0, MEM_RELEASE))
{
ShowLastError("NdbMem_Free", "VirtualFree");
}
pAWEinfo->nNumberOfPagesFreed = pAWEinfo->nNumberOfPagesActual;
if(!FreeUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesFreed), pAWEinfo->pnPhysicalMemoryPageArray))
{
ShowLastError("NdbMem_Free", "FreeUserPhysicalPages");
}
VirtualFree(pAWEinfo->pnPhysicalMemoryPageArray, 0, MEM_DECOMMIT|MEM_RELEASE);
}
int NdbMem_MemLockAll()
{
/*
HANDLE hProcess = GetCurrentProcess();
SIZE_T nMinimumWorkingSetSize;
SIZE_T nMaximumWorkingSetSize;
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
SetProcessWorkingSetSize(hProcess, 50000000, 100000000);
GetProcessWorkingSetSize(hProcess, &nMinimumWorkingSetSize, &nMaximumWorkingSetSize);
ndbout << "nMinimumWorkingSetSize=" << nMinimumWorkingSetSize << ", nMaximumWorkingSetSize=" << nMaximumWorkingSetSize << endl;
*/
return -1;
}
int NdbMem_MemUnlockAll()
{
//VirtualUnlock();
return -1;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <time.h>
#include "NdbMutex.h"
NdbMutex* NdbMutex_Create(void)
{
NdbMutex* pNdbMutex = (NdbMutex*)malloc(sizeof(NdbMutex));
if(!pNdbMutex)
return 0;
InitializeCriticalSection(pNdbMutex);
return pNdbMutex;
}
int NdbMutex_Destroy(NdbMutex* p_mutex)
{
if(!p_mutex)
return -1;
DeleteCriticalSection(p_mutex);
free(p_mutex);
return 0;
}
int NdbMutex_Lock(NdbMutex* p_mutex)
{
if(!p_mutex)
return -1;
EnterCriticalSection (p_mutex);
return 0;
}
int NdbMutex_Unlock(NdbMutex* p_mutex)
{
if(!p_mutex)
return -1;
LeaveCriticalSection(p_mutex);
return 0;
}
int NdbMutex_Trylock(NdbMutex* p_mutex)
{
int result = -1;
if(p_mutex)
{
result = (TryEnterCriticalSection(p_mutex) ? 0 : -1);
}
return result;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbSleep.h"
#include <windows.h>
int
NdbSleep_MilliSleep(int milliseconds)
{
Sleep(milliseconds);
return 0;
}
int
NdbSleep_SecSleep(int seconds)
{
return NdbSleep_MilliSleep(seconds*1000);
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "NdbTCP.h"
int
Ndb_getInAddr(struct in_addr * dst, const char *address)
{
struct hostent * hostPtr;
/* Try it as aaa.bbb.ccc.ddd. */
dst->s_addr = inet_addr(address);
if (dst->s_addr != -1) {
return 0;
}
hostPtr = gethostbyname(address);
if (hostPtr != NULL) {
dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr;
return 0;
}
return -1;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <windows.h>
#include <process.h>
#include "NdbThread.h"
#define MAX_THREAD_NAME 16
typedef unsigned (WINAPI* NDB_WIN32_THREAD_FUNC)(void*);
struct NdbThread
{
HANDLE hThread;
unsigned nThreadId;
char thread_name[MAX_THREAD_NAME];
};
struct NdbThread* NdbThread_Create(NDB_THREAD_FUNC *p_thread_func,
NDB_THREAD_ARG *p_thread_arg,
const NDB_THREAD_STACKSIZE thread_stack_size,
const char* p_thread_name,
NDB_THREAD_PRIO thread_prio)
{
struct NdbThread* tmpThread;
unsigned initflag;
int nPriority = 0;
if(!p_thread_func)
return 0;
tmpThread = (struct NdbThread*)malloc(sizeof(struct NdbThread));
if(!tmpThread)
return 0;
strncpy((char*)&tmpThread->thread_name, p_thread_name, MAX_THREAD_NAME);
switch(thread_prio)
{
case NDB_THREAD_PRIO_HIGHEST: nPriority=THREAD_PRIORITY_HIGHEST; break;
case NDB_THREAD_PRIO_HIGH: nPriority=THREAD_PRIORITY_ABOVE_NORMAL; break;
case NDB_THREAD_PRIO_MEAN: nPriority=THREAD_PRIORITY_NORMAL; break;
case NDB_THREAD_PRIO_LOW: nPriority=THREAD_PRIORITY_BELOW_NORMAL; break;
case NDB_THREAD_PRIO_LOWEST: nPriority=THREAD_PRIORITY_LOWEST; break;
}
initflag = (nPriority ? CREATE_SUSPENDED : 0);
tmpThread->hThread = (HANDLE)_beginthreadex(0, thread_stack_size,
(NDB_WIN32_THREAD_FUNC)p_thread_func, p_thread_arg,
initflag, &tmpThread->nThreadId);
if(nPriority && tmpThread->hThread)
{
SetThreadPriority(tmpThread->hThread, nPriority);
ResumeThread (tmpThread->hThread);
}
assert(tmpThread->hThread);
return tmpThread;
}
void NdbThread_Destroy(struct NdbThread** p_thread)
{
CloseHandle((*p_thread)->hThread);
(*p_thread)->hThread = 0;
free(*p_thread);
*p_thread = 0;
}
int NdbThread_WaitFor(struct NdbThread* p_wait_thread, void** status)
{
void *local_status = 0;
if (status == 0)
status = &local_status;
if(WaitForSingleObject(p_wait_thread->hThread, INFINITE) == WAIT_OBJECT_0
&& GetExitCodeThread(p_wait_thread->hThread, (LPDWORD)status))
{
CloseHandle(p_wait_thread->hThread);
p_wait_thread->hThread = 0;
return 0;
}
return -1;
}
void NdbThread_Exit(int status)
{
_endthreadex((DWORD) status);
}
int NdbThread_SetConcurrencyLevel(int level)
{
return 0;
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <windows.h>
#include "NdbTick.h"
/*
#define FILETIME_PER_MICROSEC 10
#define FILETIME_PER_MILLISEC 10000
#define FILETIME_PER_SEC 10000000
NDB_TICKS NdbTick_CurrentMillisecond(void)
{
ULONGLONG ullTime;
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
return (ullTime / FILETIME_PER_MILLISEC);
}
int
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
{
ULONGLONG ullTime;
GetSystemTimeAsFileTime((LPFILETIME)&ullTime);
*secs = (ullTime / FILETIME_PER_SEC);
*micros = (Uint32)((ullTime % FILETIME_PER_SEC) / FILETIME_PER_MICROSEC);
return 0;
}
*/
NDB_TICKS NdbTick_CurrentMillisecond(void)
{
LARGE_INTEGER liCount, liFreq;
QueryPerformanceCounter(&liCount);
QueryPerformanceFrequency(&liFreq);
return (liCount.QuadPart*1000) / liFreq.QuadPart;
}
int
NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros)
{
LARGE_INTEGER liCount, liFreq;
QueryPerformanceCounter(&liCount);
QueryPerformanceFrequency(&liFreq);
*secs = liCount.QuadPart / liFreq.QuadPart;
liCount.QuadPart -= *secs * liFreq.QuadPart;
*micros = (liCount.QuadPart*1000000) / liFreq.QuadPart;
return 0;
}
include .defs.mk
DIRS =
ifneq ($(NDB_ODBC),N)
DIRS += odbc
endif
include $(NDB_TOP)/Epilogue.mk
# before Epilogue.mk
CCFLAGS_LOC += -I..
CCFLAGS_LOC += \
-I$(call fixpath,$(NDB_TOP)/include/ndbapi) \
-I$(call fixpath,$(NDB_TOP)/include/util) \
-I$(call fixpath,$(NDB_TOP)/include/portlib)
ifeq ($(NDB_OS),SOLARIS)
CCFLAGS_LOC += -I/usr/local/include
ifeq ($(NDB_COMPILER),GCC)
LIBS_LOC += -Wl,-z,text
CCFLAGS_WARNINGS += -Wno-unused -Wformat
CCFLAGS_TOP += -D__STL_PTHREADS
endif
ifeq ($(NDB_COMPILER),FORTE6)
LIBS_LOC += -z text
LIBS_SPEC += /usr/lib/libCrun.so.1
endif
LIB_TARGET_LIBS += -lthread -lrt
endif
ifneq ($(filter $(NDB_OS), LINUX MACOSX IBMAIX TRU64X),)
LIBS_LOC += -Wl,-z,text
CCFLAGS_WARNINGS += -Wno-unused -Wformat
GCC_VER := $(shell $(CC) --version)
ifeq ($(GCC_VER),2.96)
CCFLAGS_TOP += -D__STL_PTHREADS
CCFLAGS_TOP += -fmessage-length=0
endif
CCFLAGS_TOP += -fno-rtti
LIB_TARGET_LIBS += -lpthread
endif
ifeq ($(NDB_OS),WIN32)
ifeq (RELEASE, $(NDB_VERSION))
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
else
ifeq (RELEASE_TRACE, $(NDB_VERSION))
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
else
CCFLAGS_WIN += /MT /GR /GS /Zi -D_WINDOWS -D_USRDLL -DNDBODBC_EXPORTS -DNO_COMMAND_HANDLER -D_MBCS -D_WINDLL -U_LIB
endif
endif
endif
CCFLAGS_TOP += -DYYDEBUG=0 -fexceptions
CCFLAGS_TOP += -DHAVE_LONG_LONG
include .defs.mk
TYPE = *
A_LIB = N
PIC_LIB = Y
SO_LIB = Y
LIB_TARGET = NDB_ODBC
LIB_TARGET_ARCHIVES = $(LIB_DIRS:%=odbc%) NDB_API
# Overide Defs.mk
LDFLAGS_LAST = -lstdc++ -lm
XXX = \
ndbapi \
mgmsrvcommon \
transporter \
general \
signaldataprint \
portlib \
logger \
trace
ifeq ($(NDB_OS),WIN32)
LIB_DIRS = \
handles \
dictionary \
codegen \
executor \
common
SOURCES += NdbOdbc.cpp
CFLAGS_NdbOdbc.cpp += -I. -I$(call fixpath,driver)
PIC_ARCHIVE := Y
NONPIC_ARCHIVE := N
ARCHIVE_TARGET := ndb_odbcwin32
LIB_TARGET_ARCHIVES += ndb_odbcwin32
ifeq (RELEASE, $(NDB_VERSION))
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
else
ifeq (RELEASE_TRACE, $(NDB_VERSION))
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL:NO /DLL /SUBSYSTEM:WINDOWS /MACHINE:IX86 /OPT:REF /OPT:ICF /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
else
WIN_LIBS += /VERSION:2.0x /NODEFAULTLIB:"odbc32" /INCREMENTAL /DLL /DEBUG /SUBSYSTEM:WINDOWS /MACHINE:IX86 /DEF:NdbOdbc.def odbc32.lib odbccp32.lib user32.lib
endif
endif
else
LIB_DIRS = \
driver \
handles \
dictionary \
codegen \
executor \
common
endif
include Extra.mk
include $(NDB_TOP)/Epilogue.mk
# yo
test:
$(MAKE) -j4
$(MAKE) -C $(NDB_TOP)/tools/ndbsql
$(MAKE) -C $(NDB_TOP)/test/odbc/driver tidy
$(MAKE) -C $(NDB_TOP)/test/odbc/driver
$(MAKE) -C $(NDB_TOP)/test/ndbapi/testOIBasic
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <NdbUnistd.h>
#include <odbcinst.h>
#include "driver.cpp"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL INSTAPI ConfigDSN(
HWND hwndParent,
WORD fRequest,
LPCSTR lpszDriver,
LPCSTR lpszAttributes)
{
const char* szDSN = "NDB";
switch(fRequest)
{
case ODBC_ADD_DSN:
SQLWriteDSNToIni(szDSN, lpszDriver);
break;
case ODBC_CONFIG_DSN:
break;
case ODBC_REMOVE_DSN:
SQLRemoveDSNFromIni(szDSN);
break;
}
return TRUE;
}
int FAR PASCAL
DriverConnectProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam)
{
return FALSE;
}
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void);
/* Entry point to cause DM to load using ordinals */
void __declspec( dllexport) FAR PASCAL LoadByOrdinal(void)
{
}
LIBRARY NdbOdbc.DLL
VERSION 03.51.00
EXPORTS
SQLAllocConnect
SQLAllocEnv
SQLAllocHandle
SQLAllocHandleStd
SQLAllocStmt
SQLBindCol
SQLBindParam
SQLBindParameter
SQLBrowseConnect
SQLBulkOperations
SQLCancel
SQLCloseCursor
SQLColAttribute
SQLColAttributes
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLCopyDesc
SQLDataSources
SQLDescribeCol
SQLDescribeParam
SQLDisconnect
SQLDriverConnect
SQLDrivers
SQLEndTran
SQLError
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLFreeConnect
SQLFreeEnv
SQLFreeHandle
SQLFreeStmt
SQLGetConnectAttr
SQLGetConnectOption
SQLGetCursorName
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLGetDiagField
SQLGetDiagRec
SQLGetEnvAttr
SQLGetFunctions
SQLGetInfo
SQLGetStmtAttr
SQLGetStmtOption
SQLGetTypeInfo
SQLMoreResults
SQLNativeSql
SQLNumParams
SQLNumResultCols
SQLParamData
SQLParamOptions
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLRowCount
SQLSetConnectAttr
SQLSetConnectOption
SQLSetCursorName
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetParam
SQLSetPos
SQLSetScrollOptions
SQLSetStmtAttr
SQLSetStmtOption
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLTransact
DllMain
DriverConnectProc
ConfigDSN
LoadByOrdinal
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <common/StmtArea.hpp>
#include <common/CodeTree.hpp>
#include <executor/Executor.hpp>
#include "CodeGen.hpp"
#include "Code_root.hpp"
#include <FlexLexer.h>
#include "SimpleParser.hpp"
void
CodeGen::prepare(Ctx& ctx)
{
parse(ctx);
if (! ctx.ok())
return;
analyze(ctx);
if (! ctx.ok())
return;
describe(ctx);
}
void
CodeGen::execute(Ctx& ctx)
{
DescArea& ipd = m_stmtArea.descArea(Desc_usage_IPD);
if (m_stmtArea.m_unbound) {
analyze(ctx);
if (! ctx.ok())
return;
describe(ctx);
if (! ctx.ok())
return;
if (m_stmtArea.m_unbound) {
ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "%u input parameters have unbound SQL type", m_stmtArea.m_unbound);
return;
}
ipd.setBound(true);
}
if (! ipd.isBound()) {
ctx_log2(("IPD changed between executes - reanalyze"));
// jdbc can change parameter length at each execute
analyze(ctx);
if (! ctx.ok())
return;
describe(ctx);
if (! ctx.ok())
return;
freeExec(ctx);
codegen(ctx);
if (! ctx.ok())
return;
alloc(ctx);
if (! ctx.ok())
return;
ipd.setBound(true);
}
if (m_stmtArea.m_execTree == 0) {
codegen(ctx);
if (! ctx.ok())
return;
alloc(ctx);
if (! ctx.ok())
return;
}
Executor executor(m_stmtArea);
executor.execute(ctx);
}
void
CodeGen::fetch(Ctx& ctx)
{
// XXX parameter types are not checked any more
ctx_assert(! m_stmtArea.m_unbound);
Executor executor(m_stmtArea);
executor.fetch(ctx);
}
void
CodeGen::parse(Ctx& ctx)
{
Plan_root* planRoot = new Plan_root(m_stmtArea);
SimpleParser simpleParser(ctx, m_stmtArea, planRoot);
simpleParser.yyparse();
if (! ctx.ok())
return;
planRoot->m_paramList.resize(1 + simpleParser.paramNumber());
ctx_log2(("CodeGen: parse done - plan tree follows"));
if (ctx.logLevel() >= 2)
planRoot->print(ctx);
m_stmtArea.m_planTree = planRoot;
}
void
CodeGen::analyze(Ctx& ctx)
{
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
ctx_assert(planRoot != 0);
Plan_base::Ctl ctl(0);
planRoot->analyze(ctx, ctl); // returns itself
if (! ctx.ok())
return;
ctx_log2(("CodeGen: analyze done - plan tree follows"));
if (ctx.logLevel() >= 2)
planRoot->print(ctx);
}
void
CodeGen::describe(Ctx& ctx)
{
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
ctx_assert(planRoot != 0);
planRoot->describe(ctx);
ctx_log2(("CodeGen: describe done"));
}
void
CodeGen::codegen(Ctx& ctx)
{
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
ctx_assert(planRoot != 0);
Plan_base::Ctl ctl(0);
Exec_root* execRoot = static_cast<Exec_root*>(planRoot->codegen(ctx, ctl));
if (! ctx.ok())
return;
ctx_assert(execRoot != 0);
ctx_log2(("CodeGen: codegen done - code tree follows"));
if (ctx.logLevel() >= 2)
execRoot->print(ctx);
m_stmtArea.m_execTree = execRoot;
}
void
CodeGen::alloc(Ctx& ctx)
{
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
ctx_assert(execRoot != 0);
Exec_base::Ctl ctl(0);
execRoot->alloc(ctx, ctl);
if (! ctx.ok())
return;
ctx_log2(("CodeGen: alloc done"));
}
void
CodeGen::close(Ctx& ctx)
{
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
if (execRoot != 0) {
execRoot->close(ctx);
ctx_log2(("CodeGen: close done"));
}
}
void
CodeGen::free(Ctx& ctx)
{
freePlan(ctx);
freeExec(ctx);
}
void
CodeGen::freePlan(Ctx & ctx)
{
if (m_stmtArea.m_planTree != 0) {
Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
ctx_assert(planRoot != 0);
unsigned count = 1 + planRoot->m_nodeList.size();
planRoot->freeNodeList();
delete planRoot;
m_stmtArea.m_planTree = 0;
ctx_log3(("CodeGen: freed %u plan tree nodes", count));
}
}
void
CodeGen::freeExec(Ctx & ctx)
{
if (m_stmtArea.m_execTree != 0) {
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
ctx_assert(execRoot != 0);
unsigned count = 1 + execRoot->m_nodeList.size();
execRoot->freeNodeList();
delete execRoot;
m_stmtArea.m_execTree = 0;
ctx_log3(("CodeGen: freed %u exec tree nodes", count));
}
}
// odbc support
void
CodeGen::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
{
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
ctx_assert(execRoot != 0);
execRoot->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind);
}
void
CodeGen::sqlParamData(Ctx& ctx, SQLPOINTER* value)
{
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
ctx_assert(execRoot != 0);
execRoot->sqlParamData(ctx, value);
}
void
CodeGen::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind)
{
Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
ctx_assert(execRoot != 0);
execRoot->sqlPutData(ctx, data, strlen_or_Ind);
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_CodeGen_hpp
#define ODBC_CODEGEN_CodeGen_hpp
#include <common/common.hpp>
class StmtArea;
class SqlField;
class ExtField;
/**
* @class CodeGen
* @brief Compiles SQL text into ExecTree::Code
*/
class CodeGen {
public:
CodeGen(StmtArea& stmtArea);
~CodeGen();
// parse and analyze SQL statement
void prepare(Ctx& ctx);
// these are passed to Executor
void execute(Ctx& ctx);
void fetch(Ctx& ctx);
// close statement (mainly scan)
void close(Ctx& ctx);
// free data structures
void free(Ctx& ctx);
// odbc support
void sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind);
void sqlParamData(Ctx& ctx, SQLPOINTER* value);
void sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind);
private:
void parse(Ctx& ctx);
void analyze(Ctx& ctx);
void describe(Ctx& ctx);
void codegen(Ctx& ctx);
void alloc(Ctx& ctx);
void freePlan(Ctx& ctx);
void freeExec(Ctx& ctx);
StmtArea& m_stmtArea;
};
inline
CodeGen::CodeGen(StmtArea& stmtArea) :
m_stmtArea(stmtArea)
{
}
inline
CodeGen::~CodeGen()
{
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <common/StmtArea.hpp>
#include "Code_base.hpp"
#include "Code_root.hpp"
// Plan_base
Plan_base::~Plan_base()
{
}
StmtArea&
Plan_base::stmtArea() const
{
ctx_assert(m_root != 0);
return m_root->m_stmtArea;
}
DescArea&
Plan_base::descArea(DescUsage u) const
{
return stmtArea().descArea(u);
}
ConnArea&
Plan_base::connArea() const
{
return stmtArea().connArea();
}
DictCatalog&
Plan_base::dictCatalog() const
{
return connArea().dictCatalog();
}
DictSchema&
Plan_base::dictSchema() const
{
return connArea().dictSchema();
}
Ndb*
Plan_base::ndbObject() const
{
Ndb* ndb = connArea().ndbObject();
ctx_assert(ndb != 0);
return ndb;
}
NdbSchemaCon*
Plan_base::ndbSchemaCon() const
{
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
ctx_assert(ndbSchemaCon != 0);
return ndbSchemaCon;
}
NdbConnection*
Plan_base::ndbConnection() const
{
NdbConnection* ndbConnection = connArea().ndbConnection();
ctx_assert(ndbConnection != 0);
return ndbConnection;
}
void
Plan_base::printList(Ctx& ctx, Plan_base* a[], unsigned n)
{
for (unsigned i = 0; i < n; i++) {
if (a[i] == 0)
ctx.print(" -");
else
a[i]->print(ctx);
}
}
// Exec_base
Exec_base::Code::~Code()
{
}
Exec_base::Data::~Data()
{
}
Exec_base::~Exec_base()
{
delete m_code; // remove when code becomes shared
m_code = 0;
delete m_data;
m_data = 0;
}
StmtArea&
Exec_base::stmtArea() const
{
ctx_assert(m_root != 0);
return m_root->m_stmtArea;
}
DescArea&
Exec_base::descArea(DescUsage u) const
{
return stmtArea().descArea(u);
}
ConnArea&
Exec_base::connArea() const
{
return stmtArea().connArea();
}
DictSchema&
Exec_base::dictSchema() const
{
return connArea().dictSchema();
}
Ndb*
Exec_base::ndbObject() const
{
Ndb* ndb = connArea().ndbObject();
ctx_assert(ndb != 0);
return ndb;
}
NdbSchemaCon*
Exec_base::ndbSchemaCon() const
{
NdbSchemaCon* ndbSchemaCon = connArea().ndbSchemaCon();
ctx_assert(ndbSchemaCon != 0);
return ndbSchemaCon;
}
NdbConnection*
Exec_base::ndbConnection() const
{
NdbConnection* ndbConnection = connArea().ndbConnection();
ctx_assert(ndbConnection != 0);
return ndbConnection;
}
void
Exec_base::printList(Ctx& ctx, Exec_base* a[], unsigned n)
{
for (unsigned i = 0; i < n; i++) {
ctx_assert(a[i] != 0);
a[i]->print(ctx);
}
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_base_hpp
#define ODBC_CODEGEN_Code_base_hpp
#include <set>
#include <list>
#include <vector>
#include <common/common.hpp>
#include <common/CodeTree.hpp>
#include <common/DescArea.hpp>
class Ctx;
class ConnArea;
class StmtArea;
class DescArea;
class DictCatalog;
class DictSchema;
class ResultArea;
class ResultSet;
class SpecRow;
class Ndb;
class NdbSchemaCon;
class NdbConnection;
class NdbOperation;
class NdbScanFilter;
class Plan_root;
class Plan_table;
class Plan_column;
class Plan_expr;
class Plan_expr_param;
class Plan_pred;
class Plan_dml_row;
class Plan_dml_column;
class Plan_ddl_column;
class Plan_ddl_constr;
class Plan_idx_column;
class Exec_root;
class Exec_base;
class Exec_query;
class Exec_expr;
class Exec_expr_row;
class Exec_expr_param;
/**
* @class Plan_base
* @brief Base class for plan trees
*/
class Plan_base : public PlanTree {
public:
Plan_base(Plan_root* root);
virtual ~Plan_base() = 0;
// get references to StmtArea via Plan_root
StmtArea& stmtArea() const;
DescArea& descArea(DescUsage u) const;
ConnArea& connArea() const;
// catalogs
DictCatalog& dictCatalog() const;
DictSchema& dictSchema() const;
// ndb
Ndb* ndbObject() const;
NdbSchemaCon* ndbSchemaCon() const;
NdbConnection* ndbConnection() const;
// containers for Plan classes
typedef std::vector<Plan_table*> TableVector;
typedef std::vector<Plan_column*> ColumnVector;
typedef std::vector<Plan_dml_column*> DmlColumnVector;
typedef std::vector<Plan_ddl_column*> DdlColumnVector;
typedef std::vector<Plan_ddl_constr*> DdlConstrVector;
typedef std::vector<Plan_idx_column*> IdxColumnVector;
typedef std::vector<Plan_expr*> ExprVector;
typedef std::list<Plan_expr*> ExprList;
typedef std::vector<ExprList> ExprListVector;
typedef std::list<Plan_pred*> PredList;
typedef std::set<Plan_table*> TableSet;
typedef std::vector<Plan_expr_param*> ParamVector;
// control area on the stack XXX needs to be designed
struct Ctl {
Ctl(Ctl* up);
Ctl* m_up; // up the stack
// analyze
TableVector m_tableList; // resolve column names
bool m_topand; // in top-level where clause
bool m_extra; // anything but single pk=expr
bool m_aggrok; // aggregate allowed
bool m_aggrin; // within aggregate args
bool m_const; // only constants in set clause
PredList m_topcomp; // top level comparisons
Plan_dml_row *m_dmlRow; // row type to convert to
Plan_table* m_topTable; // top level table for interpreted progs
bool m_having; // in having-predicate
// codegen
Exec_root* m_execRoot; // root of Exec tree
const Exec_query* m_execQuery; // pass to column
};
// semantic analysis and optimization
virtual Plan_base* analyze(Ctx& ctx, Ctl& ctl) = 0;
// generate "executable" code
virtual Exec_base* codegen(Ctx& ctx, Ctl& ctl) = 0;
// misc
virtual void print(Ctx& ctx) = 0;
protected:
Plan_root* m_root;
void printList(Ctx& ctx, Plan_base* a[], unsigned n);
};
inline
Plan_base::Plan_base(Plan_root* root) :
m_root(root)
{
ctx_assert(m_root != 0);
}
inline
Plan_base::Ctl::Ctl(Ctl* up) :
m_up(up),
m_tableList(1), // 1-based
m_topand(false),
m_extra(false),
m_aggrok(false),
m_aggrin(false),
m_dmlRow(0),
m_topTable(0),
m_having(false),
m_execRoot(0),
m_execQuery(0)
{
}
/**
* @class Exec_base
* @brief Base class for exec trees
*/
class Exec_base : public ExecTree {
public:
class Code : public ExecTree::Code {
public:
virtual ~Code() = 0;
};
class Data : public ExecTree::Data {
public:
virtual ~Data() = 0;
};
Exec_base(Exec_root* root);
virtual ~Exec_base() = 0;
// get references to StmtArea via Exec_root
virtual StmtArea& stmtArea() const;
DescArea& descArea(DescUsage u) const;
ConnArea& connArea() const;
// catalogs
DictSchema& dictSchema() const;
// ndb
Ndb* ndbObject() const;
NdbSchemaCon* ndbSchemaCon() const;
NdbConnection* ndbConnection() const;
// containers for Exec classes
typedef std::vector<Exec_expr*> ExprVector;
typedef std::vector<Exec_expr_param*> ParamVector;
// control area on the stack
struct Ctl {
Ctl(Ctl* up);
Ctl* m_up; // up the stack
const Exec_query* m_query; // pass Data
ExprVector m_exprList; // pass Data
NdbOperation* m_scanOp; // scan operation
bool m_postEval; // for rownum
unsigned m_groupIndex; // for group by
bool m_groupInit; // first in group
Exec_expr_row* m_sortRow; // from sort to group by
NdbScanFilter* m_scanFilter; // scan filter
};
// allocate and deallocate Data instances
virtual void alloc(Ctx& ctx, Ctl& ctl) = 0;
virtual void close(Ctx& ctx) = 0;
// set Code and Data
void setCode(const Code& code);
void setData(Data& data);
// misc
virtual void print(Ctx& ctx) = 0;
protected:
const Code* m_code;
Data* m_data;
Exec_root* m_root;
void printList(Ctx& ctx, Exec_base* a[], unsigned n);
};
inline
Exec_base::Exec_base(Exec_root* root) :
m_code(0),
m_data(0),
m_root(root)
{
ctx_assert(m_root != 0);
}
inline void
Exec_base::setCode(const Code& code)
{
ctx_assert(m_code == 0);
m_code = &code;
}
inline void
Exec_base::setData(Data& data)
{
ctx_assert(m_data == 0);
m_data = &data;
}
inline
Exec_base::Ctl::Ctl(Ctl* up) :
m_up(up),
m_scanOp(0),
m_postEval(false),
m_groupIndex(0),
m_groupInit(false),
m_sortRow(0),
m_scanFilter(0)
{
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <NdbApi.hpp>
#include <common/StmtArea.hpp>
#include <dictionary/DictSchema.hpp>
#include <dictionary/DictColumn.hpp>
#include "Code_column.hpp"
#include "Code_table_list.hpp"
#include "Code_table.hpp"
// Plan_column
Plan_column::~Plan_column()
{
}
void
Plan_column::analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl)
{
if (m_resTable != 0) // done on previous pass
return;
if (! (ctl.m_tableList.size() > 1)) {
ctx.pushStatus(Sqlstate::_42000, Error::Gen, "column %s not allowed here", getPrintName());
return;
}
unsigned resCount = 0;
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
Plan_table* table = ctl.m_tableList[i];
ctx_assert(table != 0);
int ret = table->resolveColumn(ctx, this);
if (ret < 0)
return;
if (ret)
resCount++;
}
if (resCount == 0) {
// XXX try to strip "schema name" from table name
for (unsigned i = 1; i < ctl.m_tableList.size(); i++) {
Plan_table* table = ctl.m_tableList[i];
ctx_assert(table != 0);
int ret = table->resolveColumn(ctx, this, true);
if (ret < 0)
return;
if (ret)
resCount++;
}
}
if (resCount == 0) {
ctx.pushStatus(Sqlstate::_42S22, Error::Gen, "column %s not found", getPrintName());
return;
}
if (resCount > 1) {
ctx.pushStatus(Error::Gen, "column %s is ambiguous", getPrintName());
return;
}
// copy SQL type
m_sqlType = dictColumn().sqlType();
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_column_hpp
#define ODBC_CODEGEN_Code_column_hpp
#include <common/common.hpp>
#include <common/DataType.hpp>
#include "Code_base.hpp"
class DictColumn;
class Plan_table;
/**
* @class Plan_column
* @brief Abstract base class for columns
*/
class Plan_column {
public:
enum Type {
Type_expr = 1,
Type_dml = 2,
Type_ddl = 3, // new columns in create table
Type_idx = 4 // old columns in create index
};
Plan_column(Type type, const BaseString& name);
virtual ~Plan_column() = 0;
void analyzeColumn(Ctx& ctx, Plan_base::Ctl& ctl);
// attributes
const BaseString& getName() const;
const BaseString& getCname() const;
const char* getPrintName() const;
void setCname(const BaseString& cname);
const DictColumn& dictColumn() const;
const SqlType& sqlType() const;
protected:
friend class Plan_table;
friend class Plan_comp_op;
Type m_type;
BaseString m_name;
BaseString m_cname;
BaseString m_printName;
DictColumn* m_dictColumn;
/**
* Resolve to table and operational position (for example
* column number in scan query).
*/
Plan_table* m_resTable;
unsigned m_resPos;
SqlType m_sqlType;
};
inline
Plan_column::Plan_column(Type type, const BaseString& name) :
m_type(type),
m_name(name),
m_printName(name),
m_dictColumn(0),
m_resTable(0),
m_resPos(0)
{
}
inline const BaseString&
Plan_column::getName() const
{
return m_name;
}
inline const BaseString&
Plan_column::getCname() const
{
return m_cname;
}
inline const char*
Plan_column::getPrintName() const
{
return m_printName.c_str();
}
inline void
Plan_column::setCname(const BaseString& cname)
{
m_cname.assign(cname);
if (m_cname.empty())
m_printName.assign(m_name);
else {
m_printName.assign(m_cname);
m_printName.append(".");
m_printName.append(m_name);
}
}
inline const DictColumn&
Plan_column::dictColumn() const
{
ctx_assert(m_dictColumn != 0);
return *m_dictColumn;
}
inline const SqlType&
Plan_column::sqlType() const
{
ctx_assert(m_sqlType.type() != SqlType::Undef);
return m_sqlType;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_comp_op_hpp
#define ODBC_CODEGEN_Code_comp_op_hpp
#include <common/common.hpp>
#include <common/DataField.hpp>
#include "Code_pred.hpp"
#include "Code_expr.hpp"
#include "Code_expr_column.hpp"
/**
* @class Comp_op
* @brief Comparison operations
*/
struct Comp_op {
enum Opcode {
Eq = 1, // binary
Noteq,
Lt,
Lteq,
Gt,
Gteq,
Like,
Notlike,
Isnull, // unary
Isnotnull
};
Comp_op(Opcode opcode);
const char* name() const;
unsigned arity() const;
Opcode m_opcode;
};
inline
Comp_op::Comp_op(Opcode opcode) :
m_opcode(opcode)
{
}
/**
* @class Plan_comp_op
* @brief Comparison operator node in PlanTree
*/
class Plan_comp_op : public Plan_pred {
public:
Plan_comp_op(Plan_root* root, Comp_op op);
virtual ~Plan_comp_op();
void setExpr(unsigned i, Plan_expr* expr);
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
void print(Ctx& ctx);
virtual bool isGroupBy(const Plan_expr_row* row) const;
protected:
Comp_op m_op;
Plan_expr* m_expr[1 + 2];
Plan_expr_column* m_interpColumn[1 + 2]; // candidates
};
inline
Plan_comp_op::Plan_comp_op(Plan_root* root, Comp_op op) :
Plan_pred(root, TypeComp),
m_op(op)
{
m_expr[0] = m_expr[1] = m_expr[2] = 0;
m_interpColumn[0] = m_interpColumn[1] = m_interpColumn[2] = 0;
}
inline void
Plan_comp_op::setExpr(unsigned i, Plan_expr* expr)
{
ctx_assert(1 <= i && i <= 2);
m_expr[i] = expr;
}
/**
* @class Exec_comp_op
* @brief Comparison operator node in ExecTree
*/
class Exec_comp_op : public Exec_pred {
public:
class Code : public Exec_pred::Code {
public:
Code(Comp_op op);
virtual ~Code();
protected:
friend class Plan_comp_op;
friend class Exec_comp_op;
Comp_op m_op;
unsigned m_interpColumn; // 1 or 2 if interpreted column, 0 if both constant
NdbAttrId m_interpAttrId;
};
class Data : public Exec_pred::Data {
public:
Data();
virtual ~Data();
protected:
friend class Exec_comp_op;
};
Exec_comp_op(Exec_root* root);
virtual ~Exec_comp_op();
void alloc(Ctx& ctx, Ctl& ctl);
void execInterp(Ctx& ctx, Ctl& ctl);
void evaluate(Ctx& ctx, Ctl& ctl);
void close(Ctx& ctx);
void print(Ctx& ctx);
// children
const Code& getCode() const;
Data& getData() const;
void setExpr(unsigned i, Exec_expr* expr);
protected:
Exec_expr* m_expr[1 + 2];
};
inline
Exec_comp_op::Code::Code(Comp_op op) :
m_op(op),
m_interpColumn(0),
m_interpAttrId((NdbAttrId)-1)
{
}
inline
Exec_comp_op::Data::Data()
{
}
inline
Exec_comp_op::Exec_comp_op(Exec_root* root) :
Exec_pred(root)
{
m_expr[0] = m_expr[1] = m_expr[2] = 0;
}
// children
inline const Exec_comp_op::Code&
Exec_comp_op::getCode() const
{
const Code* code = static_cast<const Code*>(m_code);
return *code;
}
inline Exec_comp_op::Data&
Exec_comp_op::getData() const
{
Data* data = static_cast<Data*>(m_data);
return *data;
}
inline void
Exec_comp_op::setExpr(unsigned i, Exec_expr* expr)
{
ctx_assert(1 <= i && i <= 2 && m_expr[i] == 0);
m_expr[i] = expr;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <common/StmtArea.hpp>
#include "Code_create_index.hpp"
#include "Code_root.hpp"
// Plan_create_index
Plan_create_index::~Plan_create_index()
{
}
Plan_base*
Plan_create_index::analyze(Ctx& ctx, Ctl& ctl)
{
stmtArea().stmtInfo().setName(Stmt_name_create_index);
// analyze the table
ctx_assert(m_table != 0);
m_table->analyze(ctx, ctl);
if (! ctx.ok())
return 0;
// analyze the columns
ctl.m_tableList.resize(1 + 1); // indexed from 1
ctl.m_tableList[1] = m_table;
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_idx_column* column = getColumn(i);
column->analyze(ctx, ctl);
if (! ctx.ok())
return 0;
}
return this;
}
void
Plan_create_index::describe(Ctx& ctx)
{
stmtArea().setFunction(ctx, "CREATE INDEX", SQL_DIAG_CREATE_INDEX);
}
Exec_base*
Plan_create_index::codegen(Ctx& ctx, Ctl& ctl)
{
Exec_create_index* exec = new Exec_create_index(ctl.m_execRoot);
ctl.m_execRoot->saveNode(exec);
const unsigned count = countColumn();
const char** attrList = new const char* [1 + count];
attrList[0] = 0; // unused
for (unsigned i = 1; i <= count; i++) {
Plan_idx_column* column = getColumn(i);
const char* cname = column->getName().c_str();
attrList[i] = strcpy(new char[strlen(cname) + 1], cname);
}
Exec_create_index::Code& code = *new Exec_create_index::Code(m_name, m_table->getName(), m_type, count, attrList);
exec->setCode(code);
code.m_fragmentType = m_fragmentType;
code.m_logging = m_logging;
return exec;
}
void
Plan_create_index::print(Ctx& ctx)
{
ctx.print(" [create_index name=%s table=%s type=%d", m_name.c_str(), m_table->getName().c_str(), (int)m_type);
ctx.print(" [");
for (unsigned i = 1; i <= countColumn(); i++) {
Plan_idx_column* column = getColumn(i);
if (i > 1)
ctx.print(" ");
column->print(ctx);
}
ctx.print("]");
}
// Exec_create_index
Exec_create_index::Code::~Code()
{
for (unsigned i = 1; i <= m_attrCount; i++) {
delete[] m_attrList[i];
m_attrList[i] = 0;
}
delete[] m_attrList;
}
Exec_create_index::Data::~Data()
{
}
Exec_create_index::~Exec_create_index()
{
}
void
Exec_create_index::alloc(Ctx& ctx, Ctl& ctl)
{
Data& data = *new Data;
setData(data);
}
void
Exec_create_index::close(Ctx& ctx)
{
}
void
Exec_create_index::print(Ctx& ctx)
{
const Code& code = getCode();
ctx.print(" [create_index %s]", code.m_tableName.c_str());
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_create_index_hpp
#define ODBC_CODEGEN_Code_create_index_hpp
#include <vector>
#include <NdbApi.hpp>
#include <common/common.hpp>
#include "Code_ddl.hpp"
#include "Code_table.hpp"
#include "Code_idx_column.hpp"
class DictTable;
class DictColumn;
/**
* @class Plan_create_index
* @brief Create table in PlanTree
*/
class Plan_create_index : public Plan_ddl {
public:
Plan_create_index(Plan_root* root, const BaseString& name);
virtual ~Plan_create_index();
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
void describe(Ctx & ctx);
void print(Ctx& ctx);
// attributes
const BaseString& getName() const;
// children
void setType(NdbDictionary::Object::Type type);
void setTable(Plan_table* table);
unsigned countColumn() const;
void addColumn(Plan_idx_column* column);
Plan_idx_column* getColumn(unsigned i) const;
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
void setLogging(bool logging);
protected:
BaseString m_name;
NdbDictionary::Object::Type m_type;
Plan_table* m_table;
IdxColumnVector m_columnList;
NdbDictionary::Object::FragmentType m_fragmentType;
bool m_logging;
};
inline
Plan_create_index::Plan_create_index(Plan_root* root, const BaseString& name) :
Plan_ddl(root),
m_name(name),
m_type(NdbDictionary::Object::TypeUndefined),
m_columnList(1),
m_fragmentType(NdbDictionary::Object::FragUndefined),
m_logging(true)
{
}
inline const BaseString&
Plan_create_index::getName() const
{
return m_name;
}
// children
inline void
Plan_create_index::setType(NdbDictionary::Object::Type type)
{
m_type = type;
}
inline void
Plan_create_index::setTable(Plan_table* table)
{
ctx_assert(table != 0);
m_table = table;
}
inline unsigned
Plan_create_index::countColumn() const
{
return m_columnList.size() - 1;
}
inline void
Plan_create_index::addColumn(Plan_idx_column* column)
{
ctx_assert(column != 0);
m_columnList.push_back(column);
}
inline Plan_idx_column*
Plan_create_index::getColumn(unsigned i) const
{
ctx_assert(1 <= i && i <= countColumn() && m_columnList[i] != 0);
return m_columnList[i];
}
inline void
Plan_create_index::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
{
m_fragmentType = fragmentType;
}
inline void
Plan_create_index::setLogging(bool logging)
{
m_logging = logging;
}
/**
* @class Exec_create_index
* @brief Create table in ExecTree
*/
class Exec_create_index : public Exec_ddl {
public:
class Code : public Exec_ddl::Code {
public:
Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList);
virtual ~Code();
protected:
friend class Plan_create_index;
friend class Exec_create_index;
const BaseString m_indexName;
const BaseString m_tableName;
NdbDictionary::Object::Type m_type;
const unsigned m_attrCount;
const char** m_attrList;
NdbDictionary::Object::FragmentType m_fragmentType;
bool m_logging;
};
class Data : public Exec_ddl::Data {
public:
Data();
virtual ~Data();
protected:
friend class Exec_create_index;
};
Exec_create_index(Exec_root* root);
virtual ~Exec_create_index();
void alloc(Ctx& ctx, Ctl& ctl);
void execute(Ctx& ctx, Ctl& ctl);
void close(Ctx& ctx);
void print(Ctx& ctx);
// children
const Code& getCode() const;
Data& getData() const;
};
inline
Exec_create_index::Code::Code(const BaseString& indexName, const BaseString& tableName, NdbDictionary::Object::Type type, unsigned attrCount, const char** attrList) :
m_indexName(indexName),
m_tableName(tableName),
m_type(type),
m_attrCount(attrCount),
m_attrList(attrList),
m_fragmentType(NdbDictionary::Object::FragUndefined),
m_logging(true)
{
}
inline
Exec_create_index::Data::Data()
{
}
inline
Exec_create_index::Exec_create_index(Exec_root* root) :
Exec_ddl(root)
{
}
// children
inline const Exec_create_index::Code&
Exec_create_index::getCode() const
{
const Code* code = static_cast<const Code*>(m_code);
return *code;
}
inline Exec_create_index::Data&
Exec_create_index::getData() const
{
Data* data = static_cast<Data*>(m_data);
return *data;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "Code_create_row.hpp"
#include "Code_root.hpp"
Plan_create_row::~Plan_create_row()
{
}
Plan_base*
Plan_create_row::analyze(Ctx& ctx, Ctl& ctl)
{
// check for duplicate column name
for (unsigned i = 1, n = countColumn(); i < n; i++) {
const BaseString& a = getColumn(i)->getName();
for (unsigned i2 = i + 1; i2 <= n; i2++) {
const BaseString& a2 = getColumn(i2)->getName();
if (strcmp(a.c_str(), a2.c_str()) == 0) {
ctx.pushStatus(Error::Gen, "duplicate column %s", a.c_str());
return 0;
}
}
}
// move single-column primary key constraint to constraint list
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_ddl_column* column = getColumn(i);
if (column->m_primaryKey) {
Plan_ddl_row* ddlRow = new Plan_ddl_row(m_root);
m_root->saveNode(ddlRow);
ddlRow->addColumn(column);
Plan_ddl_constr* constr = new Plan_ddl_constr(m_root);
m_root->saveNode(constr);
constr->setRow(ddlRow);
addConstr(constr);
column->m_primaryKey = false; // will be set again
}
}
// check primary key constraints
if (countConstr() < 1) {
ctx.pushStatus(Error::Gen, "table must have a primary key");
return 0;
}
if (countConstr() > 1) {
ctx.pushStatus(Error::Gen, "table can have only one primary key");
return 0;
}
Plan_ddl_row* ddlRow = getConstr(1)->getRow();
for (unsigned i = 1, n = ddlRow->countColumn(); i <= n; i++) {
Plan_ddl_column* column = ddlRow->getColumn(i);
const BaseString& a = column->getName();
bool found = false;
for (unsigned i2 = 1, n2 = countColumn(); i2 <= n2; i2++) {
Plan_ddl_column* column2 = getColumn(i2);
const BaseString& a2 = column2->getName();
if (strcmp(a.c_str(), a2.c_str()) != 0)
continue;
if (column2->getPrimaryKey()) {
ctx.pushStatus(Error::Gen, "duplicate primary key constraint on %s", a.c_str());
return 0;
}
column2->setPrimaryKey();
found = true;
break;
}
if (! found) {
ctx.pushStatus(Error::Gen, "undefined primary key column %s", a.c_str());
return 0;
}
}
// analyze column types
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
getColumn(i)->analyze(ctx, ctl);
if (! ctx.ok())
return 0;
}
// check TupleId
unsigned tupleId = 0;
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_ddl_column* column = getColumn(i);
if (! column->getTupleId())
continue;
if (i != 1) {
ctx.pushStatus(Error::Gen, "tuple id column %u is not first column", i);
return 0;
}
if (tupleId != 0) { // cannot happen now since attr name is fixed
ctx.pushStatus(Error::Gen, "duplicate tuple id column %u", i);
return 0;
}
tupleId = i;
}
if (tupleId != 0) {
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_ddl_column* column = getColumn(i);
if (i == tupleId)
continue;
if (! column->getPrimaryKey())
continue;
ctx.pushStatus(Error::Gen, "cannot have both tuple id and other primary key column %u", i);
return 0;
}
}
// check auto-increment
unsigned autoIncrement = 0;
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_ddl_column* column = getColumn(i);
if (! column->getAutoIncrement())
continue;
if (autoIncrement != 0) {
ctx.pushStatus(Error::Gen, "duplicate auto-increment column %u", i);
return 0;
}
autoIncrement = i;
}
if (autoIncrement != 0) {
for (unsigned i = 1, n = countColumn(); i <= n; i++) {
Plan_ddl_column* column = getColumn(i);
if (i == autoIncrement)
continue;
if (! column->getPrimaryKey())
continue;
ctx.pushStatus(Error::Gen, "cannot have both auto-increment column and other primary key column %u", i);
return 0;
}
}
return this;
}
Exec_base*
Plan_create_row::codegen(Ctx& ctx, Ctl& ctl)
{
ctx_assert(false);
return 0;
}
void
Plan_create_row::print(Ctx& ctx)
{
ctx.print(" [create_row");
for (unsigned i = 1; i <= countColumn(); i++) {
Plan_base* a = m_columnList[i];
printList(ctx, &a, 1);
}
for (unsigned i = 1; i <= countConstr(); i++) {
Plan_base* a = m_constrList[i];
printList(ctx, &a, 1);
}
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_create_row_hpp
#define ODBC_CODEGEN_Code_create_row_hpp
#include <vector>
#include <common/common.hpp>
#include "Code_base.hpp"
#include "Code_ddl_column.hpp"
#include "Code_ddl_constr.hpp"
/**
* @class Plan_create_row
* @brief Row of columns and constraints in create statement
*/
class Plan_create_row : public Plan_base {
public:
Plan_create_row(Plan_root* root);
virtual ~Plan_create_row();
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
void print(Ctx& ctx);
// children
unsigned countColumn() const;
void addColumn(Plan_ddl_column* column);
Plan_ddl_column* getColumn(unsigned i) const;
unsigned countConstr() const;
void addConstr(Plan_ddl_constr* constr);
Plan_ddl_constr* getConstr(unsigned i) const;
protected:
DdlColumnVector m_columnList;
DdlConstrVector m_constrList;
};
inline
Plan_create_row::Plan_create_row(Plan_root* root) :
Plan_base(root),
m_columnList(1),
m_constrList(1)
{
}
// children
inline unsigned
Plan_create_row::countColumn() const
{
return m_columnList.size() - 1;
}
inline void
Plan_create_row::addColumn(Plan_ddl_column* column)
{
ctx_assert(column != 0);
m_columnList.push_back(column);
}
inline Plan_ddl_column*
Plan_create_row::getColumn(unsigned i) const
{
ctx_assert(1 <= i && i <= m_columnList.size() && m_columnList[i] != 0);
return m_columnList[i];
}
inline unsigned
Plan_create_row::countConstr() const
{
return m_constrList.size() - 1;
}
inline void
Plan_create_row::addConstr(Plan_ddl_constr* constr)
{
ctx_assert(constr != 0);
m_constrList.push_back(constr);
}
inline Plan_ddl_constr*
Plan_create_row::getConstr(unsigned i) const
{
ctx_assert(1 <= i && i <= m_constrList.size() && m_constrList[i] != 0);
return m_constrList[i];
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <common/StmtArea.hpp>
#include "Code_create_table.hpp"
#include "Code_root.hpp"
// Plan_create_table
Plan_create_table::~Plan_create_table()
{
}
Plan_base*
Plan_create_table::analyze(Ctx& ctx, Ctl& ctl)
{
stmtArea().stmtInfo().setName(Stmt_name_create_table);
// analyze the create row
ctx_assert(m_createRow != 0);
m_createRow->analyze(ctx, ctl);
if (! ctx.ok())
return 0;
return this;
}
void
Plan_create_table::describe(Ctx& ctx)
{
stmtArea().setFunction(ctx, "CREATE TABLE", SQL_DIAG_CREATE_TABLE);
}
Exec_base*
Plan_create_table::codegen(Ctx& ctx, Ctl& ctl)
{
ctx_assert(m_createRow != 0);
Exec_create_table* exec = new Exec_create_table(ctl.m_execRoot);
ctl.m_execRoot->saveNode(exec);
const unsigned count = m_createRow->countColumn();
Exec_create_table::Code::Attr* attrList = new Exec_create_table::Code::Attr[1 + count];
unsigned tupleId = 0;
unsigned autoIncrement = 0;
for (unsigned i = 1; i <= count; i++) {
Plan_ddl_column* column = m_createRow->getColumn(i);
Exec_create_table::Code::Attr& attr = attrList[i];
attr.m_attrName.assign(column->getName());
attr.m_sqlType = column->sqlType();
attr.m_tupleKey = column->getPrimaryKey();
attr.m_tupleId = column->getTupleId();
attr.m_autoIncrement = column->getAutoIncrement();
if (attr.m_tupleId)
tupleId = i;
if (attr.m_autoIncrement)
autoIncrement = i;
attr.m_defaultValue = 0;
Plan_expr* expr;
if ((expr = column->getDefaultValue()) != 0) {
Exec_expr* execExpr = static_cast<Exec_expr*>(expr->codegen(ctx, ctl));
if (! ctx.ok())
return 0;
ctx_assert(execExpr != 0);
attr.m_defaultValue = execExpr;
}
}
Exec_create_table::Code& code = *new Exec_create_table::Code(m_name, count, attrList, tupleId, autoIncrement);
exec->setCode(code);
code.m_fragmentType = m_fragmentType;
code.m_logging = m_logging;
return exec;
}
void
Plan_create_table::print(Ctx& ctx)
{
ctx.print(" [create_table '%s'", m_name.c_str());
Plan_base* a[] = { m_createRow };
printList(ctx, a, 1);
ctx.print("]");
}
// Exec_create_table
Exec_create_table::Code::~Code()
{
delete[] m_attrList;
}
Exec_create_table::Data::~Data()
{
}
Exec_create_table::~Exec_create_table()
{
}
void
Exec_create_table::alloc(Ctx& ctx, Ctl& ctl)
{
const Code& code = getCode();
for (unsigned i = 1; i <= code.m_attrCount; i++) {
const Code::Attr& attr = code.m_attrList[i];
if (attr.m_defaultValue != 0)
attr.m_defaultValue->alloc(ctx, ctl);
}
Data& data = *new Data;
setData(data);
}
void
Exec_create_table::close(Ctx& ctx)
{
const Code& code = getCode();
for (unsigned i = 1; i <= code.m_attrCount; i++) {
const Code::Attr& attr = code.m_attrList[i];
if (attr.m_defaultValue != 0)
attr.m_defaultValue->close(ctx);
}
}
void
Exec_create_table::print(Ctx& ctx)
{
const Code& code = getCode();
ctx.print(" [create_table %s]", code.m_tableName.c_str());
}
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef ODBC_CODEGEN_Code_create_table_hpp
#define ODBC_CODEGEN_Code_create_table_hpp
#include <vector>
#include <common/common.hpp>
#include "Code_ddl.hpp"
#include "Code_ddl_row.hpp"
#include "Code_create_row.hpp"
class DictTable;
class DictColumn;
/**
* @class Plan_create_table
* @brief Create table in PlanTree
*/
class Plan_create_table : public Plan_ddl {
public:
Plan_create_table(Plan_root* root, const BaseString& name);
virtual ~Plan_create_table();
Plan_base* analyze(Ctx& ctx, Ctl& ctl);
Exec_base* codegen(Ctx& ctx, Ctl& ctl);
void describe(Ctx & ctx);
void print(Ctx& ctx);
// attributes
const BaseString& getName() const;
// children
void setCreateRow(Plan_create_row* createRow);
void setFragmentType(NdbDictionary::Object::FragmentType fragmentType);
void setLogging(bool logging);
protected:
BaseString m_name;
Plan_create_row* m_createRow;
NdbDictionary::Object::FragmentType m_fragmentType;
bool m_logging;
};
inline
Plan_create_table::Plan_create_table(Plan_root* root, const BaseString& name) :
Plan_ddl(root),
m_name(name),
m_createRow(0),
m_fragmentType(NdbDictionary::Object::FragUndefined),
m_logging(true)
{
}
inline const BaseString&
Plan_create_table::getName() const
{
return m_name;
}
// children
inline void
Plan_create_table::setCreateRow(Plan_create_row* createRow)
{
ctx_assert(createRow != 0);
m_createRow = createRow;
}
inline void
Plan_create_table::setFragmentType(NdbDictionary::Object::FragmentType fragmentType)
{
m_fragmentType = fragmentType;
}
inline void
Plan_create_table::setLogging(bool logging)
{
m_logging = logging;
}
/**
* @class Exec_create_table
* @brief Create table in ExecTree
*/
class Exec_create_table : public Exec_ddl {
public:
class Code : public Exec_ddl::Code {
public:
struct Attr {
Attr() : m_defaultValue(0) {}
BaseString m_attrName;
SqlType m_sqlType;
bool m_tupleKey;
bool m_tupleId;
bool m_autoIncrement;
Exec_expr* m_defaultValue;
};
Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement);
virtual ~Code();
protected:
friend class Plan_create_table;
friend class Exec_create_table;
const BaseString m_tableName;
const unsigned m_attrCount;
const Attr* const m_attrList;
unsigned m_tupleId;
unsigned m_autoIncrement;
NdbDictionary::Object::FragmentType m_fragmentType;
bool m_logging;
};
class Data : public Exec_ddl::Data {
public:
Data();
virtual ~Data();
protected:
friend class Exec_create_table;
};
Exec_create_table(Exec_root* root);
virtual ~Exec_create_table();
void alloc(Ctx& ctx, Ctl& ctl);
void execute(Ctx& ctx, Ctl& ctl);
void close(Ctx& ctx);
void print(Ctx& ctx);
// children
const Code& getCode() const;
Data& getData() const;
};
inline
Exec_create_table::Code::Code(const BaseString& tableName, unsigned attrCount, const Attr* attrList, unsigned tupleId, unsigned autoIncrement) :
m_tableName(tableName),
m_attrCount(attrCount),
m_attrList(attrList),
m_tupleId(tupleId),
m_autoIncrement(autoIncrement),
m_fragmentType(NdbDictionary::Object::FragUndefined),
m_logging(true)
{
}
inline
Exec_create_table::Data::Data()
{
}
inline
Exec_create_table::Exec_create_table(Exec_root* root) :
Exec_ddl(root)
{
}
// children
inline const Exec_create_table::Code&
Exec_create_table::getCode() const
{
const Code* code = static_cast<const Code*>(m_code);
return *code;
}
inline Exec_create_table::Data&
Exec_create_table::getData() const
{
Data* data = static_cast<Data*>(m_data);
return *data;
}
#endif
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <NdbApi.hpp>
#include <common/StmtArea.hpp>
#include "Code_data_type.hpp"
// Plan_data_type
Plan_data_type::~Plan_data_type()
{
}
Plan_base*
Plan_data_type::analyze(Ctx& ctx, Ctl& ctl)
{
return this;
}
Exec_base*
Plan_data_type::codegen(Ctx& ctx, Ctl& ctl)
{
ctx_assert(false);
return 0;
}
void
Plan_data_type::print(Ctx& ctx)
{
ctx.print(" [data_type]");
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment