/* * RPAD( string, padded_length, [ pad_string ] ) * * Right pads "string" to "padded length" characters (not bytes), * with spaces by default, or 'pad_string' otherwise * * string is the string to pad characters to (the left-hand side). * * padded_length is the number of characters to return. * If the padded_length is smaller than the original string, the RPAD * function will truncate the string to the size of padded_length. * * pad_string is optional. This is the string that will be padded to * the right-hand side of string. If this parameter is omitted, the LPAD * function will pad spaces to the right-side of string. */ extern void ora_rpad(sqlite3_context *context, int argc, sqlite3_value **argv) { int len; // Required length int clen; // number of CHARACTERS in the string unsigned char *str; unsigned char *pad; unsigned char *result; unsigned char *r; unsigned char *p; int padlen; // CHARACTER length of padding int i; _ksu_check_arg_cnt(argc, 2, 3, "rpad"); if (ksu_prm_ok(context, argc, argv, "rpad", KSU_PRM_TEXT, KSU_PRM_INT_GT_0, KSU_PRM_TEXT)) { str = (unsigned char *)sqlite3_value_text(argv[0]); len = sqlite3_value_int(argv[1]); if (argc == 2) { // Default padding pad = (unsigned char *)" "; padlen = 1; } else { pad = (unsigned char *)sqlite3_value_text(argv[2]); padlen = ksu_charlen(pad); } // Allocate memory for 4 * required length (as a character // is at most four bytes), plus one for \0 if ((result = (unsigned char *)sqlite3_malloc(4 * len + 1)) == NULL) { sqlite3_result_error_nomem(context); return; } // Check the length of the original string clen = ksu_charlen(str); // Copy - i is a CHARACTER counter r = result; p = str; i = 0; // First copy the string while (*p && (i < len)) { i++; *r = *p; r++; if ((*(p++)) >= 0xc0) { while ((*p & 0xc0) == 0x80) { *r = *p; p++; r++; } } } // Then insert padding (if required length // is greater than string length) p = pad; while (i < len) { i++; *r = *p; r++; if ((*(p++)) >= 0xc0) { while ((*p & 0xc0) == 0x80) { *r = *p; p++; r++; } } // Check whether we must repeat the padding if (*p == '\0') { p = pad; } } *r = '\0'; sqlite3_result_text(context, (char *)result, -1, // Length - -1 means terminated by \0 sqlite3_free); // Function for freeing memory } }
int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ int val = sqlite3_value_int( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; }
GEOPACKAGE_PRIVATE void fnct_gpkgAddGeometryColumn (sqlite3_context * context, int argc __attribute__ ((unused)), sqlite3_value ** argv) { /* SQL function: / gpkgAddGeomtryColumn(table_name, geometry_column_name, geometry_type, with_z, with_m, srs_id) / / Adds a geometry column to the specified table / geometry_type is a normal WKT name: "GEOMETRY", "POINT", "LINESTRING", "POLYGON", / "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMCOLLECTION" / with_z is a flag (0 for no z values, 1 for mandatory z values, 2 for optional z values) / with_m is a flag (0 for no m values, 1 for mandatory m values, 2 for optional m values) / / It also adds a matching entry into gpkg_contents (if not already present) / / returns nothing on success, raises exception on error / / This function assumes usual tile conventions, including that the tiles are power-of-two-zoom, / 256x256 pixels, 1 tile at the top level (zoom level 0). / */ const unsigned char *table; const unsigned char *geometry_column_name; const unsigned char *geometry_type_name = NULL; int with_z; int with_m; int srid; int i = 0; char *sql_stmt = NULL; sqlite3 *sqlite = NULL; char *errMsg = NULL; int ret = 0; if (sqlite3_value_type (argv[0]) != SQLITE_TEXT) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 1 [table] is not of the string type", -1); return; } table = sqlite3_value_text (argv[0]); if (sqlite3_value_type (argv[1]) != SQLITE_TEXT) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 2 [geometry_column_name] is not of the string type", -1); return; } geometry_column_name = sqlite3_value_text (argv[1]); if (sqlite3_value_type (argv[2]) != SQLITE_TEXT) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 3 [geometry_type] is not of the string type", -1); return; } for (i = 0; SUPPORTED_GEOMETRY_TYPES[i] != NULL; ++i) { if (strcasecmp ((const char *) sqlite3_value_text (argv[2]), SUPPORTED_GEOMETRY_TYPES[i]) == 0) { geometry_type_name = (const unsigned char *) SUPPORTED_GEOMETRY_TYPES[i]; break; } } if (geometry_type_name == NULL) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 3 [geometry_type] not a recognised geometry type", -1); return; } if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 4 [with_z] is not of the integer type", -1); return; } with_z = (double) sqlite3_value_int (argv[3]); if ((with_z != 0) && (with_z != 1) && (with_z != 2)) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 4 [with_z] is not a known value (expected 0, 1 or 2)", -1); return; } if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 5 [with_m] is not of the integer type", -1); return; } with_m = (double) sqlite3_value_int (argv[4]); if ((with_m != 0) && (with_m != 1) && (with_m != 2)) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 5 [with_m] is not a known value (expected 0, 1 or 2)", -1); return; } if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER) { sqlite3_result_error (context, "gpkgAddGeometryColumn() error: argument 6 [srid] is not of the integer type", -1); return; } srid = sqlite3_value_int (argv[5]); sqlite = sqlite3_context_db_handle (context); sql_stmt = sqlite3_mprintf("INSERT OR IGNORE INTO gpkg_contents " "(table_name, data_type, srs_id, min_x, min_y, max_x, max_y) " "VALUES (%Q, 'feature', %i, NULL, NULL, NULL, NULL)", table, srid); ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg); sqlite3_free (sql_stmt); if (ret != SQLITE_OK) { sqlite3_result_error (context, errMsg, -1); sqlite3_free (errMsg); return; } /* Add column definition to metadata table */ sql_stmt = sqlite3_mprintf ("INSERT INTO gpkg_geometry_columns " "(table_name, column_name, geometry_type_name, srs_id, z, m) " "VALUES (%Q, %Q, %Q, %i, %i, %i)", table, geometry_column_name, geometry_type_name, srid, with_z, with_m); ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg); sqlite3_free (sql_stmt); if (ret != SQLITE_OK) { sqlite3_result_error (context, errMsg, -1); sqlite3_free (errMsg); return; } /* extend table_name to actually have a geometry column */ sql_stmt = sqlite3_mprintf ("ALTER TABLE %s ADD COLUMN %s %s", table, geometry_column_name, geometry_type_name); ret = sqlite3_exec (sqlite, sql_stmt, NULL, NULL, &errMsg); sqlite3_free (sql_stmt); if (ret != SQLITE_OK) { sqlite3_result_error (context, errMsg, -1); sqlite3_free (errMsg); return; } /* TODO: add triggers */ }
static int do_callback(struct pdo_sqlite_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg) { zval *zargs = NULL; zval retval; int i; int ret; int fake_argc; zend_reference *agg_context = NULL; if (is_agg) { is_agg = 2; } fake_argc = argc + is_agg; fc->fci.size = sizeof(fc->fci); fc->fci.function_table = EG(function_table); ZVAL_COPY_VALUE(&fc->fci.function_name, cb); fc->fci.symbol_table = NULL; fc->fci.object = NULL; fc->fci.retval = &retval; fc->fci.param_count = fake_argc; /* build up the params */ if (fake_argc) { zargs = safe_emalloc(fake_argc, sizeof(zval), 0); } if (is_agg) { agg_context = (zend_reference*)sqlite3_aggregate_context(context, sizeof(zend_reference)); if (!agg_context) { ZVAL_NULL(&zargs[0]); } else { if (Z_ISUNDEF(agg_context->val)) { GC_REFCOUNT(agg_context) = 1; GC_TYPE_INFO(agg_context) = IS_REFERENCE; ZVAL_NULL(&agg_context->val); } ZVAL_REF(&zargs[0], agg_context); } ZVAL_LONG(&zargs[1], sqlite3_aggregate_count(context)); } for (i = 0; i < argc; i++) { /* get the value */ switch (sqlite3_value_type(argv[i])) { case SQLITE_INTEGER: ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i])); break; case SQLITE_FLOAT: ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i])); break; case SQLITE_NULL: ZVAL_NULL(&zargs[i + is_agg]); break; case SQLITE_BLOB: case SQLITE3_TEXT: default: ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i])); break; } } fc->fci.params = zargs; if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) { php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback"); } /* clean up the params */ if (zargs) { for (i = is_agg; i < fake_argc; i++) { zval_ptr_dtor(&zargs[i]); } if (is_agg) { zval_ptr_dtor(&zargs[1]); } efree(zargs); } if (!is_agg || !argv) { /* only set the sqlite return value if we are a scalar function, * or if we are finalizing an aggregate */ if (!Z_ISUNDEF(retval)) { switch (Z_TYPE(retval)) { case IS_LONG: sqlite3_result_int(context, Z_LVAL(retval)); break; case IS_NULL: sqlite3_result_null(context); break; case IS_DOUBLE: sqlite3_result_double(context, Z_DVAL(retval)); break; default: convert_to_string_ex(&retval); sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT); break; } } else { sqlite3_result_error(context, "failed to invoke callback", 0); } if (agg_context) { zval_ptr_dtor(&agg_context->val); } } else { /* we're stepping in an aggregate; the return value goes into * the context */ if (agg_context) { zval_ptr_dtor(&agg_context->val); } if (!Z_ISUNDEF(retval)) { ZVAL_COPY_VALUE(&agg_context->val, &retval); ZVAL_UNDEF(&retval); } else { ZVAL_UNDEF(&agg_context->val); } } if (!Z_ISUNDEF(retval)) { zval_ptr_dtor(&retval); } return ret; }
static void OGR2SQLITE_ogr_datasource_load_layers(sqlite3_context* pContext, int argc, sqlite3_value** argv) { sqlite3* hDB = (sqlite3*) sqlite3_user_data(pContext); if( (argc < 1 || argc > 3) || sqlite3_value_type (argv[0]) != SQLITE_TEXT ) { sqlite3_result_int (pContext, 0); return; } const char* pszDataSource = (const char*) sqlite3_value_text(argv[0]); int bUpdate = FALSE; if( argc >= 2 ) { if( sqlite3_value_type(argv[1]) != SQLITE_INTEGER ) { sqlite3_result_int (pContext, 0); return; } bUpdate = sqlite3_value_int(argv[1]); } const char* pszPrefix = NULL; if( argc >= 3 ) { if( sqlite3_value_type(argv[2]) != SQLITE_TEXT ) { sqlite3_result_int (pContext, 0); return; } pszPrefix = (const char*) sqlite3_value_text(argv[2]); } OGRDataSource* poDS = (OGRDataSource*)OGROpenShared(pszDataSource, bUpdate, NULL); if( poDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s", pszDataSource); sqlite3_result_int (pContext, 0); return; } CPLString osEscapedDataSource = OGRSQLiteEscape(pszDataSource); for(int i=0;i<poDS->GetLayerCount();i++) { const char* pszLayerName = poDS->GetLayer(i)->GetName(); CPLString osEscapedLayerName = OGRSQLiteEscape(pszLayerName); CPLString osTableName; if( pszPrefix != NULL ) { osTableName = pszPrefix; osTableName += "_"; osTableName += OGRSQLiteEscapeName(pszLayerName); } else { osTableName = OGRSQLiteEscapeName(pszLayerName); } char* pszErrMsg = NULL; if( sqlite3_exec(hDB, CPLSPrintf( "CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR('%s', %d, '%s')", osTableName.c_str(), osEscapedDataSource.c_str(), bUpdate, osEscapedLayerName.c_str()), NULL, NULL, &pszErrMsg) != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create table \"%s\" : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); } } poDS->Release(); sqlite3_result_int (pContext, 1); }
/* ** Implementation of the sha3_query(SQL,SIZE) function. ** ** This function compiles and runs the SQL statement(s) given in the ** argument. The results are hashed using a SIZE-bit SHA3. The default ** size is 256. ** ** The format of the byte stream that is hashed is summarized as follows: ** ** S<n>:<sql> ** R ** N ** I<int> ** F<ieee-float> ** B<size>:<bytes> ** T<size>:<text> ** ** <sql> is the original SQL text for each statement run and <n> is ** the size of that text. The SQL text is UTF-8. A single R character ** occurs before the start of each row. N means a NULL value. ** I mean an 8-byte little-endian integer <int>. F is a floating point ** number with an 8-byte little-endian IEEE floating point value <ieee-float>. ** B means blobs of <size> bytes. T means text rendered as <size> ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII ** text integers. ** ** For each SQL statement in the X input, there is one S segment. Each ** S segment is followed by zero or more R segments, one for each row in the ** result set. After each R, there are one or more N, I, F, B, or T segments, ** one for each column in the result set. Segments are concatentated directly ** with no delimiters of any kind. */ static void sha3QueryFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3 *db = sqlite3_context_db_handle(context); const char *zSql = (const char*)sqlite3_value_text(argv[0]); sqlite3_stmt *pStmt = 0; int nCol; /* Number of columns in the result set */ int i; /* Loop counter */ int rc; int n; const char *z; SHA3Context cx; int iSize; if( argc==1 ){ iSize = 256; }else{ iSize = sqlite3_value_int(argv[1]); if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " "384 512", -1); return; } } if( zSql==0 ) return; SHA3Init(&cx, iSize); while( zSql[0] ){ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); if( rc ){ char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", zSql, sqlite3_errmsg(db)); sqlite3_finalize(pStmt); sqlite3_result_error(context, zMsg, -1); sqlite3_free(zMsg); return; } if( !sqlite3_stmt_readonly(pStmt) ){ char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); sqlite3_finalize(pStmt); sqlite3_result_error(context, zMsg, -1); sqlite3_free(zMsg); return; } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); n = (int)strlen(z); hash_step_vformat(&cx,"S%d:",n); SHA3Update(&cx,(unsigned char*)z,n); /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ SHA3Update(&cx,(const unsigned char*)"R",1); for(i=0; i<nCol; i++){ switch( sqlite3_column_type(pStmt,i) ){ case SQLITE_NULL: { SHA3Update(&cx, (const unsigned char*)"N",1); break; } case SQLITE_INTEGER: { sqlite3_uint64 u; int j; unsigned char x[9]; sqlite3_int64 v = sqlite3_column_int64(pStmt,i); memcpy(&u, &v, 8); for(j=8; j>=1; j--){ x[j] = u & 0xff; u >>= 8; } x[0] = 'I'; SHA3Update(&cx, x, 9); break; } case SQLITE_FLOAT: { sqlite3_uint64 u; int j; unsigned char x[9]; double r = sqlite3_column_double(pStmt,i); memcpy(&u, &r, 8); for(j=8; j>=1; j--){ x[j] = u & 0xff; u >>= 8; } x[0] = 'F'; SHA3Update(&cx,x,9); break; } case SQLITE_TEXT: { int n2 = sqlite3_column_bytes(pStmt, i); const unsigned char *z2 = sqlite3_column_text(pStmt, i); hash_step_vformat(&cx,"T%d:",n2); SHA3Update(&cx, z2, n2); break; } case SQLITE_BLOB: { int n2 = sqlite3_column_bytes(pStmt, i); const unsigned char *z2 = sqlite3_column_blob(pStmt, i); hash_step_vformat(&cx,"B%d:",n2); SHA3Update(&cx, z2, n2); break; } } } } sqlite3_finalize(pStmt); } sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); }
int sqlite3Fts5ConfigSetValue( Fts5Config *pConfig, const char *zKey, sqlite3_value *pVal, int *pbBadkey ){ int rc = SQLITE_OK; if( 0==sqlite3_stricmp(zKey, "pgsz") ){ int pgsz = 0; if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ pgsz = sqlite3_value_int(pVal); } if( pgsz<=0 || pgsz>FTS5_MAX_PAGE_SIZE ){ *pbBadkey = 1; }else{ pConfig->pgsz = pgsz; } } else if( 0==sqlite3_stricmp(zKey, "automerge") ){ int nAutomerge = -1; if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ nAutomerge = sqlite3_value_int(pVal); } if( nAutomerge<0 || nAutomerge>64 ){ *pbBadkey = 1; }else{ if( nAutomerge==1 ) nAutomerge = FTS5_DEFAULT_AUTOMERGE; pConfig->nAutomerge = nAutomerge; } } else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){ int nCrisisMerge = -1; if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ nCrisisMerge = sqlite3_value_int(pVal); } if( nCrisisMerge<0 ){ *pbBadkey = 1; }else{ if( nCrisisMerge<=1 ) nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; pConfig->nCrisisMerge = nCrisisMerge; } } else if( 0==sqlite3_stricmp(zKey, "rank") ){ const char *zIn = (const char*)sqlite3_value_text(pVal); char *zRank; char *zRankArgs; rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs); if( rc==SQLITE_OK ){ sqlite3_free(pConfig->zRank); sqlite3_free(pConfig->zRankArgs); pConfig->zRank = zRank; pConfig->zRankArgs = zRankArgs; }else if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; *pbBadkey = 1; } }else{ *pbBadkey = 1; } return rc; }