gdal icon indicating copy to clipboard operation
gdal copied to clipboard

Fails to read SQL with GDALVectorTranslate

Open latot opened this issue 8 months ago • 5 comments

Hi! I has been trying to run GDALVectorTranslate, I do not know almost nothing of C/C++! so @lnicola has been helping me figure out how to run everything, the next code is not perfect, but there is a very weird error, the tables.

This works:

ogrinfo "PG:dbname=postgres host=localhost port=5432 user=postgres password=postgres" -sql "select * from communes"

Here the code:

use gdal::DriverManager;
use std::ptr::{null, null_mut};

use std::ffi::{CString, c_int};

fn main() -> Result<(), Box<dyn std::error::Error>> {
        let path = std::path::Path::new("tmp.gpkg");
        let _ = std::fs::remove_file(path);
        let drv = DriverManager::get_driver_by_name("GPKG").unwrap();
        let mut ds = drv.create_vector_only(path.to_str().unwrap()).unwrap();
        let org_path = "PG:\"dbname='postgres' host='localhost' port='5432' user='postgres' password='postgres'\"";
        let mut org = gdal::Dataset::open(org_path).unwrap();
        //This do not make any difference on the error
        let opts = gdal::DatasetOptions {
                open_options: Some(&[
                        "DBNAME=postgres",
                        "PORT=4326",
                        "HOST=localhost",
                        "USER=postgres",
                        "PASSWORD=postgres",
                ]),
                ..Default::default()
        };
        let org2 = gdal::Dataset::open_ex(org_path, opts).unwrap();
        let mut org_vc = [org2.c_dataset()];
        let mut pb_usage_error: c_int = 0;
        let mut opts = [
                CString::new("-sql").unwrap(),
                CString::new("select * from some_table").unwrap(),
        ];
        let mut ref_opts = [
                opts[0].clone().into_raw(),
                opts[1].clone().into_raw(),
                null_mut(),
        ];
        unsafe {
                let b = gdal_sys::GDALVectorTranslateOptionsNew(ref_opts.as_mut_ptr(), null_mut());
                gdal_sys::GDALVectorTranslate(
                        null(),
                        ds.c_dataset(),
                        1,
                        org_vc.as_mut_ptr(),
                        b,
                        &mut pb_usage_error,
                );
        }
        Ok(())
}

I have checked in postgres, when this code is executed this is the query that reach the server:

select
  pg_namespace.nspname as schema,
  pg_class.relname as table,
  pg_attribute.attname as column
from pg_class, pg_namespace,pg_attribute, pg_type
where
  pg_class.relnamespace = pg_namespace.oid and
    pg_class.oid = pg_attribute.attrelid and
    pg_attribute.atttypid = pg_type.oid and
    pg_type.typname = 'raster'

Thx!

latot avatar Apr 22 '25 16:04 latot

This works for me:

use gdal::{DriverManager, GdalOpenFlags};
use std::ptr::{null, null_mut};

use std::ffi::c_int;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let path = std::path::Path::new("tmp.gpkg");
    let _ = std::fs::remove_file(path);
    let drv = DriverManager::get_driver_by_name("GPKG")?;
    let ds = drv.create_vector_only(path.to_str().unwrap())?;
    let org_path =
        "PG:dbname='postgres' host='localhost' port='5432' user='postgres' password='postgres'";

    let opts = gdal::DatasetOptions {
        open_flags: GdalOpenFlags::GDAL_OF_VECTOR,
        ..Default::default()
    };
    let org2 = gdal::Dataset::open_ex(org_path, opts)?;
    let mut pb_usage_error: c_int = 0;
    let opts = [c"-sql", c"select * from geometries"];
    let mut ref_opts = [
        opts[0].as_ptr() as *mut _,
        opts[1].as_ptr() as *mut _,
        null_mut(),
    ];
    unsafe {
        let b = gdal_sys::GDALVectorTranslateOptionsNew(ref_opts.as_mut_ptr(), null_mut());
        gdal_sys::GDALVectorTranslate(
            null(),
            ds.c_dataset(),
            1,
            &mut org2.c_dataset(),
            b,
            &mut pb_usage_error,
        );
        gdal_sys::GDALVectorTranslateOptionsFree(b);
    }
    Ok(())
}

I think we should just drop Dataset::open, it's too easy to get wrong.

lnicola avatar Apr 22 '25 20:04 lnicola

yes, also make mandatory specify if is a vector or a raster.

latot avatar Apr 22 '25 20:04 latot

@lnicola I was playing more, and I got the same error with the new version if we add -dialect sqlite...... I'm out of ideas.

latot avatar Apr 23 '25 00:04 latot

I don't understand, doesn't my version work for you? Or do you mean that you're still not getting "error browsing the database for raster tables"?

lnicola avatar Apr 23 '25 05:04 lnicola

the issue seems to be in other place.

latot avatar Apr 23 '25 15:04 latot